diff options
52 files changed, 1053 insertions, 476 deletions
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index e00ce9e5d6f..903b2f220c0 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -21,8 +21,6 @@ MW-329 : MDEV-19962 Galera test failure on MW-329 MW-360 : needs rewrite to be MariaDB gtid compatible galera.galera_defaults : MDEV-21494 Galera test sporadic failure on galera.galera_defaults galera_account_management : MariaDB 10.0 does not support ALTER USER -galera_as_master_gtid : Requires MySQL GTID -galera_as_master_gtid_change_master : Requires MySQL GTID galera_as_slave_gtid_myisam : MDEV-21421 galera.galera_as_slave_gtid_myisam galera_as_slave_gtid_replicate_do_db_cc : Requires MySQL GTID galera_as_slave_preordered : wsrep-preordered feature not merged to MariaDB diff --git a/mysql-test/suite/galera/r/MDEV-10715.result b/mysql-test/suite/galera/r/MDEV-10715.result new file mode 100644 index 00000000000..5ab60f08097 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-10715.result @@ -0,0 +1,28 @@ +connection node_2; +connection node_1; +connection node_1; +create table t1(a int); +set @@wsrep_gtid_seq_no=22; +insert into t1 values(1); +insert into t1 values(2); +select @@gtid_binlog_state; +@@gtid_binlog_state +1-1-23 +select wsrep_last_seen_gtid(); +wsrep_last_seen_gtid() +1-1-23 +select wsrep_last_written_gtid(); +wsrep_last_written_gtid() +1-1-23 +connection node_2; +select @@gtid_binlog_state; +@@gtid_binlog_state +1-1-23 +select wsrep_last_seen_gtid(); +wsrep_last_seen_gtid() +1-1-23 +select wsrep_last_written_gtid(); +wsrep_last_written_gtid() +1-1-0 +connection node_1; +drop table t1; diff --git a/mysql-test/suite/galera/r/galera_as_master_gtid.result b/mysql-test/suite/galera/r/galera_as_master_gtid.result index 4f5c38b607a..51337321712 100644 --- a/mysql-test/suite/galera/r/galera_as_master_gtid.result +++ b/mysql-test/suite/galera/r/galera_as_master_gtid.result @@ -1,22 +1,28 @@ -START SLAVE USER='root'; -Warnings: -Note 1759 Sending passwords in plain text without SSL/TLS is extremely insecure. +connection node_2; +connection node_1; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +START SLAVE; +connection node_1; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; INSERT INTO t1 VALUES(1); -uuids_do_not_match -1 +SELECT @@global.gtid_binlog_pos; +@@global.gtid_binlog_pos +100-1-2 +connection node_2; INSERT INTO t1 VALUES(2); -uuids_do_not_match -1 -uuids_match -1 -uuids_do_not_match +gtid_do_not_match 1 -uuids_match +connection node_3; +gtid_do_not_match 1 +connection node_1; DROP TABLE t1; +connection node_3; +connection node_1; +connection node_2; gtid_executed_equal 1 +connection node_3; gtid_executed_equal 1 STOP SLAVE; diff --git a/mysql-test/suite/galera/r/galera_as_master_gtid_change_master.result b/mysql-test/suite/galera/r/galera_as_master_gtid_change_master.result index 80fbccf58e2..38040fbe9d7 100644 --- a/mysql-test/suite/galera/r/galera_as_master_gtid_change_master.result +++ b/mysql-test/suite/galera/r/galera_as_master_gtid_change_master.result @@ -1,15 +1,31 @@ -START SLAVE USER='root'; -Warnings: -Note 1759 Sending passwords in plain text without SSL/TLS is extremely insecure. +connection node_2; +connection node_1; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +START SLAVE; +connection node_1; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; INSERT INTO t1 VALUES(1); +connection node_2; INSERT INTO t1 VALUES(2); +connection node_3; STOP SLAVE; -START SLAVE USER='root'; -Warnings: -Note 1759 Sending passwords in plain text without SSL/TLS is extremely insecure. +START SLAVE; +connection node_1; INSERT INTO t1 VALUES(3); +connection node_2; INSERT INTO t1 VALUES(4); +connection node_3; +connection node_1; DROP TABLE t1; +connection node_3; STOP SLAVE; RESET SLAVE ALL; +RESET MASTER; +connection node_2; +SET GLOBAL wsrep_on=OFF; +RESET MASTER; +SET GLOBAL wsrep_on=ON; +connection node_1; +SET GLOBAL wsrep_on=OFF; +RESET MASTER; +SET GLOBAL wsrep_on=ON; diff --git a/mysql-test/suite/galera/r/galera_as_slave_gtid_replicate_do_db.result b/mysql-test/suite/galera/r/galera_as_slave_gtid_replicate_do_db.result index 9589d319991..afe30250811 100644 --- a/mysql-test/suite/galera/r/galera_as_slave_gtid_replicate_do_db.result +++ b/mysql-test/suite/galera/r/galera_as_slave_gtid_replicate_do_db.result @@ -97,34 +97,34 @@ master-bin.000001 256 Gtid_list 1 285 [] master-bin.000001 285 Binlog_checkpoint 1 329 master-bin.000001 master-bin.000001 329 Gtid 3 371 GTID 0-3-1 master-bin.000001 371 Query 3 458 CREATE SCHEMA test1 -master-bin.000001 458 Gtid 3 500 GTID 0-3-2 +master-bin.000001 458 Gtid 3 500 GTID 0-3-3 master-bin.000001 500 Query 3 647 use `test1`; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY,f2 CHAR(5) DEFAULT 'abc') ENGINE=InnoDB -master-bin.000001 647 Gtid 3 689 BEGIN GTID 0-3-3 +master-bin.000001 647 Gtid 3 689 BEGIN GTID 0-3-5 master-bin.000001 689 Annotate_rows 3 748 INSERT INTO test1.t1 (f1) VALUES (1) master-bin.000001 748 Table_map 3 797 table_id: ### (test1.t1) master-bin.000001 797 Write_rows_v1 3 839 table_id: ### flags: STMT_END_F master-bin.000001 839 Xid 3 870 COMMIT /* xid=### */ -master-bin.000001 870 Gtid 3 912 BEGIN GTID 0-3-4 +master-bin.000001 870 Gtid 3 912 BEGIN GTID 0-3-7 master-bin.000001 912 Annotate_rows 3 971 INSERT INTO test1.t1 (f1) VALUES (2) master-bin.000001 971 Table_map 3 1020 table_id: ### (test1.t1) master-bin.000001 1020 Write_rows_v1 3 1062 table_id: ### flags: STMT_END_F master-bin.000001 1062 Xid 3 1093 COMMIT /* xid=### */ -master-bin.000001 1093 Gtid 3 1135 BEGIN GTID 0-3-5 +master-bin.000001 1093 Gtid 3 1135 BEGIN GTID 0-3-9 master-bin.000001 1135 Annotate_rows 3 1194 INSERT INTO test1.t1 (f1) VALUES (3) master-bin.000001 1194 Table_map 3 1243 table_id: ### (test1.t1) master-bin.000001 1243 Write_rows_v1 3 1285 table_id: ### flags: STMT_END_F master-bin.000001 1285 Xid 3 1316 COMMIT /* xid=### */ -master-bin.000001 1316 Gtid 3 1358 BEGIN GTID 0-3-6 +master-bin.000001 1316 Gtid 3 1358 BEGIN GTID 0-3-12 master-bin.000001 1358 Annotate_rows 3 1451 UPDATE test1.t1, test2.t1 SET test1.t1.f2 = 'klm', test2.t1.f2 = 'xyz' master-bin.000001 1451 Table_map 3 1500 table_id: ### (test1.t1) master-bin.000001 1500 Update_rows_v1 3 1588 table_id: ### flags: STMT_END_F master-bin.000001 1588 Xid 3 1619 COMMIT /* xid=### */ -master-bin.000001 1619 Gtid 3 1661 BEGIN GTID 0-3-7 +master-bin.000001 1619 Gtid 3 1661 BEGIN GTID 0-3-13 master-bin.000001 1661 Annotate_rows 3 1795 DELETE test1.t1, test2.t1 FROM test1.t1 INNER JOIN test2.t1 WHERE test1.t1.f1 = test2.t1.f1 AND test1.t1.f1 = 3 master-bin.000001 1795 Table_map 3 1844 table_id: ### (test1.t1) master-bin.000001 1844 Delete_rows_v1 3 1886 table_id: ### flags: STMT_END_F master-bin.000001 1886 Xid 3 1917 COMMIT /* xid=### */ -master-bin.000001 1917 Gtid 3 1959 BEGIN GTID 0-3-8 +master-bin.000001 1917 Gtid 3 1959 BEGIN GTID 0-3-15 master-bin.000001 1959 Annotate_rows 3 2020 INSERT INTO test1.t1 (f1) VALUES (111) master-bin.000001 2020 Table_map 3 2069 table_id: ### (test1.t1) master-bin.000001 2069 Write_rows_v1 3 2111 table_id: ### flags: STMT_END_F @@ -132,7 +132,7 @@ master-bin.000001 2111 Annotate_rows 3 2172 INSERT INTO test1.t1 (f1) VALUES (22 master-bin.000001 2172 Table_map 3 2221 table_id: ### (test1.t1) master-bin.000001 2221 Write_rows_v1 3 2263 table_id: ### flags: STMT_END_F master-bin.000001 2263 Xid 3 2294 COMMIT /* xid=### */ -master-bin.000001 2294 Gtid 3 2336 BEGIN GTID 0-3-9 +master-bin.000001 2294 Gtid 3 2336 BEGIN GTID <effective_uuid> master-bin.000001 2336 Annotate_rows 3 2397 INSERT INTO test1.t1 (f1) VALUES (333) master-bin.000001 2397 Table_map 3 2446 table_id: ### (test1.t1) master-bin.000001 2446 Write_rows_v1 3 2488 table_id: ### flags: STMT_END_F @@ -157,3 +157,12 @@ connection node_1; connection node_2; STOP SLAVE; RESET SLAVE ALL; +SET GLOBAL wsrep_on=OFF; +RESET MASTER; +SET GLOBAL wsrep_on=ON; +connection node_1; +SET GLOBAL wsrep_on=OFF; +RESET MASTER; +SET GLOBAL wsrep_on=ON; +connection node_3; +RESET MASTER; diff --git a/mysql-test/suite/galera/r/galera_gra_log.result b/mysql-test/suite/galera/r/galera_gra_log.result index 3b133b2732e..a6dca500719 100644 --- a/mysql-test/suite/galera/r/galera_gra_log.result +++ b/mysql-test/suite/galera/r/galera_gra_log.result @@ -1,5 +1,7 @@ connection node_2; connection node_1; +connection node_1; +connection node_2; connection node_2; SET GLOBAL wsrep_ignore_apply_errors=0; SET SESSION wsrep_on=OFF; diff --git a/mysql-test/suite/galera/r/galera_gtid_slave.result b/mysql-test/suite/galera/r/galera_gtid_slave.result index 7a3048231af..1ff062064e7 100644 --- a/mysql-test/suite/galera/r/galera_gtid_slave.result +++ b/mysql-test/suite/galera/r/galera_gtid_slave.result @@ -19,12 +19,12 @@ INSERT INTO t1 VALUES(2); INSERT INTO t1 VALUES(3); SELECT @@global.gtid_binlog_state; @@global.gtid_binlog_state -0-2-2,2-3-4 +1-1-2,2-3-4 connection node_1; INSERT INTO t1 VALUES(4); SELECT @@global.gtid_binlog_state; @@global.gtid_binlog_state -1-1-1,2-3-4,2-2-6 +1-1-3,2-3-4 connection node_3; DROP TABLE t1,t2; connection node_2; diff --git a/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result b/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result index 7c5519af495..992f6c3455b 100644 --- a/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result +++ b/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result @@ -25,14 +25,14 @@ INSERT INTO t2 VALUES(5,55); INSERT INTO t2 VALUES(6,66); SELECT @@global.gtid_binlog_state; @@global.gtid_binlog_state -0-2-3,2-3-4 +1-1-3,2-3-4 #Connection 1 connection node_1; INSERT INTO t2 VALUES(7,77); INSERT INTO t2 VALUES(8,88); SELECT @@global.gtid_binlog_state; @@global.gtid_binlog_state -1-1-2,2-3-4,2-2-7 +1-1-5,2-3-4 #Connection 3 connection node_3; CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; @@ -100,12 +100,12 @@ node2_committed_before connection node_1; SELECT @@global.gtid_binlog_state; @@global.gtid_binlog_state -1-1-3,2-3-6,2-2-9 +1-1-8,2-3-6 #Connection 2 connection node_2; SELECT @@global.gtid_binlog_state; @@global.gtid_binlog_state -0-1-7,0-2-8,2-3-6 +1-1-8,2-3-6 #Connection 3 connection node_3; SET AUTOCOMMIT=ON; @@ -134,7 +134,7 @@ count(*) 12 SELECT @@global.gtid_binlog_state; @@global.gtid_binlog_state -0-1-7,0-2-11,2-3-7 +1-1-11,2-3-7 #Connection 1 connection node_1; SELECT count(*) from t1; @@ -142,7 +142,7 @@ count(*) 12 SELECT @@global.gtid_binlog_state; @@global.gtid_binlog_state -1-1-3,2-3-7,2-2-12 +1-1-11,2-3-7 #Connection 3 connection node_3; DROP TABLE t2,t1; diff --git a/mysql-test/suite/galera/r/galera_gtid_trx_conflict.result b/mysql-test/suite/galera/r/galera_gtid_trx_conflict.result new file mode 100644 index 00000000000..dcabff40841 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_gtid_trx_conflict.result @@ -0,0 +1,44 @@ +connection node_2; +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; +connection node_1; +SET AUTOCOMMIT = OFF; +START TRANSACTION; +INSERT INTO t1 VALUES(1); +connection node_2; +SET AUTOCOMMIT = OFF; +SET @@wsrep_gtid_seq_no = 100; +START TRANSACTION; +INSERT INTO t1 VALUES(1); +connection node_1; +COMMIT; +connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; +connection node_2a; +connection node_2; +COMMIT; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +# Expected GTID value 1-1-2 on both nodes +SELECT @@gtid_binlog_state; +@@gtid_binlog_state +1-1-2 +SET AUTOCOMMIT = ON; +INSERT INTO t1 VALUES(2); +# Expected GTID value 1-1-100 on both nodes, seqno is set with wsrep_gtid_seq_no +SELECT @@gtid_binlog_state; +@@gtid_binlog_state +1-1-100 +connection node_1; +SELECT @@gtid_binlog_state; +@@gtid_binlog_state +1-1-100 +SET AUTOCOMMIT = ON; +INSERT INTO t1 VALUES(3); +# Expected GTID value 1-1-101 on both nodes +SELECT @@gtid_binlog_state; +@@gtid_binlog_state +1-1-101 +connection node_2; +SELECT @@gtid_binlog_state; +@@gtid_binlog_state +1-1-101 +DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_last_committed_id.result b/mysql-test/suite/galera/r/galera_last_committed_id.result index fabc5337576..eadf49d7ce0 100644 --- a/mysql-test/suite/galera/r/galera_last_committed_id.result +++ b/mysql-test/suite/galera/r/galera_last_committed_id.result @@ -1,38 +1,35 @@ connection node_2; connection node_1; -SELECT WSREP_LAST_WRITTEN_GTID() = '00000000-0000-0000-0000-000000000000:-1'; -WSREP_LAST_WRITTEN_GTID() = '00000000-0000-0000-0000-000000000000:-1' -1 -wsrep_last_committed_id_match -1 -connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; -connection node_1a; +SELECT WSREP_LAST_WRITTEN_GTID(); +WSREP_LAST_WRITTEN_GTID() +100-1-0 +connection node_1; CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); -connection node_1; -SELECT WSREP_LAST_WRITTEN_GTID() = '00000000-0000-0000-0000-000000000000:-1'; -WSREP_LAST_WRITTEN_GTID() = '00000000-0000-0000-0000-000000000000:-1' -1 +connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;; connection node_1a; -INSERT INTO t1 VALUES (1); +SELECT WSREP_LAST_WRITTEN_GTID() != '100-1-2' AS wsrep_written_does_not_match_different_conn; +wsrep_written_does_not_match_different_conn +1 +connection node_2; +SELECT WSREP_LAST_WRITTEN_GTID() != '100-1-2' AS wsrep_written_does_not_match_different_nodes; +wsrep_written_does_not_match_different_nodes +1 connection node_1; -wsrep_last_committed_id_match +INSERT INTO t1 VALUES (1); +connection node_2; +wsrep_last_written_seen_id_match 1 +connection node_1; SET AUTOCOMMIT=OFF; START TRANSACTION; -SELECT WSREP_LAST_WRITTEN_GTID() = '00000000-0000-0000-0000-000000000000:-1'; -WSREP_LAST_WRITTEN_GTID() = '00000000-0000-0000-0000-000000000000:-1' -1 INSERT INTO t1 VALUES (1); -SELECT WSREP_LAST_WRITTEN_GTID() = '00000000-0000-0000-0000-000000000000:-1'; -WSREP_LAST_WRITTEN_GTID() = '00000000-0000-0000-0000-000000000000:-1' +WSREP_LAST_SEEN_GTID() = '100-1-3' 1 -wsrep_last_committed_id_match +wsrep_last_written_id_match 1 COMMIT; -wsrep_last_committed_id_advanced -1 -wsrep_last_committed_id_advanced +wsrep_last_written_id_advanced 1 SET AUTOCOMMIT=ON; DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_performance_schema.result b/mysql-test/suite/galera/r/galera_performance_schema.result index b40dcb0de60..8c99669c6aa 100644 --- a/mysql-test/suite/galera/r/galera_performance_schema.result +++ b/mysql-test/suite/galera/r/galera_performance_schema.result @@ -17,6 +17,7 @@ name wait/synch/mutex/sql/LOCK_wsrep_config_state name wait/synch/mutex/sql/LOCK_wsrep_desync name wait/synch/mutex/sql/LOCK_wsrep_donor_monitor name wait/synch/mutex/sql/LOCK_wsrep_group_commit +name wait/synch/mutex/sql/LOCK_wsrep_gtid_wait_upto name wait/synch/mutex/sql/LOCK_wsrep_joiner_monitor name wait/synch/mutex/sql/LOCK_wsrep_ready name wait/synch/mutex/sql/LOCK_wsrep_replaying diff --git a/mysql-test/suite/galera/r/galera_sync_wait_upto.result b/mysql-test/suite/galera/r/galera_sync_wait_upto.result index 7d691e105da..86c1f80f081 100644 --- a/mysql-test/suite/galera/r/galera_sync_wait_upto.result +++ b/mysql-test/suite/galera/r/galera_sync_wait_upto.result @@ -5,39 +5,22 @@ INSERT INTO t1 VALUES (1); SELECT WSREP_SYNC_WAIT_UPTO_GTID(NULL); ERROR HY000: Incorrect arguments to wsrep_sync_wait_upto_gtid SELECT WSREP_SYNC_WAIT_UPTO_GTID('a'); -ERROR HY000: Incorrect arguments to wsrep_sync_wait_upto_gtid +ERROR HY000: Could not parse GTID list SELECT WSREP_SYNC_WAIT_UPTO_GTID(2); +ERROR HY000: Could not parse GTID list +SELECT WSREP_SYNC_WAIT_UPTO_GTID('1-1-1,1-1-2'); ERROR HY000: Incorrect arguments to wsrep_sync_wait_upto_gtid WSREP_SYNC_WAIT_UPTO 1 WSREP_SYNC_WAIT_UPTO 1 -WSREP_SYNC_WAIT_UPTO -1 ERROR HY000: Lock wait timeout exceeded; try restarting transaction connection node_2; -SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; +SELECT WSREP_SYNC_WAIT_UPTO_GTID('100-1-3'); connection node_1; INSERT INTO t1 VALUES (2); -INSERT INTO t1 VALUES (3); -connection node_2; -SET SESSION wsrep_sync_wait = 0; -ERROR HY000: Lock wait timeout exceeded; try restarting transaction -connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; -connection node_2a; -SET SESSION wsrep_sync_wait = 0; -SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb"; connection node_2; -WSREP_SYNC_WAIT_UPTO -1 -gtid_current = gtid_first -1 -SET GLOBAL DEBUG_DBUG = ""; -SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb"; -WSREP_SYNC_WAIT_UPTO -1 -seqno_current = seqno_second +WSREP_SYNC_WAIT_UPTO_GTID('100-1-3') 1 -SET DEBUG_SYNC = "RESET"; connection node_1; DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/MDEV-10715.cnf b/mysql-test/suite/galera/t/MDEV-10715.cnf new file mode 100644 index 00000000000..589514466ed --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-10715.cnf @@ -0,0 +1,14 @@ +!include ../galera_2nodes.cnf + +[mysqld] +log-bin=mysqld-bin +log-slave-updates +binlog-format=ROW +[mysqld.1] +gtid-domain-id=1 +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=1 +[mysqld.2] +gtid-domain-id=1 +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=1
\ No newline at end of file diff --git a/mysql-test/suite/galera/t/MDEV-10715.test b/mysql-test/suite/galera/t/MDEV-10715.test new file mode 100644 index 00000000000..186320589c3 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-10715.test @@ -0,0 +1,19 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--connection node_1 +create table t1(a int); +set @@wsrep_gtid_seq_no=22; +insert into t1 values(1); +insert into t1 values(2); +select @@gtid_binlog_state; +select wsrep_last_seen_gtid(); +select wsrep_last_written_gtid(); + +--connection node_2 +select @@gtid_binlog_state; +select wsrep_last_seen_gtid(); +select wsrep_last_written_gtid(); + +--connection node_1 +drop table t1; diff --git a/mysql-test/suite/galera/t/MDEV-16509.test b/mysql-test/suite/galera/t/MDEV-16509.test index dddd8ede293..da79cdc7d4c 100644 --- a/mysql-test/suite/galera/t/MDEV-16509.test +++ b/mysql-test/suite/galera/t/MDEV-16509.test @@ -15,14 +15,13 @@ CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB; # Scenario 1: Block INSERT after commit order release after queued for # group commit. Verify that # -# - WSREP_LAST_SEEN_GTID is not advanced before commit finishes +# - wsrep_last_committed is not advanced before commit finishes # - The INSERT does not become visible before commit finishes -# Turn off sync wait to avoid blocking and use WSREP_LAST_SEEN_GTID() +# Turn off sync wait to avoid blocking and use wsrep_last_committed # to observe gtid position. SET SESSION wsrep_sync_wait = 0; ---let $last_seen_gtid_prev = `SELECT WSREP_LAST_SEEN_GTID()` - +--let $last_seen_gtid_prev = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'` --connection node_1 SET SESSION wsrep_sync_wait = 0; # Set up sync points @@ -37,7 +36,7 @@ SET DEBUG_SYNC = "after_group_after_commit SIGNAL after_group_reached WAIT_FOR a # committed in memory. SET DEBUG_SYNC = "now WAIT_FOR bcol_reached"; --disable_query_log ---eval SELECT WSREP_LAST_SEEN_GTID() = '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_match +--eval SELECT VARIABLE_VALUE = '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_match FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed' --enable_query_log SELECT * FROM t1; SET DEBUG_SYNC = "now SIGNAL bcol_continue"; @@ -45,14 +44,14 @@ SET DEBUG_SYNC = "now SIGNAL bcol_continue"; # SE commit finished but wsrep_after_commit() has not called yet. SET DEBUG_SYNC = "now WAIT_FOR acol_reached"; --disable_query_log ---eval SELECT WSREP_LAST_SEEN_GTID() = '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_match +--eval SELECT VARIABLE_VALUE = '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_match FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed' --enable_query_log SELECT * FROM t1; SET DEBUG_SYNC = "now SIGNAL acol_continue"; SET DEBUG_SYNC = "now WAIT_FOR after_group_reached"; --disable_query_log ---eval SELECT WSREP_LAST_SEEN_GTID() != '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_do_not_match +--eval SELECT VARIABLE_VALUE != '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_do_not_match FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed' --enable_query_log SET DEBUG_SYNC = "now SIGNAL after_group_continue"; @@ -69,7 +68,7 @@ SET DEBUG_SYNC = "now SIGNAL after_group_continue"; SET SESSION wsrep_sync_wait = 0; --connection ctrl ---let $last_seen_gtid_prev = `SELECT WSREP_LAST_SEEN_GTID()` +--let $last_seen_gtid_prev = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'` --connection node_1 SET DEBUG_SYNC = "wsrep_before_commit_order_leave SIGNAL bcol_reached_1 WAIT_FOR bcol_continue_1"; @@ -80,7 +79,7 @@ SET DEBUG_SYNC = "after_group_after_commit SIGNAL agac_reached_1 WAIT_FOR agac_c SET DEBUG_SYNC = "now WAIT_FOR bcol_reached_1"; --disable_query_log ---eval SELECT WSREP_LAST_SEEN_GTID() = '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_match +--eval SELECT VARIABLE_VALUE = '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_match FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed' --enable_query_log --connection node_1a @@ -97,14 +96,14 @@ SET DEBUG_SYNC = "now WAIT_FOR acol_reached_1"; SET DEBUG_SYNC = "now WAIT_FOR bcol_reached_2"; --disable_query_log ---eval SELECT WSREP_LAST_SEEN_GTID() = '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_match +--eval SELECT VARIABLE_VALUE = '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_match FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed' --enable_query_log SET DEBUG_SYNC = "now SIGNAL bcol_continue_2"; SET DEBUG_SYNC = "now WAIT_FOR acol_reached_2"; --disable_query_log ---eval SELECT WSREP_LAST_SEEN_GTID() = '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_match +--eval SELECT VARIABLE_VALUE = '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_match FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed' --enable_query_log # Last seen GTIDs are incremented one by one once after_group_after_commit @@ -113,14 +112,14 @@ SET DEBUG_SYNC = "now SIGNAL acol_continue_1"; SET DEBUG_SYNC = "now WAIT_FOR agac_reached_1"; --disable_query_log ---eval SELECT WSREP_LAST_SEEN_GTID() != '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_no_match +--eval SELECT VARIABLE_VALUE != '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_no_match FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed' --enable_query_log ---let $last_seen_gtid_prev = `SELECT WSREP_LAST_SEEN_GTID()` +--let $last_seen_gtid_prev = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'` SET DEBUG_SYNC = "now SIGNAL acol_continue_2"; SET DEBUG_SYNC = "now WAIT_FOR agac_reached_2"; --disable_query_log ---eval SELECT WSREP_LAST_SEEN_GTID() != '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_no_match +--eval SELECT VARIABLE_VALUE != '$last_seen_gtid_prev' AS wsrep_last_seen_gtid_no_match FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed' --enable_query_log SET DEBUG_SYNC = "now SIGNAL agac_continue_1"; diff --git a/mysql-test/suite/galera/t/galera_as_master_gtid.cnf b/mysql-test/suite/galera/t/galera_as_master_gtid.cnf index 75caba5420a..53d8b5e59dd 100644 --- a/mysql-test/suite/galera/t/galera_as_master_gtid.cnf +++ b/mysql-test/suite/galera/t/galera_as_master_gtid.cnf @@ -4,3 +4,12 @@ log-bin=mysqld-bin log-slave-updates binlog-format=ROW +[mysqld.1] +gtid-domain-id=1 +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=100 +[mysqld.2] +gtid-domain-id=1 +wsrep_gtid_mode=1 +[mysqld.3] +gtid-domain-id=2
\ No newline at end of file diff --git a/mysql-test/suite/galera/t/galera_as_master_gtid.test b/mysql-test/suite/galera/t/galera_as_master_gtid.test index 9be065e448b..3ddccf94da1 100644 --- a/mysql-test/suite/galera/t/galera_as_master_gtid.test +++ b/mysql-test/suite/galera/t/galera_as_master_gtid.test @@ -14,25 +14,22 @@ --connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 --disable_query_log ---eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$NODE_MYPORT_1; +--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_1; --enable_query_log -START SLAVE USER='root'; +START SLAVE; --connection node_1 CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; INSERT INTO t1 VALUES(1); ---let $effective_uuid = `SELECT LEFT(@@global.gtid_executed, 36)` ---disable_query_log ---eval SELECT '$effective_uuid' != @@global.server_uuid AS uuids_do_not_match; ---enable_query_log +SELECT @@global.gtid_binlog_pos; +--let $effective_gtid = @@global.gtid_binlog_pos --connection node_2 INSERT INTO t1 VALUES(2); --disable_query_log ---eval SELECT '$effective_uuid' != @@global.server_uuid AS uuids_do_not_match; ---eval SELECT '$effective_uuid' = LEFT(@@global.gtid_executed, 36) AS uuids_match; +--eval SELECT '$effective_gtid' != @@global.gtid_binlog_pos AS gtid_do_not_match; --enable_query_log --connection node_3 @@ -43,8 +40,7 @@ INSERT INTO t1 VALUES(2); --source include/wait_condition.inc --disable_query_log ---eval SELECT '$effective_uuid' != @@global.server_uuid AS uuids_do_not_match; ---eval SELECT '$effective_uuid' = LEFT(@@global.gtid_executed, 36) AS uuids_match; +--eval SELECT '$effective_gtid' != @@global.gtid_binlog_pos AS gtid_do_not_match; --enable_query_log --connection node_1 @@ -55,15 +51,14 @@ DROP TABLE t1; --source include/wait_condition.inc --connection node_1 ---let $gtid_executed_node1 = `SELECT @@global.gtid_executed;` - +--let $gtid_executed_node1 = `SELECT @@global.gtid_binlog_pos;` --connection node_2 --disable_query_log ---eval SELECT '$gtid_executed_node1' = @@global.gtid_executed AS gtid_executed_equal +--eval SELECT '$gtid_executed_node1' = @@global.gtid_binlog_pos AS gtid_executed_equal --enable_query_log --connection node_3 --disable_query_log ---eval SELECT '$gtid_executed_node1' = @@global.gtid_executed AS gtid_executed_equal +--eval SELECT '$gtid_executed_node1' = @@global.gtid_binlog_pos AS gtid_executed_equal --enable_query_log STOP SLAVE; diff --git a/mysql-test/suite/galera/t/galera_as_master_gtid_change_master.test b/mysql-test/suite/galera/t/galera_as_master_gtid_change_master.test index 61c7eed6543..e67456dddaf 100644 --- a/mysql-test/suite/galera/t/galera_as_master_gtid_change_master.test +++ b/mysql-test/suite/galera/t/galera_as_master_gtid_change_master.test @@ -12,9 +12,9 @@ --connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 --disable_query_log ---eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$NODE_MYPORT_1; +--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_1; --enable_query_log -START SLAVE USER='root'; +START SLAVE; --connection node_1 CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; @@ -28,9 +28,9 @@ INSERT INTO t1 VALUES(2); --source include/wait_condition.inc STOP SLAVE; --disable_query_log ---eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$NODE_MYPORT_2, MASTER_AUTO_POSITION=1; +--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$NODE_MYPORT_2, MASTER_USER='root'; --enable_query_log -START SLAVE USER='root'; +START SLAVE; --connection node_1 INSERT INTO t1 VALUES(3); @@ -54,3 +54,14 @@ DROP TABLE t1; STOP SLAVE; RESET SLAVE ALL; +RESET MASTER; + +--connection node_2 +SET GLOBAL wsrep_on=OFF; +RESET MASTER; +SET GLOBAL wsrep_on=ON; + +--connection node_1 +SET GLOBAL wsrep_on=OFF; +RESET MASTER; +SET GLOBAL wsrep_on=ON; diff --git a/mysql-test/suite/galera/t/galera_as_slave_gtid_replicate_do_db.test b/mysql-test/suite/galera/t/galera_as_slave_gtid_replicate_do_db.test index 81b6d446ba6..10886c41fde 100644 --- a/mysql-test/suite/galera/t/galera_as_slave_gtid_replicate_do_db.test +++ b/mysql-test/suite/galera/t/galera_as_slave_gtid_replicate_do_db.test @@ -148,3 +148,14 @@ DROP SCHEMA test2; STOP SLAVE; RESET SLAVE ALL; +SET GLOBAL wsrep_on=OFF; +RESET MASTER; +SET GLOBAL wsrep_on=ON; + +--connection node_1 +SET GLOBAL wsrep_on=OFF; +RESET MASTER; +SET GLOBAL wsrep_on=ON; + +--connection node_3 +RESET MASTER; diff --git a/mysql-test/suite/galera/t/galera_gra_log.test b/mysql-test/suite/galera/t/galera_gra_log.test index aeadafad969..23561d9a2b1 100644 --- a/mysql-test/suite/galera/t/galera_gra_log.test +++ b/mysql-test/suite/galera/t/galera_gra_log.test @@ -5,6 +5,11 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + --connection node_2 --exec rm -rf $MYSQLTEST_VARDIR/mysqld.2/data/GRA_*.log let $restore_wsrep_ignore_apply_errors = `SELECT @@GLOBAL.wsrep_ignore_apply_errors`; @@ -39,3 +44,6 @@ CREATE TABLE t1 (f1 INTEGER); DROP TABLE t1; CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on"); + +# Restore original auto_increment_offset values. +--source include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera/t/galera_gtid_slave.cnf b/mysql-test/suite/galera/t/galera_gtid_slave.cnf index 409d0d1609a..112c487851f 100644 --- a/mysql-test/suite/galera/t/galera_gtid_slave.cnf +++ b/mysql-test/suite/galera/t/galera_gtid_slave.cnf @@ -4,15 +4,13 @@ log-bin=mysqld-bin log-slave-updates binlog-format=ROW - [mysqld.1] gtid-domain-id=1 +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=1 [mysqld.2] -gtid-domain-id=2 +gtid-domain-id=1 wsrep_gtid_mode=1 -wsrep_gtid_domain_id=2 +wsrep_gtid_domain_id=1 [mysqld.3] gtid-domain-id=2 -wsrep_gtid_mode=1 -wsrep_gtid_domain_id=2 - diff --git a/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.cnf b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.cnf index bb9c8e84f1b..efeb536de96 100644 --- a/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.cnf +++ b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.cnf @@ -7,12 +7,12 @@ binlog-format=ROW wsrep_sst_method=rsync [mysqld.1] gtid-domain-id=1 +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=1 [mysqld.2] -gtid-domain-id=2 +gtid-domain-id=1 wsrep_gtid_mode=1 -wsrep_gtid_domain_id=2 +wsrep_gtid_domain_id=1 [mysqld.3] gtid-domain-id=2 -wsrep_gtid_mode=1 -wsrep_gtid_domain_id=2 diff --git a/mysql-test/suite/galera/t/galera_gtid_trx_conflict.cnf b/mysql-test/suite/galera/t/galera_gtid_trx_conflict.cnf new file mode 100644 index 00000000000..5f129e7c168 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_gtid_trx_conflict.cnf @@ -0,0 +1,14 @@ +!include ../galera_2nodes.cnf + +[mysqld] +log-bin=mysqld-bin +log-slave-updates +binlog-format=ROW +[mysqld.1] +gtid-domain-id=1 +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=1 +[mysqld.2] +gtid-domain-id=1 +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=1 diff --git a/mysql-test/suite/galera/t/galera_gtid_trx_conflict.test b/mysql-test/suite/galera/t/galera_gtid_trx_conflict.test new file mode 100644 index 00000000000..27539b2ab52 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_gtid_trx_conflict.test @@ -0,0 +1,56 @@ +# +# Test galera GTID with conflicting trx and @@wsrep_gtid_seq_no set on one node. +# + +--source include/galera_cluster.inc +--source include/have_log_bin.inc +--source include/have_innodb.inc + +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; + +--connection node_1 +SET AUTOCOMMIT = OFF; +START TRANSACTION; +INSERT INTO t1 VALUES(1); + +--connection node_2 +SET AUTOCOMMIT = OFF; +SET @@wsrep_gtid_seq_no = 100; +START TRANSACTION; +INSERT INTO t1 VALUES(1); + +--connection node_1 +COMMIT; + +--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 +--connection node_2a +--let $wait_condition = SELECT COUNT(*) = 1 FROM t1; +--source include/wait_condition.inc + +--connection node_2 +--error ER_LOCK_DEADLOCK +COMMIT; + +--echo # Expected GTID value 1-1-2 on both nodes +SELECT @@gtid_binlog_state; + +SET AUTOCOMMIT = ON; +INSERT INTO t1 VALUES(2); + +--echo # Expected GTID value 1-1-100 on both nodes, seqno is set with wsrep_gtid_seq_no +SELECT @@gtid_binlog_state; + +--connection node_1 +SELECT @@gtid_binlog_state; + +SET AUTOCOMMIT = ON; +INSERT INTO t1 VALUES(3); + +--echo # Expected GTID value 1-1-101 on both nodes +SELECT @@gtid_binlog_state; + +--connection node_2 +SELECT @@gtid_binlog_state; + + +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_last_committed_id.cnf b/mysql-test/suite/galera/t/galera_last_committed_id.cnf new file mode 100644 index 00000000000..375d2480f23 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_last_committed_id.cnf @@ -0,0 +1,9 @@ +!include ../galera_2nodes.cnf + +[mysqld.1] +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=100 + +[mysqld.2] +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=100 diff --git a/mysql-test/suite/galera/t/galera_last_committed_id.combinations b/mysql-test/suite/galera/t/galera_last_committed_id.combinations new file mode 100644 index 00000000000..dd92b9fa81f --- /dev/null +++ b/mysql-test/suite/galera/t/galera_last_committed_id.combinations @@ -0,0 +1,6 @@ +[binlogoff] + +[binlogon] +--log-bin=master-bin +--log-bin-index=master-bin +--log-slave-updates diff --git a/mysql-test/suite/galera/t/galera_last_committed_id.test b/mysql-test/suite/galera/t/galera_last_committed_id.test index 550838cdcd9..b6e3e1f7e7a 100644 --- a/mysql-test/suite/galera/t/galera_last_committed_id.test +++ b/mysql-test/suite/galera/t/galera_last_committed_id.test @@ -4,64 +4,62 @@ --source include/galera_cluster.inc -# Returns -1 if no transactions have been run +# Returns domain-server-0 if no transactions have been run -SELECT WSREP_LAST_WRITTEN_GTID() = '00000000-0000-0000-0000-000000000000:-1'; +SELECT WSREP_LAST_WRITTEN_GTID(); + +# WSREP_LAST_WRITTEN_GTID() should not be influenced by transactions written +# on other nodes or connections + +--connection node_1 +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); --disable_query_log ---let $seqno = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'` ---let $state = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_uuid'` ---eval SELECT WSREP_LAST_SEEN_GTID() = '$state:$seqno' AS wsrep_last_committed_id_match; +--let $wsrep_last_written_id_conn_1 = `SELECT WSREP_LAST_WRITTEN_GTID()` --enable_query_log -# WSREP_LAST_WRITTEN_GTID() should not be influenced by transactions committed -# on other connections - ---connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; --connection node_1a -CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1); +--eval SELECT WSREP_LAST_WRITTEN_GTID() != '$wsrep_last_written_id_conn_1' AS wsrep_written_does_not_match_different_conn ---connection node_1 -SELECT WSREP_LAST_WRITTEN_GTID() = '00000000-0000-0000-0000-000000000000:-1'; +--connection node_2 +--eval SELECT WSREP_LAST_WRITTEN_GTID() != '$wsrep_last_written_id_conn_1' AS wsrep_written_does_not_match_different_nodes -# WSREP_LAST_SEEN_GTID() should be influenced by transactions committed +# WSREP_LAST_SEEN_GTID() should be influenced by transactions written # on other connections ---connection node_1a +--connection node_1 INSERT INTO t1 VALUES (1); --disable_query_log ---let $wsrep_last_committed_id_conn_1a = `SELECT WSREP_LAST_SEEN_GTID()` +--let $wsrep_last_written_id_conn_1 = `SELECT WSREP_LAST_WRITTEN_GTID()` --enable_query_log ---connection node_1 +--connection node_2 --disable_query_log ---eval SELECT WSREP_LAST_SEEN_GTID() = '$wsrep_last_committed_id_conn_1a' AS wsrep_last_committed_id_match; +--eval SELECT WSREP_LAST_SEEN_GTID() = '$wsrep_last_written_id_conn_1' AS wsrep_last_written_seen_id_match --enable_query_log # Should not advance while a transaction is in progress +--connection node_1 SET AUTOCOMMIT=OFF; START TRANSACTION; -SELECT WSREP_LAST_WRITTEN_GTID() = '00000000-0000-0000-0000-000000000000:-1'; --disable_query_log ---let $wsrep_last_committed_id_before = `SELECT WSREP_LAST_SEEN_GTID()` +--let $wsrep_last_written_id_before = `SELECT WSREP_LAST_WRITTEN_GTID()` --enable_query_log INSERT INTO t1 VALUES (1); -SELECT WSREP_LAST_WRITTEN_GTID() = '00000000-0000-0000-0000-000000000000:-1'; --disable_query_log ---eval SELECT WSREP_LAST_SEEN_GTID() = '$wsrep_last_committed_id_before' AS wsrep_last_committed_id_match; +--eval SELECT WSREP_LAST_SEEN_GTID() = '$wsrep_last_written_id_before' +--eval SELECT WSREP_LAST_WRITTEN_GTID() = '$wsrep_last_written_id_before' AS wsrep_last_written_id_match --enable_query_log -# Should only advance after the transaction has been committed +# Should only advance after the transaction has been commited COMMIT; --disable_query_log ---let $seqno = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'` ---let $state = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_uuid'` ---eval SELECT WSREP_LAST_WRITTEN_GTID() = '$state:$seqno' AS wsrep_last_committed_id_advanced; ---eval SELECT WSREP_LAST_SEEN_GTID() = '$state:$seqno' AS wsrep_last_committed_id_advanced; +--eval SELECT WSREP_LAST_WRITTEN_GTID() != 'wsrep_last_written_id_before' AS wsrep_last_written_id_advanced --enable_query_log SET AUTOCOMMIT=ON; diff --git a/mysql-test/suite/galera/t/galera_sync_wait_upto.cnf b/mysql-test/suite/galera/t/galera_sync_wait_upto.cnf new file mode 100644 index 00000000000..375d2480f23 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sync_wait_upto.cnf @@ -0,0 +1,9 @@ +!include ../galera_2nodes.cnf + +[mysqld.1] +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=100 + +[mysqld.2] +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=100 diff --git a/mysql-test/suite/galera/t/galera_sync_wait_upto.combinations b/mysql-test/suite/galera/t/galera_sync_wait_upto.combinations new file mode 100644 index 00000000000..dd92b9fa81f --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sync_wait_upto.combinations @@ -0,0 +1,6 @@ +[binlogoff] + +[binlogon] +--log-bin=master-bin +--log-bin-index=master-bin +--log-slave-updates diff --git a/mysql-test/suite/galera/t/galera_sync_wait_upto.test b/mysql-test/suite/galera/t/galera_sync_wait_upto.test index 32c6b590c84..460abf061b2 100644 --- a/mysql-test/suite/galera/t/galera_sync_wait_upto.test +++ b/mysql-test/suite/galera/t/galera_sync_wait_upto.test @@ -8,108 +8,64 @@ CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); - # Test with invalid values --error ER_WRONG_ARGUMENTS SELECT WSREP_SYNC_WAIT_UPTO_GTID(NULL); ---error ER_WRONG_ARGUMENTS +--error ER_INCORRECT_GTID_STATE SELECT WSREP_SYNC_WAIT_UPTO_GTID('a'); ---error ER_WRONG_ARGUMENTS +--error ER_INCORRECT_GTID_STATE SELECT WSREP_SYNC_WAIT_UPTO_GTID(2); +--error ER_WRONG_ARGUMENTS +SELECT WSREP_SYNC_WAIT_UPTO_GTID('1-1-1,1-1-2'); -# If set to low value, expect no waiting +# Expected starting seqno ---disable_query_log ---let $seqno = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'` ---let $state = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_uuid'` ---enable_query_log +--let $start_seqno = 2 ---disable_query_log ---eval SELECT WSREP_SYNC_WAIT_UPTO_GTID('00000000-0000-0000-0000-000000000000:-1') AS WSREP_SYNC_WAIT_UPTO; ---enable_query_log +# If set to low value, expect no waiting --disable_query_log ---eval SELECT WSREP_SYNC_WAIT_UPTO_GTID('$state:0') AS WSREP_SYNC_WAIT_UPTO; +--let $lower_seqno = $start_seqno +--dec $lower_seqno +--eval SELECT WSREP_SYNC_WAIT_UPTO_GTID('100-1-$lower_seqno') AS WSREP_SYNC_WAIT_UPTO; --enable_query_log - -# If set to current last_committed value +# If set to current last_committed value no waiting --disable_query_log ---eval SELECT WSREP_SYNC_WAIT_UPTO_GTID('$state:$seqno') AS WSREP_SYNC_WAIT_UPTO; +--let $wsrep_last_committed_gtid = `SELECT WSREP_LAST_SEEN_GTID()` +--eval SELECT WSREP_SYNC_WAIT_UPTO_GTID('$wsrep_last_committed_gtid') AS WSREP_SYNC_WAIT_UPTO; --enable_query_log -# If set to very high value, will wait +# Timeout if GTID is not received on time --disable_query_log +--let $high_seqno = $start_seqno +--inc $high_seqno --error ER_LOCK_WAIT_TIMEOUT ---eval SELECT WSREP_SYNC_WAIT_UPTO_GTID('$state:9223372036854775807', 1) AS WSREP_SYNC_WAIT_UPTO; +--eval SELECT WSREP_SYNC_WAIT_UPTO_GTID('100-1-$high_seqno', 1) AS WSREP_SYNC_WAIT_UPTO; --enable_query_log - -# If applier is blocked, will wait - ---connection node_2 -SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; - - ---connection node_1 -# Perform two inserts and record the IDs of each -INSERT INTO t1 VALUES (2); ---let $gtid_first = `SELECT WSREP_LAST_WRITTEN_GTID()` - -INSERT INTO t1 VALUES (3); ---let $gtid_second = `SELECT WSREP_LAST_WRITTEN_GTID()` +# Wait for GTID value --connection node_2 -SET SESSION wsrep_sync_wait = 0; - --disable_query_log ---error ER_LOCK_WAIT_TIMEOUT ---eval SELECT WSREP_SYNC_WAIT_UPTO_GTID('$gtid_first', 1) AS WSREP_SYNC_WAIT_UPTO; +--let $wait_seqno = $start_seqno +--inc $wait_seqno --enable_query_log ---disable_query_log ---send_eval SELECT WSREP_SYNC_WAIT_UPTO_GTID('$gtid_first') AS WSREP_SYNC_WAIT_UPTO; ---enable_query_log +--send_eval SELECT WSREP_SYNC_WAIT_UPTO_GTID('100-1-$wait_seqno') -# Unblock applier ---connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 ---connection node_2a -SET SESSION wsrep_sync_wait = 0; ---let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE 'SELECT WSREP_SYNC_WAIT%'; ---source include/wait_condition.inc -SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb"; +--connection node_1 +INSERT INTO t1 VALUES (2); --connection node_2 --reap -# Confirm that we were allowed to proceed when the applier reached $seqno_first ---let $gtid_current = `SELECT WSREP_LAST_SEEN_GTID()` ---disable_query_log ---eval SELECT '$gtid_current' = '$gtid_first' AS `gtid_current = gtid_first` ---enable_query_log - -SET GLOBAL DEBUG_DBUG = ""; -SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb"; - -# Move forward some more, to $seqno_second; - ---disable_query_log ---eval SELECT WSREP_SYNC_WAIT_UPTO_GTID('$gtid_second') AS WSREP_SYNC_WAIT_UPTO; ---enable_query_log - ---let $gtid_current = `SELECT WSREP_LAST_SEEN_GTID()` ---disable_query_log ---eval SELECT '$gtid_current' = '$gtid_second' AS `seqno_current = seqno_second` ---enable_query_log - -SET DEBUG_SYNC = "RESET"; - --connection node_1 DROP TABLE t1; diff --git a/mysql-test/suite/galera_3nodes/r/galera_gtid_2_cluster.result b/mysql-test/suite/galera_3nodes/r/galera_gtid_2_cluster.result index afb94d493c4..7d4751e79af 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_gtid_2_cluster.result +++ b/mysql-test/suite/galera_3nodes/r/galera_gtid_2_cluster.result @@ -92,7 +92,7 @@ select @@gtid_binlog_state; insert into t1 values (1, 12, 3); select @@gtid_binlog_state; @@gtid_binlog_state -1-11-2,1-12-3,2-21-1 +1-11-3,2-21-1 #wait for sync cluster 1 and 2 connection node_1; include/save_master_gtid.inc @@ -102,11 +102,11 @@ cluster 1 node 3 connection node_3; select @@gtid_binlog_state; @@gtid_binlog_state -1-11-2,1-12-3,2-21-1 +1-11-3,2-21-1 insert into t1 values (1, 13, 4); select @@gtid_binlog_state; @@gtid_binlog_state -1-12-3,1-11-2,1-13-4,2-21-1 +1-11-4,2-21-1 #wait for sync cluster 1 and 2 connection node_1; include/save_master_gtid.inc @@ -116,11 +116,11 @@ cluster 2 node 2 connection node_5; select @@gtid_binlog_state; @@gtid_binlog_state -1-12-3,1-11-2,1-13-4,2-21-1 +1-11-4,2-21-1 insert into t1 values (2, 22, 2); select @@gtid_binlog_state; @@gtid_binlog_state -1-12-3,1-11-2,1-13-4,2-21-1,2-22-2 +1-11-4,2-21-2 #wait for sync cluster 2 and 1 connection node_4; include/save_master_gtid.inc @@ -130,11 +130,11 @@ cluster 2 node 3 connection node_6; select @@gtid_binlog_state; @@gtid_binlog_state -1-12-3,1-11-2,1-13-4,2-21-1,2-22-2 +1-11-4,2-21-2 insert into t1 values (2, 23, 3); select @@gtid_binlog_state; @@gtid_binlog_state -1-12-3,1-11-2,1-13-4,2-21-1,2-22-2,2-23-3 +1-11-4,2-21-3 #wait for sync cluster 2 and 1 connection node_4; include/save_master_gtid.inc @@ -144,7 +144,7 @@ cluster 1 node 1 connection node_1; select @@gtid_binlog_state; @@gtid_binlog_state -1-12-3,1-11-2,1-13-4,2-21-1,2-22-2,2-23-3 +1-11-4,2-21-3 drop table t1; stop slave; reset slave; @@ -208,7 +208,7 @@ create table t1 (cluster_domain_id int ,node_server_id int, seq_no int); insert into t1 values (1, 11, 2); select @@gtid_binlog_state; @@gtid_binlog_state -1-11-2 +1-11-7 #wait for sync cluster 1 and 2 connection node_1; include/save_master_gtid.inc @@ -219,7 +219,7 @@ connection node_4; insert into t1 values (2, 21, 1); select @@gtid_binlog_state; @@gtid_binlog_state -1-11-2,2-21-1 +1-11-7,2-21-4 select * from t1; cluster_domain_id node_server_id seq_no 1 11 2 @@ -233,11 +233,11 @@ cluster 1 node 2 connection node_2; select @@gtid_binlog_state; @@gtid_binlog_state -1-11-2,2-21-1 +1-11-7,2-21-4 insert into t1 values (1, 12, 3); select @@gtid_binlog_state; @@gtid_binlog_state -1-11-2,1-12-3,2-21-1 +1-11-8,2-21-4 #wait for sync cluster 1 and 2 connection node_1; include/save_master_gtid.inc @@ -247,11 +247,11 @@ cluster 1 node 3 connection node_3; select @@gtid_binlog_state; @@gtid_binlog_state -1-11-2,1-12-3,2-21-1 +1-11-8,2-21-4 insert into t1 values (1, 13, 4); select @@gtid_binlog_state; @@gtid_binlog_state -1-12-3,1-11-2,1-13-4,2-21-1 +1-11-9,2-21-4 #wait for sync cluster 1 and 2 connection node_1; include/save_master_gtid.inc @@ -261,11 +261,11 @@ cluster 2 node 2 connection node_5; select @@gtid_binlog_state; @@gtid_binlog_state -1-12-3,1-11-2,1-13-4,2-21-1 +1-11-9,2-21-4 insert into t1 values (2, 22, 2); select @@gtid_binlog_state; @@gtid_binlog_state -1-12-3,1-11-2,1-13-4,2-21-1,2-22-2 +1-11-9,2-21-5 #wait for sync cluster 2 and 1 connection node_4; include/save_master_gtid.inc @@ -275,11 +275,11 @@ cluster 2 node 3 connection node_6; select @@gtid_binlog_state; @@gtid_binlog_state -1-12-3,1-11-2,1-13-4,2-21-1,2-22-2 +1-11-9,2-21-5 insert into t1 values (2, 23, 3); select @@gtid_binlog_state; @@gtid_binlog_state -1-12-3,1-11-2,1-13-4,2-21-1,2-22-2,2-23-3 +1-11-9,2-21-6 #wait for sync cluster 2 and 1 connection node_4; include/save_master_gtid.inc @@ -289,7 +289,7 @@ cluster 1 node 1 connection node_1; select @@gtid_binlog_state; @@gtid_binlog_state -1-12-3,1-11-2,1-13-4,2-21-1,2-22-2,2-23-3 +1-11-9,2-21-6 drop table t1; stop slave; change master to master_use_gtid=no, ignore_server_ids=(); diff --git a/mysql-test/suite/sys_vars/r/sysvars_wsrep.result b/mysql-test/suite/sys_vars/r/sysvars_wsrep.result index 67209c5e846..a1d66e4d112 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_wsrep.result +++ b/mysql-test/suite/sys_vars/r/sysvars_wsrep.result @@ -241,6 +241,21 @@ ENUM_VALUE_LIST OFF,ON READ_ONLY NO COMMAND_LINE_ARGUMENT OPTIONAL GLOBAL_VALUE_PATH NULL +VARIABLE_NAME WSREP_GTID_SEQ_NO +SESSION_VALUE 0 +GLOBAL_VALUE NULL +GLOBAL_VALUE_ORIGIN COMPILE-TIME +DEFAULT_VALUE 0 +VARIABLE_SCOPE SESSION ONLY +VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_COMMENT Internal server usage, manually set WSREP GTID seqno. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_BLOCK_SIZE 1 +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT NULL +GLOBAL_VALUE_PATH NULL VARIABLE_NAME WSREP_IGNORE_APPLY_ERRORS SESSION_VALUE NULL GLOBAL_VALUE 7 diff --git a/sql/handler.cc b/sql/handler.cc index ac6b4f3f453..7d61252eea6 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2057,7 +2057,7 @@ static my_xid wsrep_order_and_check_continuity(XID *list, int len) { #ifdef WITH_WSREP wsrep_sort_xid_array(list, len); - wsrep::gtid cur_position= wsrep_get_SE_checkpoint(); + wsrep::gtid cur_position= wsrep_get_SE_checkpoint<wsrep::gtid>(); long long cur_seqno= cur_position.seqno().get(); for (int i= 0; i < len; ++i) { diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index e689a71e431..82259cd6924 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -5234,28 +5234,33 @@ String *Item_temptable_rowid::val_str(String *str) str_value.set((char*)(table->file->ref), max_length, &my_charset_bin); return &str_value; } + #ifdef WITH_WSREP #include "wsrep_mysqld.h" +/* Format is %d-%d-%llu */ +#define WSREP_MAX_WSREP_SERVER_GTID_STR_LEN 10+1+10+1+20 String *Item_func_wsrep_last_written_gtid::val_str_ascii(String *str) { - wsrep::gtid gtid= current_thd->wsrep_cs().last_written_gtid(); - if (gtid_str.alloc(wsrep::gtid_c_str_len())) + if (gtid_str.alloc(WSREP_MAX_WSREP_SERVER_GTID_STR_LEN+1)) { - my_error(ER_OUTOFMEMORY, wsrep::gtid_c_str_len()); - null_value= true; - return NULL; + my_error(ER_OUTOFMEMORY, WSREP_MAX_WSREP_SERVER_GTID_STR_LEN); + null_value= TRUE; + return 0; } - ssize_t gtid_len= gtid_print_to_c_str(gtid, (char*) gtid_str.ptr(), - wsrep::gtid_c_str_len()); + ssize_t gtid_len= my_snprintf((char*)gtid_str.ptr(), + WSREP_MAX_WSREP_SERVER_GTID_STR_LEN+1, + "%u-%u-%llu", wsrep_gtid_server.domain_id, + wsrep_gtid_server.server_id, + current_thd->wsrep_last_written_gtid_seqno); if (gtid_len < 0) { my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), func_name(), - "wsrep_gtid_print failed"); - null_value= true; - return NULL; + "wsrep_gtid_print failed"); + null_value= TRUE; + return 0; } gtid_str.length(gtid_len); return >id_str; @@ -5263,23 +5268,23 @@ String *Item_func_wsrep_last_written_gtid::val_str_ascii(String *str) String *Item_func_wsrep_last_seen_gtid::val_str_ascii(String *str) { - /* TODO: Should call Wsrep_server_state.instance().last_committed_gtid() - instead. */ - wsrep::gtid gtid= Wsrep_server_state::instance().provider().last_committed_gtid(); - if (gtid_str.alloc(wsrep::gtid_c_str_len())) + if (gtid_str.alloc(WSREP_MAX_WSREP_SERVER_GTID_STR_LEN+1)) { - my_error(ER_OUTOFMEMORY, wsrep::gtid_c_str_len()); - null_value= true; - return NULL; + my_error(ER_OUTOFMEMORY, WSREP_MAX_WSREP_SERVER_GTID_STR_LEN); + null_value= TRUE; + return 0; } - ssize_t gtid_len= wsrep::gtid_print_to_c_str(gtid, (char*) gtid_str.ptr(), - wsrep::gtid_c_str_len()); + ssize_t gtid_len= my_snprintf((char*)gtid_str.ptr(), + WSREP_MAX_WSREP_SERVER_GTID_STR_LEN+1, + "%u-%u-%llu", wsrep_gtid_server.domain_id, + wsrep_gtid_server.server_id, + wsrep_gtid_server.seqno()); if (gtid_len < 0) { my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), func_name(), "wsrep_gtid_print failed"); - null_value= true; - return NULL; + null_value= TRUE; + return 0; } gtid_str.length(gtid_len); return >id_str; @@ -5287,49 +5292,52 @@ String *Item_func_wsrep_last_seen_gtid::val_str_ascii(String *str) longlong Item_func_wsrep_sync_wait_upto::val_int() { - int timeout= -1; - String* gtid_str= args[0]->val_str(&value); - if (gtid_str == NULL) - { - my_error(ER_WRONG_ARGUMENTS, MYF(0), func_name()); - return 0LL; - } - - if (arg_count == 2) - { - timeout= args[1]->val_int(); - } + String *gtid_str __attribute__((unused)) = args[0]->val_str(&value); + null_value=0; + uint timeout; + rpl_gtid *gtid_list; + uint32 count; + int ret= 1; - wsrep_gtid_t gtid; - int gtid_len= wsrep_gtid_scan(gtid_str->ptr(), gtid_str->length(), >id); - if (gtid_len < 0) + if (args[0]->null_value) { my_error(ER_WRONG_ARGUMENTS, MYF(0), func_name()); - return 0LL; + null_value= TRUE; + return 0; } - if (gtid.seqno == WSREP_SEQNO_UNDEFINED && - wsrep_uuid_compare(>id.uuid, &WSREP_UUID_UNDEFINED) == 0) + if (arg_count==2 && !args[1]->null_value) + timeout= (uint)(args[1]->val_real()); + else + timeout= (uint)-1; + + if (!(gtid_list= gtid_parse_string_to_list(gtid_str->ptr(), gtid_str->length(), + &count))) { - return 1LL; + my_error(ER_INCORRECT_GTID_STATE, MYF(0), func_name()); + null_value= TRUE; + return 0; } - - enum wsrep::provider::status status= - wsrep_sync_wait_upto(current_thd, >id, timeout); - - if (status) + if (count == 1) { - int err; - switch (status) { - case wsrep::provider::error_transaction_missing: - err= ER_WRONG_ARGUMENTS; - break; - default: - err= ER_LOCK_WAIT_TIMEOUT; + if (wsrep_check_gtid_seqno(gtid_list[0].domain_id, gtid_list[0].server_id, + gtid_list[0].seq_no)) + { + if (wsrep_gtid_server.wait_gtid_upto(gtid_list[0].seq_no, timeout)) + { + my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0), func_name()); + ret= 0; + } } - my_error(err, MYF(0), func_name()); - return 0LL; } - return 1LL; + else + { + my_error(ER_WRONG_ARGUMENTS, MYF(0), func_name()); + null_value= TRUE; + ret= 0; + } + my_free(gtid_list); + return ret; } + #endif /* WITH_WSREP */ diff --git a/sql/log.cc b/sql/log.cc index bf19946210a..93b5d697d14 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -5048,55 +5048,6 @@ MYSQL_BIN_LOG::is_xidlist_idle_nolock() return true; } -#ifdef WITH_WSREP -inline bool -is_gtid_cached_internal(IO_CACHE *file) -{ - uchar data[EVENT_TYPE_OFFSET+1]; - bool result= false; - my_off_t write_pos= my_b_tell(file); - if (reinit_io_cache(file, READ_CACHE, 0, 0, 0)) - return false; - /* - In the cache we have gtid event if , below condition is true, - */ - my_b_read(file, data, sizeof(data)); - uint event_type= (uchar)data[EVENT_TYPE_OFFSET]; - if (event_type == GTID_LOG_EVENT) - result= true; - /* - Cleanup , Why because we have not read the full buffer - and this will cause next to next reinit_io_cache(called in write_cache) - to make cache empty. - */ - file->read_pos= file->read_end; - if (reinit_io_cache(file, WRITE_CACHE, write_pos, 0, 0)) - return false; - return result; -} -#endif - -#ifdef WITH_WSREP -inline bool -MYSQL_BIN_LOG::is_gtid_cached(THD *thd) -{ - binlog_cache_mngr *mngr= (binlog_cache_mngr *) thd_get_ha_data( - thd, binlog_hton); - if (!mngr) - return false; - binlog_cache_data *cache_trans= mngr->get_binlog_cache_data( - use_trans_cache(thd, true)); - binlog_cache_data *cache_stmt= mngr->get_binlog_cache_data( - use_trans_cache(thd, false)); - if (cache_trans && !cache_trans->empty() && - is_gtid_cached_internal(&cache_trans->cache_log)) - return true; - if (cache_stmt && !cache_stmt->empty() && - is_gtid_cached_internal(&cache_stmt->cache_log)) - return true; - return false; -} -#endif /** Create a new log file name. @@ -5719,31 +5670,47 @@ THD::binlog_start_trans_and_stmt() { DBUG_VOID_RETURN; } - /* Write Gtid - Get domain id only when gtid mode is set - If this event is replicate through a master then , - we will forward the same gtid another nodes - We have to do this only one time in mysql transaction. - Since this function is called multiple times , We will check for - ha_info->is_started() - */ + /* If this event replicates through a master-slave then we need to + inject manually GTID so it is preserved in the cluster. We are writing + directly to WSREP buffer and not in IO cache because in case of IO cache + GTID event will be duplicated in binlog. + We have to do this only one time in mysql transaction. + Since this function is called multiple times , We will check for + ha_info->is_started(). + */ Ha_trx_info *ha_info; ha_info= this->ha_data[binlog_hton->slot].ha_info + (mstmt_mode ? 1 : 0); - if (!ha_info->is_started() && wsrep_gtid_mode - && this->variables.gtid_seq_no) + if (!ha_info->is_started() && + (this->variables.gtid_seq_no || this->variables.wsrep_gtid_seq_no) && + wsrep_on(this) && + (this->wsrep_cs().mode() == wsrep::client_state::m_local)) { - binlog_cache_mngr *const cache_mngr= - (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton); - binlog_cache_data *cache_data= cache_mngr->get_binlog_cache_data(1); - IO_CACHE *file= &cache_data->cache_log; - Log_event_writer writer(file, cache_data); - Gtid_log_event gtid_event(this, this->variables.gtid_seq_no, - this->variables.gtid_domain_id, - true, LOG_EVENT_SUPPRESS_USE_F, - true, 0); - gtid_event.server_id= this->variables.server_id; - writer.write(>id_event); + uchar *buf= 0; + size_t len= 0; + IO_CACHE tmp_io_cache; + Log_event_writer writer(&tmp_io_cache, 0); + if(!open_cached_file(&tmp_io_cache, mysql_tmpdir, TEMP_PREFIX, + 128, MYF(MY_WME))) + { + uint64 seqno= this->variables.gtid_seq_no; + uint32 domain_id= this->variables.gtid_domain_id; + uint32 server_id= this->variables.server_id; + if (!this->variables.gtid_seq_no && this->variables.wsrep_gtid_seq_no) + { + seqno= this->variables.wsrep_gtid_seq_no; + domain_id= wsrep_gtid_server.domain_id; + server_id= wsrep_gtid_server.server_id; + } + Gtid_log_event gtid_event(this, seqno, domain_id, true, + LOG_EVENT_SUPPRESS_USE_F, true, 0); + gtid_event.server_id= server_id; + writer.write(>id_event); + wsrep_write_cache_buf(&tmp_io_cache, &buf, &len); + if (len > 0) this->wsrep_cs().append_data(wsrep::const_buffer(buf, len)); + if (buf) my_free(buf); + close_cached_file(&tmp_io_cache); + } } #endif if (mstmt_mode) @@ -6024,20 +5991,9 @@ MYSQL_BIN_LOG::write_gtid_event(THD *thd, bool standalone, DBUG_ENTER("write_gtid_event"); DBUG_PRINT("enter", ("standalone: %d", standalone)); -#ifdef WITH_WSREP - if (WSREP(thd) && - (wsrep_thd_trx_seqno(thd) > 0) && - wsrep_gtid_mode && !thd->variables.gtid_seq_no) - { - domain_id= wsrep_gtid_domain_id; - } else { -#endif /* WITH_WSREP */ + seq_no= thd->variables.gtid_seq_no; domain_id= thd->variables.gtid_domain_id; -#ifdef WITH_WSREP - } -#endif /* WITH_WSREP */ local_server_id= thd->variables.server_id; - seq_no= thd->variables.gtid_seq_no; DBUG_ASSERT(local_server_id != 0); @@ -6084,8 +6040,11 @@ MYSQL_BIN_LOG::write_gtid_event(THD *thd, bool standalone, DBUG_ASSERT(this == &mysql_bin_log); #ifdef WITH_WSREP - if (wsrep_gtid_mode && is_gtid_cached(thd)) - DBUG_RETURN(false); + if (wsrep_gtid_mode) + { + thd->variables.gtid_domain_id= global_system_variables.gtid_domain_id; + thd->variables.server_id= global_system_variables.server_id; + } #endif if (write_event(>id_event)) diff --git a/sql/log.h b/sql/log.h index bf1dbd30c6c..7ccfd606f21 100644 --- a/sql/log.h +++ b/sql/log.h @@ -561,13 +561,6 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG bool write_transaction_to_binlog_events(group_commit_entry *entry); void trx_group_commit_leader(group_commit_entry *leader); bool is_xidlist_idle_nolock(); -#ifdef WITH_WSREP - /* - When this mariadb node is slave and galera enabled. So in this case - we write the gtid in wsrep_run_commit itself. - */ - inline bool is_gtid_cached(THD *thd); -#endif public: /* A list of struct xid_count_per_binlog is used to keep track of how many diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7fe98c756cd..e2489f7706f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5724,6 +5724,8 @@ int mysqld_main(int argc, char **argv) { wsrep_shutdown_replication(); } + /* Release threads if they are waiting in WSREP_SYNC_WAIT_UPTO_GTID */ + wsrep_gtid_server.signal_waiters(0, true); #endif close_connections(); diff --git a/sql/service_wsrep.cc b/sql/service_wsrep.cc index 36ea311f59f..68de55b5778 100644 --- a/sql/service_wsrep.cc +++ b/sql/service_wsrep.cc @@ -281,16 +281,34 @@ extern "C" int wsrep_thd_append_key(THD *thd, } ret= client_state.append_key(wsrep_key); } + /* + In case of `wsrep_gtid_mode` when WS will be replicated, we need to set + `server_id` for events that are going to be written in IO, and in case of + manual SET gtid_seq_no=X we are ignoring value. + */ + if (!ret && wsrep_gtid_mode && !thd->slave_thread && !wsrep_thd_is_applying(thd)) + { + thd->variables.server_id= wsrep_gtid_server.server_id; + thd->variables.gtid_seq_no= 0; + } return ret; } extern "C" void wsrep_commit_ordered(THD *thd) { if (wsrep_is_active(thd) && - thd->wsrep_trx().state() == wsrep::transaction::s_committing && - !wsrep_commit_will_write_binlog(thd)) + (thd->wsrep_trx().state() == wsrep::transaction::s_committing || + thd->wsrep_trx().state() == wsrep::transaction::s_ordered_commit)) { - thd->wsrep_cs().ordered_commit(); + wsrep_gtid_server.signal_waiters(thd->wsrep_current_gtid_seqno, false); + if (wsrep_thd_is_local(thd)) + { + thd->wsrep_last_written_gtid_seqno= thd->wsrep_current_gtid_seqno; + } + if (!wsrep_commit_will_write_binlog(thd)) + { + thd->wsrep_cs().ordered_commit(); + } } } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 1fdf4f17447..b5054557c46 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -697,9 +697,10 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) wsrep_apply_format(0), wsrep_rbr_buf(NULL), wsrep_sync_wait_gtid(WSREP_GTID_UNDEFINED), + wsrep_last_written_gtid_seqno(0), + wsrep_current_gtid_seqno(0), wsrep_affected_rows(0), wsrep_has_ignored_error(false), - wsrep_replicate_GTID(false), wsrep_ignore_table(false), /* wsrep-lib */ @@ -1313,7 +1314,6 @@ void THD::init() wsrep_rbr_buf = NULL; wsrep_affected_rows = 0; m_wsrep_next_trx_id = WSREP_UNDEFINED_TRX_ID; - wsrep_replicate_GTID = false; #endif /* WITH_WSREP */ if (variables.sql_log_bin) diff --git a/sql/sql_class.h b/sql/sql_class.h index 5bbe2e386d0..0891cd214f8 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -629,6 +629,7 @@ typedef struct system_variables are based on the cluster size): */ ulong saved_auto_increment_increment, saved_auto_increment_offset; + ulonglong wsrep_gtid_seq_no; #endif /* WITH_WSREP */ uint eq_range_index_dive_limit; ulong column_compression_zlib_strategy; @@ -4875,17 +4876,13 @@ public: size_t wsrep_TOI_pre_query_len; wsrep_po_handle_t wsrep_po_handle; size_t wsrep_po_cnt; -#ifdef GTID_SUPPORT - my_bool wsrep_po_in_trans; - rpl_sid wsrep_po_sid; -#endif /* GTID_SUPPORT */ void *wsrep_apply_format; uchar* wsrep_rbr_buf; wsrep_gtid_t wsrep_sync_wait_gtid; - // wsrep_gtid_t wsrep_last_written_gtid; + uint64 wsrep_last_written_gtid_seqno; + uint64 wsrep_current_gtid_seqno; ulong wsrep_affected_rows; bool wsrep_has_ignored_error; - bool wsrep_replicate_GTID; /* When enabled, do not replicate/binlog updates from the current table that's diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index de476042a80..ab382304973 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -5792,9 +5792,17 @@ static Sys_var_uint Sys_wsrep_gtid_domain_id( "wsrep_gtid_domain_id", "When wsrep_gtid_mode is set, this value is " "used as gtid_domain_id for galera transactions and also copied to the " "joiner nodes during state transfer. It is ignored, otherwise.", - GLOBAL_VAR(wsrep_gtid_domain_id), CMD_LINE(REQUIRED_ARG), + GLOBAL_VAR(wsrep_gtid_server.domain_id), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, UINT_MAX32), DEFAULT(0), BLOCK_SIZE(1)); +static Sys_var_ulonglong Sys_wsrep_gtid_seq_no( + "wsrep_gtid_seq_no", + "Internal server usage, manually set WSREP GTID seqno.", + SESSION_ONLY(wsrep_gtid_seq_no), + NO_CMD_LINE, VALID_RANGE(0, ULONGLONG_MAX), DEFAULT(0), + BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(wsrep_gtid_seq_no_check)); + static Sys_var_mybool Sys_wsrep_gtid_mode( "wsrep_gtid_mode", "Automatically update the (joiner) node's " "wsrep_gtid_domain_id value with that of donor's (received during " diff --git a/sql/wsrep_applier.cc b/sql/wsrep_applier.cc index 1ab65df1ca3..25a4e22aeb4 100644 --- a/sql/wsrep_applier.cc +++ b/sql/wsrep_applier.cc @@ -131,6 +131,12 @@ int wsrep_apply_events(THD* thd, if (!buf_len) WSREP_DEBUG("empty rbr buffer to apply: %lld", (long long) wsrep_thd_trx_seqno(thd)); + thd->variables.gtid_seq_no= 0; + if (wsrep_gtid_mode) + thd->variables.gtid_domain_id= wsrep_gtid_server.domain_id; + else + thd->variables.gtid_domain_id= global_system_variables.gtid_domain_id; + while (buf_len) { int exec_res; @@ -150,22 +156,38 @@ int wsrep_apply_events(THD* thd, case FORMAT_DESCRIPTION_EVENT: wsrep_set_apply_format(thd, (Format_description_log_event*)ev); continue; -#ifdef GTID_SUPPORT - case GTID_LOG_EVENT: - { - Gtid_log_event* gev= (Gtid_log_event*)ev; - if (gev->get_gno() == 0) + case GTID_EVENT: { - /* Skip GTID log event to make binlog to generate LTID on commit */ + Gtid_log_event *gtid_ev= (Gtid_log_event*)ev; + thd->variables.server_id= gtid_ev->server_id; + thd->variables.gtid_domain_id= gtid_ev->domain_id; + if ((gtid_ev->server_id == wsrep_gtid_server.server_id) && + (gtid_ev->domain_id == wsrep_gtid_server.domain_id)) + { + thd->variables.wsrep_gtid_seq_no= gtid_ev->seq_no; + } + else + { + thd->variables.gtid_seq_no= gtid_ev->seq_no; + } delete ev; - continue; } - } -#endif /* GTID_SUPPORT */ + continue; default: break; } + + if (!thd->variables.gtid_seq_no && wsrep_thd_is_toi(thd) && + (ev->get_type_code() == QUERY_EVENT)) + { + uint64 seqno= wsrep_gtid_server.seqno_inc(); + thd->wsrep_current_gtid_seqno= seqno; + if (mysql_bin_log.is_open() && wsrep_gtid_mode) + { + thd->variables.gtid_seq_no= seqno; + } + } /* Use the original server id for logging. */ thd->set_server_id(ev->server_id); thd->set_time(); // time the query diff --git a/sql/wsrep_high_priority_service.cc b/sql/wsrep_high_priority_service.cc index 06d398baf5f..d73b9cb09ce 100644 --- a/sql/wsrep_high_priority_service.cc +++ b/sql/wsrep_high_priority_service.cc @@ -396,7 +396,8 @@ int Wsrep_high_priority_service::apply_toi(const wsrep::ws_meta& ws_meta, thd->close_temporary_tables(); thd->lex->sql_command= SQLCOM_END; - wsrep_set_SE_checkpoint(client_state.toi_meta().gtid()); + wsrep_gtid_server.signal_waiters(thd->wsrep_current_gtid_seqno, false); + wsrep_set_SE_checkpoint(client_state.toi_meta().gtid(), wsrep_gtid_server.gtid()); must_exit_= check_exit_status(); @@ -448,7 +449,7 @@ int Wsrep_high_priority_service::log_dummy_write_set(const wsrep::ws_handle& ws_ cs.before_rollback(); cs.after_rollback(); } - wsrep_set_SE_checkpoint(ws_meta.gtid()); + wsrep_set_SE_checkpoint(ws_meta.gtid(), wsrep_gtid_server.gtid()); ret= ret || cs.provider().commit_order_leave(ws_handle, ws_meta, err); cs.after_applying(); } diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 444a187ea57..4c1d683b03e 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -52,11 +52,7 @@ /* wsrep-lib */ Wsrep_server_state* Wsrep_server_state::m_instance; -my_bool wsrep_emulate_bin_log = FALSE; // activating parts of binlog interface -#ifdef GTID_SUPPORT -/* Sidno in global_sid_map corresponding to group uuid */ -rpl_sidno wsrep_sidno= -1; -#endif /* GTID_SUPPORT */ +my_bool wsrep_emulate_bin_log= FALSE; // activating parts of binlog interface my_bool wsrep_preordered_opt= FALSE; /* Streaming Replication */ @@ -106,10 +102,9 @@ ulong wsrep_max_ws_size; // Max allowed ws (RBR buffer) s ulong wsrep_max_ws_rows; // Max number of rows in ws ulong wsrep_forced_binlog_format; ulong wsrep_mysql_replication_bundle; -bool wsrep_gtid_mode; // Use wsrep_gtid_domain_id - // for galera transactions? -uint32 wsrep_gtid_domain_id; // gtid_domain_id for galera - // transactions + +bool wsrep_gtid_mode; // Enable WSREP native GTID support +Wsrep_gtid_server wsrep_gtid_server; /* Other configuration variables and their default values. */ my_bool wsrep_incremental_data_collection= 0; // Incremental data collection @@ -144,6 +139,7 @@ mysql_mutex_t LOCK_wsrep_replaying; mysql_cond_t COND_wsrep_replaying; mysql_mutex_t LOCK_wsrep_slave_threads; mysql_cond_t COND_wsrep_slave_threads; +mysql_mutex_t LOCK_wsrep_gtid_wait_upto; mysql_mutex_t LOCK_wsrep_cluster_config; mysql_mutex_t LOCK_wsrep_desync; mysql_mutex_t LOCK_wsrep_config_state; @@ -167,7 +163,8 @@ ulong my_bind_addr; PSI_mutex_key key_LOCK_wsrep_replaying, key_LOCK_wsrep_ready, key_LOCK_wsrep_sst, key_LOCK_wsrep_sst_thread, key_LOCK_wsrep_sst_init, - key_LOCK_wsrep_slave_threads, key_LOCK_wsrep_desync, + key_LOCK_wsrep_slave_threads, key_LOCK_wsrep_gtid_wait_upto, + key_LOCK_wsrep_desync, key_LOCK_wsrep_config_state, key_LOCK_wsrep_cluster_config, key_LOCK_wsrep_group_commit, key_LOCK_wsrep_SR_pool, @@ -179,7 +176,7 @@ PSI_mutex_key PSI_cond_key key_COND_wsrep_thd, key_COND_wsrep_replaying, key_COND_wsrep_ready, key_COND_wsrep_sst, key_COND_wsrep_sst_init, key_COND_wsrep_sst_thread, - key_COND_wsrep_thd_queue, key_COND_wsrep_slave_threads, + key_COND_wsrep_thd_queue, key_COND_wsrep_slave_threads, key_COND_wsrep_gtid_wait_upto, key_COND_wsrep_joiner_monitor, key_COND_wsrep_donor_monitor; PSI_file_key key_file_wsrep_gra_log; @@ -193,6 +190,7 @@ static PSI_mutex_info wsrep_mutexes[]= { &key_LOCK_wsrep_sst, "LOCK_wsrep_sst", PSI_FLAG_GLOBAL}, { &key_LOCK_wsrep_replaying, "LOCK_wsrep_replaying", PSI_FLAG_GLOBAL}, { &key_LOCK_wsrep_slave_threads, "LOCK_wsrep_slave_threads", PSI_FLAG_GLOBAL}, + { &key_LOCK_wsrep_gtid_wait_upto, "LOCK_wsrep_gtid_wait_upto", PSI_FLAG_GLOBAL}, { &key_LOCK_wsrep_cluster_config, "LOCK_wsrep_cluster_config", PSI_FLAG_GLOBAL}, { &key_LOCK_wsrep_desync, "LOCK_wsrep_desync", PSI_FLAG_GLOBAL}, { &key_LOCK_wsrep_config_state, "LOCK_wsrep_config_state", PSI_FLAG_GLOBAL}, @@ -212,6 +210,7 @@ static PSI_cond_info wsrep_conds[]= { &key_COND_wsrep_thd, "THD::COND_wsrep_thd", 0}, { &key_COND_wsrep_replaying, "COND_wsrep_replaying", PSI_FLAG_GLOBAL}, { &key_COND_wsrep_slave_threads, "COND_wsrep_wsrep_slave_threads", PSI_FLAG_GLOBAL}, + { &key_COND_wsrep_gtid_wait_upto, "COND_wsrep_gtid_wait_upto", PSI_FLAG_GLOBAL}, { &key_COND_wsrep_joiner_monitor, "COND_wsrep_joiner_monitor", PSI_FLAG_GLOBAL}, { &key_COND_wsrep_donor_monitor, "COND_wsrep_donor_monitor", PSI_FLAG_GLOBAL} }; @@ -302,6 +301,58 @@ static void wsrep_log_cb(wsrep::log::level level, const char *msg) } } +void wsrep_init_gtid() +{ + wsrep_server_gtid_t stored_gtid= wsrep_get_SE_checkpoint<wsrep_server_gtid_t>(); + if (stored_gtid.server_id == 0) + { + rpl_gtid wsrep_last_gtid; + stored_gtid.domain_id= wsrep_gtid_server.domain_id; + if (mysql_bin_log.is_open() && + mysql_bin_log.lookup_domain_in_binlog_state(stored_gtid.domain_id, + &wsrep_last_gtid)) + { + stored_gtid.server_id= wsrep_last_gtid.server_id; + stored_gtid.seqno= wsrep_last_gtid.seq_no; + } + else + { + stored_gtid.server_id= global_system_variables.server_id; + stored_gtid.seqno= 0; + } + } + wsrep_gtid_server.gtid(stored_gtid); +} + +bool wsrep_get_binlog_gtid_seqno(wsrep_server_gtid_t& gtid) +{ + rpl_gtid binlog_gtid; + int ret= 0; + if (mysql_bin_log.is_open() && + mysql_bin_log.find_in_binlog_state(gtid.domain_id, + gtid.server_id, + &binlog_gtid)) + { + gtid.domain_id= binlog_gtid.domain_id; + gtid.server_id= binlog_gtid.server_id; + gtid.seqno= binlog_gtid.seq_no; + ret= 1; + } + return ret; +} + +bool wsrep_check_gtid_seqno(const uint32& domain, const uint32& server, + uint64& seqno) +{ + if (domain == wsrep_gtid_server.domain_id && + server == wsrep_gtid_server.server_id) + { + if (wsrep_gtid_server.seqno_committed() < seqno) return 1; + return 0; + } + return 0; +} + void wsrep_init_sidno(const wsrep::id& uuid) { /* @@ -692,6 +743,16 @@ int wsrep_init_server() void wsrep_init_globals() { wsrep_init_sidno(Wsrep_server_state::instance().connected_gtid().id()); + wsrep_init_gtid(); + /* Recover last written wsrep gtid */ + if (wsrep_new_cluster) + { + wsrep_server_gtid_t gtid= {wsrep_gtid_server.domain_id, + wsrep_gtid_server.server_id, 0}; + wsrep_get_binlog_gtid_seqno(gtid); + wsrep_gtid_server.seqno(gtid.seqno); + } + wsrep_new_cluster= 0; wsrep_init_schema(); if (WSREP_ON) { @@ -793,6 +854,7 @@ void wsrep_thr_init() mysql_cond_init(key_COND_wsrep_replaying, &COND_wsrep_replaying, NULL); mysql_mutex_init(key_LOCK_wsrep_slave_threads, &LOCK_wsrep_slave_threads, MY_MUTEX_INIT_FAST); mysql_cond_init(key_COND_wsrep_slave_threads, &COND_wsrep_slave_threads, NULL); + mysql_mutex_init(key_LOCK_wsrep_gtid_wait_upto, &LOCK_wsrep_gtid_wait_upto, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_wsrep_cluster_config, &LOCK_wsrep_cluster_config, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_wsrep_desync, &LOCK_wsrep_desync, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_wsrep_config_state, &LOCK_wsrep_config_state, MY_MUTEX_INIT_FAST); @@ -903,6 +965,7 @@ void wsrep_thr_deinit() mysql_cond_destroy(&COND_wsrep_sst_init); mysql_mutex_destroy(&LOCK_wsrep_replaying); mysql_cond_destroy(&COND_wsrep_replaying); + mysql_mutex_destroy(&LOCK_wsrep_gtid_wait_upto); mysql_mutex_destroy(&LOCK_wsrep_slave_threads); mysql_cond_destroy(&COND_wsrep_slave_threads); mysql_mutex_destroy(&LOCK_wsrep_cluster_config); @@ -939,10 +1002,20 @@ void wsrep_recover() uuid_str, (long long)local_seqno); return; } - wsrep::gtid gtid= wsrep_get_SE_checkpoint(); + wsrep::gtid gtid= wsrep_get_SE_checkpoint<wsrep::gtid>(); std::ostringstream oss; oss << gtid; - WSREP_INFO("Recovered position: %s", oss.str().c_str()); + if (wsrep_gtid_mode) + { + wsrep_server_gtid_t server_gtid= wsrep_get_SE_checkpoint<wsrep_server_gtid_t>(); + WSREP_INFO("Recovered position: %s,%d-%d-%llu", oss.str().c_str(), server_gtid.domain_id, + server_gtid.server_id, server_gtid.seqno); + } + else + { + WSREP_INFO("Recovered position: %s", oss.str().c_str()); + } + } @@ -1012,7 +1085,6 @@ bool wsrep_start_replication() } bool const bootstrap(TRUE == wsrep_new_cluster); - wsrep_new_cluster= FALSE; WSREP_INFO("Start replication"); @@ -1445,16 +1517,36 @@ int wsrep_to_buf_helper( if (!ret && writer.write(>id_ev)) ret= 1; } #endif /* GTID_SUPPORT */ - if (wsrep_gtid_mode && thd->variables.gtid_seq_no) + /* + * Check if this is applier thread, slave_thread or + * we have set manually WSREP GTID seqno. Add GTID event. + */ + if (thd->slave_thread || wsrep_thd_is_applying(thd) || + thd->variables.wsrep_gtid_seq_no) { - Gtid_log_event gtid_event(thd, thd->variables.gtid_seq_no, - thd->variables.gtid_domain_id, - true, LOG_EVENT_SUPPRESS_USE_F, - true, 0); - gtid_event.server_id= thd->variables.server_id; + uint64 seqno= thd->variables.gtid_seq_no; + uint32 domain_id= thd->variables.gtid_domain_id; + uint32 server_id= thd->variables.server_id; + if (!thd->variables.gtid_seq_no && thd->variables.wsrep_gtid_seq_no) + { + seqno= thd->variables.wsrep_gtid_seq_no; + domain_id= wsrep_gtid_server.domain_id; + server_id= wsrep_gtid_server.server_id; + } + Gtid_log_event gtid_event(thd, seqno, domain_id, true, + LOG_EVENT_SUPPRESS_USE_F, true, 0); + gtid_event.server_id= server_id; if (!gtid_event.is_valid()) ret= 0; ret= writer.write(>id_event); } + /* + It's local DDL so in case of possible gtid seqno (SET gtid_seq_no=X) + manipulation, seqno value will be ignored. + */ + else + { + thd->variables.gtid_seq_no= 0; + } /* if there is prepare query, add event for it */ if (!ret && thd->wsrep_TOI_pre_query) @@ -1468,6 +1560,9 @@ int wsrep_to_buf_helper( /* continue to append the actual query */ Query_log_event ev(thd, query, query_len, FALSE, FALSE, FALSE, 0); + /* WSREP GTID mode, we need to change server_id */ + if (wsrep_gtid_mode && !thd->variables.gtid_seq_no) + ev.server_id= wsrep_gtid_server.server_id; ev.checksum_alg= current_binlog_check_alg; if (!ret && writer.write(&ev)) ret= 1; if (!ret && wsrep_write_cache_buf(&tmp_io_cache, buf, buf_len)) ret= 1; @@ -1947,6 +2042,28 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table, rc= -1; } else { + if (!thd->variables.gtid_seq_no) + { + uint64 seqno= 0; + if (thd->variables.wsrep_gtid_seq_no && + thd->variables.wsrep_gtid_seq_no > wsrep_gtid_server.seqno()) + { + seqno= thd->variables.wsrep_gtid_seq_no; + wsrep_gtid_server.seqno(thd->variables.wsrep_gtid_seq_no); + } + else + { + seqno= wsrep_gtid_server.seqno_inc(); + } + thd->variables.wsrep_gtid_seq_no= 0; + thd->wsrep_current_gtid_seqno= seqno; + if (mysql_bin_log.is_open() && wsrep_gtid_mode) + { + thd->variables.gtid_seq_no= seqno; + thd->variables.gtid_domain_id= wsrep_gtid_server.domain_id; + thd->variables.server_id= wsrep_gtid_server.server_id; + } + } ++wsrep_to_isolation; rc= 0; } @@ -1965,15 +2082,22 @@ static void wsrep_TOI_end(THD *thd) { WSREP_DEBUG("TO END: %lld: %s", client_state.toi_meta().seqno().get(), WSREP_QUERY(thd)); + wsrep_gtid_server.signal_waiters(thd->wsrep_current_gtid_seqno, false); + if (wsrep_thd_is_local_toi(thd)) { - wsrep_set_SE_checkpoint(client_state.toi_meta().gtid()); wsrep::mutable_buffer err; + + thd->wsrep_last_written_gtid_seqno= thd->wsrep_current_gtid_seqno; + wsrep_set_SE_checkpoint(client_state.toi_meta().gtid(), wsrep_gtid_server.gtid()); + if (thd->is_error() && !wsrep_must_ignore_error(thd)) { - wsrep_store_error(thd, err); + wsrep_store_error(thd, err); } + int const ret= client_state.leave_toi_local(err); + if (!ret) { WSREP_DEBUG("TO END: %lld", client_state.toi_meta().seqno().get()); @@ -2666,12 +2790,6 @@ void* start_wsrep_THD(void *arg) statistic_increment(thread_created, &LOCK_status); - if (wsrep_gtid_mode) - { - /* Adjust domain_id. */ - thd->variables.gtid_domain_id= wsrep_gtid_domain_id; - } - thd->real_id=pthread_self(); // Keep purify happy my_net_init(&thd->net,(st_vio*) 0, thd, MYF(0)); diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 5ad68fbe423..222b265248f 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -38,6 +38,7 @@ typedef struct st_mysql_show_var SHOW_VAR; #include "wsrep/streaming_context.hpp" #include "wsrep_api.h" #include <vector> +#include <map> #include "wsrep_server_state.h" #define WSREP_UNDEFINED_TRX_ID ULONGLONG_MAX @@ -97,7 +98,6 @@ extern ulong wsrep_running_applier_threads; extern ulong wsrep_running_rollbacker_threads; extern bool wsrep_new_cluster; extern bool wsrep_gtid_mode; -extern uint32 wsrep_gtid_domain_id; enum enum_wsrep_reject_types { WSREP_REJECT_NONE, /* nothing rejected */ @@ -303,6 +303,7 @@ extern mysql_mutex_t LOCK_wsrep_replaying; extern mysql_cond_t COND_wsrep_replaying; extern mysql_mutex_t LOCK_wsrep_slave_threads; extern mysql_cond_t COND_wsrep_slave_threads; +extern mysql_mutex_t LOCK_wsrep_gtid_wait_upto; extern mysql_mutex_t LOCK_wsrep_cluster_config; extern mysql_mutex_t LOCK_wsrep_desync; extern mysql_mutex_t LOCK_wsrep_SR_pool; @@ -316,9 +317,6 @@ extern mysql_cond_t COND_wsrep_donor_monitor; extern my_bool wsrep_emulate_bin_log; extern int wsrep_to_isolation; -#ifdef GTID_SUPPORT -extern rpl_sidno wsrep_sidno; -#endif /* GTID_SUPPORT */ extern my_bool wsrep_preordered_opt; #ifdef HAVE_PSI_INTERFACE @@ -337,6 +335,8 @@ extern PSI_mutex_key key_LOCK_wsrep_replaying; extern PSI_cond_key key_COND_wsrep_replaying; extern PSI_mutex_key key_LOCK_wsrep_slave_threads; extern PSI_cond_key key_COND_wsrep_slave_threads; +extern PSI_mutex_key key_LOCK_wsrep_gtid_wait_upto; +extern PSI_cond_key key_COND_wsrep_gtid_wait_upto; extern PSI_mutex_key key_LOCK_wsrep_cluster_config; extern PSI_mutex_key key_LOCK_wsrep_desync; extern PSI_mutex_key key_LOCK_wsrep_SR_pool; @@ -387,7 +387,122 @@ class Log_event; int wsrep_ignored_error_code(Log_event* ev, int error); int wsrep_must_ignore_error(THD* thd); -bool wsrep_replicate_GTID(THD* thd); +struct wsrep_server_gtid_t +{ + uint32 domain_id; + uint32 server_id; + uint64 seqno; +}; +class Wsrep_gtid_server +{ +public: + uint32 domain_id; + uint32 server_id; + Wsrep_gtid_server() + : m_force_signal(false) + , m_seqno(0) + , m_committed_seqno(0) + { } + void gtid(const wsrep_server_gtid_t& gtid) + { + domain_id= gtid.domain_id; + server_id= gtid.server_id; + m_seqno= gtid.seqno; + } + wsrep_server_gtid_t gtid() + { + wsrep_server_gtid_t gtid; + gtid.domain_id= domain_id; + gtid.server_id= server_id; + gtid.seqno= m_seqno; + return gtid; + } + void seqno(const uint64 seqno) { m_seqno= seqno; } + uint64 seqno() const { return m_seqno; } + uint64 seqno_committed() const { return m_committed_seqno; } + uint64 seqno_inc() + { + m_seqno++; + return m_seqno; + } + const wsrep_server_gtid_t& undefined() + { + return m_undefined; + } + int wait_gtid_upto(const uint64_t seqno, uint timeout) + { + int wait_result; + struct timespec wait_time; + int ret= 0; + mysql_cond_t wait_cond; + mysql_cond_init(key_COND_wsrep_gtid_wait_upto, &wait_cond, NULL); + set_timespec(wait_time, timeout); + mysql_mutex_lock(&LOCK_wsrep_gtid_wait_upto); + std::multimap<uint64, mysql_cond_t*>::iterator it; + try + { + it= m_wait_map.insert(std::make_pair(seqno, &wait_cond)); + } + catch (std::bad_alloc& e) + { + return 0; + } + while ((m_committed_seqno < seqno) && !m_force_signal) + { + wait_result= mysql_cond_timedwait(&wait_cond, + &LOCK_wsrep_gtid_wait_upto, + &wait_time); + if (wait_result == ETIMEDOUT || wait_result == ETIME) + { + ret= 1; + break; + } + } + m_wait_map.erase(it); + mysql_mutex_unlock(&LOCK_wsrep_gtid_wait_upto); + mysql_cond_destroy(&wait_cond); + return ret; + } + void signal_waiters(uint64 seqno, bool signal_all) + { + if (!signal_all && (m_committed_seqno >= seqno)) + { + return; + } + mysql_mutex_lock(&LOCK_wsrep_gtid_wait_upto); + m_force_signal= true; + std::multimap<uint64, mysql_cond_t*>::iterator it_end; + std::multimap<uint64, mysql_cond_t*>::iterator it_begin; + if (signal_all) + { + it_end= m_wait_map.end(); + } + else + { + it_end= m_wait_map.upper_bound(seqno); + } + for (it_begin = m_wait_map.begin(); it_begin != it_end; ++it_begin) + { + mysql_cond_signal(it_begin->second); + } + m_force_signal= false; + mysql_mutex_unlock(&LOCK_wsrep_gtid_wait_upto); + if (m_committed_seqno < seqno) + { + m_committed_seqno= seqno; + } + } +private: + const wsrep_server_gtid_t m_undefined= {0,0,0}; + std::multimap<uint64, mysql_cond_t*> m_wait_map; + bool m_force_signal; + Atomic_counter<uint64_t> m_seqno; + Atomic_counter<uint64_t> m_committed_seqno; +}; +extern Wsrep_gtid_server wsrep_gtid_server; +void wsrep_init_gtid(); +bool wsrep_check_gtid_seqno(const uint32&, const uint32&, uint64&); +bool wsrep_get_binlog_gtid_seqno(wsrep_server_gtid_t&); typedef struct wsrep_key_arr { diff --git a/sql/wsrep_server_service.cc b/sql/wsrep_server_service.cc index d0a9b54ac1b..6d737463f07 100644 --- a/sql/wsrep_server_service.cc +++ b/sql/wsrep_server_service.cc @@ -153,7 +153,7 @@ void Wsrep_server_service::bootstrap() wsrep::log_info() << "Bootstrapping a new cluster, setting initial position to " << wsrep::gtid::undefined(); - wsrep_set_SE_checkpoint(wsrep::gtid::undefined()); + wsrep_set_SE_checkpoint(wsrep::gtid::undefined(), wsrep_gtid_server.undefined()); } void Wsrep_server_service::log_message(enum wsrep::log::level level, @@ -212,7 +212,7 @@ void Wsrep_server_service::log_view( if (prev_view.state_id().id() != view.state_id().id()) { WSREP_DEBUG("New cluster UUID was generated, resetting position info"); - wsrep_set_SE_checkpoint(wsrep::gtid::undefined()); + wsrep_set_SE_checkpoint(wsrep::gtid::undefined(), wsrep_gtid_server.undefined()); checkpoint_was_reset= true; } @@ -263,9 +263,9 @@ void Wsrep_server_service::log_view( Wsrep_server_state::instance().provider().last_committed_gtid().seqno(); if (checkpoint_was_reset || last_committed != view.state_id().seqno()) { - wsrep_set_SE_checkpoint(view.state_id()); + wsrep_set_SE_checkpoint(view.state_id(), wsrep_gtid_server.gtid()); } - DBUG_ASSERT(wsrep_get_SE_checkpoint().id() == view.state_id().id()); + DBUG_ASSERT(wsrep_get_SE_checkpoint<wsrep::gtid>().id() == view.state_id().id()); } else { @@ -299,13 +299,13 @@ wsrep::view Wsrep_server_service::get_view(wsrep::client_service& c, wsrep::gtid Wsrep_server_service::get_position(wsrep::client_service&) { - return wsrep_get_SE_checkpoint(); + return wsrep_get_SE_checkpoint<wsrep::gtid>(); } void Wsrep_server_service::set_position(wsrep::client_service&, const wsrep::gtid& gtid) { - wsrep_set_SE_checkpoint(gtid); + wsrep_set_SE_checkpoint(gtid, wsrep_gtid_server.gtid()); } void Wsrep_server_service::log_state_change( diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index 02f7d4b6760..d478ea486cd 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -351,8 +351,8 @@ void wsrep_sst_received (THD* thd, wsrep::seqno(seqno)); if (!wsrep_before_SE()) { - wsrep_set_SE_checkpoint(wsrep::gtid::undefined()); - wsrep_set_SE_checkpoint(sst_gtid); + wsrep_set_SE_checkpoint(wsrep::gtid::undefined(), wsrep_gtid_server.undefined()); + wsrep_set_SE_checkpoint(sst_gtid, wsrep_gtid_server.gtid()); } wsrep_verify_SE_checkpoint(uuid, seqno); @@ -594,7 +594,7 @@ static void* sst_joiner_thread (void* a) err= EINVAL; goto err; } else { - wsrep_gtid_domain_id= (uint32) domain_id; + wsrep_gtid_server.domain_id= (uint32) domain_id; } } } @@ -1365,13 +1365,15 @@ static int sst_donate_mysqldump (const char* addr, WSREP_SST_OPT_LPORT " '%u' " WSREP_SST_OPT_SOCKET " '%s' " "%s" - WSREP_SST_OPT_GTID " '%s:%lld' " + WSREP_SST_OPT_GTID " '%s:%lld,%d-%d-%llu' " WSREP_SST_OPT_GTID_DOMAIN_ID " '%d'" "%s", addr, port, mysqld_port, mysqld_unix_port, wsrep_defaults_file, uuid_oss.str().c_str(), gtid.seqno().get(), - wsrep_gtid_domain_id, + wsrep_gtid_server.domain_id, wsrep_gtid_server.server_id, + wsrep_gtid_server.seqno(), + wsrep_gtid_server.domain_id, bypass ? " " WSREP_SST_OPT_BYPASS : ""); if (ret < 0 || size_t(ret) >= cmd_len) @@ -1538,7 +1540,7 @@ static int sst_flush_tables(THD* thd) */ char content[100]; snprintf(content, sizeof(content), "%s:%lld %d\n", wsrep_cluster_state_uuid, - (long long)wsrep_locked_seqno, wsrep_gtid_domain_id); + (long long)wsrep_locked_seqno, wsrep_gtid_server.domain_id); err= sst_create_file(flush_success, content); const char base_name[]= "tables_flushed"; @@ -1563,7 +1565,7 @@ static int sst_flush_tables(THD* thd) fprintf(file, "%s:%lld %u\n", uuid_oss.str().c_str(), server_state.pause_seqno().get(), - wsrep_gtid_domain_id); + wsrep_gtid_server.domain_id); fsync(fileno(file)); fclose(file); if (rename(tmp_name, real_name) == -1) @@ -1783,7 +1785,7 @@ static int sst_donate_other (const char* method, "%s", method, addr, mysqld_unix_port, mysql_real_data_home, wsrep_defaults_file, - uuid_oss.str().c_str(), gtid.seqno().get(), wsrep_gtid_domain_id, + uuid_oss.str().c_str(), gtid.seqno().get(), wsrep_gtid_server.domain_id, binlog_opt_val, binlog_index_opt_val, bypass ? " " WSREP_SST_OPT_BYPASS : ""); diff --git a/sql/wsrep_trans_observer.h b/sql/wsrep_trans_observer.h index b8ce7eb42d0..006d412e6aa 100644 --- a/sql/wsrep_trans_observer.h +++ b/sql/wsrep_trans_observer.h @@ -233,7 +233,8 @@ static inline int wsrep_before_prepare(THD* thd, bool all) { DBUG_ASSERT(!thd->wsrep_trx().ws_meta().gtid().is_undefined()); wsrep_xid_init(&thd->wsrep_xid, - thd->wsrep_trx().ws_meta().gtid()); + thd->wsrep_trx().ws_meta().gtid(), + wsrep_gtid_server.gtid()); } DBUG_RETURN(ret); } @@ -273,8 +274,33 @@ static inline int wsrep_before_commit(THD* thd, bool all) if ((ret= thd->wsrep_cs().before_commit()) == 0) { DBUG_ASSERT(!thd->wsrep_trx().ws_meta().gtid().is_undefined()); + if (!thd->variables.gtid_seq_no && + (thd->wsrep_trx().ws_meta().flags() & wsrep::provider::flag::commit)) + { + uint64 seqno= 0; + if (thd->variables.wsrep_gtid_seq_no && + thd->variables.wsrep_gtid_seq_no > wsrep_gtid_server.seqno()) + { + seqno= thd->variables.wsrep_gtid_seq_no; + wsrep_gtid_server.seqno(thd->variables.wsrep_gtid_seq_no); + } + else + { + seqno= wsrep_gtid_server.seqno_inc(); + } + thd->variables.wsrep_gtid_seq_no= 0; + thd->wsrep_current_gtid_seqno= seqno; + if (mysql_bin_log.is_open() && wsrep_gtid_mode) + { + thd->variables.gtid_seq_no= seqno; + thd->variables.gtid_domain_id= wsrep_gtid_server.domain_id; + thd->variables.server_id= wsrep_gtid_server.server_id; + } + } + wsrep_xid_init(&thd->wsrep_xid, - thd->wsrep_trx().ws_meta().gtid()); + thd->wsrep_trx().ws_meta().gtid(), + wsrep_gtid_server.gtid()); wsrep_register_for_group_commit(thd); } DBUG_RETURN(ret); diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index 5f76f650b34..daf12f94fb9 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -37,7 +37,10 @@ int wsrep_init_vars() wsrep_node_name = my_strdup("", MYF(MY_WME)); wsrep_node_address = my_strdup("", MYF(MY_WME)); wsrep_node_incoming_address= my_strdup(WSREP_NODE_INCOMING_AUTO, MYF(MY_WME)); - wsrep_start_position = my_strdup(WSREP_START_POSITION_ZERO, MYF(MY_WME)); + if (wsrep_gtid_mode) + wsrep_start_position = my_strdup(WSREP_START_POSITION_ZERO_GTID, MYF(MY_WME)); + else + wsrep_start_position = my_strdup(WSREP_START_POSITION_ZERO, MYF(MY_WME)); return 0; } @@ -103,6 +106,13 @@ bool wsrep_sync_wait_update (sys_var* self, THD* thd, enum_var_type var_type) return false; } +template<typename T> +static T parse_value(char** startptr, char** endptr) +{ + T val= strtoll(*startptr, *&endptr, 10); + *startptr= *endptr; + return val; +} /* Verify the format of the given UUID:seqno. @@ -136,8 +146,25 @@ bool wsrep_start_position_verify (const char* start_str) return true; char* endptr; + char* startptr= (char *)start_str + uuid_len + 1; wsrep_seqno_t const seqno __attribute__((unused)) // to avoid GCC warnings - (strtoll(&start_str[uuid_len + 1], &endptr, 10)); + (parse_value<uint64_t>(&startptr, &endptr)); + + // Start parsing native GTID part + if (*startptr == ',') + { + startptr++; + uint32_t domain __attribute__((unused)) + (parse_value<uint32_t>(&startptr, &endptr)); + if (*endptr != '-') return true; + startptr++; + uint32_t server __attribute__((unused)) + (parse_value<uint32_t>(&startptr, &endptr)); + if (*endptr != '-') return true; + startptr++; + uint64_t seq __attribute__((unused)) + (parse_value<uint64_t>(&startptr, &endptr)); + } // Remaining string was seqno. if (*endptr == '\0') return false; @@ -150,9 +177,22 @@ static bool wsrep_set_local_position(THD* thd, const char* const value, size_t length, bool const sst) { + char* endptr; + char* startptr; wsrep_uuid_t uuid; size_t const uuid_len= wsrep_uuid_scan(value, length, &uuid); - wsrep_seqno_t const seqno= strtoll(value + uuid_len + 1, NULL, 10); + startptr= (char *)value + uuid_len + 1; + wsrep_seqno_t const seqno= parse_value<uint64_t>(&startptr, &endptr); + + if (*startptr == ',') + { + startptr++; + wsrep_gtid_server.domain_id= parse_value<uint32_t>(&startptr, &endptr); + startptr++; + wsrep_gtid_server.server_id= parse_value<uint32_t>(&startptr, &endptr); + startptr++; + wsrep_gtid_server.seqno(parse_value<uint64_t>(&startptr, &endptr)); + } if (sst) { wsrep_sst_received (thd, uuid, seqno, NULL, 0); @@ -436,6 +476,15 @@ bool wsrep_debug_update(sys_var *self, THD* thd, enum_var_type type) return false; } +bool +wsrep_gtid_seq_no_check(sys_var *self, THD *thd, set_var *var) +{ + ulonglong new_wsrep_gtid_seq_no= var->save_result.ulonglong_value; + if (wsrep_gtid_mode && new_wsrep_gtid_seq_no > wsrep_gtid_server.seqno()) + return false; + return true; +} + static int wsrep_cluster_address_verify (const char* cluster_address_str) { /* There is no predefined address format, it depends on provider. */ diff --git a/sql/wsrep_var.h b/sql/wsrep_var.h index 481df02f2d5..810ed4f3dd7 100644 --- a/sql/wsrep_var.h +++ b/sql/wsrep_var.h @@ -20,9 +20,10 @@ #ifdef WITH_WSREP -#define WSREP_CLUSTER_NAME "my_wsrep_cluster" -#define WSREP_NODE_INCOMING_AUTO "AUTO" -#define WSREP_START_POSITION_ZERO "00000000-0000-0000-0000-000000000000:-1" +#define WSREP_CLUSTER_NAME "my_wsrep_cluster" +#define WSREP_NODE_INCOMING_AUTO "AUTO" +#define WSREP_START_POSITION_ZERO "00000000-0000-0000-0000-000000000000:-1" +#define WSREP_START_POSITION_ZERO_GTID "00000000-0000-0000-0000-000000000000:-1,0-0-0" // MySQL variables funcs @@ -102,6 +103,8 @@ extern bool wsrep_reject_queries_update UPDATE_ARGS; extern bool wsrep_debug_update UPDATE_ARGS; +extern bool wsrep_gtid_seq_no_check CHECK_ARGS; + #else /* WITH_WSREP */ #define wsrep_provider_init(X) diff --git a/sql/wsrep_xid.cc b/sql/wsrep_xid.cc index d8f6e013820..c84071e13d0 100644 --- a/sql/wsrep_xid.cc +++ b/sql/wsrep_xid.cc @@ -33,20 +33,24 @@ #define WSREP_XID_VERSION_OFFSET WSREP_XID_PREFIX_LEN #define WSREP_XID_VERSION_1 'd' #define WSREP_XID_VERSION_2 'e' +#define WSREP_XID_VERSION_3 'f' #define WSREP_XID_UUID_OFFSET 8 #define WSREP_XID_SEQNO_OFFSET (WSREP_XID_UUID_OFFSET + sizeof(wsrep_uuid_t)) -#define WSREP_XID_GTRID_LEN (WSREP_XID_SEQNO_OFFSET + sizeof(wsrep_seqno_t)) +#define WSREP_XID_GTRID_LEN_V_1_2 (WSREP_XID_SEQNO_OFFSET + sizeof(wsrep_seqno_t)) +#define WSREP_XID_RPL_GTID_OFFSET (WSREP_XID_SEQNO_OFFSET + sizeof(wsrep_seqno_t)) +#define WSREP_XID_GTRID_LEN_V_3 (WSREP_XID_RPL_GTID_OFFSET + sizeof(wsrep_server_gtid_t)) -void wsrep_xid_init(XID* xid, const wsrep::gtid& wsgtid) +void wsrep_xid_init(XID* xid, const wsrep::gtid& wsgtid, const wsrep_server_gtid_t& gtid) { xid->formatID= 1; - xid->gtrid_length= WSREP_XID_GTRID_LEN; + xid->gtrid_length= WSREP_XID_GTRID_LEN_V_3; xid->bqual_length= 0; memset(xid->data, 0, sizeof(xid->data)); memcpy(xid->data, WSREP_XID_PREFIX, WSREP_XID_PREFIX_LEN); - xid->data[WSREP_XID_VERSION_OFFSET]= WSREP_XID_VERSION_2; + xid->data[WSREP_XID_VERSION_OFFSET]= WSREP_XID_VERSION_3; memcpy(xid->data + WSREP_XID_UUID_OFFSET, wsgtid.id().data(),sizeof(wsrep::id)); int8store(xid->data + WSREP_XID_SEQNO_OFFSET, wsgtid.seqno().get()); + memcpy(xid->data + WSREP_XID_RPL_GTID_OFFSET, >id, sizeof(wsrep_server_gtid_t)); } extern "C" @@ -54,11 +58,13 @@ int wsrep_is_wsrep_xid(const void* xid_ptr) { const XID* xid= static_cast<const XID*>(xid_ptr); return (xid->formatID == 1 && - xid->gtrid_length == WSREP_XID_GTRID_LEN && xid->bqual_length == 0 && - !memcmp(xid->data, WSREP_XID_PREFIX, WSREP_XID_PREFIX_LEN) && - (xid->data[WSREP_XID_VERSION_OFFSET] == WSREP_XID_VERSION_1 || - xid->data[WSREP_XID_VERSION_OFFSET] == WSREP_XID_VERSION_2)); + !memcmp(xid->data, WSREP_XID_PREFIX, WSREP_XID_PREFIX_LEN) && + (((xid->data[WSREP_XID_VERSION_OFFSET] == WSREP_XID_VERSION_1 || + xid->data[WSREP_XID_VERSION_OFFSET] == WSREP_XID_VERSION_2) && + xid->gtrid_length == WSREP_XID_GTRID_LEN_V_1_2) || + (xid->data[WSREP_XID_VERSION_OFFSET] == WSREP_XID_VERSION_3 && + xid->gtrid_length == WSREP_XID_GTRID_LEN_V_3))); } const unsigned char* wsrep_xid_uuid(const xid_t* xid) @@ -90,6 +96,7 @@ long long wsrep_xid_seqno(const xid_t* xid) memcpy(&ret, xid->data + WSREP_XID_SEQNO_OFFSET, sizeof ret); break; case WSREP_XID_VERSION_2: + case WSREP_XID_VERSION_3: ret= sint8korr(xid->data + WSREP_XID_SEQNO_OFFSET); break; default: @@ -127,10 +134,10 @@ bool wsrep_set_SE_checkpoint(XID& xid) &xid); } -bool wsrep_set_SE_checkpoint(const wsrep::gtid& wsgtid) +bool wsrep_set_SE_checkpoint(const wsrep::gtid& wsgtid, const wsrep_server_gtid_t& gtid) { XID xid; - wsrep_xid_init(&xid, wsgtid); + wsrep_xid_init(&xid, wsgtid, gtid); return wsrep_set_SE_checkpoint(xid); } @@ -158,30 +165,61 @@ bool wsrep_get_SE_checkpoint(XID& xid) &xid); } -wsrep::gtid wsrep_get_SE_checkpoint() +static bool wsrep_get_SE_checkpoint_common(XID& xid) { - XID xid; xid.null(); if (wsrep_get_SE_checkpoint(xid)) { - return wsrep::gtid(); + return FALSE; } if (xid.is_null()) { - return wsrep::gtid(); + return FALSE; } if (!wsrep_is_wsrep_xid(&xid)) { WSREP_WARN("Read non-wsrep XID from storage engines."); + return FALSE; + } + + return TRUE; +} + +template<> +wsrep::gtid wsrep_get_SE_checkpoint() +{ + XID xid; + + if (!wsrep_get_SE_checkpoint_common(xid)) + { return wsrep::gtid(); } return wsrep::gtid(wsrep_xid_uuid(xid),wsrep_xid_seqno(xid)); } +template<> +wsrep_server_gtid_t wsrep_get_SE_checkpoint() +{ + XID xid; + wsrep_server_gtid_t gtid= {0,0,0}; + + if (!wsrep_get_SE_checkpoint_common(xid)) + { + return gtid; + } + + if (xid.data[WSREP_XID_VERSION_OFFSET] == WSREP_XID_VERSION_3) + { + memcpy(>id, &xid.data[WSREP_XID_RPL_GTID_OFFSET], sizeof(wsrep_server_gtid_t)); + } + + return gtid; +} + /* Sort order for XIDs. Wsrep XIDs are sorted according to seqno in ascending order. Non-wsrep XIDs are considered diff --git a/sql/wsrep_xid.h b/sql/wsrep_xid.h index a1b9afc1817..45ba6ffee6b 100644 --- a/sql/wsrep_xid.h +++ b/sql/wsrep_xid.h @@ -20,15 +20,16 @@ #ifdef WITH_WSREP +#include "wsrep_mysqld.h" #include "wsrep/gtid.hpp" #include "handler.h" // XID typedef -void wsrep_xid_init(xid_t*, const wsrep::gtid&); +void wsrep_xid_init(xid_t*, const wsrep::gtid&, const wsrep_server_gtid_t&); const wsrep::id& wsrep_xid_uuid(const XID&); wsrep::seqno wsrep_xid_seqno(const XID&); -wsrep::gtid wsrep_get_SE_checkpoint(); -bool wsrep_set_SE_checkpoint(const wsrep::gtid& gtid); +template<typename T> T wsrep_get_SE_checkpoint(); +bool wsrep_set_SE_checkpoint(const wsrep::gtid& gtid, const wsrep_server_gtid_t&); //void wsrep_get_SE_checkpoint(XID&); /* uncomment if needed */ //void wsrep_set_SE_checkpoint(XID&); /* uncomment if needed */ |