summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-04-08 07:47:49 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-04-08 07:47:49 +0300
commit7b48da4d7e84759b9d4ceb40b9aeb6d28b27f93c (patch)
treeb437f9ab63a66034822348f77f6b4654a9a95669
parent81258f14323e1d1ad0203bae93bc55a30d47c1b3 (diff)
parentf69c1c9dcb815d7597ec2035470a81ac3b6c9380 (diff)
downloadmariadb-git-7b48da4d7e84759b9d4ceb40b9aeb6d28b27f93c.tar.gz
Merge 10.4 into 10.5
-rw-r--r--include/my_pthread.h1
-rw-r--r--mysql-test/suite/galera/r/galera_var_wsrep_on_off.result46
-rw-r--r--mysql-test/suite/galera/t/galera_var_wsrep_on_off.test57
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_2_cluster.result89
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_wsrep_schema_init.result94
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_2_cluster.cnf25
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_2_cluster.test148
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_wsrep_schema_init.cnf5
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_wsrep_schema_init.test58
-rw-r--r--mysql-test/suite/galera_sr/r/MDEV-25226.result24
-rw-r--r--mysql-test/suite/galera_sr/t/MDEV-25226.test33
-rw-r--r--sql/mysqld.cc19
-rw-r--r--sql/sql_admin.cc11
-rw-r--r--sql/sql_alter.cc2
-rw-r--r--sql/wsrep_mysqld.cc12
-rw-r--r--sql/wsrep_mysqld.h7
-rw-r--r--sql/wsrep_schema.cc36
-rw-r--r--sql/wsrep_trans_observer.h2
-rw-r--r--sql/wsrep_var.cc14
-rw-r--r--sql/wsrep_var.h1
20 files changed, 653 insertions, 31 deletions
diff --git a/include/my_pthread.h b/include/my_pthread.h
index a1b80889ed3..ee4cd15b958 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -197,7 +197,6 @@ static inline int my_sigwait(sigset_t *set, int *sig, int *code)
*code= siginfo.si_code;
return *sig < 0 ? errno : 0;
#else
-#define SI_KERNEL 128
*code= 0;
return sigwait(set, sig);
#endif
diff --git a/mysql-test/suite/galera/r/galera_var_wsrep_on_off.result b/mysql-test/suite/galera/r/galera_var_wsrep_on_off.result
index 5323bc9bf60..b3096afd387 100644
--- a/mysql-test/suite/galera/r/galera_var_wsrep_on_off.result
+++ b/mysql-test/suite/galera/r/galera_var_wsrep_on_off.result
@@ -22,3 +22,49 @@ SELECT COUNT(*) = 1 FROM t1 WHERE f1 = 3;
COUNT(*) = 1
1
DROP TABLE t1;
+START TRANSACTION;
+SET SESSION wsrep_on=OFF;
+ERROR 25000: You are not allowed to execute this command in a transaction
+SET GLOBAL wsrep_on=OFF;
+ERROR 25000: You are not allowed to execute this command in a transaction
+COMMIT;
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
+START TRANSACTION;
+INSERT INTO t1 VALUES (1);
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;;
+connection node_1a;
+SET GLOBAL wsrep_on = OFF;
+connection node_1;
+SHOW SESSION VARIABLES LIKE 'wsrep_on';
+Variable_name Value
+wsrep_on ON
+SHOW GLOBAL VARIABLES LIKE 'wsrep_on';
+Variable_name Value
+wsrep_on OFF
+INSERT INTO t1 VALUES (2);
+COMMIT;
+connection node_2;
+SET SESSION wsrep_sync_wait = 15;
+SELECT * FROM t1;
+f1
+1
+2
+connection node_1a;
+SET GLOBAL wsrep_on = ON;
+DROP TABLE t1;
+connection node_1;
+SET GLOBAL wsrep_on = OFF;
+connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1;;
+connection node_1b;
+SHOW SESSION VARIABLES LIKE 'wsrep_on';
+Variable_name Value
+wsrep_on OFF
+SHOW GLOBAL VARIABLES LIKE 'wsrep_on';
+Variable_name Value
+wsrep_on OFF
+CREATE TABLE t2 (f1 INTEGER);
+DROP TABLE t2;
+SET GLOBAL wsrep_on = ON;
+SHOW SESSION VARIABLES LIKE 'wsrep_on';
+Variable_name Value
+wsrep_on ON
diff --git a/mysql-test/suite/galera/t/galera_var_wsrep_on_off.test b/mysql-test/suite/galera/t/galera_var_wsrep_on_off.test
index 783b78792e6..1a48abc25eb 100644
--- a/mysql-test/suite/galera/t/galera_var_wsrep_on_off.test
+++ b/mysql-test/suite/galera/t/galera_var_wsrep_on_off.test
@@ -30,3 +30,60 @@ SELECT COUNT(*) = 1 FROM t1 WHERE f1 = 3;
DROP TABLE t1;
+
+#
+# Test that variable wsrep_on cannot be changed while in
+# active transaction.
+#
+
+START TRANSACTION;
+--error ER_CANT_DO_THIS_DURING_AN_TRANSACTION
+SET SESSION wsrep_on=OFF;
+--error ER_CANT_DO_THIS_DURING_AN_TRANSACTION
+SET GLOBAL wsrep_on=OFF;
+COMMIT;
+
+
+#
+# Test that @@global.wsrep_on does not affect the value of
+# @@session.wsrep_on of current sessions
+#
+
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
+START TRANSACTION;
+INSERT INTO t1 VALUES (1);
+
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+--connection node_1a
+SET GLOBAL wsrep_on = OFF;
+
+--connection node_1
+SHOW SESSION VARIABLES LIKE 'wsrep_on';
+SHOW GLOBAL VARIABLES LIKE 'wsrep_on';
+INSERT INTO t1 VALUES (2);
+COMMIT;
+
+--connection node_2
+SET SESSION wsrep_sync_wait = 15;
+SELECT * FROM t1;
+
+--connection node_1a
+SET GLOBAL wsrep_on = ON;
+DROP TABLE t1;
+
+
+#
+# New connections inherit @@session.wsrep_on from @@global.wsrep_on
+#
+--connection node_1
+SET GLOBAL wsrep_on = OFF;
+
+--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+--connection node_1b
+SHOW SESSION VARIABLES LIKE 'wsrep_on';
+SHOW GLOBAL VARIABLES LIKE 'wsrep_on';
+CREATE TABLE t2 (f1 INTEGER);
+DROP TABLE t2;
+
+SET GLOBAL wsrep_on = ON;
+SHOW SESSION VARIABLES LIKE 'wsrep_on';
diff --git a/mysql-test/suite/galera_3nodes/r/galera_2_cluster.result b/mysql-test/suite/galera_3nodes/r/galera_2_cluster.result
new file mode 100644
index 00000000000..87898891f9b
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/r/galera_2_cluster.result
@@ -0,0 +1,89 @@
+connection node_2;
+connection node_1;
+connect node_5, 127.0.0.1, root, , test, $NODE_MYPORT_5;
+connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4;
+connection node_4;
+CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_port=NODE_MYPORT_1, master_use_gtid=current_pos;;
+START SLAVE;
+include/wait_for_slave_to_start.inc
+connection node_1;
+CREATE TABLE t1(c1 INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, c2 INTEGER);
+INSERT INTO t1(c2) VALUES(1);
+connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3;
+connection node_3;
+SELECT COUNT(*) = 1 FROM t1;
+COUNT(*) = 1
+1
+connection node_1;
+include/save_master_gtid.inc
+connection node_4;
+include/sync_with_master_gtid.inc
+SELECT COUNT(*) = 1 FROM t1;
+COUNT(*) = 1
+1
+connect node_6, 127.0.0.1, root, , test, $NODE_MYPORT_6;
+connection node_6;
+SELECT COUNT(*) = 1 FROM t1;
+COUNT(*) = 1
+1
+connection node_2;
+ALTER TABLE t1 ADD COLUMN t3 INTEGER;
+Node 2 column number AFTER ALTER
+SELECT COUNT(*) = 3 FROM information_schema.columns WHERE table_name ='t1';
+COUNT(*) = 3
+1
+connection node_3;
+Node 3 column number AFTER ALTER
+SELECT COUNT(*) = 3 FROM information_schema.columns WHERE table_name ='t1';
+COUNT(*) = 3
+1
+connection node_1;
+include/save_master_gtid.inc
+connection node_4;
+include/sync_with_master_gtid.inc
+Node 4 column number AFTER ALTER
+SELECT COUNT(*) = 3 FROM information_schema.columns WHERE table_name ='t1';
+COUNT(*) = 3
+1
+connection node_6;
+Node 6 column number AFTER ALTER
+SELECT COUNT(*) = 3 FROM information_schema.columns WHERE table_name ='t1';
+COUNT(*) = 3
+1
+connection node_2;
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize status OK
+connection node_1;
+connection node_4;
+connection node_6;
+connection node_1;
+DROP TABLE t1;
+connection node_4;
+STOP SLAVE;
+RESET SLAVE;
+SET GLOBAL wsrep_on = OFF;
+RESET MASTER;
+SET GLOBAL wsrep_on = ON;
+SET GLOBAL GTID_SLAVE_POS="";
+connection node_1;
+SET GLOBAL wsrep_on = OFF;
+RESET MASTER;
+SET GLOBAL wsrep_on = ON;
+connection node_2;
+SET GLOBAL wsrep_on = OFF;
+RESET MASTER;
+SET GLOBAL wsrep_on = ON;
+connection node_3;
+SET GLOBAL wsrep_on = OFF;
+RESET MASTER;
+SET GLOBAL wsrep_on = ON;
+connection node_5;
+SET GLOBAL wsrep_on = OFF;
+RESET MASTER;
+SET GLOBAL wsrep_on = ON;
+connection node_6;
+SET GLOBAL wsrep_on = OFF;
+RESET MASTER;
+SET GLOBAL wsrep_on = ON;
diff --git a/mysql-test/suite/galera_3nodes/r/galera_wsrep_schema_init.result b/mysql-test/suite/galera_3nodes/r/galera_wsrep_schema_init.result
new file mode 100644
index 00000000000..2a29afd62be
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/r/galera_wsrep_schema_init.result
@@ -0,0 +1,94 @@
+connection node_2;
+connection node_1;
+connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3;
+connection node_1;
+connection node_1;
+connection node_2;
+connection node_3;
+SHOW CREATE TABLE mysql.wsrep_cluster;
+Table Create Table
+wsrep_cluster CREATE TABLE `wsrep_cluster` (
+ `cluster_uuid` char(36) NOT NULL,
+ `view_id` bigint(20) NOT NULL,
+ `view_seqno` bigint(20) NOT NULL,
+ `protocol_version` int(11) NOT NULL,
+ `capabilities` int(11) NOT NULL,
+ PRIMARY KEY (`cluster_uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW CREATE TABLE mysql.wsrep_cluster_members;
+Table Create Table
+wsrep_cluster_members CREATE TABLE `wsrep_cluster_members` (
+ `node_uuid` char(36) NOT NULL,
+ `cluster_uuid` char(36) NOT NULL,
+ `node_name` char(32) NOT NULL,
+ `node_incoming_address` varchar(256) NOT NULL,
+ PRIMARY KEY (`node_uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT @@sql_safe_updates;
+@@sql_safe_updates
+1
+SELECT COUNT(*) = 1 FROM mysql.wsrep_cluster;
+COUNT(*) = 1
+1
+SELECT cluster_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_state_uuid') FROM mysql.wsrep_cluster;
+cluster_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_state_uuid')
+1
+SELECT COUNT(*) = 3 FROM mysql.wsrep_cluster_members;
+COUNT(*) = 3
+1
+SELECT COUNT(*) = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size') FROM mysql.wsrep_cluster_members;
+COUNT(*) = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size')
+1
+SELECT COUNT(*) = 1 FROM mysql.wsrep_cluster_members WHERE node_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_gcomm_uuid');
+COUNT(*) = 1
+1
+SELECT node_incoming_address LIKE '127.0.0.1:%' from mysql.wsrep_cluster_members;
+node_incoming_address LIKE '127.0.0.1:%'
+1
+1
+1
+SELECT cluster_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_state_uuid') FROM mysql.wsrep_cluster_members;
+cluster_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_state_uuid')
+1
+1
+1
+connection node_2;
+SELECT COUNT(*) = 3 FROM mysql.wsrep_cluster_members;
+COUNT(*) = 3
+1
+SELECT COUNT(*) = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size') FROM mysql.wsrep_cluster_members;
+COUNT(*) = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size')
+1
+SELECT COUNT(*) = 1 FROM mysql.wsrep_cluster_members WHERE node_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_gcomm_uuid');
+COUNT(*) = 1
+1
+SELECT node_incoming_address LIKE '127.0.0.1:%' from mysql.wsrep_cluster_members;
+node_incoming_address LIKE '127.0.0.1:%'
+1
+1
+1
+SELECT cluster_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_state_uuid') FROM mysql.wsrep_cluster_members;
+cluster_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_state_uuid')
+1
+1
+1
+connection node_3;
+SELECT COUNT(*) = 3 FROM mysql.wsrep_cluster_members;
+COUNT(*) = 3
+1
+SELECT COUNT(*) = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size') FROM mysql.wsrep_cluster_members;
+COUNT(*) = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size')
+1
+SELECT COUNT(*) = 1 FROM mysql.wsrep_cluster_members WHERE node_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_gcomm_uuid');
+COUNT(*) = 1
+1
+SELECT node_incoming_address LIKE '127.0.0.1:%' from mysql.wsrep_cluster_members;
+node_incoming_address LIKE '127.0.0.1:%'
+1
+1
+1
+SELECT cluster_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_state_uuid') FROM mysql.wsrep_cluster_members;
+cluster_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_state_uuid')
+1
+1
+1
diff --git a/mysql-test/suite/galera_3nodes/t/galera_2_cluster.cnf b/mysql-test/suite/galera_3nodes/t/galera_2_cluster.cnf
new file mode 100644
index 00000000000..3889a4f4fdd
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_2_cluster.cnf
@@ -0,0 +1,25 @@
+!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 \ No newline at end of file
diff --git a/mysql-test/suite/galera_3nodes/t/galera_2_cluster.test b/mysql-test/suite/galera_3nodes/t/galera_2_cluster.test
new file mode 100644
index 00000000000..8a9a74a7252
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_2_cluster.test
@@ -0,0 +1,148 @@
+#
+# This test creates 2x3 nodes galera cluster.
+#
+# A(1) <-> B(2) <-> C(3) {Galera cluster 1}
+# | {Circular Async replication}
+# D(4) <-> E(5) <-> F(6) {Galera cluster 2}
+#
+
+--source include/big_test.inc
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+
+--connect node_5, 127.0.0.1, root, , test, $NODE_MYPORT_5
+
+--connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4
+--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;
+START SLAVE;
+--source include/wait_for_slave_to_start.inc
+
+#
+# CREATE TABLE & INSERT
+#
+
+--connection node_1
+
+CREATE TABLE t1(c1 INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, c2 INTEGER);
+INSERT INTO t1(c2) VALUES(1);
+
+--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
+--connection node_3
+
+SELECT COUNT(*) = 1 FROM t1;
+
+--connection node_1
+--source include/save_master_gtid.inc
+
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+SELECT COUNT(*) = 1 FROM t1;
+
+--connect node_6, 127.0.0.1, root, , test, $NODE_MYPORT_6
+--connection node_6
+
+SELECT COUNT(*) = 1 FROM t1;
+
+#
+# ALTER TABLE
+#
+
+--connection node_2
+
+ALTER TABLE t1 ADD COLUMN t3 INTEGER;
+--echo Node 2 column number AFTER ALTER
+SELECT COUNT(*) = 3 FROM information_schema.columns WHERE table_name ='t1';
+
+--connection node_3
+
+--echo Node 3 column number AFTER ALTER
+SELECT COUNT(*) = 3 FROM information_schema.columns WHERE table_name ='t1';
+
+--connection node_1
+--source include/save_master_gtid.inc
+
+--connection node_4
+--source include/sync_with_master_gtid.inc
+
+--echo Node 4 column number AFTER ALTER
+SELECT COUNT(*) = 3 FROM information_schema.columns WHERE table_name ='t1';
+
+--connection node_6
+
+--echo Node 6 column number AFTER ALTER
+SELECT COUNT(*) = 3 FROM information_schema.columns WHERE table_name ='t1';
+
+#
+# OPTIMIZE TABLE
+#
+
+--connection node_2
+
+--let $wsrep_last_committed_before = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'`
+OPTIMIZE TABLE t1;
+
+--connection node_1
+
+--let $wait_condition = SELECT VARIABLE_VALUE >= $wsrep_last_committed_before + 1 FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'
+--source include/wait_condition.inc
+
+--connection node_4
+
+--let $wait_condition = SELECT VARIABLE_VALUE >= $wsrep_last_committed_before + 1 FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'
+--source include/wait_condition.inc
+
+--connection node_6
+
+--let $wait_condition = SELECT VARIABLE_VALUE >= $wsrep_last_committed_before + 1 FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'
+--source include/wait_condition.inc
+
+#
+# Cleanup
+#
+
+--connection node_1
+
+DROP TABLE t1;
+
+--connection node_4
+
+STOP SLAVE;
+RESET SLAVE;
+SET GLOBAL wsrep_on = OFF;
+RESET MASTER;
+SET GLOBAL wsrep_on = ON;
+SET GLOBAL GTID_SLAVE_POS="";
+
+--connection node_1
+
+SET GLOBAL wsrep_on = OFF;
+RESET MASTER;
+SET GLOBAL wsrep_on = ON;
+
+--connection node_2
+
+SET GLOBAL wsrep_on = OFF;
+RESET MASTER;
+SET GLOBAL wsrep_on = ON;
+
+--connection node_3
+
+SET GLOBAL wsrep_on = OFF;
+RESET MASTER;
+SET GLOBAL wsrep_on = ON;
+
+--connection node_5
+
+SET GLOBAL wsrep_on = OFF;
+RESET MASTER;
+SET GLOBAL wsrep_on = ON;
+
+--connection node_6
+
+SET GLOBAL wsrep_on = OFF;
+RESET MASTER;
+SET GLOBAL wsrep_on = ON;
diff --git a/mysql-test/suite/galera_3nodes/t/galera_wsrep_schema_init.cnf b/mysql-test/suite/galera_3nodes/t/galera_wsrep_schema_init.cnf
new file mode 100644
index 00000000000..317094cea72
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_wsrep_schema_init.cnf
@@ -0,0 +1,5 @@
+!include ../galera_3nodes.cnf
+
+[mysqld]
+sql-safe-updates=1
+wsrep-debug=1
diff --git a/mysql-test/suite/galera_3nodes/t/galera_wsrep_schema_init.test b/mysql-test/suite/galera_3nodes/t/galera_wsrep_schema_init.test
new file mode 100644
index 00000000000..7d8089a8ceb
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_wsrep_schema_init.test
@@ -0,0 +1,58 @@
+#
+# This test performs basic checks on the contents of the wsrep_schema
+#
+# wsrep_members_history checks are temporarily disabled until it
+# can be made configurable.
+#
+
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+
+--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
+--connection node_1
+# Save original auto_increment_offset values.
+--let $node_1=node_1
+--let $node_2=node_2
+--let $node_3=node_3
+--source ../galera/include/auto_increment_offset_save.inc
+
+# Make the test fail if table structure has changed
+
+SHOW CREATE TABLE mysql.wsrep_cluster;
+SHOW CREATE TABLE mysql.wsrep_cluster_members;
+#disabled SHOW CREATE TABLE mysql.wsrep_member_history;
+SELECT @@sql_safe_updates;
+
+# Checks for the wsrep_cluster table
+
+SELECT COUNT(*) = 1 FROM mysql.wsrep_cluster;
+SELECT cluster_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_state_uuid') FROM mysql.wsrep_cluster;
+
+# Checks for the wsrep_cluster_members table
+
+SELECT COUNT(*) = 3 FROM mysql.wsrep_cluster_members;
+SELECT COUNT(*) = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size') FROM mysql.wsrep_cluster_members;
+SELECT COUNT(*) = 1 FROM mysql.wsrep_cluster_members WHERE node_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_gcomm_uuid');
+
+SELECT node_incoming_address LIKE '127.0.0.1:%' from mysql.wsrep_cluster_members;
+SELECT cluster_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_state_uuid') FROM mysql.wsrep_cluster_members;
+
+--connection node_2
+
+SELECT COUNT(*) = 3 FROM mysql.wsrep_cluster_members;
+SELECT COUNT(*) = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size') FROM mysql.wsrep_cluster_members;
+SELECT COUNT(*) = 1 FROM mysql.wsrep_cluster_members WHERE node_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_gcomm_uuid');
+
+SELECT node_incoming_address LIKE '127.0.0.1:%' from mysql.wsrep_cluster_members;
+SELECT cluster_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_state_uuid') FROM mysql.wsrep_cluster_members;
+
+--connection node_3
+SELECT COUNT(*) = 3 FROM mysql.wsrep_cluster_members;
+SELECT COUNT(*) = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size') FROM mysql.wsrep_cluster_members;
+SELECT COUNT(*) = 1 FROM mysql.wsrep_cluster_members WHERE node_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_gcomm_uuid');
+
+SELECT node_incoming_address LIKE '127.0.0.1:%' from mysql.wsrep_cluster_members;
+SELECT cluster_uuid = (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_state_uuid') FROM mysql.wsrep_cluster_members;
+
+--source ../galera/include/auto_increment_offset_restore.inc
+
diff --git a/mysql-test/suite/galera_sr/r/MDEV-25226.result b/mysql-test/suite/galera_sr/r/MDEV-25226.result
new file mode 100644
index 00000000000..4699023562d
--- /dev/null
+++ b/mysql-test/suite/galera_sr/r/MDEV-25226.result
@@ -0,0 +1,24 @@
+connection node_2;
+connection node_1;
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
+SET SESSION wsrep_trx_fragment_size=1;
+START TRANSACTION;
+INSERT INTO t1 VALUES(1);
+SET SESSION wsrep_on=OFF;
+ERROR 25000: You are not allowed to execute this command in a transaction
+SET GLOBAL wsrep_on=OFF;
+ERROR 25000: You are not allowed to execute this command in a transaction
+INSERT INTO t1 VALUES(2);
+COMMIT;
+connection node_1;
+SELECT * FROM t1;
+f1
+1
+2
+connection node_2;
+SELECT * FROM t1;
+f1
+1
+2
+connection node_1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/galera_sr/t/MDEV-25226.test b/mysql-test/suite/galera_sr/t/MDEV-25226.test
new file mode 100644
index 00000000000..3d19a0b9675
--- /dev/null
+++ b/mysql-test/suite/galera_sr/t/MDEV-25226.test
@@ -0,0 +1,33 @@
+#
+# MDEV-25226 - Test the case the where wsrep_on is set OFF
+# on a transaction that has already replicated a fragment.
+#
+# This would cause: Assertion `transaction_.active() == false ||
+# (transaction_.state() == wsrep::transaction::s_executing ||
+# transaction_.state() == wsrep::transaction::s_prepared ||
+# transaction_.state() == wsrep::transaction::s_aborted ||
+# transaction_.state() == wsrep::transaction::s_must_abort)'
+#
+
+--source include/galera_cluster.inc
+
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
+
+SET SESSION wsrep_trx_fragment_size=1;
+START TRANSACTION;
+INSERT INTO t1 VALUES(1);
+--error ER_CANT_DO_THIS_DURING_AN_TRANSACTION
+SET SESSION wsrep_on=OFF;
+--error ER_CANT_DO_THIS_DURING_AN_TRANSACTION
+SET GLOBAL wsrep_on=OFF;
+INSERT INTO t1 VALUES(2);
+COMMIT;
+
+--connection node_1
+SELECT * FROM t1;
+
+--connection node_2
+SELECT * FROM t1;
+
+--connection node_1
+DROP TABLE t1;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 306d924b625..29aaf389ca1 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1127,14 +1127,6 @@ PSI_file_key key_file_map;
PSI_statement_info stmt_info_new_packet;
#endif
-#ifdef WITH_WSREP
-/** Whether the Galera write-set replication is enabled. A cached copy of
-global_system_variables.wsrep_on && wsrep_provider &&
- strcmp(wsrep_provider, WSREP_NONE)
-*/
-bool WSREP_ON_;
-#endif /* WITH_WSREP */
-
#ifndef EMBEDDED_LIBRARY
void net_before_header_psi(struct st_net *net, void *thd, size_t /* unused: count */)
{
@@ -3002,7 +2994,13 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
}
break;
case SIGHUP:
+#if defined(SI_KERNEL)
if (!abort_loop && origin != SI_KERNEL)
+#elif defined(SI_USER)
+ if (!abort_loop && origin <= SI_USER)
+#else
+ if (!abort_loop)
+#endif
{
int not_used;
mysql_print_status(); // Print some debug info
@@ -5465,10 +5463,7 @@ int mysqld_main(int argc, char **argv)
}
#ifdef WITH_WSREP
- WSREP_ON_= (global_system_variables.wsrep_on &&
- wsrep_provider &&
- strcmp(wsrep_provider, WSREP_NONE));
-
+ wsrep_set_wsrep_on();
if (WSREP_ON && wsrep_check_opts()) unireg_abort(1);
#endif
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index 3f5b15715f9..3a4cc281e8c 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -440,8 +440,6 @@ dbug_err:
*/
static bool wsrep_toi_replication(THD *thd, TABLE_LIST *tables)
{
- if (!WSREP(thd) || !WSREP_CLIENT(thd)) return false;
-
LEX *lex= thd->lex;
/* only handle OPTIMIZE and REPAIR here */
switch (lex->sql_command)
@@ -542,10 +540,13 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
for (table= tables; table; table= table->next_local)
table->table= NULL;
#ifdef WITH_WSREP
- if (wsrep_toi_replication(thd, tables))
+ if (WSREP(thd))
{
- WSREP_INFO("wsrep TOI replication of has failed, skipping OPTIMIZE");
- goto err;
+ if(wsrep_toi_replication(thd, tables))
+ {
+ WSREP_INFO("wsrep TOI replication of has failed.");
+ goto err;
+ }
}
#endif /* WITH_WSREP */
diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc
index 0184f6beaf4..7901c9b5e32 100644
--- a/sql/sql_alter.cc
+++ b/sql/sql_alter.cc
@@ -491,7 +491,7 @@ bool Sql_cmd_alter_table::execute(THD *thd)
if (check_grant(thd, priv_needed, first_table, FALSE, UINT_MAX, FALSE))
DBUG_RETURN(TRUE); /* purecov: inspected */
#ifdef WITH_WSREP
- if (WSREP(thd) && WSREP_CLIENT(thd) &&
+ if (WSREP(thd) &&
(!thd->is_current_stmt_binlog_format_row() ||
!thd->find_temporary_table(first_table)))
{
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index f14bf06800a..d1529bf8547 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -133,6 +133,18 @@ uint wsrep_ignore_apply_errors= 0;
*/
/*
+ * Cached variables
+ */
+
+// Whether the Galera write-set replication provider is set
+// wsrep_provider && strcmp(wsrep_provider, WSREP_NONE)
+bool WSREP_PROVIDER_EXISTS_;
+
+// Whether the Galera write-set replication is enabled
+// global_system_variables.wsrep_on && WSREP_PROVIDER_EXISTS_
+bool WSREP_ON_;
+
+/*
* Other wsrep global variables.
*/
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 28c012a607c..9981b247f3f 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -21,6 +21,7 @@
#ifdef WITH_WSREP
extern bool WSREP_ON_;
+extern bool WSREP_PROVIDER_EXISTS_;
#include <mysql/plugin.h>
#include "mysql/service_wsrep.h"
@@ -225,7 +226,8 @@ extern wsrep_seqno_t wsrep_locked_seqno;
/* use xxxxxx_NNULL macros when thd pointer is guaranteed to be non-null to
* avoid compiler warnings (GCC 6 and later) */
-#define WSREP_NNULL(thd) (WSREP_ON && thd->variables.wsrep_on)
+#define WSREP_NNULL(thd) \
+ (WSREP_PROVIDER_EXISTS_ && thd->variables.wsrep_on)
#define WSREP(thd) \
(thd && WSREP_NNULL(thd))
@@ -282,8 +284,7 @@ void WSREP_LOG(void (*fun)(const char* fmt, ...), const char* fmt, ...);
WSREP_INFO("context: %s:%d", __FILE__, __LINE__); \
}
-#define WSREP_PROVIDER_EXISTS \
- (wsrep_provider && strncasecmp(wsrep_provider, WSREP_NONE, FN_REFLEN))
+#define WSREP_PROVIDER_EXISTS (WSREP_PROVIDER_EXISTS_)
static inline bool wsrep_cluster_address_exists()
{
diff --git a/sql/wsrep_schema.cc b/sql/wsrep_schema.cc
index 43ddcb93abb..6fa00dfe979 100644
--- a/sql/wsrep_schema.cc
+++ b/sql/wsrep_schema.cc
@@ -178,6 +178,24 @@ private:
THD *m_cur_thd;
};
+class sql_safe_updates
+{
+public:
+ sql_safe_updates(THD* thd)
+ : m_thd(thd)
+ , m_option_bits(thd->variables.option_bits)
+ {
+ thd->variables.option_bits&= ~OPTION_SAFE_UPDATES;
+ }
+ ~sql_safe_updates()
+ {
+ m_thd->variables.option_bits= m_option_bits;
+ }
+private:
+ THD* m_thd;
+ ulonglong m_option_bits;
+};
+
static int execute_SQL(THD* thd, const char* sql, uint length) {
DBUG_ENTER("Wsrep_schema::execute_SQL()");
int err= 0;
@@ -621,13 +639,15 @@ static void wsrep_init_thd_for_schema(THD *thd)
thd->prior_thr_create_utime= thd->start_utime= thd->thr_create_utime;
- /* */
- thd->variables.wsrep_on = 0;
+ /* No Galera replication */
+ thd->variables.wsrep_on= 0;
/* No binlogging */
- thd->variables.sql_log_bin = 0;
- thd->variables.option_bits &= ~OPTION_BIN_LOG;
+ thd->variables.sql_log_bin= 0;
+ thd->variables.option_bits&= ~OPTION_BIN_LOG;
+ /* No safe updates */
+ thd->variables.option_bits&= ~OPTION_SAFE_UPDATES;
/* No general log */
- thd->variables.option_bits |= OPTION_LOG_OFF;
+ thd->variables.option_bits|= OPTION_LOG_OFF;
/* Read committed isolation to avoid gap locking */
thd->variables.tx_isolation= ISO_READ_COMMITTED;
wsrep_assign_from_threadvars(thd);
@@ -682,6 +702,7 @@ int Wsrep_schema::store_view(THD* thd, const Wsrep_view& view)
Wsrep_schema_impl::wsrep_off wsrep_off(thd);
Wsrep_schema_impl::binlog_off binlog_off(thd);
+ Wsrep_schema_impl::sql_safe_updates sql_safe_updates(thd);
/*
Clean up cluster table and members table.
@@ -936,6 +957,7 @@ int Wsrep_schema::append_fragment(THD* thd,
thd->lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
Wsrep_schema_impl::binlog_off binlog_off(thd);
+ Wsrep_schema_impl::sql_safe_updates sql_safe_updates(thd);
Wsrep_schema_impl::init_stmt(thd);
TABLE* frag_table= 0;
@@ -985,6 +1007,7 @@ int Wsrep_schema::update_fragment_meta(THD* thd,
thd->lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
Wsrep_schema_impl::binlog_off binlog_off(thd);
+ Wsrep_schema_impl::sql_safe_updates sql_safe_updates(thd);
int error;
uchar *key=NULL;
key_part_map key_map= 0;
@@ -1107,6 +1130,7 @@ int Wsrep_schema::remove_fragments(THD* thd,
WSREP_DEBUG("Removing %zu fragments", fragments.size());
Wsrep_schema_impl::wsrep_off wsrep_off(thd);
Wsrep_schema_impl::binlog_off binlog_off(thd);
+ Wsrep_schema_impl::sql_safe_updates sql_safe_updates(thd);
Query_tables_list query_tables_list_backup;
Open_tables_backup open_tables_backup;
@@ -1177,6 +1201,7 @@ int Wsrep_schema::replay_transaction(THD* orig_thd,
Wsrep_schema_impl::wsrep_off wsrep_off(&thd);
Wsrep_schema_impl::binlog_off binlog_off(&thd);
+ Wsrep_schema_impl::sql_safe_updates sql_safe_updates(&thd);
Wsrep_schema_impl::thd_context_switch thd_context_switch(orig_thd, &thd);
int ret= 1;
@@ -1291,6 +1316,7 @@ int Wsrep_schema::recover_sr_transactions(THD *orig_thd)
Wsrep_storage_service storage_service(&storage_thd);
Wsrep_schema_impl::binlog_off binlog_off(&storage_thd);
Wsrep_schema_impl::wsrep_off wsrep_off(&storage_thd);
+ Wsrep_schema_impl::sql_safe_updates sql_safe_updates(&storage_thd);
Wsrep_schema_impl::thd_context_switch thd_context_switch(orig_thd,
&storage_thd);
Wsrep_server_state& server_state(Wsrep_server_state::instance());
diff --git a/sql/wsrep_trans_observer.h b/sql/wsrep_trans_observer.h
index e9b4ab8af15..1f6576093cb 100644
--- a/sql/wsrep_trans_observer.h
+++ b/sql/wsrep_trans_observer.h
@@ -439,7 +439,7 @@ static inline void wsrep_after_apply(THD* thd)
static inline void wsrep_open(THD* thd)
{
DBUG_ENTER("wsrep_open");
- if (WSREP(thd))
+ if (WSREP_PROVIDER_EXISTS)
{
thd->wsrep_cs().open(wsrep::client_id(thd->thread_id));
thd->wsrep_cs().debug_log_level(wsrep_debug);
diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc
index 9ba8f081c83..2db3768f7fc 100644
--- a/sql/wsrep_var.cc
+++ b/sql/wsrep_var.cc
@@ -91,10 +91,11 @@ static bool refresh_provider_options()
}
}
-static void wsrep_set_wsrep_on()
+void wsrep_set_wsrep_on()
{
- WSREP_ON_= global_system_variables.wsrep_on && wsrep_provider &&
- strcmp(wsrep_provider, WSREP_NONE);
+ WSREP_PROVIDER_EXISTS_= wsrep_provider &&
+ strncasecmp(wsrep_provider, WSREP_NONE, FN_REFLEN);
+ WSREP_ON_= global_system_variables.wsrep_on && WSREP_PROVIDER_EXISTS_;
}
/* This is intentionally declared as a weak global symbol, so that
@@ -149,6 +150,13 @@ bool wsrep_on_check(sys_var *self, THD* thd, set_var* var)
" innodb_lock_schedule_algorithm=FCFS and restart.", MYF(0));
return true;
}
+
+ if (thd->in_active_multi_stmt_transaction())
+ {
+ my_error(ER_CANT_DO_THIS_DURING_AN_TRANSACTION, MYF(0));
+ return true;
+ }
+
return false;
}
diff --git a/sql/wsrep_var.h b/sql/wsrep_var.h
index fb23182dbf2..997784674dd 100644
--- a/sql/wsrep_var.h
+++ b/sql/wsrep_var.h
@@ -36,6 +36,7 @@ class set_var;
class THD;
int wsrep_init_vars();
+void wsrep_set_wsrep_on();
#define CHECK_ARGS (sys_var *self, THD* thd, set_var *var)
#define UPDATE_ARGS (sys_var *self, THD* thd, enum_var_type type)