diff options
author | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2017-12-28 19:27:00 +0200 |
---|---|---|
committer | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2017-12-28 19:27:00 +0200 |
commit | 9aeb5d01d6bb1506febfcab6ef9d78417efa87df (patch) | |
tree | 96602fb6d88d8a14a69d27aa241fe0e59e2ebc3e | |
parent | 14de2ad3cb4e1f8f48b83d5e9aafa4e3a366d152 (diff) | |
parent | 7e4c185c774cabaa1912760e143d9385ce959eea (diff) | |
download | mariadb-git-9aeb5d01d6bb1506febfcab6ef9d78417efa87df.tar.gz |
Merge remote-tracking branch 'origin/10.1' into bb-10.2-vicentiu
21 files changed, 1504 insertions, 80 deletions
diff --git a/mysql-test/r/partition_windows.result b/mysql-test/r/partition_windows.result index dabcedcb3f9..756690925f8 100644 --- a/mysql-test/r/partition_windows.result +++ b/mysql-test/r/partition_windows.result @@ -26,9 +26,5 @@ ALTER TABLE t1 ADD PARTITION (PARTITION p3 DATA DIRECTORY = 'G:/mysqltest/p3Data Warnings: Warning 1618 <DATA DIRECTORY> option ignored Warning 1618 <INDEX DIRECTORY> option ignored -Warning 1618 <DATA DIRECTORY> option ignored -Warning 1618 <INDEX DIRECTORY> option ignored -Warning 1618 <DATA DIRECTORY> option ignored -Warning 1618 <INDEX DIRECTORY> option ignored INSERT INTO t1 VALUES (NULL, "last", 4); DROP TABLE t1; 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/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index 8e0e6d5b512..d44dfa3f9ee 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -3354,3 +3354,83 @@ show status like "handler_read_key"; Variable_name Value Handler_read_key 0 drop table t1; +CREATE TABLE t1 (c1 INT) ENGINE=InnoDB; +CREATE TEMPORARY TABLE t2 (c1 INT) ENGINE=InnoDB; +START TRANSACTION READ ONLY; +INSERT INTO t2 VALUES(0); +INSERT INTO t1 VALUES(0); +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +ROLLBACK; +SELECT * FROM t1; +c1 +SELECT * FROM t2; +c1 +START TRANSACTION READ ONLY; +INSERT INTO t1 VALUES(0); +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +INSERT INTO t2 VALUES(1); +COMMIT; +SET TRANSACTION READ ONLY; +START TRANSACTION; +INSERT INTO t2 VALUES(3); +INSERT INTO t1 VALUES(0); +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +COMMIT; +SELECT * FROM t1; +c1 +SELECT * FROM t2; +c1 +1 +3 +DROP TABLE t2; +CREATE TEMPORARY TABLE t2 ( +c1 INT AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TEMPORARY TABLE `t2` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` int(11) DEFAULT NULL, + PRIMARY KEY (`c1`), + KEY `idx` (`c2`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +START TRANSACTION READ ONLY; +INSERT INTO t2 VALUES(NULL,1),(NULL,2),(NULL,3); +INSERT INTO t1 VALUES(0); +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +ROLLBACK; +SELECT * FROM t1; +c1 +SELECT * FROM t2; +c1 c2 +START TRANSACTION READ ONLY; +INSERT INTO t1 VALUES(0); +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +INSERT INTO t2 VALUES(NULL,1),(NULL,2),(NULL,3); +COMMIT; +SET TRANSACTION READ ONLY; +START TRANSACTION; +INSERT INTO t2 VALUES(NULL,1),(NULL,2),(NULL,3); +INSERT INTO t1 VALUES(0); +ERROR 25006: Cannot execute statement in a READ ONLY transaction. +COMMIT; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TEMPORARY TABLE `t2` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` int(11) DEFAULT NULL, + PRIMARY KEY (`c1`), + KEY `idx` (`c2`) +) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1 +SELECT * FROM t1; +c1 +SELECT * FROM t2; +c1 c2 +4 1 +7 1 +5 2 +8 2 +6 3 +9 3 +DROP TABLE t1; +DROP TABLE t2; diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test index c3908abcf34..05c135bfcbe 100644 --- a/mysql-test/suite/innodb/t/innodb.test +++ b/mysql-test/suite/innodb/t/innodb.test @@ -2618,6 +2618,76 @@ select f1 from t1; show status like "handler_read_key"; drop table t1; +# +# Test handling of writes to TEMPORARY tables for read-only transactions +# +CREATE TABLE t1 (c1 INT) ENGINE=InnoDB; +CREATE TEMPORARY TABLE t2 (c1 INT) ENGINE=InnoDB; + +# Check that the rollback works +START TRANSACTION READ ONLY; +INSERT INTO t2 VALUES(0); +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +INSERT INTO t1 VALUES(0); +ROLLBACK; + +SELECT * FROM t1; +SELECT * FROM t2; + +START TRANSACTION READ ONLY; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +INSERT INTO t1 VALUES(0); +INSERT INTO t2 VALUES(1); +COMMIT; + +SET TRANSACTION READ ONLY; +START TRANSACTION; +INSERT INTO t2 VALUES(3); +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +INSERT INTO t1 VALUES(0); +COMMIT; + +SELECT * FROM t1; +SELECT * FROM t2; + +DROP TABLE t2; + +# This time with some indexes +CREATE TEMPORARY TABLE t2 ( + c1 INT AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB; + +SHOW CREATE TABLE t2; + +# Check that the rollback works +START TRANSACTION READ ONLY; +INSERT INTO t2 VALUES(NULL,1),(NULL,2),(NULL,3); +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +INSERT INTO t1 VALUES(0); +ROLLBACK; + +SELECT * FROM t1; +SELECT * FROM t2; + +START TRANSACTION READ ONLY; +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +INSERT INTO t1 VALUES(0); +INSERT INTO t2 VALUES(NULL,1),(NULL,2),(NULL,3); +COMMIT; + +SET TRANSACTION READ ONLY; +START TRANSACTION; +INSERT INTO t2 VALUES(NULL,1),(NULL,2),(NULL,3); +--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION +INSERT INTO t1 VALUES(0); +COMMIT; + +SHOW CREATE TABLE t2; +SELECT * FROM t1; +SELECT * FROM t2; + +DROP TABLE t1; +DROP TABLE t2; ####################################################################### # # # Please, DO NOT TOUCH this file as well as the innodb.result file. # diff --git a/mysql-test/suite/parts/r/partition_alter_myisam.result b/mysql-test/suite/parts/r/partition_alter_myisam.result index 12308e259e0..50b8b802ad4 100644 --- a/mysql-test/suite/parts/r/partition_alter_myisam.result +++ b/mysql-test/suite/parts/r/partition_alter_myisam.result @@ -42,3 +42,16 @@ PARTITION p3 VALUES IN (4,5,6) ); ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition DROP TABLE t1; +create table t1 ( c1 int, c2 int, c3 varchar(100)) delay_key_write=1 +partition by key(c1) ( +partition p01 data directory = 'MYSQL_TMP_DIR' + index directory = 'MYSQL_TMP_DIR', +partition p02 data directory = 'MYSQL_TMP_DIR' + index directory = 'MYSQL_TMP_DIR'); +insert into t1 values (1, 1, repeat('a', 100)); +insert into t1 select rand()*1000, rand()*1000, repeat('b', 100) from t1; +insert into t1 select rand()*1000, rand()*1000, repeat('b', 100) from t1; +insert into t1 select rand()*1000, rand()*1000, repeat('b', 100) from t1; +alter online table t1 delay_key_write=0; +alter online table t1 delay_key_write=1; +drop table t1; diff --git a/mysql-test/suite/parts/t/partition_alter_myisam.test b/mysql-test/suite/parts/t/partition_alter_myisam.test index a53fa333abd..b2bd0e72e4c 100644 --- a/mysql-test/suite/parts/t/partition_alter_myisam.test +++ b/mysql-test/suite/parts/t/partition_alter_myisam.test @@ -1,3 +1,22 @@ --source include/have_partition.inc --let $engine=MyISAM --source inc/part_alter_values.inc + +# +# MDEV-14026 ALTER TABLE ... DELAY_KEY_WRITE=1 creates table copy for partitioned MyISAM table with DATA DIRECTORY/INDEX DIRECTORY options +# + +replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR; +eval create table t1 ( c1 int, c2 int, c3 varchar(100)) delay_key_write=1 + partition by key(c1) ( + partition p01 data directory = '$MYSQL_TMP_DIR' + index directory = '$MYSQL_TMP_DIR', + partition p02 data directory = '$MYSQL_TMP_DIR' + index directory = '$MYSQL_TMP_DIR'); +insert into t1 values (1, 1, repeat('a', 100)); +insert into t1 select rand()*1000, rand()*1000, repeat('b', 100) from t1; +insert into t1 select rand()*1000, rand()*1000, repeat('b', 100) from t1; +insert into t1 select rand()*1000, rand()*1000, repeat('b', 100) from t1; +alter online table t1 delay_key_write=0; +alter online table t1 delay_key_write=1; +drop table t1; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index cc5521114f4..56e1f649286 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -2184,38 +2184,19 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info) DBUG_ASSERT(sub_elem); part= i * num_subparts + j; DBUG_ASSERT(part < m_file_tot_parts && m_file[part]); - if (ha_legacy_type(m_file[part]->ht) == DB_TYPE_INNODB) - { - dummy_info.data_file_name= dummy_info.index_file_name = NULL; - m_file[part]->update_create_info(&dummy_info); - - if (dummy_info.data_file_name || sub_elem->data_file_name) - { - sub_elem->data_file_name = (char*) dummy_info.data_file_name; - } - if (dummy_info.index_file_name || sub_elem->index_file_name) - { - sub_elem->index_file_name = (char*) dummy_info.index_file_name; - } - } + dummy_info.data_file_name= dummy_info.index_file_name = NULL; + m_file[part]->update_create_info(&dummy_info); + sub_elem->data_file_name = (char*) dummy_info.data_file_name; + sub_elem->index_file_name = (char*) dummy_info.index_file_name; } } else { DBUG_ASSERT(m_file[i]); - if (ha_legacy_type(m_file[i]->ht) == DB_TYPE_INNODB) - { - dummy_info.data_file_name= dummy_info.index_file_name= NULL; - m_file[i]->update_create_info(&dummy_info); - if (dummy_info.data_file_name || part_elem->data_file_name) - { - part_elem->data_file_name = (char*) dummy_info.data_file_name; - } - if (dummy_info.index_file_name || part_elem->index_file_name) - { - part_elem->index_file_name = (char*) dummy_info.index_file_name; - } - } + dummy_info.data_file_name= dummy_info.index_file_name= NULL; + m_file[i]->update_create_info(&dummy_info); + part_elem->data_file_name = (char*) dummy_info.data_file_name; + part_elem->index_file_name = (char*) dummy_info.index_file_name; } } DBUG_VOID_RETURN; @@ -8160,20 +8141,36 @@ uint ha_partition::alter_table_flags(uint flags) bool ha_partition::check_if_incompatible_data(HA_CREATE_INFO *create_info, uint table_changes) { - handler **file; - bool ret= COMPATIBLE_DATA_YES; - /* The check for any partitioning related changes have already been done in mysql_alter_table (by fix_partition_func), so it is only up to the underlying handlers. */ - for (file= m_file; *file; file++) - if ((ret= (*file)->check_if_incompatible_data(create_info, - table_changes)) != - COMPATIBLE_DATA_YES) - break; - return ret; + List_iterator<partition_element> part_it(m_part_info->partitions); + HA_CREATE_INFO dummy_info= *create_info; + uint i=0; + while (partition_element *part_elem= part_it++) + { + if (m_is_sub_partitioned) + { + List_iterator<partition_element> subpart_it(part_elem->subpartitions); + while (partition_element *sub_elem= subpart_it++) + { + dummy_info.data_file_name= sub_elem->data_file_name; + dummy_info.index_file_name= sub_elem->index_file_name; + if (m_file[i++]->check_if_incompatible_data(&dummy_info, table_changes)) + return COMPATIBLE_DATA_NO; + } + } + else + { + dummy_info.data_file_name= part_elem->data_file_name; + dummy_info.index_file_name= part_elem->index_file_name; + if (m_file[i++]->check_if_incompatible_data(&dummy_info, table_changes)) + return COMPATIBLE_DATA_NO; + } + } + return COMPATIBLE_DATA_YES; } diff --git a/sql/log.cc b/sql/log.cc index 3aff3b2c40d..a905e2b8caf 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4946,7 +4946,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. @@ -5541,7 +5589,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(>id_event); + } +#endif + if (mstmt_mode) trans_register_ha(this, TRUE, binlog_hton); trans_register_ha(this, FALSE, binlog_hton); /* @@ -5823,7 +5901,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 { @@ -5875,6 +5953,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(>id_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 97e257829b7..5589cbf168b 100644 --- a/sql/log.h +++ b/sql/log.h @@ -560,7 +560,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/sql_acl.cc b/sql/sql_acl.cc index 9c7eb8af736..34c28e95e89 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -6301,6 +6301,8 @@ static int merge_role_privileges(ACL_ROLE *role __attribute__((unused)), if (--grantee->counter) return 1; // don't recurse into grantee just yet + grantee->counter= 1; // Mark the grantee as merged. + /* if we'll do db/table/routine privileges, create a hash of role names */ role_hash_t role_hash(role_key); if (data->what != PRIVS_TO_MERGE::GLOBAL) @@ -7399,14 +7401,16 @@ end_index_init: DBUG_RETURN(return_val); } -static my_bool collect_leaf_roles(void *role_ptr, - void *roles_array) +static my_bool propagate_role_grants_action(void *role_ptr, + void *ptr __attribute__((unused))) { ACL_ROLE *role= static_cast<ACL_ROLE *>(role_ptr); - Dynamic_array<ACL_ROLE *> *array= - static_cast<Dynamic_array<ACL_ROLE *> *>(roles_array); - if (!role->counter) - array->push(role); + if (role->counter) + return 0; + + mysql_mutex_assert_owner(&acl_cache->lock); + PRIVS_TO_MERGE data= { PRIVS_TO_MERGE::ALL, 0, 0 }; + traverse_role_graph_up(role, &data, NULL, merge_role_privileges); return 0; } @@ -7476,15 +7480,7 @@ bool grant_reload(THD *thd) } mysql_mutex_lock(&acl_cache->lock); - Dynamic_array<ACL_ROLE *> leaf_roles; - my_hash_iterate(&acl_roles, collect_leaf_roles, &leaf_roles); - PRIVS_TO_MERGE data= { PRIVS_TO_MERGE::ALL, 0, 0 }; - for (size_t i= 0; i < leaf_roles.elements(); i++) - { - traverse_role_graph_up(leaf_roles.at(i), &data, NULL, - merge_role_privileges); - } - + my_hash_iterate(&acl_roles, propagate_role_grants_action, NULL); mysql_mutex_unlock(&acl_cache->lock); mysql_rwlock_unlock(&LOCK_grant); diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 2ac158817cb..76c753cf0b4 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1252,6 +1252,16 @@ 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) + { + 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(>id_event); + } /* if there is prepare query, add event for it */ if (!ret && thd->wsrep_TOI_pre_query) diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 69301390003..74c55b75352 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -755,6 +755,7 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked) { MI_KEYDEF *keyinfo; MI_COLUMNDEF *recinfo= 0; + char readlink_buf[FN_REFLEN], name_buff[FN_REFLEN]; uint recs; uint i; @@ -810,6 +811,30 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked) (void) mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0); info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); + + /* + Set data_file_name and index_file_name to point at the symlink value + if table is symlinked (Ie; Real name is not same as generated name) + */ + fn_format(name_buff, file->filename, "", MI_NAME_DEXT, + MY_APPEND_EXT | MY_UNPACK_FILENAME); + if (my_is_symlink(name_buff)) + { + my_readlink(readlink_buf, name_buff, MYF(0)); + data_file_name= strdup_root(&table->mem_root, readlink_buf); + } + else + data_file_name= 0; + fn_format(name_buff, file->filename, "", MI_NAME_IEXT, + MY_APPEND_EXT | MY_UNPACK_FILENAME); + if (my_is_symlink(name_buff)) + { + my_readlink(readlink_buf, name_buff, MYF(0)); + index_file_name= strdup_root(&table->mem_root, readlink_buf); + } + else + index_file_name= 0; + if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED)) (void) mi_extra(file, HA_EXTRA_WAIT_LOCK, 0); if (!table->s->db_record_offset) @@ -1939,7 +1964,6 @@ void ha_myisam::position(const uchar *record) int ha_myisam::info(uint flag) { MI_ISAMINFO misam_info; - char name_buff[FN_REFLEN]; if (!table) return 1; @@ -1987,27 +2011,6 @@ int ha_myisam::info(uint flag) sizeof(table->key_info[0].rec_per_key[0])*share->key_parts); if (table_share->tmp_table == NO_TMP_TABLE) mysql_mutex_unlock(&table_share->LOCK_share); - - /* - Set data_file_name and index_file_name to point at the symlink value - if table is symlinked (Ie; Real name is not same as generated name) - */ - char buf[FN_REFLEN]; - data_file_name= index_file_name= 0; - fn_format(name_buff, file->filename, "", MI_NAME_DEXT, - MY_APPEND_EXT | MY_UNPACK_FILENAME); - if (my_is_symlink(name_buff)) - { - my_readlink(buf, name_buff, MYF(0)); - data_file_name= ha_thd()->strdup(buf); - } - fn_format(name_buff, file->filename, "", MI_NAME_IEXT, - MY_APPEND_EXT | MY_UNPACK_FILENAME); - if (my_is_symlink(name_buff)) - { - my_readlink(buf, name_buff, MYF(0)); - index_file_name= ha_thd()->strdup(buf); - } } if (flag & HA_STATUS_ERRKEY) { |