summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSachin Setiya <sachinsetia1001@gmail.com>2017-12-25 05:09:49 +0530
committerSachin Setiya <sachinsetia1001@gmail.com>2017-12-25 05:09:49 +0530
commit5a4d45980c5365cf7df7c5bb4e67893dc8e3198a (patch)
treedb8a2561edcf2f043fdedc8d58f0063cfc8328f2
parentde76cbdcb0728b80c0f7b453b24b0b81f653e450 (diff)
downloadmariadb-git-bb-10.1-10715.tar.gz
MDEV-10715 Galera: Replicate MariaDB GTID to other nodes in the clusterbb-10.1-10715
Problem:- Gtid are not transferred in Galera Cluster. Solution:- We need to transfer gtid in the case on either when cluster is slave/master in async replication. In normal Gtid replication gtid are generated on recieving node itself and it is always on sync with other nodes. Because galera keeps node in sync , So all nodes get same no of event groups. So the issue arises when say galera is slave in async replication. A | (Async replication) D <-> E <-> F {Galera replication} So what should happen is that all node should apply the master gtid but this does node happen, becuase node E, F does not recieve gtid from D in write set , So what E(or F) does is that it applies wsrep_gtid_domain_id, D server-id , E gtid next seq no. This generated gtid does not always work when say A has different domain id. So In this commit, on galera node when we see that this event is recieved from master we simply write Gtid_Log_Event in write_set and send it to other nodes.
-rw-r--r--mysql-test/suite/galera/r/galera_gtid_slave.result26
-rw-r--r--mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result130
-rw-r--r--mysql-test/suite/galera/t/galera_gtid_slave.cnf18
-rw-r--r--mysql-test/suite/galera/t/galera_gtid_slave.test78
-rw-r--r--mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.cnf18
-rw-r--r--mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test207
-rw-r--r--mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf122
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_gtid_2_cluster.result231
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.cnf28
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.test292
-rw-r--r--sql/log.cc88
-rw-r--r--sql/log.h8
-rw-r--r--sql/wsrep_mysqld.cc10
13 files changed, 1253 insertions, 3 deletions
diff --git a/mysql-test/suite/galera/r/galera_gtid_slave.result b/mysql-test/suite/galera/r/galera_gtid_slave.result
new file mode 100644
index 00000000000..40f3f1c0d53
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_gtid_slave.result
@@ -0,0 +1,26 @@
+START SLAVE;
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t2 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(1);
+begin;
+insert into t2 values(21);
+insert into t2 values(22);
+commit;
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4
+INSERT INTO t1 VALUES(2);
+INSERT INTO t1 VALUES(3);
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4,2-2-2
+INSERT INTO t1 VALUES(4);
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4,2-2-2,2-3-3
+DROP TABLE t1,t2;
+reset master;
+STOP SLAVE;
+RESET SLAVE ALL;
+reset master;
+reset master;
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
new file mode 100644
index 00000000000..81fae57d731
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result
@@ -0,0 +1,130 @@
+#Connection 2
+START SLAVE;
+#Connection 1
+CREATE TABLE t2 (f1 INTEGER PRIMARY KEY, f2 int unique) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(1,11);
+INSERT INTO t2 VALUES(2,22);
+INSERT INTO t2 VALUES(3,33);
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4
+include/save_master_gtid.inc
+#Connection 2
+include/sync_with_master_gtid.inc
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4
+INSERT INTO t2 VALUES(4,44);
+INSERT INTO t2 VALUES(5,55);
+INSERT INTO t2 VALUES(6,66);
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4,2-2-3
+#Connection 3
+INSERT INTO t2 VALUES(7,77);
+INSERT INTO t2 VALUES(8,88);
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-4,2-2-3,2-3-5
+#Connection 1
+CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+COMMIT;
+include/save_master_gtid.inc
+#Connection 2
+include/sync_with_master_gtid.inc
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+COMMIT;
+#Connection 3
+Shutting down server ...
+#Connection 2
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+COMMIT;
+#Connection 3
+Starting server ...
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node3_committed_after');
+INSERT INTO t1 VALUES ('node3_committed_after');
+COMMIT;
+#Connection 2
+Select * from t1 order by f1;
+f1
+node1_committed_before
+node1_committed_before
+node1_committed_during
+node1_committed_during
+node2_committed_before
+node2_committed_before
+node3_committed_after
+node3_committed_after
+#Connection 3
+Select * from t1 order by f1;
+f1
+node1_committed_before
+node1_committed_before
+node1_committed_during
+node1_committed_during
+node2_committed_before
+node2_committed_before
+node3_committed_after
+node3_committed_after
+#Connection 2
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-6,2-2-7,2-3-8
+#Connection 3
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-6,2-2-7,2-3-8
+#Connection 1
+SET AUTOCOMMIT=ON;
+#Connection 2
+SET AUTOCOMMIT=ON;
+#Connection 3
+SET AUTOCOMMIT=ON;
+#Connection 2
+STOP slave;
+INSERT INTO t1 VALUES ('node2_slave_stoped');
+#Connection 1
+INSERT INTO t1 VALUES ('node1_normal_entry');
+include/save_master_gtid.inc
+#Connection 2
+INSERT INTO t1 VALUES ('node2_slave_stoped_inserted');
+start slave;
+include/sync_with_master_gtid.inc
+INSERT INTO t1 VALUES ('node2_slave_started');
+SELECT count(*) from t1;
+count(*)
+12
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-7,2-3-8,2-2-11
+#Connection 3
+SELECT count(*) from t1;
+count(*)
+12
+SELECT @@global.gtid_binlog_state;
+@@global.gtid_binlog_state
+1-1-7,2-3-8,2-2-11
+#Connection 1
+DROP TABLE t2,t1;
+#Connection 2
+#Connection 3
+#Connection 2
+STOP SLAVE;
+RESET SLAVE ALL;
+reset master;
+#Connection 3
+reset master;
+#Connection 1
+reset master;
diff --git a/mysql-test/suite/galera/t/galera_gtid_slave.cnf b/mysql-test/suite/galera/t/galera_gtid_slave.cnf
new file mode 100644
index 00000000000..409d0d1609a
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_gtid_slave.cnf
@@ -0,0 +1,18 @@
+!include ../galera_2nodes_as_slave.cnf
+
+[mysqld]
+log-bin=mysqld-bin
+log-slave-updates
+binlog-format=ROW
+
+[mysqld.1]
+gtid-domain-id=1
+[mysqld.2]
+gtid-domain-id=2
+wsrep_gtid_mode=1
+wsrep_gtid_domain_id=2
+[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.test b/mysql-test/suite/galera/t/galera_gtid_slave.test
new file mode 100644
index 00000000000..8ef87452a5b
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_gtid_slave.test
@@ -0,0 +1,78 @@
+#
+# Test Galera as a slave to a MariaDB master using GTIDs
+#
+# suite/galera/galera_2nodes_as_slave.cnf describes the setup of the nodes
+# suite/galera/t/galera_as_slave_gtid.cnf has the GTID options
+#
+# In addition to performing DDL and DML, we check that the gtid of the master is preserved inside the cluster
+#
+
+--source include/have_innodb.inc
+
+# As node #1 is not a Galera node, we connect to node #2 in order to run include/galera_cluster.inc
+--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
+--source include/galera_cluster.inc
+
+--connection node_2
+--disable_query_log
+--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_1;
+--enable_query_log
+START SLAVE;
+
+--connection node_1
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t2 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(1);
+
+#multi stmt trans
+begin;
+insert into t2 values(21);
+insert into t2 values(22);
+commit;
+
+SELECT @@global.gtid_binlog_state;
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
+--source include/wait_condition.inc
+
+--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
+--source include/wait_condition.inc
+--sleep 1
+INSERT INTO t1 VALUES(2);
+INSERT INTO t1 VALUES(3);
+SELECT @@global.gtid_binlog_state;
+
+--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
+--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES(4);
+SELECT @@global.gtid_binlog_state;
+
+--connection node_1
+DROP TABLE t1,t2;
+reset master;
+#
+# Unfortunately without the sleep below the following statement fails with "query returned no rows", which
+# is difficult to understand given that it is an aggregate query. A "query execution was interrupted"
+# warning is also reported by MTR, which is also weird.
+#
+
+--sleep 1
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
+--source include/wait_condition.inc
+
+--connection node_2
+STOP SLAVE;
+RESET SLAVE ALL;
+reset master;
+
+--connection node_3
+reset master;
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
new file mode 100644
index 00000000000..bb9c8e84f1b
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.cnf
@@ -0,0 +1,18 @@
+!include ../galera_2nodes_as_slave.cnf
+
+[mysqld]
+log-bin=mysqld-bin
+log-slave-updates
+binlog-format=ROW
+wsrep_sst_method=rsync
+[mysqld.1]
+gtid-domain-id=1
+[mysqld.2]
+gtid-domain-id=2
+wsrep_gtid_mode=1
+wsrep_gtid_domain_id=2
+[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.test b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test
new file mode 100644
index 00000000000..3fe94ad16b7
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test
@@ -0,0 +1,207 @@
+#
+# Test Galera as a slave to a MariaDB master using GTIDs
+#
+# suite/galera/galera_2nodes_as_slave.cnf describes the setup of the nodes
+#
+# In addition to performing DDL and DML, we check that the gtid of the master is preserved inside the cluster
+#
+
+--source include/big_test.inc
+--source include/have_innodb.inc
+# As node #1 is not a Galera node, we connect to node #2 in order to run include/galera_cluster.inc
+--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
+--source include/galera_cluster.inc
+
+--echo #Connection 2
+--connection node_2
+--disable_query_log
+--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_1,master_use_gtid=slave_pos;
+--enable_query_log
+START SLAVE;
+--sleep 1
+
+
+--echo #Connection 1
+--connection node_1
+CREATE TABLE t2 (f1 INTEGER PRIMARY KEY, f2 int unique) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(1,11);
+INSERT INTO t2 VALUES(2,22);
+INSERT INTO t2 VALUES(3,33);
+
+SELECT @@global.gtid_binlog_state;
+--source include/save_master_gtid.inc
+
+--echo #Connection 2
+--connection node_2
+--source include/sync_with_master_gtid.inc
+SELECT @@global.gtid_binlog_state;
+
+INSERT INTO t2 VALUES(4,44);
+INSERT INTO t2 VALUES(5,55);
+INSERT INTO t2 VALUES(6,66);
+SELECT @@global.gtid_binlog_state;
+
+--echo #Connection 3
+--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
+--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME= 't2';
+--source include/wait_condition.inc
+--let $wait_condition = SELECT COUNT(*) = 6 FROM t2;
+--source include/wait_condition.inc
+
+INSERT INTO t2 VALUES(7,77);
+INSERT INTO t2 VALUES(8,88);
+SELECT @@global.gtid_binlog_state;
+
+#Perform SST
+--echo #Connection 1
+--connection node_1
+CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+COMMIT;
+--source include/save_master_gtid.inc
+
+--echo #Connection 2
+--connection node_2
+--source include/sync_with_master_gtid.inc
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+COMMIT;
+
+--echo #Connection 3
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME= 't1';
+--source include/wait_condition.inc
+--let $wait_condition = SELECT COUNT(*) = 4 FROM t1;
+--source include/wait_condition.inc
+--let $node_1= node_2
+--let $node_2= node_3
+--source include/auto_increment_offset_save.inc
+--echo Shutting down server ...
+--source include/shutdown_mysqld.inc
+
+
+--echo #Connection 2
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'
+--source include/wait_condition.inc
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+COMMIT;
+
+--echo #Connection 3
+--connection node_3
+--echo Starting server ...
+--source include/start_mysqld.inc
+--source include/wait_until_ready.inc
+--source include/auto_increment_offset_restore.inc
+
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node3_committed_after');
+INSERT INTO t1 VALUES ('node3_committed_after');
+COMMIT;
+
+--echo #Connection 2
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 8 FROM t1;
+--source include/wait_condition.inc
+Select * from t1 order by f1;
+
+--echo #Connection 3
+--connection node_3
+Select * from t1 order by f1;
+
+#SST Done
+--sleep 1
+--echo #Connection 2
+--connection node_2
+SELECT @@global.gtid_binlog_state;
+
+--echo #Connection 3
+--connection node_3
+SELECT @@global.gtid_binlog_state;
+
+--echo #Connection 1
+--connection node_1
+SET AUTOCOMMIT=ON;
+#drop table t1;
+#CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB;
+
+--echo #Connection 2
+--connection node_2
+SET AUTOCOMMIT=ON;
+--echo #Connection 3
+--connection node_3
+SET AUTOCOMMIT=ON;
+
+#
+#stop slave on node 2
+--echo #Connection 2
+--connection node_2
+STOP slave;
+--sleep 1
+INSERT INTO t1 VALUES ('node2_slave_stoped');
+
+--echo #Connection 1
+--connection node_1
+INSERT INTO t1 VALUES ('node1_normal_entry');
+--source include/save_master_gtid.inc
+
+#start slave
+--echo #Connection 2
+--connection node_2
+INSERT INTO t1 VALUES ('node2_slave_stoped_inserted');
+start slave;
+--source include/sync_with_master_gtid.inc
+INSERT INTO t1 VALUES ('node2_slave_started');
+SELECT count(*) from t1;
+SELECT @@global.gtid_binlog_state;
+
+--echo #Connection 3
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 12 FROM t1;
+--source include/wait_condition.inc
+SELECT count(*) from t1;
+SELECT @@global.gtid_binlog_state;
+
+--echo #Connection 1
+--connection node_1
+DROP TABLE t2,t1;
+
+# Unfortunately without the sleep below the following statement fails with "query returned no rows", which
+# is difficult to understand given that it is an aggregate query. A "query execution was interrupted"
+# warning is also reported by MTR, which is also weird.
+#
+
+--sleep 3
+
+--echo #Connection 2
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2';
+--source include/wait_condition.inc
+
+--echo #Connection 3
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
+--source include/wait_condition.inc
+
+--echo #Connection 2
+--connection node_2
+STOP SLAVE;
+RESET SLAVE ALL;
+reset master;
+
+--echo #Connection 3
+--connection node_3
+reset master;
+
+--echo #Connection 1
+--connection node_1
+reset master;
diff --git a/mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf b/mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf
new file mode 100644
index 00000000000..3f39b82f7b7
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/galera_2x3nodes.cnf
@@ -0,0 +1,122 @@
+# Use default setting for mysqld processes
+!include include/default_mysqld.cnf
+
+[mysqld]
+log-bin
+log-slave-updates
+binlog-format=row
+innodb-autoinc-lock-mode=2
+default-storage-engine=innodb
+wsrep_gtid_mode=1
+gtid_ignore_duplicates
+
+wsrep-on=1
+wsrep-provider=@ENV.WSREP_PROVIDER
+wsrep_node_address=127.0.0.1
+# enforce read-committed characteristics across the cluster
+# wsrep-causal-reads=ON
+# wsrep-sync-wait=15
+
+[mysqld.1]
+#galera_port=@OPT.port
+#ist_port=@OPT.port
+#sst_port=@OPT.port
+wsrep-cluster-address='gcomm://'
+wsrep_provider_options='base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S'
+
+wsrep_sst_receive_address=127.0.0.2:@mysqld.1.#sst_port
+wsrep_node_incoming_address=127.0.0.1:@mysqld.1.port
+wsrep_sst_receive_address='127.0.0.1:@mysqld.1.#sst_port'
+
+[mysqld.2]
+#galera_port=@OPT.port
+#ist_port=@OPT.port
+#sst_port=@OPT.port
+wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.1.#galera_port'
+wsrep_provider_options='base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S'
+
+wsrep_sst_receive_address=127.0.0.2:@mysqld.2.#sst_port
+wsrep_node_incoming_address=127.0.0.1:@mysqld.2.port
+wsrep_sst_receive_address='127.0.0.1:@mysqld.2.#sst_port'
+
+[mysqld.3]
+#galera_port=@OPT.port
+#ist_port=@OPT.port
+#sst_port=@OPT.port
+wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.1.#galera_port'
+wsrep_provider_options='base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S'
+
+wsrep_sst_receive_address=127.0.0.2:@mysqld.3.#sst_port
+wsrep_node_incoming_address=127.0.0.1:@mysqld.3.port
+wsrep_sst_receive_address='127.0.0.1:@mysqld.3.#sst_port'
+
+
+[mysqld.4]
+wsrep_cluster_name=cluster2
+#galera_port=@OPT.port
+#ist_port=@OPT.port
+#sst_port=@OPT.port
+
+wsrep-cluster-address='gcomm://'
+wsrep_provider_options='base_port=@mysqld.4.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S'
+
+wsrep_sst_receive_address=127.0.0.2:@mysqld.4.#sst_port
+wsrep_node_incoming_address=127.0.0.1:@mysqld.4.port
+wsrep_sst_receive_address='127.0.0.1:@mysqld.4.#sst_port'
+
+[mysqld.5]
+wsrep_cluster_name=cluster2
+#galera_port=@OPT.port
+#ist_port=@OPT.port
+#sst_port=@OPT.port
+wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.4.#galera_port'
+wsrep_provider_options='base_port=@mysqld.5.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S'
+
+wsrep_sst_receive_address=127.0.0.2:@mysqld.5.#sst_port
+wsrep_node_incoming_address=127.0.0.1:@mysqld.5.port
+wsrep_sst_receive_address='127.0.0.1:@mysqld.5.#sst_port'
+
+[mysqld.6]
+wsrep_cluster_name=cluster2
+#galera_port=@OPT.port
+#ist_port=@OPT.port
+#sst_port=@OPT.port
+wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.4.#galera_port'
+wsrep_provider_options='base_port=@mysqld.6.#galera_port;evs.suspect_timeout=PT300S;evs.inactive_timeout=PT1000M;evs.install_timeout=PT155S;evs.keepalive_period = PT100S'
+
+wsrep_sst_receive_address=127.0.0.2:@mysqld.6.#sst_port
+wsrep_node_incoming_address=127.0.0.1:@mysqld.6.port
+wsrep_sst_receive_address='127.0.0.1:@mysqld.6.#sst_port'
+
+[ENV]
+NODE_MYPORT_1= @mysqld.1.port
+NODE_MYSOCK_1= @mysqld.1.socket
+
+NODE_MYPORT_2= @mysqld.2.port
+NODE_MYSOCK_2= @mysqld.2.socket
+
+NODE_MYPORT_3= @mysqld.3.port
+NODE_MYSOCK_3= @mysqld.3.socket
+
+NODE_MYPORT_4= @mysqld.4.port
+NODE_MYSOCK_4= @mysqld.4.socket
+
+NODE_MYPORT_5= @mysqld.5.port
+NODE_MYSOCK_5= @mysqld.5.socket
+
+NODE_MYPORT_6= @mysqld.6.port
+NODE_MYSOCK_6= @mysqld.6.socket
+
+NODE_GALERAPORT_1= @mysqld.1.#galera_port
+NODE_GALERAPORT_2= @mysqld.2.#galera_port
+NODE_GALERAPORT_3= @mysqld.3.#galera_port
+NODE_GALERAPORT_4= @mysqld.4.#galera_port
+NODE_GALERAPORT_5= @mysqld.5.#galera_port
+NODE_GALERAPORT_6= @mysqld.6.#galera_port
+
+NODE_SSTPORT_1= @mysqld.1.#sst_port
+NODE_SSTPORT_2= @mysqld.2.#sst_port
+NODE_SSTPORT_3= @mysqld.3.#sst_port
+NODE_SSTPORT_4= @mysqld.4.#sst_port
+NODE_SSTPORT_5= @mysqld.5.#sst_port
+NODE_SSTPORT_6= @mysqld.6.#sst_port
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
new file mode 100644
index 00000000000..35ca84119e7
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/r/galera_gtid_2_cluster.result
@@ -0,0 +1,231 @@
+cluster 1 node 1
+SHOW STATUS LIKE 'wsrep_cluster_size';
+Variable_name Value
+wsrep_cluster_size 3
+cluster 1 node 2
+SHOW STATUS LIKE 'wsrep_cluster_size';
+Variable_name Value
+wsrep_cluster_size 3
+cluster 1 node 3
+SHOW STATUS LIKE 'wsrep_cluster_size';
+Variable_name Value
+wsrep_cluster_size 3
+cluster 2 node 1
+SHOW STATUS LIKE 'wsrep_cluster_size';
+Variable_name Value
+wsrep_cluster_size 3
+cluster 2 node 2
+SHOW STATUS LIKE 'wsrep_cluster_size';
+Variable_name Value
+wsrep_cluster_size 3
+cluster 2 node 3
+SHOW STATUS LIKE 'wsrep_cluster_size';
+Variable_name Value
+wsrep_cluster_size 3
+change master to master_host='127.0.0.1', master_user='root', master_port=NODE_MYPORT_4, master_use_gtid=current_pos, ignore_server_ids=(12,13);;
+start slave;
+include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+
+select @@gtid_slave_pos;
+@@gtid_slave_pos
+
+change master to master_host='127.0.0.1', master_user='root', master_port=NODE_MYPORT_1, master_use_gtid=current_pos, ignore_server_ids=(22,23);;
+start slave;
+include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+
+select @@gtid_slave_pos;
+@@gtid_slave_pos
+
+cluster 1 node 1
+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
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 2 node 1
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2
+insert into t1 values (2, 21, 1);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,2-21-1
+select * from t1;
+cluster_domain_id node_server_id seq_no
+1 11 2
+2 21 1
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 1 node 2
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,2-21-1
+insert into t1 values (1, 12, 3);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,1-12-3,2-21-1
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 1 node 3
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,1-12-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
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 2 node 2
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-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
+#wait for sync cluster 2 and 1
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 2 node 3
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-4,2-21-1,2-22-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
+#wait for sync cluster 2 and 1
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 1 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
+drop table t1;
+stop slave;
+reset slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+cluster 2 node 1
+stop slave;
+reset slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+reset master;
+reset master;
+reset master;
+reset master;
+change master to master_host='127.0.0.1', master_user='root', master_port=NODE_MYPORT_6, master_use_gtid=current_pos, ignore_server_ids=(12,13);;
+start slave;
+include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+
+select @@gtid_slave_pos;
+@@gtid_slave_pos
+
+change master to master_host='127.0.0.1', master_user='root', master_port=NODE_MYPORT_3, master_use_gtid=current_pos, ignore_server_ids=(22,23);;
+start slave;
+include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+
+select @@gtid_slave_pos;
+@@gtid_slave_pos
+
+cluster 1 node 1
+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
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 2 node 1
+insert into t1 values (2, 21, 1);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,2-21-1
+select * from t1;
+cluster_domain_id node_server_id seq_no
+1 11 2
+2 21 1
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 1 node 2
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,2-21-1
+insert into t1 values (1, 12, 3);
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,1-12-3,2-21-1
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 1 node 3
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-11-2,1-12-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
+#wait for sync cluster 1 and 2
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 2 node 2
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-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
+#wait for sync cluster 2 and 1
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 2 node 3
+select @@gtid_binlog_state;
+@@gtid_binlog_state
+1-12-3,1-11-2,1-13-4,2-21-1,2-22-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
+#wait for sync cluster 2 and 1
+include/save_master_gtid.inc
+include/sync_with_master_gtid.inc
+cluster 1 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
+drop table t1;
+stop slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+cluster 2 node 1
+stop slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+reset master;
+reset master;
+reset master;
+reset master;
diff --git a/mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.cnf b/mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.cnf
new file mode 100644
index 00000000000..dc5535ef34a
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.cnf
@@ -0,0 +1,28 @@
+# We need a dedicated .cnf file, even if empty, in order to force this test to run
+# alone on a freshly started cluster. Otherwise there are adverse interactions with
+# following tests such as galera_3nodes.galera_var_dirty_reads2
+
+!include ../galera_2x3nodes.cnf
+[mysqld.1]
+wsrep_gtid_domain_id=1
+server-id=11
+
+[mysqld.2]
+wsrep_gtid_domain_id=1
+server-id=12
+
+[mysqld.3]
+wsrep_gtid_domain_id=1
+server-id=13
+
+[mysqld.4]
+wsrep_gtid_domain_id=2
+server-id=21
+
+[mysqld.5]
+wsrep_gtid_domain_id=2
+server-id=22
+
+[mysqld.6]
+wsrep_gtid_domain_id=2
+server-id=23
diff --git a/mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.test b/mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.test
new file mode 100644
index 00000000000..c679db1305d
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_gtid_2_cluster.test
@@ -0,0 +1,292 @@
+#
+# This test creates 2x 3 nodes galera cluster.
+# The whole test case
+# A <-> B <-> C {Galera cluster 1}
+# | {Circular Async replication}
+# D <-> E <-> F {Galera cluster 2}
+# We will write on any random node to see if gtid is consitent or not
+# Then we will kill node D and set up the replication between A and E
+# To see whether fail over works or not.
+
+--source include/big_test.inc
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+
+--connection node_1
+--echo cluster 1 node 1
+SHOW STATUS LIKE 'wsrep_cluster_size';
+
+--connection node_2
+--echo cluster 1 node 2
+SHOW STATUS LIKE 'wsrep_cluster_size';
+
+--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
+--connection node_3
+--echo cluster 1 node 3
+SHOW STATUS LIKE 'wsrep_cluster_size';
+
+--connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4
+--connection node_4
+--echo cluster 2 node 1
+SHOW STATUS LIKE 'wsrep_cluster_size';
+
+--connect node_5, 127.0.0.1, root, , test, $NODE_MYPORT_5
+--connection node_5
+--echo cluster 2 node 2
+SHOW STATUS LIKE 'wsrep_cluster_size';
+
+--connect node_6, 127.0.0.1, root, , test, $NODE_MYPORT_6
+--connection node_6
+--echo cluster 2 node 3
+SHOW STATUS LIKE 'wsrep_cluster_size';
+#--disable_parsing
+--connection node_1
+--replace_result $NODE_MYPORT_4 NODE_MYPORT_4
+--eval change master to master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_4, master_use_gtid=current_pos, ignore_server_ids=(12,13);
+start slave;
+--source include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+select @@gtid_slave_pos;
+#--query_vertical SHOW SLAVE STATUS;
+
+--connection node_4
+--replace_result $NODE_MYPORT_1 NODE_MYPORT_1
+--eval change master to master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_1, master_use_gtid=current_pos, ignore_server_ids=(22,23);
+start slave;
+--source include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+select @@gtid_slave_pos;
+#--query_vertical SHOW SLAVE STATUS;
+
+--echo cluster 1 node 1
+--connection node_1
+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;
+
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+--echo cluster 2 node 1
+--connection node_4
+select @@gtid_binlog_state;
+insert into t1 values (2, 21, 1);
+select @@gtid_binlog_state;
+select * from t1;
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+
+--echo cluster 1 node 2
+--connection node_2
+select @@gtid_binlog_state;
+insert into t1 values (1, 12, 3);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+--echo cluster 1 node 3
+--connection node_3
+select @@gtid_binlog_state;
+insert into t1 values (1, 13, 4);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+--echo cluster 2 node 2
+--connection node_5
+select @@gtid_binlog_state;
+insert into t1 values (2, 22, 2);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 2 and 1
+--connection node_4
+--source include/save_master_gtid.inc
+--connection node_1
+--source include/sync_with_master_gtid.inc
+
+--echo cluster 2 node 3
+--connection node_6
+select @@gtid_binlog_state;
+insert into t1 values (2, 23, 3);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 2 and 1
+--connection node_4
+--source include/save_master_gtid.inc
+--connection node_1
+--source include/sync_with_master_gtid.inc
+
+
+--echo cluster 1 node 1
+--connection node_1
+select @@gtid_binlog_state;
+drop table t1;
+stop slave;
+reset slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+--sleep 2
+
+--echo cluster 2 node 1
+--connection node_4
+stop slave;
+reset slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+
+--connection node_2
+reset master;
+--connection node_3
+reset master;
+--connection node_5
+reset master;
+--connection node_6
+reset master;
+#--enable_parsing
+#
+# This test creates 2x 3 nodes galera cluster.
+# The whole test case
+# A <-> B <-> C {Galera cluster 1}
+# \ /
+# \ /
+# / {C->D, F->A , Async normal slave repl}
+# / \
+# | \
+# D <-> E <-> F {Galera cluster 2}
+# We will write on any random node to see if gtid is consitent or not
+# Then we will kill node D and set up the replication between A and E
+# To see whether fail over works or not.
+--connection node_1
+--replace_result $NODE_MYPORT_6 NODE_MYPORT_6
+--eval change master to master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_6, master_use_gtid=current_pos, ignore_server_ids=(12,13);
+start slave;
+--source include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+select @@gtid_slave_pos;
+#--query_vertical SHOW SLAVE STATUS;
+
+--connection node_4
+--replace_result $NODE_MYPORT_3 NODE_MYPORT_3
+--eval change master to master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_3, master_use_gtid=current_pos, ignore_server_ids=(22,23);
+start slave;
+--source include/wait_for_slave_to_start.inc
+select @@gtid_binlog_state;
+select @@gtid_slave_pos;
+#--query_vertical SHOW SLAVE STATUS;
+
+--echo cluster 1 node 1
+--connection node_1
+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;
+
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+--sleep 2
+--echo cluster 2 node 1
+--connection node_4
+insert into t1 values (2, 21, 1);
+select @@gtid_binlog_state;
+select * from t1;
+
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+
+--echo cluster 1 node 2
+--connection node_2
+select @@gtid_binlog_state;
+insert into t1 values (1, 12, 3);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+--echo cluster 1 node 3
+--connection node_3
+select @@gtid_binlog_state;
+insert into t1 values (1, 13, 4);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 1 and 2
+--connection node_1
+--source include/save_master_gtid.inc
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+--echo cluster 2 node 2
+--connection node_5
+select @@gtid_binlog_state;
+insert into t1 values (2, 22, 2);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 2 and 1
+--connection node_4
+--source include/save_master_gtid.inc
+--connection node_1
+--source include/sync_with_master_gtid.inc
+
+--echo cluster 2 node 3
+--connection node_6
+select @@gtid_binlog_state;
+insert into t1 values (2, 23, 3);
+select @@gtid_binlog_state;
+
+--echo #wait for sync cluster 2 and 1
+--connection node_4
+--source include/save_master_gtid.inc
+--connection node_1
+--source include/sync_with_master_gtid.inc
+
+
+--echo cluster 1 node 1
+--connection node_1
+select @@gtid_binlog_state;
+drop table t1;
+stop slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+
+--echo cluster 2 node 1
+--connection node_4
+stop slave;
+change master to master_use_gtid=no, ignore_server_ids=();
+reset master;
+set global GTID_SLAVE_POS="";
+
+--connection node_2
+reset master;
+--connection node_3
+reset master;
+--connection node_5
+reset master;
+--connection node_6
+reset master;
diff --git a/sql/log.cc b/sql/log.cc
index 07d4074c3d4..29f8c5639cf 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -4947,7 +4947,55 @@ 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.
@@ -5544,7 +5592,37 @@ THD::binlog_start_trans_and_stmt()
cache_mngr->trx_cache.get_prev_position() == MY_OFF_T_UNDEF)
{
this->binlog_set_stmt_begin();
- if (in_multi_stmt_transaction_mode())
+ bool mstmt_mode= in_multi_stmt_transaction_mode();
+#ifdef WITH_WSREP
+ /* 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()
+ */
+ 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)
+ {
+ binlog_cache_mngr *const cache_mngr=
+ (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton);
+
+ IO_CACHE *file=
+ cache_mngr->get_binlog_cache_log(use_trans_cache(this, true));
+ Log_event_writer writer(file);
+ 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(&gtid_event);
+ }
+#endif
+ if (mstmt_mode)
trans_register_ha(this, TRUE, binlog_hton);
trans_register_ha(this, FALSE, binlog_hton);
/*
@@ -5826,7 +5904,7 @@ MYSQL_BIN_LOG::write_gtid_event(THD *thd, bool standalone,
DBUG_PRINT("enter", ("standalone: %d", standalone));
#ifdef WITH_WSREP
- if (WSREP(thd) && thd->wsrep_trx_meta.gtid.seqno != -1 && wsrep_gtid_mode)
+ if (WSREP(thd) && thd->wsrep_trx_meta.gtid.seqno != -1 && wsrep_gtid_mode && !thd->variables.gtid_seq_no)
{
domain_id= wsrep_gtid_domain_id;
} else {
@@ -5878,6 +5956,12 @@ MYSQL_BIN_LOG::write_gtid_event(THD *thd, bool standalone,
/* Write the event to the binary log. */
DBUG_ASSERT(this == &mysql_bin_log);
+
+#ifdef WITH_WSREP
+ if (wsrep_gtid_mode && is_gtid_cached(thd))
+ DBUG_RETURN(false);
+#endif
+
if (write_event(&gtid_event))
DBUG_RETURN(true);
status_var_add(thd->status_var.binlog_bytes_written, gtid_event.data_written);
diff --git a/sql/log.h b/sql/log.h
index 3026ca11e31..2118bd7a059 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -559,7 +559,13 @@ 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/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index bdc8491080d..285bb520b87 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -1227,6 +1227,16 @@ int wsrep_to_buf_helper(
if (!ret && writer.write(&gtid_ev)) ret= 1;
}
#endif /* GTID_SUPPORT */
+ if (wsrep_gtid_mode && thd->variables.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;
+ if (!gtid_event.is_valid()) ret= 0;
+ ret= writer.write(&gtid_event);
+ }
/* if there is prepare query, add event for it */
if (!ret && thd->wsrep_TOI_pre_query)