From ff8676e0e1f9665a92f44ef7685a7221a451ddc3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 18 Feb 2013 15:41:17 +0100 Subject: [PATCH] MDEV-26: Global transaction ID. Fix initial loading of mysql.rpl_slave_state, the code had several issues. Some very basic MTR stuff, more to come. --- mysql-test/include/check-testcase.test | 1 + mysql-test/mysql-test-run.pl | 5 +- mysql-test/suite/rpl/r/rpl_gtid_basic.result | 48 +++++++++++++++ mysql-test/suite/rpl/t/rpl_gtid_basic.cnf | 24 ++++++++ mysql-test/suite/rpl/t/rpl_gtid_basic.test | 37 +++++++++++ sql/sql_repl.cc | 65 +++++++++++++++++--- 6 files changed, 170 insertions(+), 10 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_gtid_basic.result create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_basic.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_basic.test diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test index 858a89f706c..e9efc6c8907 100644 --- a/mysql-test/include/check-testcase.test +++ b/mysql-test/include/check-testcase.test @@ -60,6 +60,7 @@ if ($tmp) --echo Last_SQL_Error --echo Replicate_Ignore_Server_Ids --echo Master_Server_Id # + --echo Gtid_Pos_Auto 0 } if (!$tmp) { # Note: after WL#5177, fields 13-18 shall not be filtered-out. diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index ac911c5e4e8..1ebcb74593e 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3449,8 +3449,9 @@ sub mysql_install_db { mtr_add_arg($args, "--bootstrap"); mtr_add_arg($args, "--basedir=%s", $install_basedir); mtr_add_arg($args, "--datadir=%s", $install_datadir); - mtr_add_arg($args, "--default-storage-engine=myisam"); - mtr_add_arg($args, "--skip-$_") for @optional_plugins; + mtr_add_arg($args, "--innodb"); + mtr_add_arg($args, "--default-storage-engine=innodb"); + mtr_add_arg($args, "--skip-$_") for grep (!/^innodb/, @optional_plugins); mtr_add_arg($args, "--disable-sync-frm"); mtr_add_arg($args, "--tmpdir=%s", "$opt_vardir/tmp/"); mtr_add_arg($args, "--core-file"); diff --git a/mysql-test/suite/rpl/r/rpl_gtid_basic.result b/mysql-test/suite/rpl/r/rpl_gtid_basic.result new file mode 100644 index 00000000000..11de46c7e23 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_gtid_basic.result @@ -0,0 +1,48 @@ +include/rpl_init.inc [topology=1->2->3->4] +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(10)) ENGINE=MyISAM; +CREATE TABLE t2 (a INT PRIMARY KEY, b VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, "m1"); +INSERT INTO t1 VALUES (2, "m2"), (3, "m3"), (4, "m4"); +INSERT INTO t2 VALUES (1, "i1"); +BEGIN; +INSERT INTO t2 VALUES (2, "i2"), (3, "i3"); +INSERT INTO t2 VALUES (4, "i4"); +COMMIT; +SELECT * FROM t1 ORDER BY a; +a b +1 m1 +2 m2 +3 m3 +4 m4 +SELECT * FROM t2 ORDER BY a; +a b +1 i1 +2 i2 +3 i3 +4 i4 +SELECT * FROM t1 ORDER BY a; +a b +1 m1 +2 m2 +3 m3 +4 m4 +SELECT * FROM t2 ORDER BY a; +a b +1 i1 +2 i2 +3 i3 +4 i4 +SELECT * FROM t1 ORDER BY a; +a b +1 m1 +2 m2 +3 m3 +4 m4 +SELECT * FROM t2 ORDER BY a; +a b +1 i1 +2 i2 +3 i3 +4 i4 +DROP TABLE t1,t2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_basic.cnf b/mysql-test/suite/rpl/t/rpl_gtid_basic.cnf new file mode 100644 index 00000000000..3ff94e458ce --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_basic.cnf @@ -0,0 +1,24 @@ +!include ../my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb + +[mysqld.3] +log-slave-updates +loose-innodb + +[mysqld.4] +log-slave-updates +loose-innodb + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket + +SERVER_MYPORT_4= @mysqld.4.port +SERVER_MYSOCK_4= @mysqld.4.socket diff --git a/mysql-test/suite/rpl/t/rpl_gtid_basic.test b/mysql-test/suite/rpl/t/rpl_gtid_basic.test new file mode 100644 index 00000000000..791d093b9a0 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_basic.test @@ -0,0 +1,37 @@ +--source include/have_innodb.inc +--let $rpl_topology=1->2->3->4 +--source include/rpl_init.inc + +connection server_1; +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(10)) ENGINE=MyISAM; +CREATE TABLE t2 (a INT PRIMARY KEY, b VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, "m1"); +INSERT INTO t1 VALUES (2, "m2"), (3, "m3"), (4, "m4"); +INSERT INTO t2 VALUES (1, "i1"); +BEGIN; +INSERT INTO t2 VALUES (2, "i2"), (3, "i3"); +INSERT INTO t2 VALUES (4, "i4"); +COMMIT; +save_master_pos; + +connection server_2; +sync_with_master; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +save_master_pos; + +connection server_3; +sync_with_master; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +save_master_pos; + +connection server_4; +sync_with_master; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +connection server_1; +DROP TABLE t1,t2; + +--source include/rpl_end.inc diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index bd491b17e7c..46e27abd7f5 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -3035,11 +3035,21 @@ rpl_load_gtid_slave_state(THD *thd) TABLE *table; bool table_opened= false; bool table_scanned= false; + struct local_element { uint64 sub_id; rpl_gtid gtid; }; + struct local_element *entry; + HASH hash; + int err= 0; + uint32 i; DBUG_ENTER("rpl_load_gtid_slave_state"); - int err= 0; + my_hash_init(&hash, &my_charset_bin, 32, + offsetof(local_element, gtid) + offsetof(rpl_gtid, domain_id), + sizeof(uint32), NULL, my_free, HASH_UNIQUE); + rpl_global_gtid_slave_state.lock(); - if (rpl_global_gtid_slave_state.loaded) + bool loaded= rpl_global_gtid_slave_state.loaded; + rpl_global_gtid_slave_state.unlock(); + if (loaded) goto end; mysql_reset_thd_for_next_command(thd, 0); @@ -3069,6 +3079,8 @@ rpl_load_gtid_slave_state(THD *thd) { uint32 domain_id, server_id; uint64 sub_id, seq_no; + uchar *rec; + if ((err= table->file->ha_rnd_next(table->record[0]))) { if (err == HA_ERR_RECORD_DELETED) @@ -3085,13 +3097,50 @@ rpl_load_gtid_slave_state(THD *thd) DBUG_PRINT("info", ("Read slave state row: %u:%u-%lu sub_id=%lu\n", (unsigned)domain_id, (unsigned)server_id, (ulong)seq_no, (ulong)sub_id)); - if ((err= rpl_global_gtid_slave_state.update(domain_id, server_id, - sub_id, seq_no))) - goto end; - } - err= 0; /* Clear HA_ERR_END_OF_FILE */ + if ((rec= my_hash_search(&hash, (const uchar *)&domain_id, 0))) + { + entry= (struct local_element *)rec; + if (entry->sub_id >= sub_id) + continue; + } + else + { + if (!(entry= (struct local_element *)my_malloc(sizeof(*entry), + MYF(MY_WME)))) + { + err= 1; + goto end; + } + if ((err= my_hash_insert(&hash, (uchar *)entry))) + { + my_free(entry); + goto end; + } + } + entry->sub_id= sub_id; + entry->gtid.domain_id= domain_id; + entry->gtid.server_id= server_id; + entry->gtid.seq_no= seq_no; + } + + rpl_global_gtid_slave_state.lock(); + for (i= 0; i < hash.records; ++i) + { + entry= (struct local_element *)my_hash_element(&hash, i); + if ((err= rpl_global_gtid_slave_state.update(entry->gtid.domain_id, + entry->gtid.server_id, + entry->sub_id, + entry->gtid.seq_no))) + { + rpl_global_gtid_slave_state.unlock(); + goto end; + } + } rpl_global_gtid_slave_state.loaded= true; + rpl_global_gtid_slave_state.unlock(); + + err= 0; /* Clear HA_ERR_END_OF_FILE */ end: if (table_scanned) @@ -3102,7 +3151,7 @@ end: } if (table_opened) close_thread_tables(thd); - rpl_global_gtid_slave_state.unlock(); + my_hash_free(&hash); DBUG_RETURN(err); }