From 3045b60f0fa953b779eaf8bd4e83a8dd807c2107 Mon Sep 17 00:00:00 2001 From: Alexey Yurchenko Date: Sat, 20 Aug 2016 13:42:11 +0200 Subject: [PATCH 01/66] GAL-401: MTR test for the fix. --- mysql-test/suite/galera/r/GAL-401.result | 21 +++++++++++ mysql-test/suite/galera/t/GAL-401.test | 48 ++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 mysql-test/suite/galera/r/GAL-401.result create mode 100644 mysql-test/suite/galera/t/GAL-401.test diff --git a/mysql-test/suite/galera/r/GAL-401.result b/mysql-test/suite/galera/r/GAL-401.result new file mode 100644 index 00000000000..e1da2b4cf1a --- /dev/null +++ b/mysql-test/suite/galera/r/GAL-401.result @@ -0,0 +1,21 @@ +SET GLOBAL wsrep_provider_options = 'pc.ignore_sb=true'; +SET @@global.wsrep_desync = 1; +SET SESSION wsrep_dirty_reads=1; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)); +SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; +SET wsrep_dirty_reads=0; +SHOW STATUS LIKE 'wsrep_desync_count'; +Variable_name Value +wsrep_desync_count 0 +SET @@global.wsrep_desync = 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + `f2` char(1) DEFAULT NULL, + PRIMARY KEY (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; +CALL mtr.add_suppression("WSREP: Protocol violation. JOIN message sender (.*) is not in state transfer \\(SYNCED\\). Message ignored."); +SET GLOBAL wsrep_provider_options = 'pc.ignore_sb=false'; diff --git a/mysql-test/suite/galera/t/GAL-401.test b/mysql-test/suite/galera/t/GAL-401.test new file mode 100644 index 00000000000..1f7b493717f --- /dev/null +++ b/mysql-test/suite/galera/t/GAL-401.test @@ -0,0 +1,48 @@ +# This tests proper desync counter cleanup when DONOR/DESYNC state is cleared. + +--source include/galera_cluster.inc +--source include/have_innodb.inc + +# Make node 1 tolerate split-brain +SET GLOBAL wsrep_provider_options = 'pc.ignore_sb=true'; + +# Desync and disconnect node 2 from the PC: +--connection node_2 +SET @@global.wsrep_desync = 1; +SET SESSION wsrep_dirty_reads=1; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; +--let $wait_condition = SELECT VARIABLE_VALUE = 'non-Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +--source include/wait_condition.inc + +# Wait until node 2 disappears from the PC: +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +--source include/wait_condition.inc + +# Modify app state to force node 2 into PRIMARY upon reconnection. +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)); + +# Reconnect node 2 to the PC: +--connection node_2 +SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; +SET wsrep_dirty_reads=0; +--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +--source include/wait_condition.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +# Must return 0: +SHOW STATUS LIKE 'wsrep_desync_count'; + +# Resync node_2, should pass: +SET @@global.wsrep_desync = 0; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CALL mtr.add_suppression("WSREP: Protocol violation. JOIN message sender (.*) is not in state transfer \\(SYNCED\\). Message ignored."); + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc +SET GLOBAL wsrep_provider_options = 'pc.ignore_sb=false'; From 86ec6c221a16733cc0d8280b52fc79f48e842b8f Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Sun, 12 Mar 2017 13:56:29 +0530 Subject: [PATCH 02/66] MW-267: followup to the original pull request, removed unnecessary cast. Signed-off-by: Sachin Setiya --- mysql-test/include/galera_wait_ready.inc | 2 + .../galera/galera_2nodes_as_master_slave.cnf | 83 +++++++ ...lera_2nodes_as_master_with_repl_filter.cnf | 87 +++++++ mysql-test/suite/galera/r/ev51914.result | 162 +++++++++++++ mysql-test/suite/galera/r/galera_admin.result | 43 ++++ .../galera/r/galera_desync_overlapped.result | 45 ++++ .../r/galera_restart_on_unknown_option.result | 40 ++++ .../galera/r/galera_toi_ddl_fk_update.result | 23 ++ .../galera/r/galera_toi_ddl_online.result | 27 +++ .../galera/r/galera_toi_drop_database.result | 22 ++ .../suite/galera/r/galera_toi_truncate.result | 17 ++ ...alera_wsrep_provider_options_syntax.result | 5 + mysql-test/suite/galera/r/lp1376747-2.result | 19 ++ mysql-test/suite/galera/r/lp1376747-3.result | 21 ++ mysql-test/suite/galera/r/lp1376747-4.result | 36 +++ mysql-test/suite/galera/r/lp1376747.result | 19 ++ mysql-test/suite/galera/r/pxc-421.result | 35 +++ mysql-test/suite/galera/t/ev51914.test | 214 ++++++++++++++++++ mysql-test/suite/galera/t/galera_admin.test | 86 +++++++ .../galera/t/galera_desync_overlapped.test | 59 +++++ .../suite/galera/t/galera_flush_local.opt | 2 +- .../t/galera_restart_on_unknown_option.test | 150 ++++++++++++ .../galera/t/galera_toi_ddl_fk_update.test | 49 ++++ .../suite/galera/t/galera_toi_ddl_online.test | 53 +++++ .../galera/t/galera_toi_drop_database.test | 54 +++++ .../suite/galera/t/galera_toi_truncate.test | 77 +++++++ .../galera_wsrep_provider_options_syntax.test | 20 ++ mysql-test/suite/galera/t/lp1376747-2.test | 22 ++ mysql-test/suite/galera/t/lp1376747-3.test | 28 +++ mysql-test/suite/galera/t/lp1376747-4.test | 53 +++++ mysql-test/suite/galera/t/lp1376747.test | 24 ++ mysql-test/suite/galera/t/pxc-421.test | 60 +++++ 32 files changed, 1636 insertions(+), 1 deletion(-) create mode 100644 mysql-test/include/galera_wait_ready.inc create mode 100644 mysql-test/suite/galera/galera_2nodes_as_master_slave.cnf create mode 100644 mysql-test/suite/galera/galera_2nodes_as_master_with_repl_filter.cnf create mode 100644 mysql-test/suite/galera/r/ev51914.result create mode 100644 mysql-test/suite/galera/r/galera_admin.result create mode 100644 mysql-test/suite/galera/r/galera_desync_overlapped.result create mode 100644 mysql-test/suite/galera/r/galera_restart_on_unknown_option.result create mode 100644 mysql-test/suite/galera/r/galera_toi_ddl_fk_update.result create mode 100644 mysql-test/suite/galera/r/galera_toi_ddl_online.result create mode 100644 mysql-test/suite/galera/r/galera_toi_drop_database.result create mode 100644 mysql-test/suite/galera/r/galera_toi_truncate.result create mode 100644 mysql-test/suite/galera/r/galera_wsrep_provider_options_syntax.result create mode 100644 mysql-test/suite/galera/r/lp1376747-2.result create mode 100644 mysql-test/suite/galera/r/lp1376747-3.result create mode 100644 mysql-test/suite/galera/r/lp1376747-4.result create mode 100644 mysql-test/suite/galera/r/lp1376747.result create mode 100644 mysql-test/suite/galera/r/pxc-421.result create mode 100644 mysql-test/suite/galera/t/ev51914.test create mode 100644 mysql-test/suite/galera/t/galera_admin.test create mode 100644 mysql-test/suite/galera/t/galera_desync_overlapped.test create mode 100644 mysql-test/suite/galera/t/galera_restart_on_unknown_option.test create mode 100644 mysql-test/suite/galera/t/galera_toi_ddl_fk_update.test create mode 100644 mysql-test/suite/galera/t/galera_toi_ddl_online.test create mode 100644 mysql-test/suite/galera/t/galera_toi_drop_database.test create mode 100644 mysql-test/suite/galera/t/galera_toi_truncate.test create mode 100644 mysql-test/suite/galera/t/galera_wsrep_provider_options_syntax.test create mode 100644 mysql-test/suite/galera/t/lp1376747-2.test create mode 100644 mysql-test/suite/galera/t/lp1376747-3.test create mode 100644 mysql-test/suite/galera/t/lp1376747-4.test create mode 100644 mysql-test/suite/galera/t/lp1376747.test create mode 100644 mysql-test/suite/galera/t/pxc-421.test diff --git a/mysql-test/include/galera_wait_ready.inc b/mysql-test/include/galera_wait_ready.inc new file mode 100644 index 00000000000..e20f01fad90 --- /dev/null +++ b/mysql-test/include/galera_wait_ready.inc @@ -0,0 +1,2 @@ +let $wait_condition = SELECT 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready' AND VARIABLE_VALUE = 'ON'; +--source include/wait_condition.inc diff --git a/mysql-test/suite/galera/galera_2nodes_as_master_slave.cnf b/mysql-test/suite/galera/galera_2nodes_as_master_slave.cnf new file mode 100644 index 00000000000..716a790fea6 --- /dev/null +++ b/mysql-test/suite/galera/galera_2nodes_as_master_slave.cnf @@ -0,0 +1,83 @@ + +# +# Let's understand the topology. +# * Independent Master with server-id = 1 +# * Galera cluster with 2 nodes: node#1 and node#2 with server-id = 2, 3 +# node#1 act as slave to Independent Master with server-id = 1 +# * Independent Slave with server-id = 4 replicating from galera node#2 +# + +# Use default setting for mysqld processes +!include include/default_mysqld.cnf + +[mysqld] +log-slave-updates +log-bin=mysqld-bin +binlog-format=row +gtid-mode=on +enforce-gtid-consistency=true + +[mysqld.1] +server-id=1 + +[mysqld.2] +server-id=2 + +wsrep_provider=@ENV.WSREP_PROVIDER +wsrep_cluster_address='gcomm://' +wsrep_provider_options='base_port=@mysqld.2.#galera_port;evs.install_timeout = PT15S; evs.max_install_timeouts=1;' + +# enforce read-committed characteristics across the cluster +wsrep_causal_reads=ON +wsrep_sync_wait = 7 + +wsrep_node_address=127.0.0.1 +wsrep_sst_receive_address=127.0.0.2:@mysqld.2.#sst_port +wsrep_node_incoming_address=127.0.0.1:@mysqld.2.port + +# Required for Galera +innodb_autoinc_lock_mode=2 + +innodb_flush_log_at_trx_commit=2 + +[mysqld.3] +server-id=3 + +wsrep_provider=@ENV.WSREP_PROVIDER +wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.2.#galera_port' +wsrep_provider_options='base_port=@mysqld.3.#galera_port;evs.install_timeout = PT15S; evs.max_install_timeouts = 1;' + +# enforce read-committed characteristics across the cluster +wsrep_causal_reads=ON +wsrep_sync_wait = 7 + +wsrep_node_address=127.0.0.1 +wsrep_sst_receive_address=127.0.0.2:@mysqld.3.#sst_port +wsrep_node_incoming_address=127.0.0.1:@mysqld.3.port + +# Required for Galera +innodb_autoinc_lock_mode=2 + +innodb_flush_log_at_trx_commit=2 + +[mysqld.4] +server-id=4 + +[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_GALERAPORT_2= @mysqld.2.#galera_port +NODE_GALERAPORT_3= @mysqld.3.#galera_port + +NODE_SSTPORT_2= @mysqld.2.#sst_port +NODE_SSTPORT_3= @mysqld.3.#sst_port diff --git a/mysql-test/suite/galera/galera_2nodes_as_master_with_repl_filter.cnf b/mysql-test/suite/galera/galera_2nodes_as_master_with_repl_filter.cnf new file mode 100644 index 00000000000..5f0af2e58e5 --- /dev/null +++ b/mysql-test/suite/galera/galera_2nodes_as_master_with_repl_filter.cnf @@ -0,0 +1,87 @@ +# +# This .cnf file creates a setup with a 2-node Galera cluster and one stand-alone MySQL server, to be used as a slave +# + +# Use default setting for mysqld processes +!include include/default_mysqld.cnf + +[mysqld] +default-storage-engine=InnoDB + +[mysqld.1] +server-id=1 +binlog-format=row +log-bin=mysqld-bin +log_slave_updates +gtid-mode=on +enforce-gtid-consistency=true +event-scheduler=1 + +wsrep_provider=@ENV.WSREP_PROVIDER +wsrep_cluster_address='gcomm://' +wsrep_provider_options='base_port=@mysqld.1.#galera_port' + +# enforce read-committed characteristics across the cluster +wsrep_causal_reads=ON +wsrep_sync_wait = 7 + +wsrep_node_address=127.0.0.1 +wsrep_sst_receive_address=127.0.0.2:@mysqld.1.#sst_port +wsrep_node_incoming_address=127.0.0.1:@mysqld.1.port + +# Required for Galera +innodb_autoinc_lock_mode=2 + +innodb_flush_log_at_trx_commit=2 + +[mysqld.2] +server-id=2 +binlog-format=row +log-bin=mysqld-bin +log_slave_updates +gtid-mode=on +enforce-gtid-consistency=true +event-scheduler=1 + +wsrep_provider=@ENV.WSREP_PROVIDER +wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.1.#galera_port' +wsrep_provider_options='base_port=@mysqld.2.#galera_port' + +# enforce read-committed characteristics across the cluster +wsrep_causal_reads=ON +wsrep_sync_wait = 7 + +wsrep_node_address=127.0.0.1 +wsrep_sst_receive_address=127.0.0.2:@mysqld.2.#sst_port +wsrep_node_incoming_address=127.0.0.1:@mysqld.2.port + +# Required for Galera +innodb_autoinc_lock_mode=2 + +innodb_flush_log_at_trx_commit=2 + +[mysqld.3] +server-id=3 +replicate-ignore-db=test +replicate-wild-ignore-table=test.% +log-bin=mysqld-bin +log_slave_updates +gtid-mode=on +enforce-gtid-consistency=true +event-scheduler=1 + +[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_GALERAPORT_1= @mysqld.1.#galera_port +NODE_GALERAPORT_2= @mysqld.2.#galera_port + +NODE_SSTPORT_1= @mysqld.1.#sst_port +NODE_SSTPORT_2= @mysqld.2.#sst_port diff --git a/mysql-test/suite/galera/r/ev51914.result b/mysql-test/suite/galera/r/ev51914.result new file mode 100644 index 00000000000..4b9f7ace0da --- /dev/null +++ b/mysql-test/suite/galera/r/ev51914.result @@ -0,0 +1,162 @@ +SAVEPOINT in a stored function should be forbidden +CREATE FUNCTION f1 () RETURNS INT BEGIN +SAVEPOINT s; +RETURN 1; +END| +SELECT f1(); +f1() +1 +DROP FUNCTION f1; +ROLLBACK TO SAVEPOINT in a stored function should be forbidden +CREATE FUNCTION f2 () RETURNS INT BEGIN +ROLLBACK TO SAVEPOINT s; +RETURN 1; +END| +BEGIN; +SAVEPOINT s; +SELECT f2(); +ERROR 42000: SAVEPOINT s does not exist +COMMIT; +DROP FUNCTION f2; +BEGIN; +SAVEPOINT S; +ROLLBACK TO SAVEPOINT S; +COMMIT; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB; +INSERT INTO t1 values (110), (111), (112), (113), (114); +Direct SAVEPOINT in a trigger should be forbidden +CREATE TRIGGER i1_t1 BEFORE INSERT ON t1 FOR EACH ROW SAVEPOINT s; +INSERT INTO t1 VALUES (1); +DROP TRIGGER i1_t1; +CREATE TRIGGER i2_t1 AFTER INSERT ON t1 FOR EACH ROW SAVEPOINT s; +INSERT INTO t1 VALUES (2); +DROP TRIGGER i2_t1; +INSERT INTO t1 VALUES (3); +CREATE TRIGGER u1_t1 BEFORE UPDATE ON t1 FOR EACH ROW SAVEPOINT s; +UPDATE t1 SET a=4 WHERE a=3; +DROP TRIGGER u1_t1; +CREATE TRIGGER u2_t1 AFTER UPDATE ON t1 FOR EACH ROW SAVEPOINT s; +UPDATE t1 SET a=4 WHERE a=3; +DROP TRIGGER u2_t1; +CREATE TRIGGER d1_t1 BEFORE DELETE ON t1 FOR EACH ROW SAVEPOINT s; +DELETE FROM t1; +DROP TRIGGER d1_t1; +CREATE TRIGGER d1_t1 AFTER DELETE ON t1 FOR EACH ROW SAVEPOINT s; +DELETE FROM t1; +DROP TRIGGER d1_t1; +SAVEPOINT in a compound statement in a trigger should be forbidden +CREATE TRIGGER i3_t1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN +SAVEPOINT s; +END| +INSERT INTO t1 VALUES (5); +DROP TRIGGER i3_t1; +SAVEPOINT in a PS call in a trigger should be forbidden +CREATE TRIGGER i4_t1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN +PREPARE set_savepoint FROM "SAVEPOINT s"; +EXECUTE set_savepoint; +DEALLOCATE PREPARE set_savepoint; +END| +ERROR 0A000: Dynamic SQL is not allowed in stored function or trigger +SAVEPOINT in SP called from a trigger should be forbidden +CREATE PROCEDURE p1() BEGIN +SAVEPOINT s; +END| +CREATE TRIGGER i5_t1 BEFORE INSERT ON t1 FOR EACH ROW CALL p1; +INSERT INTO t1 VALUES (6); +DROP TRIGGER i5_t1; +SAVEPOINT in a SP called from a PS called from a trigger be forbidden +PREPARE call_p1 FROM "CALL p1"; +CREATE TRIGGER i6_t1 BEFORE INSERT ON t1 FOR EACH ROW EXECUTE call_p1; +ERROR 0A000: Dynamic SQL is not allowed in stored function or trigger +SAVEPOINT in a function called from a trigger should be forbidden +CREATE FUNCTION f1 () RETURNS INT BEGIN +SAVEPOINT s; +RETURN 1; +END| +CREATE TRIGGER i7_t1 BEFORE INSERT ON t1 FOR EACH ROW SET @foo = f1(); +INSERT INTO t1 VALUES (7); +DROP TRIGGER i7_t1; +SAVEPOINT in a SP called from a SP called from a trigger should be forbidden +CREATE PROCEDURE p2() BEGIN +CALL p1(); +END| +CREATE TRIGGER i8_t1 BEFORE INSERT ON t1 FOR EACH ROW CALL p2; +INSERT INTO t1 VALUES (8); +DROP TRIGGER i8_t1; +SAVEPOINT in a SP called from a trigger called from a SP should be forbidden +CREATE TRIGGER i9_t1 BEFORE INSERT ON t1 FOR EACH ROW CALL p1; +CREATE PROCEDURE p3() BEGIN +INSERT INTO t1 VALUES (9); +END| +CALL p3(); +DROP TRIGGER i9_t1; +ROLLBACK TO SAVEPOINT in trigger as a trivial statement should be forbidden +CREATE TRIGGER i4_t1 BEFORE INSERT ON t1 FOR EACH ROW ROLLBACK TO SAVEPOINT s; +BEGIN; +SAVEPOINT s; +INSERT INTO t1 VALUES (5); +ERROR 42000: SAVEPOINT s does not exist +COMMIT; +DROP TRIGGER i4_t1; +ROLLBACK TO SAVEPOINT in a trigger in a SP call should be forbidden +CREATE PROCEDURE p4() BEGIN +ROLLBACK TO SAVEPOINT s; +END| +CREATE TRIGGER i5_t1 BEFORE INSERT ON t1 FOR EACH ROW CALL p4; +BEGIN; +SAVEPOINT s; +INSERT INTO t1 VALUES (6); +ERROR 42000: SAVEPOINT s does not exist +COMMIT; +DROP TRIGGER i5_t1; +SAVEPOINT in a SP next to a trigger should work +CREATE TRIGGER i6_t1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a = NEW.a + 1; +CREATE PROCEDURE p5() BEGIN +SAVEPOINT s; +INSERT INTO t1 VALUES (10); +ROLLBACK TO SAVEPOINT s; +END| +BEGIN; +CALL p5(); +COMMIT; +DROP TRIGGER i6_t1; +create trigger t1 before insert on t1 for each row +begin +insert into t2 values (NULL); +end| +INSERT INTO t1 VALUES (201), (202), (203); +SELECT * FROM t1; +a +5 +6 +7 +8 +9 +201 +202 +203 +SELECT COUNT(*) FROM t2; +COUNT(*) +3 +SELECT * FROM t1; +a +5 +6 +7 +8 +9 +201 +202 +203 +SELECT COUNT(*) FROM t2; +COUNT(*) +3 +DEALLOCATE PREPARE call_p1; +DROP TABLE t1, t2; +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP PROCEDURE p3; +DROP PROCEDURE p4; +DROP PROCEDURE p5; +DROP FUNCTION f1; diff --git a/mysql-test/suite/galera/r/galera_admin.result b/mysql-test/suite/galera/r/galera_admin.result new file mode 100644 index 00000000000..e58b0a5e310 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_admin.result @@ -0,0 +1,43 @@ +DROP TABLE IF EXISTS t1, t2; +DROP TABLE IF EXISTS x1, x2; +CREATE TABLE t1 (f1 INTEGER); +CREATE TABLE t2 (f1 INT PRIMARY KEY AUTO_INCREMENT, f2 INTEGER); +SET GLOBAL wsrep_replicate_myisam = TRUE; +CREATE TABLE x1 (f1 INTEGER) ENGINE=MyISAM; +CREATE TABLE x2 (f1 INT PRIMARY KEY AUTO_INCREMENT, f2 INTEGER) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +INSERT INTO x1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +INSERT INTO t2 (f2) SELECT 1 FROM t1 AS a1, t1 AS a2, t1 AS a3, t1 AS a4; +INSERT INTO x2 (f2) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +# ANALYZE test +ANALYZE TABLE t1, t2; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK +# OPTIMIZE test +OPTIMIZE TABLE t1, t2; +Table Op Msg_type Msg_text +test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize status OK +test.t2 optimize note Table does not support optimize, doing recreate + analyze instead +test.t2 optimize status OK +# REPAIR test +REPAIR TABLE x1, x2; +Table Op Msg_type Msg_text +test.x1 repair status OK +test.x2 repair status OK +SELECT COUNT(*) = 10 FROM t1; +COUNT(*) = 10 +1 +SELECT COUNT(*) = 10 FROM x1; +COUNT(*) = 10 +1 +SELECT COUNT(*) = 10000 FROM t2; +COUNT(*) = 10000 +1 +SELECT COUNT(*) = 10 FROM x2; +COUNT(*) = 10 +1 +DROP TABLE t1, t2; +DROP TABLE x1, x2; +SET GLOBAL wsrep_replicate_myisam = FALSE; diff --git a/mysql-test/suite/galera/r/galera_desync_overlapped.result b/mysql-test/suite/galera/r/galera_desync_overlapped.result new file mode 100644 index 00000000000..a1e7d59a661 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_desync_overlapped.result @@ -0,0 +1,45 @@ +CREATE TABLE ten (f1 INTEGER); +INSERT INTO ten VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +CREATE TABLE t1 (f1 INTEGER, PRIMARY KEY (f1)) Engine=InnoDB; +CREATE TABLE t2 (f1 INTEGER, PRIMARY KEY (f1)) Engine=InnoDB; +SET GLOBAL wsrep_desync = 1; +show status like 'wsrep_desync_count'; +Variable_name Value +wsrep_desync_count 1 +SET DEBUG_SYNC='before_execute_sql_command SIGNAL alter1 WAIT_FOR alter2'; +INSERT INTO t1 (f1) SELECT 0000 + (100 * a1.f1) + (10 * a2.f1) + a3.f1 FROM ten AS a1, ten AS a2, ten AS a3; +SET GLOBAL wsrep_desync = 1; +Warnings: +Warning 1231 'wsrep_desync' is already ON. +show status like 'wsrep_desync_count'; +Variable_name Value +wsrep_desync_count 1 +SET DEBUG_SYNC='now WAIT_FOR alter1'; +SET DEBUG_SYNC='before_execute_sql_command SIGNAL alter2'; +INSERT INTO t2 (f1) SELECT 0000 + (100 * a1.f1) + (10 * a2.f1) + a3.f1 FROM ten AS a1, ten AS a2, ten AS a3; +SET DEBUG_SYNC='RESET'; +SET GLOBAL wsrep_desync = 0; +show status like 'wsrep_desync_count'; +Variable_name Value +wsrep_desync_count 0 +SET GLOBAL wsrep_desync = 0; +Warnings: +Warning 1231 'wsrep_desync' is already OFF. +show status like 'wsrep_desync_count'; +Variable_name Value +wsrep_desync_count 0 +show status like 'wsrep_desync_count'; +Variable_name Value +wsrep_desync_count 0 +SET GLOBAL wsrep_desync = 0; +Warnings: +Warning 1231 'wsrep_desync' is already OFF. +SELECT COUNT(*) FROM t1; +COUNT(*) +1000 +SELECT COUNT(*) FROM t2; +COUNT(*) +1000 +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE ten; diff --git a/mysql-test/suite/galera/r/galera_restart_on_unknown_option.result b/mysql-test/suite/galera/r/galera_restart_on_unknown_option.result new file mode 100644 index 00000000000..a21b1edf3e7 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_restart_on_unknown_option.result @@ -0,0 +1,40 @@ +CALL mtr.add_suppression("Aborting"); +CALL mtr.add_suppression("unknown option '--galera-unknown-option'"); +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)); +INSERT INTO t1 VALUES (1, 'a'), (2, 'a'), (3, 'a'); +SELECT * FROM t1; +f1 f2 +1 a +2 a +3 a +Shutting down server ... +UPDATE t1 SET f2 = 'b' WHERE f1 > 1; +UPDATE t1 SET f2 = 'c' WHERE f1 > 2; +SELECT * FROM t1; +f1 f2 +1 a +2 b +3 c +Starting server ... +Starting server ... +SELECT * FROM t1; +f1 f2 +1 a +2 b +3 c +Shutting down server ... +UPDATE t1 SET f2 = 'd' WHERE f1 > 1; +UPDATE t1 SET f2 = 'd' WHERE f1 > 2; +SELECT * FROM t1; +f1 f2 +1 a +2 d +3 d +Starting server ... +Starting server ... +SELECT * FROM t1; +f1 f2 +1 a +2 d +3 d +DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_toi_ddl_fk_update.result b/mysql-test/suite/galera/r/galera_toi_ddl_fk_update.result new file mode 100644 index 00000000000..8366cfd27c8 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_toi_ddl_fk_update.result @@ -0,0 +1,23 @@ +CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +CREATE TABLE parent ( +id INT PRIMARY KEY, +KEY (id) +) ENGINE=InnoDB; +CREATE TABLE child ( +id INT PRIMARY KEY AUTO_INCREMENT, +parent_id INT +) ENGINE=InnoDB; +INSERT INTO parent VALUES (1); +INSERT INTO child (parent_id) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4; +ALTER TABLE child ADD FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE;; +UPDATE parent SET id = 2 WHERE id = 1;; +SELECT COUNT(*) = 10000 FROM child WHERE parent_id = 2; +COUNT(*) = 10000 +1 +SELECT COUNT(*) = 10000 FROM child WHERE parent_id = 2; +COUNT(*) = 10000 +1 +DROP TABLE child; +DROP TABLE parent; +DROP TABLE ten; diff --git a/mysql-test/suite/galera/r/galera_toi_ddl_online.result b/mysql-test/suite/galera/r/galera_toi_ddl_online.result new file mode 100644 index 00000000000..488b72ab843 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_toi_ddl_online.result @@ -0,0 +1,27 @@ +CREATE TABLE ten (f1 INTEGER); +INSERT INTO ten VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 INTEGER) ENGINE=InnoDB; +INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5; +INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;; +CREATE INDEX i1 ON t1 (f2);; +ALTER TABLE t1 ADD COLUMN f3 INTEGER;; +SELECT COUNT(*) = 200000 FROM t1; +COUNT(*) = 200000 +1 +SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 3 +1 +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 +SELECT COUNT(*) = 200000 FROM t1; +COUNT(*) = 200000 +1 +SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 3 +1 +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 +DROP TABLE t1; +DROP TABLE ten; diff --git a/mysql-test/suite/galera/r/galera_toi_drop_database.result b/mysql-test/suite/galera/r/galera_toi_drop_database.result new file mode 100644 index 00000000000..d4f98c38847 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_toi_drop_database.result @@ -0,0 +1,22 @@ +CREATE DATABASE database1; +USE database1; +CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +CREATE TABLE t2 (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;; +USE database1; +INSERT INTO t2 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;; +DROP DATABASE database1;; +ERROR 42S02: Table 'database1.t1' doesn't exist +ERROR 42S02: Table 'database1.t2' doesn't exist +SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'database1'; +COUNT(*) = 0 +1 +USE database1; +ERROR 42000: Unknown database 'database1' +SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'database1'; +COUNT(*) = 0 +1 +USE database1; +ERROR 42000: Unknown database 'database1' diff --git a/mysql-test/suite/galera/r/galera_toi_truncate.result b/mysql-test/suite/galera/r/galera_toi_truncate.result new file mode 100644 index 00000000000..98bc9f4850b --- /dev/null +++ b/mysql-test/suite/galera/r/galera_toi_truncate.result @@ -0,0 +1,17 @@ +CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6;; +TRUNCATE TABLE t1;; +SELECT COUNT(*) = 1000000 FROM t1; +COUNT(*) = 1000000 +1 +DROP TABLE t1; +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6;; +TRUNCATE TABLE t1;; +SELECT COUNT(*) = 1000000 FROM t1; +COUNT(*) = 1000000 +1 +DROP TABLE t1; +DROP TABLE ten; diff --git a/mysql-test/suite/galera/r/galera_wsrep_provider_options_syntax.result b/mysql-test/suite/galera/r/galera_wsrep_provider_options_syntax.result new file mode 100644 index 00000000000..f19dc40205b --- /dev/null +++ b/mysql-test/suite/galera/r/galera_wsrep_provider_options_syntax.result @@ -0,0 +1,5 @@ +call mtr.add_suppression("WSREP\: Unknown parameter 'gmcasts\.segment'"); +call mtr.add_suppression("WSREP\: Set options returned 7"); +SET GLOBAL wsrep_provider_options="gmcasts.segment=1"; +ERROR HY000: Incorrect arguments to SET +Unhandled exceptions: 0 diff --git a/mysql-test/suite/galera/r/lp1376747-2.result b/mysql-test/suite/galera/r/lp1376747-2.result new file mode 100644 index 00000000000..3b8aee61ed2 --- /dev/null +++ b/mysql-test/suite/galera/r/lp1376747-2.result @@ -0,0 +1,19 @@ +CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +FLUSH TABLES t1 FOR EXPORT; +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +INSERT INTO t1 VALUES (2,3); +UNLOCK TABLES; +### t1 should have column f2 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `f2` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT * from t1; +id f2 +1 NULL +2 3 +DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/lp1376747-3.result b/mysql-test/suite/galera/r/lp1376747-3.result new file mode 100644 index 00000000000..fc982c94244 --- /dev/null +++ b/mysql-test/suite/galera/r/lp1376747-3.result @@ -0,0 +1,21 @@ +CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +FLUSH TABLE WITH READ LOCK; +### This shouldn't block. +FLUSH TABLES t1 FOR EXPORT; +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +UNLOCK TABLES; +### t1 should have column f2 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `f2` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES (2,3); +SELECT * from t1; +id f2 +1 NULL +2 3 +DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/lp1376747-4.result b/mysql-test/suite/galera/r/lp1376747-4.result new file mode 100644 index 00000000000..b0ae2b7fc92 --- /dev/null +++ b/mysql-test/suite/galera/r/lp1376747-4.result @@ -0,0 +1,36 @@ +CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +SET session wsrep_sync_wait=0; +SET session wsrep_causal_reads=OFF; +FLUSH TABLE WITH READ LOCK; +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +INSERT INTO t1 VALUES (2,3); +SET session wsrep_sync_wait=0; +SET session wsrep_causal_reads=OFF; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +FLUSH TABLES t1 WITH READ LOCK;; +UNLOCK TABLES; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +UNLOCK TABLES; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `f2` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT * from t1; +id f2 +1 NULL +2 3 +DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/lp1376747.result b/mysql-test/suite/galera/r/lp1376747.result new file mode 100644 index 00000000000..4617d5952bb --- /dev/null +++ b/mysql-test/suite/galera/r/lp1376747.result @@ -0,0 +1,19 @@ +CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +FLUSH TABLES t1 WITH READ LOCK; +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +INSERT INTO t1 VALUES (2,3); +UNLOCK TABLES; +### t1 should have column f2 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `f2` int(11) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT * from t1; +id f2 +1 NULL +2 3 +DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/pxc-421.result b/mysql-test/suite/galera/r/pxc-421.result new file mode 100644 index 00000000000..1822201f338 --- /dev/null +++ b/mysql-test/suite/galera/r/pxc-421.result @@ -0,0 +1,35 @@ +set GLOBAL wsrep_slave_threads=26; +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 (f1) SELECT * from t1 as x1; +set GLOBAL wsrep_slave_threads=16; +SET GLOBAL wsrep_provider='none'; +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (3); +INSERT INTO t1 VALUES (4); +set GLOBAL wsrep_slave_threads=5; +SELECT COUNT(*) = 5 FROM t1; +COUNT(*) = 5 +1 +set GLOBAL wsrep_slave_threads=12; +SELECT COUNT(*) = 4 FROM t1; +COUNT(*) = 4 +1 +INSERT INTO t1 VALUES (100), (101), (102); +set GLOBAL wsrep_slave_threads=5; +INSERT INTO t1 (f1) SELECT * from t1 as x1; +show global variables like 'wsrep_slave_threads'; +Variable_name Value +wsrep_slave_threads 5 +SET GLOBAL wsrep_slave_threads = 1; +SELECT COUNT(*) FROM t1; +COUNT(*) +16 +SELECT COUNT(*) FROM t1; +COUNT(*) +15 +show global variables like 'wsrep_slave_threads'; +Variable_name Value +wsrep_slave_threads 12 +SET GLOBAL wsrep_slave_threads = 1; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/ev51914.test b/mysql-test/suite/galera/t/ev51914.test new file mode 100644 index 00000000000..e5edacabe89 --- /dev/null +++ b/mysql-test/suite/galera/t/ev51914.test @@ -0,0 +1,214 @@ +# Disable SAVEPOINT and ROLLBACK TO SAVEPOINT in SP, SF, TR. + +--source include/galera_cluster.inc +--source include/have_innodb.inc + + +--connection node_1 +--echo SAVEPOINT in a stored function should be forbidden +--delimiter | +CREATE FUNCTION f1 () RETURNS INT BEGIN + SAVEPOINT s; + RETURN 1; +END| +--delimiter ; + +SELECT f1(); + +DROP FUNCTION f1; + +--echo ROLLBACK TO SAVEPOINT in a stored function should be forbidden +--delimiter | +CREATE FUNCTION f2 () RETURNS INT BEGIN + ROLLBACK TO SAVEPOINT s; + RETURN 1; +END| +--delimiter ; + +BEGIN; +SAVEPOINT s; +--error ER_SP_DOES_NOT_EXIST +SELECT f2(); +COMMIT; + +DROP FUNCTION f2; + +BEGIN; +SAVEPOINT S; +ROLLBACK TO SAVEPOINT S; +COMMIT; + + +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB; +INSERT INTO t1 values (110), (111), (112), (113), (114); + +--echo Direct SAVEPOINT in a trigger should be forbidden +--connection node_2 +CREATE TRIGGER i1_t1 BEFORE INSERT ON t1 FOR EACH ROW SAVEPOINT s; + +--connection node_1 +INSERT INTO t1 VALUES (1); +DROP TRIGGER i1_t1; + +CREATE TRIGGER i2_t1 AFTER INSERT ON t1 FOR EACH ROW SAVEPOINT s; +INSERT INTO t1 VALUES (2); +DROP TRIGGER i2_t1; + +INSERT INTO t1 VALUES (3); +CREATE TRIGGER u1_t1 BEFORE UPDATE ON t1 FOR EACH ROW SAVEPOINT s; +UPDATE t1 SET a=4 WHERE a=3; +DROP TRIGGER u1_t1; + +CREATE TRIGGER u2_t1 AFTER UPDATE ON t1 FOR EACH ROW SAVEPOINT s; +UPDATE t1 SET a=4 WHERE a=3; +DROP TRIGGER u2_t1; + +CREATE TRIGGER d1_t1 BEFORE DELETE ON t1 FOR EACH ROW SAVEPOINT s; +DELETE FROM t1; +DROP TRIGGER d1_t1; + +CREATE TRIGGER d1_t1 AFTER DELETE ON t1 FOR EACH ROW SAVEPOINT s; +DELETE FROM t1; +DROP TRIGGER d1_t1; + +--echo SAVEPOINT in a compound statement in a trigger should be forbidden +--delimiter | +CREATE TRIGGER i3_t1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN + SAVEPOINT s; +END| +--delimiter ; +INSERT INTO t1 VALUES (5); +DROP TRIGGER i3_t1; + +--echo SAVEPOINT in a PS call in a trigger should be forbidden +# echo handled by SAVEPOINT forbidden in PS +--delimiter | +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +CREATE TRIGGER i4_t1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN + PREPARE set_savepoint FROM "SAVEPOINT s"; + EXECUTE set_savepoint; + DEALLOCATE PREPARE set_savepoint; +END| +--delimiter ; + +--connection node_2 +--echo SAVEPOINT in SP called from a trigger should be forbidden +--delimiter | +CREATE PROCEDURE p1() BEGIN + SAVEPOINT s; +END| +--delimiter ; +--connection node_1 +CREATE TRIGGER i5_t1 BEFORE INSERT ON t1 FOR EACH ROW CALL p1; +INSERT INTO t1 VALUES (6); +DROP TRIGGER i5_t1; + +--echo SAVEPOINT in a SP called from a PS called from a trigger be forbidden +# echo handled by SAVEPOINT forbidden in PS +PREPARE call_p1 FROM "CALL p1"; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +CREATE TRIGGER i6_t1 BEFORE INSERT ON t1 FOR EACH ROW EXECUTE call_p1; + +--echo SAVEPOINT in a function called from a trigger should be forbidden +--delimiter | +CREATE FUNCTION f1 () RETURNS INT BEGIN + SAVEPOINT s; + RETURN 1; +END| +--delimiter ; +CREATE TRIGGER i7_t1 BEFORE INSERT ON t1 FOR EACH ROW SET @foo = f1(); +INSERT INTO t1 VALUES (7); +DROP TRIGGER i7_t1; + +--echo SAVEPOINT in a SP called from a SP called from a trigger should be forbidden +--delimiter | +CREATE PROCEDURE p2() BEGIN + CALL p1(); +END| +--delimiter ; +CREATE TRIGGER i8_t1 BEFORE INSERT ON t1 FOR EACH ROW CALL p2; +INSERT INTO t1 VALUES (8); +DROP TRIGGER i8_t1; + +--echo SAVEPOINT in a SP called from a trigger called from a SP should be forbidden +CREATE TRIGGER i9_t1 BEFORE INSERT ON t1 FOR EACH ROW CALL p1; +--delimiter | +CREATE PROCEDURE p3() BEGIN + INSERT INTO t1 VALUES (9); +END| +--delimiter ; +CALL p3(); +DROP TRIGGER i9_t1; + +--echo ROLLBACK TO SAVEPOINT in trigger as a trivial statement should be forbidden +# Trigger activation creates a new savepoint level, making the earlier levels +# inaccessible. Thus forbidding SAVEPOINT should be enough as then there is +# no valid savepoint to pass to ROLLBACK TO SAVEPOINT, but we forbid it once +# more just in case. +CREATE TRIGGER i4_t1 BEFORE INSERT ON t1 FOR EACH ROW ROLLBACK TO SAVEPOINT s; +BEGIN; +SAVEPOINT s; +--error ER_SP_DOES_NOT_EXIST +INSERT INTO t1 VALUES (5); +COMMIT; +DROP TRIGGER i4_t1; + +--echo ROLLBACK TO SAVEPOINT in a trigger in a SP call should be forbidden +--delimiter | +CREATE PROCEDURE p4() BEGIN + ROLLBACK TO SAVEPOINT s; +END| +--delimiter ; +CREATE TRIGGER i5_t1 BEFORE INSERT ON t1 FOR EACH ROW CALL p4; +BEGIN; +SAVEPOINT s; +--error ER_SP_DOES_NOT_EXIST +INSERT INTO t1 VALUES (6); +COMMIT; +DROP TRIGGER i5_t1; + +--echo SAVEPOINT in a SP next to a trigger should work +CREATE TRIGGER i6_t1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a = NEW.a + 1; +--delimiter | +CREATE PROCEDURE p5() BEGIN + SAVEPOINT s; + INSERT INTO t1 VALUES (10); + ROLLBACK TO SAVEPOINT s; +END| +--delimiter ; +BEGIN; +CALL p5(); +COMMIT; +DROP TRIGGER i6_t1; + +--connection node_2 +delimiter |; +create trigger t1 before insert on t1 for each row +begin + insert into t2 values (NULL); +end| +delimiter ;| + +--connection node_1 +INSERT INTO t1 VALUES (201), (202), (203); + +--connection node_1 +SELECT * FROM t1; +SELECT COUNT(*) FROM t2; + +--connection node_2 +SELECT * FROM t1; +SELECT COUNT(*) FROM t2; + +--connection node_1 +DEALLOCATE PREPARE call_p1; + +--connection node_2 +DROP TABLE t1, t2; +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP PROCEDURE p3; +DROP PROCEDURE p4; +DROP PROCEDURE p5; +DROP FUNCTION f1; diff --git a/mysql-test/suite/galera/t/galera_admin.test b/mysql-test/suite/galera/t/galera_admin.test new file mode 100644 index 00000000000..d62c454bdfa --- /dev/null +++ b/mysql-test/suite/galera/t/galera_admin.test @@ -0,0 +1,86 @@ +# +# Test that various admin commands from sql_admin.cc +# Currently, REPAIR, OPTIMIZE and ANALYZE are tested. +# Jira: PXC-390 +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +DROP TABLE IF EXISTS x1, x2; +--enable_warnings + +--connection node_1 +CREATE TABLE t1 (f1 INTEGER); +CREATE TABLE t2 (f1 INT PRIMARY KEY AUTO_INCREMENT, f2 INTEGER); +SET GLOBAL wsrep_replicate_myisam = TRUE; +CREATE TABLE x1 (f1 INTEGER) ENGINE=MyISAM; +CREATE TABLE x2 (f1 INT PRIMARY KEY AUTO_INCREMENT, f2 INTEGER) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +INSERT INTO x1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +INSERT INTO t2 (f2) SELECT 1 FROM t1 AS a1, t1 AS a2, t1 AS a3, t1 AS a4; +INSERT INTO x2 (f2) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); + +# Wait until all the data from t2 has been replicated +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 10 FROM x1; +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 10 FROM x2; +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 10 FROM t1; +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 10000 FROM t2; +--source include/wait_condition.inc + + +--echo # ANALYZE test +--connection node_2 +--let $wsrep_last_committed_before = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'` + +--connection node_1 +ANALYZE TABLE t1, t2; + +--connection node_2 +--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 + + + +--echo # OPTIMIZE test +--connection node_2 +--let $wsrep_last_committed_before = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'` + +--connection node_1 +OPTIMIZE TABLE t1, t2; + +--connection node_2 +--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 + + + +--echo # REPAIR test +--connection node_2 +--let $wsrep_last_committed_before = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed'` + +--connection node_1 +REPAIR TABLE x1, x2; + +--connection node_2 +--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_2 +SELECT COUNT(*) = 10 FROM t1; +SELECT COUNT(*) = 10 FROM x1; +SELECT COUNT(*) = 10000 FROM t2; +SELECT COUNT(*) = 10 FROM x2; + +--connection node_1 +DROP TABLE t1, t2; +DROP TABLE x1, x2; +SET GLOBAL wsrep_replicate_myisam = FALSE; diff --git a/mysql-test/suite/galera/t/galera_desync_overlapped.test b/mysql-test/suite/galera/t/galera_desync_overlapped.test new file mode 100644 index 00000000000..8b78e8cdeb7 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_desync_overlapped.test @@ -0,0 +1,59 @@ +# +# Test for overlapped transactions under manual desync. +# +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_debug_sync.inc + +--let $galera_connection_name = node_1a +--let $galera_server_number = 1 +--source include/galera_connect.inc + +--connection node_1 + +CREATE TABLE ten (f1 INTEGER); +INSERT INTO ten VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +CREATE TABLE t1 (f1 INTEGER, PRIMARY KEY (f1)) Engine=InnoDB; +CREATE TABLE t2 (f1 INTEGER, PRIMARY KEY (f1)) Engine=InnoDB; + +SET GLOBAL wsrep_desync = 1; +show status like 'wsrep_desync_count'; +SET DEBUG_SYNC='before_execute_sql_command SIGNAL alter1 WAIT_FOR alter2'; +send INSERT INTO t1 (f1) SELECT 0000 + (100 * a1.f1) + (10 * a2.f1) + a3.f1 FROM ten AS a1, ten AS a2, ten AS a3; + +--connection node_1a + +SET GLOBAL wsrep_desync = 1; +show status like 'wsrep_desync_count'; +SET DEBUG_SYNC='now WAIT_FOR alter1'; +SET DEBUG_SYNC='before_execute_sql_command SIGNAL alter2'; +send INSERT INTO t2 (f1) SELECT 0000 + (100 * a1.f1) + (10 * a2.f1) + a3.f1 FROM ten AS a1, ten AS a2, ten AS a3; + +--connection node_1 +reap; + +--connection node_1a +reap; + +--connection node_1 + +SET DEBUG_SYNC='RESET'; + +SET GLOBAL wsrep_desync = 0; +show status like 'wsrep_desync_count'; +SET GLOBAL wsrep_desync = 0; +show status like 'wsrep_desync_count'; + +--disable_query_log +call mtr.add_suppression("Trying to make wsrep_desync = OFF on the node that is already synchronized."); +--enable_query_log +show status like 'wsrep_desync_count'; +SET GLOBAL wsrep_desync = 0; + +SELECT COUNT(*) FROM t1; +SELECT COUNT(*) FROM t2; + +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE ten; diff --git a/mysql-test/suite/galera/t/galera_flush_local.opt b/mysql-test/suite/galera/t/galera_flush_local.opt index 45a0ca24dc7..5a1fb6748d9 100644 --- a/mysql-test/suite/galera/t/galera_flush_local.opt +++ b/mysql-test/suite/galera/t/galera_flush_local.opt @@ -1 +1 @@ ---query_cache_type=1 --query_cache_size=1000000 --userstat=1 --wsrep_replicate_myisam=true +--query_cache_type=1 --query_cache_size=1000000 diff --git a/mysql-test/suite/galera/t/galera_restart_on_unknown_option.test b/mysql-test/suite/galera/t/galera_restart_on_unknown_option.test new file mode 100644 index 00000000000..2f27678b547 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_restart_on_unknown_option.test @@ -0,0 +1,150 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc + +# Suppress expected warnings: + +CALL mtr.add_suppression("Aborting"); +CALL mtr.add_suppression("unknown option '--galera-unknown-option'"); + +# +# We should count the number of "Assertion failed" warnings +# in the log file before and after testing. To do this we need +# to save original log file before testing: +# +--let TEST_LOG=$MYSQLTEST_VARDIR/log/mysqld.2.err +--perl + use strict; + my $test_log=$ENV{'TEST_LOG'} or die "TEST_LOG not set"; + my $test_log_copy=$test_log . '.copy'; + if (-e $test_log_copy) { + unlink $test_log_copy; + } +EOF +--copy_file $TEST_LOG $TEST_LOG.copy + +--connection node_2 + +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)); +INSERT INTO t1 VALUES (1, 'a'), (2, 'a'), (3, 'a'); + +SELECT * FROM t1; + +# Initiate normal shutdown on the node 2 and +# waiting until shutdown has been completed: + +--echo Shutting down server ... +--source include/shutdown_mysqld.inc + +--connection node_1 + +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +# Some updates on node 1: + +UPDATE t1 SET f2 = 'b' WHERE f1 > 1; +UPDATE t1 SET f2 = 'c' WHERE f1 > 2; + +SELECT * FROM t1; + +# Remove the "grastate.dat" file (to initiate new SST) +# and restart node 2 with unknown option: + +--connection node_2 + +--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat + +--let $start_mysqld_params=--galera-unknown-option + +--echo Starting server ... +--exec echo "try:$start_mysqld_params" > $_expect_file_name + +# Sleep to ensure that server exited... + +--sleep 30 + +# Restart node 2 without unknown option: + +--let $start_mysqld_params= + +--echo Starting server ... +--source include/start_mysqld.inc + +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +# Sanity check (node 2 is running now and can perform SQL operators): + +SELECT * FROM t1; + +# Initiate normal shutdown on the node 2 and +# waiting until shutdown has been completed: + +--echo Shutting down server ... +--source include/shutdown_mysqld.inc + +--connection node_1 + +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +# Some updates on node 1 - to initiate IST next time: + +UPDATE t1 SET f2 = 'd' WHERE f1 > 1; +UPDATE t1 SET f2 = 'd' WHERE f1 > 2; + +SELECT * FROM t1; + +# Restart node 2 with unknown option: + +--connection node_2 + +--let $start_mysqld_params=--galera-unknown-option + +--echo Starting server ... +--exec echo "try:$start_mysqld_params" > $_expect_file_name + +# Sleep to ensure that server exited... + +--sleep 30 + +# Restart node 2 without unknown option: + +--let $start_mysqld_params= + +--echo Starting server ... +--source include/start_mysqld.inc + +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +# Sanity check (node 2 is running now and can perform SQL operators): + +SELECT * FROM t1; + +--connection node_1 + +DROP TABLE t1; + +# +# We should count the number of "Assertion failed" warnings +# in the log file during test phase - to print the error message +# if quantity of such warnings in log file increased at the end +# of the test: +# +--perl + use strict; + my $test_log=$ENV{'TEST_LOG'} or die "TEST_LOG not set"; + my $test_log_copy=$test_log . '.copy'; + open(FILE, $test_log_copy) or die("Unable to open $test_log_copy: $!\n"); + my $initial=grep(/Assertion * failed/gi,); + close(FILE); + open(FILE, $test_log) or die("Unable to open $test_log: $!\n"); + my $count_warnings=grep(/Assertion * failed/gi,); + close(FILE); + if ($count_warnings != $initial) { + my $diff=$count_warnings-$initial; + print "Assertion failed $diff times.\n"; + } +EOF +--remove_file $TEST_LOG.copy diff --git a/mysql-test/suite/galera/t/galera_toi_ddl_fk_update.test b/mysql-test/suite/galera/t/galera_toi_ddl_fk_update.test new file mode 100644 index 00000000000..f42fae4ed51 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_toi_ddl_fk_update.test @@ -0,0 +1,49 @@ +--source include/big_test.inc +--source include/galera_cluster.inc +--source include/have_innodb.inc + +# +# This test creates a new FK constraint while an UPDATE is running +# + +CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); + +CREATE TABLE parent ( + id INT PRIMARY KEY, + KEY (id) +) ENGINE=InnoDB; + +CREATE TABLE child ( + id INT PRIMARY KEY AUTO_INCREMENT, + parent_id INT +) ENGINE=InnoDB; + +INSERT INTO parent VALUES (1); + +INSERT INTO child (parent_id) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4; + +--connection node_1 +--sleep 1 +--send ALTER TABLE child ADD FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE; + +--connection node_2 +--sleep 1 +--send UPDATE parent SET id = 2 WHERE id = 1; + +--connection node_1 +--reap + +--connection node_2 +--reap + +--connection node_2 +SELECT COUNT(*) = 10000 FROM child WHERE parent_id = 2; + +--connection node_1 +SELECT COUNT(*) = 10000 FROM child WHERE parent_id = 2; + +DROP TABLE child; +DROP TABLE parent; + +DROP TABLE ten; diff --git a/mysql-test/suite/galera/t/galera_toi_ddl_online.test b/mysql-test/suite/galera/t/galera_toi_ddl_online.test new file mode 100644 index 00000000000..af45acc5953 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_toi_ddl_online.test @@ -0,0 +1,53 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc + +# +# In this test, we run concurrent INSERT against a table against which we have issued concurrent DDL statements that are fully online, +# that is, DDL statements that allow for the DML to proceed non-blocking while the DDL is in progress +# + +CREATE TABLE ten (f1 INTEGER); +INSERT INTO ten VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 INTEGER) ENGINE=InnoDB; +INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5; + +--connection node_1 +--send INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5; + +--let $galera_connection_name = node_1a +--let $galera_server_number = 1 +--source include/galera_connect.inc + +--connection node_1a +--send CREATE INDEX i1 ON t1 (f2); + + +--let $galera_connection_name = node_1b +--let $galera_server_number = 1 +--source include/galera_connect.inc + +--connection node_1b +--send ALTER TABLE t1 ADD COLUMN f3 INTEGER; + +--connection node_1 +--reap + +--connection node_1a +--reap + +--connection node_1b +--reap + +--connection node_2 +SELECT COUNT(*) = 200000 FROM t1; +SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; + +--connection node_1 +SELECT COUNT(*) = 200000 FROM t1; +SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; + +DROP TABLE t1; +DROP TABLE ten; diff --git a/mysql-test/suite/galera/t/galera_toi_drop_database.test b/mysql-test/suite/galera/t/galera_toi_drop_database.test new file mode 100644 index 00000000000..3176b11dfc0 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_toi_drop_database.test @@ -0,0 +1,54 @@ +# +# Test the operation of DDLs that affect multiple database objects +# + +--source include/big_test.inc +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--let $galera_connection_name = node_1a +--let $galera_server_number = 1 +--source include/galera_connect.inc + +--connection node_1 +CREATE DATABASE database1; +USE database1; + +CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); + +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +CREATE TABLE t2 (f1 INTEGER) ENGINE=InnoDB; + +# Insert 1M rows +--send INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5; + +--connection node_1a +USE database1; +--send INSERT INTO t2 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5; + +--connection node_2 +--sleep 1 +--send DROP DATABASE database1; + +--connection node_1 +--sleep 30 +--error ER_NO_SUCH_TABLE +--reap + +--connection node_1a +--error ER_NO_SUCH_TABLE +--reap + +--connection node_2 +--reap + +--connection node_1 +SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'database1'; +--error ER_BAD_DB_ERROR +USE database1; + +--connection node_2 +SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'database1'; +--error ER_BAD_DB_ERROR +USE database1; diff --git a/mysql-test/suite/galera/t/galera_toi_truncate.test b/mysql-test/suite/galera/t/galera_toi_truncate.test new file mode 100644 index 00000000000..2d6027b17c2 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_toi_truncate.test @@ -0,0 +1,77 @@ +# +# Test the operation of TRUNCATE with concurrent DML. Even in the face of a concurrent INSERT, +# the TRUNCATE will complete first and be recorded in the history before the INSERT. +# + +--source include/big_test.inc +--source include/galera_cluster.inc +--source include/have_innodb.inc + +# +# INSERT and TRUNCATE on different nodes +# + +--connection node_1 +CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); + +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; + +# Insert 100K rows +--connection node_2 +--send INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6; + +--connection node_1 +--sleep 1 +--send TRUNCATE TABLE t1; + +--connection node_1 +--reap + +--connection node_2 +--reap + +--connection node_2 +SELECT COUNT(*) = 1000000 FROM t1; + +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 1000000 FROM t1; +--source include/wait_condition.inc + +DROP TABLE t1; + +# +# INSERT AND TRUNCATE on same node +# + +--let $galera_connection_name = node_1a +--let $galera_server_number = 1 +--source include/galera_connect.inc + +--connection node_1 + +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; + +# Insert 100K rows +--connection node_1 +--send INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6; + +--connection node_1a +--sleep 1 +--send TRUNCATE TABLE t1; + +--connection node_1 +--reap + +--connection node_1a +--reap + +--connection node_1 +SELECT COUNT(*) = 1000000 FROM t1; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1000000 FROM t1; +--source include/wait_condition.inc + +DROP TABLE t1; +DROP TABLE ten; diff --git a/mysql-test/suite/galera/t/galera_wsrep_provider_options_syntax.test b/mysql-test/suite/galera/t/galera_wsrep_provider_options_syntax.test new file mode 100644 index 00000000000..fe1abcf6c35 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_wsrep_provider_options_syntax.test @@ -0,0 +1,20 @@ +# +# PXC-318: Typo in wsrep_provider_options causes an unhandled exception +# +--source include/galera_cluster.inc +--source include/have_innodb.inc +--let LOGF=$MYSQLTEST_VARDIR/log/mysqld.1.err +--disable_info +call mtr.add_suppression("WSREP\: Unknown parameter 'gmcasts\.segment'"); +call mtr.add_suppression("WSREP\: Set options returned 7"); +--error ER_WRONG_ARGUMENTS +SET GLOBAL wsrep_provider_options="gmcasts.segment=1"; +# Search for unhandled exception message. +perl; + use strict; + my $logf= $ENV{'LOGF'} or die "LOGF not set"; + open(FILE, "$logf") or die("Unable to open $logf: $!\n"); + my $count_warnings=grep(/terminate called after throwing an instance of /gi,); + print "Unhandled exceptions: $count_warnings\n"; + close(FILE); +EOF diff --git a/mysql-test/suite/galera/t/lp1376747-2.test b/mysql-test/suite/galera/t/lp1376747-2.test new file mode 100644 index 00000000000..360681d7674 --- /dev/null +++ b/mysql-test/suite/galera/t/lp1376747-2.test @@ -0,0 +1,22 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc + +CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); + +--connection node_2 +FLUSH TABLES t1 FOR EXPORT; + +--connection node_1 +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +INSERT INTO t1 VALUES (2,3); + +--connection node_2 +UNLOCK TABLES; + +--echo ### t1 should have column f2 +SHOW CREATE TABLE t1; +SELECT * from t1; + +--connection node_1 +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/lp1376747-3.test b/mysql-test/suite/galera/t/lp1376747-3.test new file mode 100644 index 00000000000..75fe7d276cd --- /dev/null +++ b/mysql-test/suite/galera/t/lp1376747-3.test @@ -0,0 +1,28 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc + +CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); + +--connection node_2 +FLUSH TABLE WITH READ LOCK; +--echo ### This shouldn't block. +FLUSH TABLES t1 FOR EXPORT; + +--connection node_1 +ALTER TABLE t1 ADD COLUMN f2 INTEGER; + +--connection node_2 +UNLOCK TABLES; + +--echo ### t1 should have column f2 +SHOW CREATE TABLE t1; + +--connection node_1 +INSERT INTO t1 VALUES (2,3); + +--connection node_2 +SELECT * from t1; + +--connection node_1 +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/lp1376747-4.test b/mysql-test/suite/galera/t/lp1376747-4.test new file mode 100644 index 00000000000..be56ee5edc1 --- /dev/null +++ b/mysql-test/suite/galera/t/lp1376747-4.test @@ -0,0 +1,53 @@ +# +# Test Flush tables with read lock along with +# flush tables with read lock for compatibility. +# Also, making sure all DDL and DMLs are propagated +# after provider is unpaused +# +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--let $galera_connection_name = node_2a +--let $galera_server_number = 2 +--source include/galera_connect.inc + +--connection node_1 +CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); + +--connection node_2 +SET session wsrep_sync_wait=0; +SET session wsrep_causal_reads=OFF; +FLUSH TABLE WITH READ LOCK; + +--connection node_1 +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +INSERT INTO t1 VALUES (2,3); + +--connection node_2a +SET session wsrep_sync_wait=0; +SET session wsrep_causal_reads=OFF; +SHOW CREATE TABLE t1; +--sleep 1 +--send FLUSH TABLES t1 WITH READ LOCK; + +--connection node_2 +# let the flush table wait in pause state before we unlock +# table otherwise there is window where-in flush table is +# yet to wait in pause and unlock allows alter table to proceed. +# this is because send in asynchronous. +--sleep 3 +# this will release existing lock but will not resume +# the cluster as there is new FTRL that is still pausing it. +UNLOCK TABLES; +SHOW CREATE TABLE t1; + +--connection node_2a +--reap +UNLOCK TABLES; +--sleep 1 +SHOW CREATE TABLE t1; +SELECT * from t1; + +--connection node_1 +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/lp1376747.test b/mysql-test/suite/galera/t/lp1376747.test new file mode 100644 index 00000000000..769bb665c77 --- /dev/null +++ b/mysql-test/suite/galera/t/lp1376747.test @@ -0,0 +1,24 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc + +CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); + +--connection node_2 +FLUSH TABLES t1 WITH READ LOCK; + +--connection node_1 +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +INSERT INTO t1 VALUES (2,3); + +--sleep 2 + +--connection node_2 +UNLOCK TABLES; + +--echo ### t1 should have column f2 +SHOW CREATE TABLE t1; +SELECT * from t1; + +--connection node_1 +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/pxc-421.test b/mysql-test/suite/galera/t/pxc-421.test new file mode 100644 index 00000000000..8a360b12f4c --- /dev/null +++ b/mysql-test/suite/galera/t/pxc-421.test @@ -0,0 +1,60 @@ +# +# PXC-421: Test deadlock involving updates of +# wsrep_provider, wsrep_cluster_address and wsrep_slave_threads. +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--connection node_1 +--let $wsrep_slave_1 = `SELECT @@wsrep_slave_threads` +set GLOBAL wsrep_slave_threads=26; +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 (f1) SELECT * from t1 as x1; + +--connection node_2 +--let $wsrep_slave_2 = `SELECT @@wsrep_slave_threads` +set GLOBAL wsrep_slave_threads=16; +--let $wsrep_provider_orig = `SELECT @@wsrep_provider` +--let $wsrep_cluster_address_orig = `SELECT @@wsrep_cluster_address` + +SET GLOBAL wsrep_provider='none'; +INSERT INTO t1 VALUES (2); + +--connection node_1 +INSERT INTO t1 VALUES (3); + +--connection node_2 +--disable_query_log +--eval SET GLOBAL wsrep_provider = '$wsrep_provider_orig'; +--eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_orig'; +--enable_query_log + +--source include/wait_until_connected_again.inc +--source include/galera_wait_ready.inc + +INSERT INTO t1 VALUES (4); +set GLOBAL wsrep_slave_threads=5; + +# Node #2 has all the inserts +SELECT COUNT(*) = 5 FROM t1; + +--connection node_1 +set GLOBAL wsrep_slave_threads=12; +# Node #1 is missing the insert made while Node #2 was not replicated +SELECT COUNT(*) = 4 FROM t1; +INSERT INTO t1 VALUES (100), (101), (102); + +--connection node_2 +set GLOBAL wsrep_slave_threads=5; +INSERT INTO t1 (f1) SELECT * from t1 as x1; +show global variables like 'wsrep_slave_threads'; +--eval SET GLOBAL wsrep_slave_threads = $wsrep_slave_2 +SELECT COUNT(*) FROM t1; + +--connection node_1 +SELECT COUNT(*) FROM t1; +show global variables like 'wsrep_slave_threads'; +--eval SET GLOBAL wsrep_slave_threads = $wsrep_slave_1 +DROP TABLE t1; From 15298689cbabf18f71cf2d2cba8a1c4b72bc1809 Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Wed, 14 Sep 2016 14:33:59 +0300 Subject: [PATCH 03/66] Bump WSREP_PATCH_VERSION to 17 --- cmake/wsrep.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake index f54efc274fb..7d6418e71f2 100644 --- a/cmake/wsrep.cmake +++ b/cmake/wsrep.cmake @@ -18,7 +18,7 @@ # so WSREP_VERSION is produced regardless # Set the patch version -SET(WSREP_PATCH_VERSION "16") +SET(WSREP_PATCH_VERSION "17") # MariaDB addition: Revision number of the last revision merged from # codership branch visible in @@visible_comment. From 0e105bc1f22743d50c3dc64799b7969a7227748e Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Mon, 3 Oct 2016 03:09:49 -0700 Subject: [PATCH 04/66] Galera MTR Tests: Test for GCF-942 - safe_to_bootstrap flag in grastate.dat --- mysql-test/include/assert_grep.inc | 154 ++++++++++++++++ mysql-test/suite/galera_3nodes/disabled.def | 1 + .../r/galera_safe_to_bootstrap.result | 26 +++ .../t/galera_safe_to_bootstrap.test | 164 ++++++++++++++++++ 4 files changed, 345 insertions(+) create mode 100644 mysql-test/include/assert_grep.inc create mode 100644 mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result create mode 100644 mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test diff --git a/mysql-test/include/assert_grep.inc b/mysql-test/include/assert_grep.inc new file mode 100644 index 00000000000..a980a6d73b1 --- /dev/null +++ b/mysql-test/include/assert_grep.inc @@ -0,0 +1,154 @@ +# ==== Purpose ==== +# +# Grep a file for a pattern, produce a single string out of the +# matching lines, and assert that the string matches a given regular +# expression. +# +# ==== Usage ==== +# +# --let $assert_text= TEXT +# --let $assert_file= FILE +# --let $assert_select= REGEX +# [--let $assert_match= REGEX | --let $assert_count= NUMBER] +# [--let $assert_only_after= REGEX] +# --source include/assert_grep.inc +# +# Parameters: +# +# $assert_text +# Text that describes what is being checked. This text is written to +# the query log so it should not contain non-deterministic elements. +# +# $assert_file +# File to search. +# +# $assert_select +# All lines matching this text will be checked. +# +# $assert_match +# The script will find all lines that match $assert_select, +# concatenate them to a long string, and assert that it matches +# $assert_match. +# +# $assert_count +# Instead of asserting that the selected lines match +# $assert_match, assert that there were exactly $assert_count +# matching lines. +# +# $assert_only_after +# Reset all the lines matched and the counter when finding this pattern. +# It is useful for searching things in the mysqld.err log file just +# after the last server restart for example (discarding the log content +# of previous server executions). + + +if (!$assert_text) +{ + --die !!!ERROR IN TEST: you must set $assert_text +} +if (!$assert_file) +{ + --die !!!ERROR IN TEST: you must set $assert_file +} +if (!$assert_select) +{ + --die !!!ERROR IN TEST: you must set $assert_select +} +if ($assert_match == '') +{ + if ($assert_count == '') + { + --die !!!ERROR IN TEST: you must set either $assert_match or $assert_count + } +} +if ($assert_match != '') +{ + if ($assert_count != '') + { + --echo assert_text='$assert_text' assert_count='$assert_count' + --die !!!ERROR IN TEST: you must set only one of $assert_match or $assert_count + } +} + + +--let $include_filename= assert_grep.inc [$assert_text] +--source include/begin_include_file.inc + + +--let _AG_ASSERT_TEXT= $assert_text +--let _AG_ASSERT_FILE= $assert_file +--let _AG_ASSERT_SELECT= $assert_select +--let _AG_ASSERT_MATCH= $assert_match +--let _AG_ASSERT_COUNT= $assert_count +--let _AG_OUT= `SELECT CONCAT('$MYSQLTEST_VARDIR/tmp/_ag_', UUID())` +--let _AG_ASSERT_ONLY_AFTER= $assert_only_after + + +--perl + use strict; + use warnings; + my $file= $ENV{'_AG_ASSERT_FILE'}; + my $assert_select= $ENV{'_AG_ASSERT_SELECT'}; + my $assert_match= $ENV{'_AG_ASSERT_MATCH'}; + my $assert_count= $ENV{'_AG_ASSERT_COUNT'}; + my $assert_only_after= $ENV{'_AG_ASSERT_ONLY_AFTER'}; + my $out= $ENV{'_AG_OUT'}; + + my $result= ''; + my $count= 0; + open(FILE, "$file") or die("Error $? opening $file: $!\n"); + while () { + my $line = $_; + if ($assert_only_after && $line =~ /$assert_only_after/) { + $result = ""; + $count = 0; + } + if ($line =~ /$assert_select/) { + if ($assert_count ne '') { + $count++; + } + else { + $result .= $line; + } + } + } + close(FILE) or die("Error $? closing $file: $!"); + open OUT, "> $out" or die("Error $? opening $out: $!"); + if ($assert_count ne '' && ($count != $assert_count)) { + print OUT ($count) or die("Error $? writing $out: $!"); + } + elsif ($assert_count eq '' && $result !~ /$assert_match/) { + print OUT ($result) or die("Error $? writing $out: $!"); + } + else { + print OUT ("assert_grep.inc ok"); + } + close OUT or die("Error $? closing $out: $!"); +EOF + + +--let $_ag_outcome= `SELECT LOAD_FILE('$_AG_OUT')` +if ($_ag_outcome != 'assert_grep.inc ok') +{ + --source include/show_rpl_debug_info.inc + --echo include/assert_grep.inc failed! + --echo assert_text: '$assert_text' + --echo assert_file: '$assert_file' + --echo assert_select: '$assert_select' + --echo assert_match: '$assert_match' + --echo assert_count: '$assert_count' + --echo assert_only_after: '$assert_only_after' + if ($assert_match != '') + { + --echo matching lines: '$_ag_outcome' + } + if ($assert_count != '') + { + --echo number of matching lines: $_ag_outcome + } + --die assert_grep.inc failed. +} + + +--let $include_filename= include/assert_grep.inc [$assert_text] +--source include/end_include_file.inc diff --git a/mysql-test/suite/galera_3nodes/disabled.def b/mysql-test/suite/galera_3nodes/disabled.def index ca55c41ff72..502e7bfba68 100644 --- a/mysql-test/suite/galera_3nodes/disabled.def +++ b/mysql-test/suite/galera_3nodes/disabled.def @@ -5,3 +5,4 @@ galera_slave_options_do :MDEV-8798 galera_slave_options_ignore : MDEV-8798 galera_pc_bootstrap : TODO: Investigate: Timeout in wait_condition.inc galera_pc_weight : Test times out +galera_safe_to_bootstrap : I Really dont know :( diff --git a/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result b/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result new file mode 100644 index 00000000000..21f747d280b --- /dev/null +++ b/mysql-test/suite/galera_3nodes/r/galera_safe_to_bootstrap.result @@ -0,0 +1,26 @@ +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] +include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] +include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] +include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] +include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] +include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] +include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] +include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] +include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 1'] +include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] +include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] +include/assert_grep.inc [grastate.dat does not have 'safe_to_bootstrap: 0'] +SET SESSION wsrep_on = OFF; +Killing server ... +safe_to_bootstrap: 1 +safe_to_bootstrap: 0 +safe_to_bootstrap: 0 +CALL mtr.add_suppression("Failed to prepare for incremental state transfer"); +CALL mtr.add_suppression("Failed to prepare for incremental state transfer"); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test b/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test new file mode 100644 index 00000000000..c82f01a3d5c --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test @@ -0,0 +1,164 @@ +# +# Test the safe_to_bootstrap in grastate.dat +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; + +# +# At start, all grastate.dat files have safe_to_boostrap: 0 +# + +--let $assert_text= grastate.dat does not have 'safe_to_bootstrap: 0' +--let $assert_select= safe_to_bootstrap: 0 +--let $assert_count= 1 + +--let $assert_file= $MYSQLTEST_VARDIR/mysqld.1/data/grastate.dat +--source include/assert_grep.inc + +--let $assert_file= $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat +--source include/assert_grep.inc + +--let $assert_file= $MYSQLTEST_VARDIR/mysqld.3/data/grastate.dat +--source include/assert_grep.inc + +# +# Shut down one node +# + +--connection node_2 +--source include/shutdown_mysqld.inc + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +# Still, all grastate.dat files should have safe_to_boostrap: 0 + +--let $assert_file= $MYSQLTEST_VARDIR/mysqld.1/data/grastate.dat +--source include/assert_grep.inc + +--let $assert_file= $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat +--source include/assert_grep.inc + +--let $assert_file= $MYSQLTEST_VARDIR/mysqld.3/data/grastate.dat +--source include/assert_grep.inc + +# +# Shut down one more node +# + +--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 +--connection node_3 +--source include/shutdown_mysqld.inc + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +# Now, nodes 2,3 should have safe_to_boostrap: 0 + +--let $assert_file= $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat +--source include/assert_grep.inc + +--let $assert_file= $MYSQLTEST_VARDIR/mysqld.3/data/grastate.dat +--source include/assert_grep.inc + +# But node #1 should have safe_to_boostrap: 1 + +--let $assert_text= grastate.dat does not have 'safe_to_bootstrap: 1' +--let $assert_select= safe_to_bootstrap: 1 + +--let $assert_file= $MYSQLTEST_VARDIR/mysqld.1/data/grastate.dat +--source include/assert_grep.inc + +# Restart one node + +--connection node_2 +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--source include/start_mysqld.inc + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +# All nodes should be back to 'safe_to_bootstrap: 0' + +--let $assert_text= grastate.dat does not have 'safe_to_bootstrap: 0' +--let $assert_select= safe_to_bootstrap: 0 + +--let $assert_file= $MYSQLTEST_VARDIR/mysqld.1/data/grastate.dat +--source include/assert_grep.inc + +--let $assert_file= $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat +--source include/assert_grep.inc + +--let $assert_file= $MYSQLTEST_VARDIR/mysqld.3/data/grastate.dat +--source include/assert_grep.inc + +# +# Kill the cluster +# + +--connection node_2 +--source include/shutdown_mysqld.inc + +--connection node_1 +SET SESSION wsrep_on = OFF; +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +--source include/kill_galera.inc + +# +# Only node #1 should have safe_to_bootstrap: 1 +# include/assert_grep.inc requires a running server, so we revert to simple grep +# + +--error 0 +--exec grep 'safe_to_bootstrap: 1' $MYSQLTEST_VARDIR/mysqld.1/data/grastate.dat + +--error 0 +--exec grep 'safe_to_bootstrap: 0' $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat + +--error 0 +--exec grep 'safe_to_bootstrap: 0' $MYSQLTEST_VARDIR/mysqld.3/data/grastate.dat + +# +# Attempt to bootstrap nodes #2, #3, should fail +# + +--error 1 +--exec $MYSQLD --defaults-group-suffix=.2 --defaults-file=$MYSQLTEST_VARDIR/my.cnf --wsrep-new-cluster | grep 'This node is not safe to bootstrap the cluster' +--error 1 +--exec $MYSQLD --defaults-group-suffix=.3 --defaults-file=$MYSQLTEST_VARDIR/my.cnf --wsrep-new-cluster | grep 'This node is not safe to bootstrap the cluster' + +# +# Attempt to bootstrap starting from node #1, should succeed +# + +--connection node_1 +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/start_mysqld.inc +--source include/wait_until_connected_again.inc + +--connection node_2 +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--source include/start_mysqld.inc + +--connection node_3 +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.3.expect +--source include/start_mysqld.inc + +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +--connection node_2 +CALL mtr.add_suppression("Failed to prepare for incremental state transfer"); + +--connection node_3 +CALL mtr.add_suppression("Failed to prepare for incremental state transfer"); +SHOW CREATE TABLE t1; + +DROP TABLE t1; From c2eaae268dad0ec280efb1ede83b18832629ea98 Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Tue, 11 Oct 2016 03:37:42 -0700 Subject: [PATCH 05/66] Galera MTR Tests: GCF-981 - galera_bf_abort is non deterministic --- mysql-test/suite/galera/r/galera_bf_abort.result | 8 ++++---- mysql-test/suite/galera/t/galera_bf_abort.test | 13 +++++++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_bf_abort.result b/mysql-test/suite/galera/r/galera_bf_abort.result index c55f1a4dfcb..cc750f05050 100644 --- a/mysql-test/suite/galera/r/galera_bf_abort.result +++ b/mysql-test/suite/galera/r/galera_bf_abort.result @@ -1,9 +1,9 @@ -CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(6)) ENGINE=InnoDB; SET AUTOCOMMIT=OFF; START TRANSACTION; -INSERT INTO t1 VALUES (1); -INSERT INTO t1 VALUES (1); -INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (1,'node_2'); +INSERT INTO t1 VALUES (1,'node_1'); +INSERT INTO t1 VALUES (2, 'node_2'); ERROR 40001: Deadlock found when trying to get lock; try restarting transaction wsrep_local_aborts_increment 1 diff --git a/mysql-test/suite/galera/t/galera_bf_abort.test b/mysql-test/suite/galera/t/galera_bf_abort.test index 69825ea4919..f3476fba490 100644 --- a/mysql-test/suite/galera/t/galera_bf_abort.test +++ b/mysql-test/suite/galera/t/galera_bf_abort.test @@ -5,20 +5,25 @@ # Test a local transaction being aborted by a slave one # -CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(6)) ENGINE=InnoDB; +--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 --connection node_2 --let $wsrep_local_bf_aborts_before = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'` SET AUTOCOMMIT=OFF; START TRANSACTION; -INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (1,'node_2'); --connection node_1 -INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (1,'node_1'); + +--connection node_2a +--let $wait_condition = SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'node_1' +--source include/wait_condition.inc --connection node_2 --error ER_LOCK_DEADLOCK -INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (2, 'node_2'); --let $wsrep_local_bf_aborts_after = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'` From 4573924f7d0efd47ee44ae8cc8bb6cef3ccd6ca4 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Sun, 12 Mar 2017 23:00:20 +0530 Subject: [PATCH 06/66] Galera MTR Tests: MW-308 , MW-307, GCF-992 * a dedicated test for wsrep_retry_autocommit * some galera_toi_* tests were only passing because wsrep_retry_autocommit was in effect. The tests were changed to do not use autocommit * higher timeout values in galera_2nodes.cnf , galera_3nodes.cnf # Conflicts: # mysql-test/suite/galera/galera_2nodes.cnf # mysql-test/suite/galera/r/galera_defaults.result # mysql-test/suite/galera_3nodes/galera_3nodes.cnf --- mysql-test/suite/galera/galera_2nodes.cnf | 6 +- .../suite/galera/r/galera_defaults.result | 2 +- .../galera/r/galera_toi_ddl_online.result | 27 ------ .../galera/r/galera_toi_drop_database.result | 6 +- .../suite/galera/r/galera_toi_truncate.result | 14 ++- .../r/galera_var_retry_autocommit.result | 32 ++++++ .../suite/galera/t/galera_toi_ddl_online.test | 53 ---------- .../galera/t/galera_toi_drop_database.test | 12 ++- .../suite/galera/t/galera_toi_truncate.test | 48 ++------- .../galera/t/galera_var_retry_autocommit.test | 97 +++++++++++++++++++ .../suite/galera_3nodes/galera_3nodes.cnf | 17 ++-- 11 files changed, 169 insertions(+), 145 deletions(-) delete mode 100644 mysql-test/suite/galera/r/galera_toi_ddl_online.result create mode 100644 mysql-test/suite/galera/r/galera_var_retry_autocommit.result delete mode 100644 mysql-test/suite/galera/t/galera_toi_ddl_online.test create mode 100644 mysql-test/suite/galera/t/galera_var_retry_autocommit.test diff --git a/mysql-test/suite/galera/galera_2nodes.cnf b/mysql-test/suite/galera/galera_2nodes.cnf index 956e09e7b82..36630f718c4 100644 --- a/mysql-test/suite/galera/galera_2nodes.cnf +++ b/mysql-test/suite/galera/galera_2nodes.cnf @@ -7,6 +7,9 @@ innodb-autoinc-lock-mode=2 default-storage-engine=innodb wsrep-provider=@ENV.WSREP_PROVIDER wsrep_node_address=127.0.0.1 +wsrep_cluster_address='gcomm://' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S' + # enforce read-committed characteristics across the cluster wsrep-causal-reads=ON wsrep-sync-wait=7 @@ -25,7 +28,8 @@ wsrep_sst_receive_address='127.0.0.1:@mysqld.1.#sst_port' #ist_port=@OPT.port #sst_port=@OPT.port wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.1.#galera_port' -wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.2.#galera_port;gcache.size=10M;evs.suspect_timeout=PT10S' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S' + wsrep_node_incoming_address=127.0.0.1:@mysqld.2.port wsrep_sst_receive_address='127.0.0.1:@mysqld.2.#sst_port' diff --git a/mysql-test/suite/galera/r/galera_defaults.result b/mysql-test/suite/galera/r/galera_defaults.result index 3d75b86172a..a9bec4fc1dc 100644 --- a/mysql-test/suite/galera/r/galera_defaults.result +++ b/mysql-test/suite/galera/r/galera_defaults.result @@ -47,7 +47,7 @@ WSREP_SST_DONOR WSREP_SST_DONOR_REJECTS_QUERIES OFF WSREP_SST_METHOD rsync WSREP_SYNC_WAIT 7 -; ; ; cert.log_conflicts = no; debug = no; evs.auto_evict = 0; evs.causal_keepalive_period = PT1S; evs.debug_log_mask = 0x1; evs.delay_margin = PT1S; evs.delayed_keep_period = PT30S; evs.inactive_check_period = PT0.5S; evs.inactive_timeout = PT15S; evs.info_log_mask = 0; evs.install_timeout = PT7.5S; evs.join_retrans_period = PT1S; evs.keepalive_period = PT1S; evs.max_install_timeouts = 3; evs.send_window = 4; evs.stats_report_period = PT1M; evs.suspect_timeout = PT10S; evs.use_aggregate = true; evs.user_send_window = 2; evs.version = 0; evs.view_forget_timeout = P1D; ; gcache.keep_pages_size = 0; gcache.mem_size = 0; ; gcache.page_size = 128M; gcache.size = 10M; gcomm.thread_prio = ; gcs.fc_debug = 0; gcs.fc_factor = 1.0; gcs.fc_limit = 16; gcs.fc_master_slave = no; gcs.max_packet_size = 64500; gcs.max_throttle = 0.25; ; gcs.recv_q_soft_limit = 0.25; gcs.sync_donor = no; ; gmcast.mcast_addr = ; gmcast.mcast_ttl = 1; gmcast.peer_timeout = PT3S; gmcast.segment = 0; gmcast.time_wait = PT5S; gmcast.version = 0; ; pc.announce_timeout = PT3S; pc.checksum = false; pc.ignore_quorum = false; pc.ignore_sb = false; pc.linger = PT20S; pc.npvo = false; pc.recovery = true; pc.version = 0; pc.wait_prim = true; pc.wait_prim_timeout = P30S; pc.weight = 1; protonet.backend = asio; protonet.version = 0; repl.causal_read_timeout = PT90S; repl.commit_order = 3; repl.key_format = FLAT8; repl.max_ws_size = 2147483647; repl.proto_max = 7; socket.checksum = 2; socket.recv_buf_size = 212992; +; ; ; cert.log_conflicts = no; debug = no; evs.auto_evict = 0; evs.causal_keepalive_period = PT1S; evs.debug_log_mask = 0x1; evs.delay_margin = PT1S; evs.delayed_keep_period = PT30S; evs.inactive_check_period = PT0.5S; evs.inactive_timeout = PT30S; evs.info_log_mask = 0; evs.install_timeout = PT15S; evs.join_retrans_period = PT1S; evs.keepalive_period = PT1S; evs.max_install_timeouts = 3; evs.send_window = 4; evs.stats_report_period = PT1M; evs.suspect_timeout = PT10S; evs.use_aggregate = true; evs.user_send_window = 2; evs.version = 0; evs.view_forget_timeout = P1D; ; gcache.keep_pages_size = 0; gcache.mem_size = 0; ; gcache.page_size = 128M; gcache.size = 128M; gcomm.thread_prio = ; gcs.fc_debug = 0; gcs.fc_factor = 1.0; gcs.fc_limit = 16; gcs.fc_master_slave = no; gcs.max_packet_size = 64500; gcs.max_throttle = 0.25; ;gcs.recv_q_soft_limit = 0.25; gcs.sync_donor = no; ; gmcast.mcast_addr = ; gmcast.mcast_ttl = 1; gmcast.peer_timeout = PT3S; gmcast.segment = 0; gmcast.time_wait = PT5S; gmcast.version = 0; ; pc.announce_timeout = PT3S; pc.checksum = false; pc.ignore_quorum = false; pc.ignore_sb = false; pc.linger = PT20S; pc.npvo = false; pc.recovery = true; pc.version = 0; pc.wait_prim = true; pc.wait_prim_timeout = P30S; pc.weight = 1; protonet.backend = asio; protonet.version = 0; repl.causal_read_timeout = PT90S; repl.commit_order = 3; repl.key_format = FLAT8; repl.max_ws_size = 2147483647; repl.proto_max = 7; socket.checksum = 2; socket.recv_buf_size = 212992; SELECT COUNT(*) FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE 'wsrep_%' AND VARIABLE_NAME != 'wsrep_debug_sync_waiters'; diff --git a/mysql-test/suite/galera/r/galera_toi_ddl_online.result b/mysql-test/suite/galera/r/galera_toi_ddl_online.result deleted file mode 100644 index 488b72ab843..00000000000 --- a/mysql-test/suite/galera/r/galera_toi_ddl_online.result +++ /dev/null @@ -1,27 +0,0 @@ -CREATE TABLE ten (f1 INTEGER); -INSERT INTO ten VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); -CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 INTEGER) ENGINE=InnoDB; -INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5; -INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;; -CREATE INDEX i1 ON t1 (f2);; -ALTER TABLE t1 ADD COLUMN f3 INTEGER;; -SELECT COUNT(*) = 200000 FROM t1; -COUNT(*) = 200000 -1 -SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; -COUNT(*) = 3 -1 -SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; -COUNT(*) = 2 -1 -SELECT COUNT(*) = 200000 FROM t1; -COUNT(*) = 200000 -1 -SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; -COUNT(*) = 3 -1 -SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; -COUNT(*) = 2 -1 -DROP TABLE t1; -DROP TABLE ten; diff --git a/mysql-test/suite/galera/r/galera_toi_drop_database.result b/mysql-test/suite/galera/r/galera_toi_drop_database.result index d4f98c38847..8f4098419eb 100644 --- a/mysql-test/suite/galera/r/galera_toi_drop_database.result +++ b/mysql-test/suite/galera/r/galera_toi_drop_database.result @@ -4,12 +4,14 @@ CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB; INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; CREATE TABLE t2 (f1 INTEGER) ENGINE=InnoDB; +SET SESSION wsrep_retry_autocommit = 0; INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;; USE database1; +SET SESSION wsrep_retry_autocommit = 0; INSERT INTO t2 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;; DROP DATABASE database1;; -ERROR 42S02: Table 'database1.t1' doesn't exist -ERROR 42S02: Table 'database1.t2' doesn't exist +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'database1'; COUNT(*) = 0 1 diff --git a/mysql-test/suite/galera/r/galera_toi_truncate.result b/mysql-test/suite/galera/r/galera_toi_truncate.result index 98bc9f4850b..f52316f3cbc 100644 --- a/mysql-test/suite/galera/r/galera_toi_truncate.result +++ b/mysql-test/suite/galera/r/galera_toi_truncate.result @@ -1,17 +1,15 @@ CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB; INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +SET SESSION wsrep_retry_autocommit = 0; INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6;; TRUNCATE TABLE t1;; -SELECT COUNT(*) = 1000000 FROM t1; -COUNT(*) = 1000000 +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT COUNT(*) = 0 FROM t1; +COUNT(*) = 0 1 -DROP TABLE t1; -CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; -INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6;; -TRUNCATE TABLE t1;; -SELECT COUNT(*) = 1000000 FROM t1; -COUNT(*) = 1000000 +SELECT COUNT(*) = 0 FROM t1; +COUNT(*) = 0 1 DROP TABLE t1; DROP TABLE ten; diff --git a/mysql-test/suite/galera/r/galera_var_retry_autocommit.result b/mysql-test/suite/galera/r/galera_var_retry_autocommit.result new file mode 100644 index 00000000000..f4d17ad9a41 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_var_retry_autocommit.result @@ -0,0 +1,32 @@ +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=InnoDB; +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.f2 = SLEEP(5); +SET SESSION wsrep_retry_autocommit = 0; +INSERT INTO t1 (f1) VALUES (1),(2);; +TRUNCATE TABLE t1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SET SESSION wsrep_retry_autocommit = 1; +INSERT INTO t1 (f1) VALUES (3),(4);; +TRUNCATE TABLE t1; +SELECT * FROM test.t1; +f1 f2 +3 0 +4 0 +CREATE PROCEDURE repeated_truncate () +BEGIN +DECLARE i INT; +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +SET i = 0; +WHILE i <= 1000 DO +TRUNCATE TABLE t1; +SET i = i + 1; +END WHILE; +END| +CALL repeated_truncate(); +SET SESSION wsrep_retry_autocommit = 1; +INSERT INTO t1 (f1) VALUES (5),(6); +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SET SESSION wsrep_retry_autocommit = 1024; +INSERT INTO t1 (f1) VALUES (7),(8);; +include/diff_servers.inc [servers=1 2] +DROP TABLE t1; +DROP PROCEDURE repeated_truncate; diff --git a/mysql-test/suite/galera/t/galera_toi_ddl_online.test b/mysql-test/suite/galera/t/galera_toi_ddl_online.test deleted file mode 100644 index af45acc5953..00000000000 --- a/mysql-test/suite/galera/t/galera_toi_ddl_online.test +++ /dev/null @@ -1,53 +0,0 @@ ---source include/galera_cluster.inc ---source include/have_innodb.inc - -# -# In this test, we run concurrent INSERT against a table against which we have issued concurrent DDL statements that are fully online, -# that is, DDL statements that allow for the DML to proceed non-blocking while the DDL is in progress -# - -CREATE TABLE ten (f1 INTEGER); -INSERT INTO ten VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); - -CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 INTEGER) ENGINE=InnoDB; -INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5; - ---connection node_1 ---send INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5; - ---let $galera_connection_name = node_1a ---let $galera_server_number = 1 ---source include/galera_connect.inc - ---connection node_1a ---send CREATE INDEX i1 ON t1 (f2); - - ---let $galera_connection_name = node_1b ---let $galera_server_number = 1 ---source include/galera_connect.inc - ---connection node_1b ---send ALTER TABLE t1 ADD COLUMN f3 INTEGER; - ---connection node_1 ---reap - ---connection node_1a ---reap - ---connection node_1b ---reap - ---connection node_2 -SELECT COUNT(*) = 200000 FROM t1; -SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; -SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; - ---connection node_1 -SELECT COUNT(*) = 200000 FROM t1; -SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; -SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; - -DROP TABLE t1; -DROP TABLE ten; diff --git a/mysql-test/suite/galera/t/galera_toi_drop_database.test b/mysql-test/suite/galera/t/galera_toi_drop_database.test index 3176b11dfc0..0a37a4010ce 100644 --- a/mysql-test/suite/galera/t/galera_toi_drop_database.test +++ b/mysql-test/suite/galera/t/galera_toi_drop_database.test @@ -2,7 +2,6 @@ # Test the operation of DDLs that affect multiple database objects # ---source include/big_test.inc --source include/galera_cluster.inc --source include/have_innodb.inc @@ -20,11 +19,14 @@ INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; CREATE TABLE t2 (f1 INTEGER) ENGINE=InnoDB; -# Insert 1M rows +# Make sure autocommit retrying does not kick in as this will mask the error we expect to get +SET SESSION wsrep_retry_autocommit = 0; +# Attemp to insert 1M rows --send INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5; --connection node_1a USE database1; +SET SESSION wsrep_retry_autocommit = 0; --send INSERT INTO t2 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5; --connection node_2 @@ -32,12 +34,12 @@ USE database1; --send DROP DATABASE database1; --connection node_1 ---sleep 30 ---error ER_NO_SUCH_TABLE +--sleep 1 +--error ER_LOCK_DEADLOCK --reap --connection node_1a ---error ER_NO_SUCH_TABLE +--error ER_LOCK_DEADLOCK --reap --connection node_2 diff --git a/mysql-test/suite/galera/t/galera_toi_truncate.test b/mysql-test/suite/galera/t/galera_toi_truncate.test index 2d6027b17c2..59ef5c2028f 100644 --- a/mysql-test/suite/galera/t/galera_toi_truncate.test +++ b/mysql-test/suite/galera/t/galera_toi_truncate.test @@ -1,9 +1,8 @@ # -# Test the operation of TRUNCATE with concurrent DML. Even in the face of a concurrent INSERT, -# the TRUNCATE will complete first and be recorded in the history before the INSERT. +# Test the operation of TRUNCATE with concurrent DML. +# The DML should be BF-aborted if the DDL arrives from another node # ---source include/big_test.inc --source include/galera_cluster.inc --source include/have_innodb.inc @@ -19,6 +18,8 @@ CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; # Insert 100K rows --connection node_2 +# Prevent autocommit retring from masking the deadlock error we expect to get +SET SESSION wsrep_retry_autocommit = 0; --send INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6; --connection node_1 @@ -29,49 +30,14 @@ CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; --reap --connection node_2 +--error ER_LOCK_DEADLOCK --reap --connection node_2 -SELECT COUNT(*) = 1000000 FROM t1; +SELECT COUNT(*) = 0 FROM t1; --connection node_1 ---let $wait_condition = SELECT COUNT(*) = 1000000 FROM t1; ---source include/wait_condition.inc - -DROP TABLE t1; - -# -# INSERT AND TRUNCATE on same node -# - ---let $galera_connection_name = node_1a ---let $galera_server_number = 1 ---source include/galera_connect.inc - ---connection node_1 - -CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; - -# Insert 100K rows ---connection node_1 ---send INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6; - ---connection node_1a ---sleep 1 ---send TRUNCATE TABLE t1; - ---connection node_1 ---reap - ---connection node_1a ---reap - ---connection node_1 -SELECT COUNT(*) = 1000000 FROM t1; - ---connection node_2 ---let $wait_condition = SELECT COUNT(*) = 1000000 FROM t1; ---source include/wait_condition.inc +SELECT COUNT(*) = 0 FROM t1; DROP TABLE t1; DROP TABLE ten; diff --git a/mysql-test/suite/galera/t/galera_var_retry_autocommit.test b/mysql-test/suite/galera/t/galera_var_retry_autocommit.test new file mode 100644 index 00000000000..6ef647b24e1 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_var_retry_autocommit.test @@ -0,0 +1,97 @@ +# +# Test that the wsrep_retry_autocommit variable is respected. We use an INSERT that +# proceeds very slowly due to extra SLEEP() in a trigger +# + +--source include/galera_cluster.inc + +--connection node_1 +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=InnoDB; +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.f2 = SLEEP(5); + +# +# With wsrep_retry_autocommit = 0, error is certain +# + +--connection node_1 +SET SESSION wsrep_retry_autocommit = 0; +--send INSERT INTO t1 (f1) VALUES (1),(2); + +--connection node_2 +--sleep 1 +TRUNCATE TABLE t1; + +--connection node_1 +--error ER_LOCK_DEADLOCK +--reap + +# +# With wsrep_retry_autocommit = 1, success against one TRUNCATE +# + +--connection node_1 +SET SESSION wsrep_retry_autocommit = 1; +--send INSERT INTO t1 (f1) VALUES (3),(4); + +--connection node_2 +--sleep 1 +TRUNCATE TABLE t1; + +--connection node_1 +--error 0 +--reap +SELECT * FROM test.t1; + +# +# With wsrep_retry_autocommit = 1, failure against multiple TRUNCATEs +# + +--connection node_2 +DELIMITER |; +CREATE PROCEDURE repeated_truncate () +BEGIN + DECLARE i INT; + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + + SET i = 0; + WHILE i <= 1000 DO + TRUNCATE TABLE t1; + SET i = i + 1; + END WHILE; +END| +DELIMITER ;| + +# Begin streaming TRUNCATEs +--let $truncate_connection_id = `SELECT CONNECTION_ID()` +--send CALL repeated_truncate() + +--connection node_1 +SET SESSION wsrep_retry_autocommit = 1; +--sleep 1 +--error ER_LOCK_DEADLOCK +INSERT INTO t1 (f1) VALUES (5),(6); + +# +# With wsrep_retry_autocommit = 1024, success against multiple TRUNCATEs +# + +--connection node_1 +SET SESSION wsrep_retry_autocommit = 1024; +--send INSERT INTO t1 (f1) VALUES (7),(8); + +--sleep 6 + +# Once he stream of TRUNCATEs is complete +--connection node_2 +--reap + +# the INSERT will eventually be sucessfull +--connection node_1 +--error 0 +--reap + +--let $diff_servers = 1 2 +--source include/diff_servers.inc + +DROP TABLE t1; +DROP PROCEDURE repeated_truncate; diff --git a/mysql-test/suite/galera_3nodes/galera_3nodes.cnf b/mysql-test/suite/galera_3nodes/galera_3nodes.cnf index f19277bb36a..3921e3aa362 100644 --- a/mysql-test/suite/galera_3nodes/galera_3nodes.cnf +++ b/mysql-test/suite/galera_3nodes/galera_3nodes.cnf @@ -12,11 +12,10 @@ wsrep-causal-reads=ON wsrep-sync-wait=7 [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;gcache.size=10M;evs.suspect_timeout=PT10S' +wsrep-cluster-address='gcomm://' +wsrep_provider_options='base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S' + +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' @@ -25,7 +24,9 @@ wsrep_sst_receive_address='127.0.0.1:@mysqld.1.#sst_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;gcache.size=10M;evs.suspect_timeout=PT10S' +wsrep_provider_options='base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S' + +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' @@ -34,7 +35,9 @@ wsrep_sst_receive_address='127.0.0.1:@mysqld.2.#sst_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;gcache.size=10M;evs.suspect_timeout=PT10S' +wsrep_provider_options='base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S' + +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' From 9be994ba693483b240a49c2e6e72bae9fa8cbcca Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Mon, 13 Mar 2017 05:30:02 +0530 Subject: [PATCH 07/66] MW-309 Fix wsrep_max_ws_rows so that it does not affect queries Option wsrep_max_ws_rows is intended to limit the maximum number of rows in a writeset. To enforce this limit, we increment THD::wsrep_affected_rows on every INSERT, UPDATE or DELETE. The problem is that we do so even on insertion to internal temporary tables used for SELECTs and such. THD::wsrep_affected_rows is now incremented only for rows that are actually replicated. Signed-off-by: Sachin Setiya --- sql/handler.cc | 69 ++++++++++++++------------------------------------ 1 file changed, 19 insertions(+), 50 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 6749dd0257e..2aaaff3500c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5933,15 +5933,26 @@ static int binlog_log_row(TABLE* table, THD *const thd= table->in_use; #ifdef WITH_WSREP - /* only InnoDB tables will be replicated through binlog emulation */ - if (WSREP_EMULATE_BINLOG(thd) && - table->file->ht->db_type != DB_TYPE_INNODB && - !(table->file->ht->db_type == DB_TYPE_PARTITION_DB && - (((ha_partition*)(table->file))->wsrep_db_type() == DB_TYPE_INNODB))) - // !strcmp(table->file->table_type(), "InnoDB")) + if (WSREP_EMULATE_BINLOG(thd)) { - return 0; - } + /* only InnoDB tables will be replicated through binlog emulation */ + if (table->file->ht->db_type != DB_TYPE_INNODB && + !(table->file->ht->db_type == DB_TYPE_PARTITION_DB && + (((ha_partition*)(table->file))->wsrep_db_type() == DB_TYPE_INNODB))) + { + return 0; + } + + thd->wsrep_affected_rows++; + if (wsrep_max_ws_rows && + thd->wsrep_exec_mode != REPL_RECV && + thd->wsrep_affected_rows > wsrep_max_ws_rows) + { + trans_rollback_stmt(thd) || trans_rollback(thd); + my_message(ER_ERROR_DURING_COMMIT, "wsrep_max_ws_rows exceeded", MYF(0)); + return ER_ERROR_DURING_COMMIT; + } + } #endif /* WITH_WSREP */ if (check_table_binlog_row_based(thd, table)) { @@ -6108,20 +6119,6 @@ int handler::ha_write_row(uchar *buf) rows_changed++; if (unlikely(error= binlog_log_row(table, 0, buf, log_func))) DBUG_RETURN(error); /* purecov: inspected */ -#ifdef WITH_WSREP - if (WSREP(current_thd)) - { - current_thd->wsrep_affected_rows++; - if (wsrep_max_ws_rows && - current_thd->wsrep_exec_mode != REPL_RECV && - current_thd->wsrep_affected_rows > wsrep_max_ws_rows) - { - trans_rollback_stmt(current_thd) || trans_rollback(current_thd); - my_message(ER_ERROR_DURING_COMMIT, "wsrep_max_ws_rows exceeded", MYF(0)); - DBUG_RETURN(ER_ERROR_DURING_COMMIT); - } - } -#endif /* WITH_WSREP */ DEBUG_SYNC_C("ha_write_row_end"); DBUG_RETURN(0); @@ -6155,20 +6152,6 @@ int handler::ha_update_row(const uchar *old_data, uchar *new_data) rows_changed++; if (unlikely(error= binlog_log_row(table, old_data, new_data, log_func))) return error; -#ifdef WITH_WSREP - if (WSREP(current_thd)) - { - current_thd->wsrep_affected_rows++; - if (wsrep_max_ws_rows && - current_thd->wsrep_exec_mode != REPL_RECV && - current_thd->wsrep_affected_rows > wsrep_max_ws_rows) - { - trans_rollback_stmt(current_thd) || trans_rollback(current_thd); - my_message(ER_ERROR_DURING_COMMIT, "wsrep_max_ws_rows exceeded", MYF(0)); - return ER_ERROR_DURING_COMMIT; - } - } -#endif /* WITH_WSREP */ return 0; } @@ -6196,20 +6179,6 @@ int handler::ha_delete_row(const uchar *buf) rows_changed++; if (unlikely(error= binlog_log_row(table, buf, 0, log_func))) return error; -#ifdef WITH_WSREP - if (WSREP(current_thd)) - { - current_thd->wsrep_affected_rows++; - if (wsrep_max_ws_rows && - current_thd->wsrep_exec_mode != REPL_RECV && - current_thd->wsrep_affected_rows > wsrep_max_ws_rows) - { - trans_rollback_stmt(current_thd) || trans_rollback(current_thd); - my_message(ER_ERROR_DURING_COMMIT, "wsrep_max_ws_rows exceeded", MYF(0)); - return ER_ERROR_DURING_COMMIT; - } - } -#endif /* WITH_WSREP */ return 0; } From 108fd77486f9876c4b718abf23b91aea7426e9c0 Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Wed, 2 Nov 2016 02:01:10 -0700 Subject: [PATCH 08/66] Galera MTR Tests: GAL-405 Initial implementation of GCache recovery on startup. --- .../suite/galera/r/galera_defaults.result | 2 +- .../galera/r/galera_gcache_recover.result | 18 ++ .../galera_gcache_recover_full_gcache.result | 19 ++ .../r/galera_gcache_recover_manytrx.result | 107 +++++++++ .../suite/galera/t/galera_gcache_recover.cnf | 7 + .../suite/galera/t/galera_gcache_recover.test | 77 +++++++ .../t/galera_gcache_recover_full_gcache.cnf | 9 + .../t/galera_gcache_recover_full_gcache.test | 59 +++++ .../t/galera_gcache_recover_manytrx.cnf | 8 + .../t/galera_gcache_recover_manytrx.test | 216 ++++++++++++++++++ 10 files changed, 521 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/galera/r/galera_gcache_recover.result create mode 100644 mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result create mode 100644 mysql-test/suite/galera/r/galera_gcache_recover_manytrx.result create mode 100644 mysql-test/suite/galera/t/galera_gcache_recover.cnf create mode 100644 mysql-test/suite/galera/t/galera_gcache_recover.test create mode 100644 mysql-test/suite/galera/t/galera_gcache_recover_full_gcache.cnf create mode 100644 mysql-test/suite/galera/t/galera_gcache_recover_full_gcache.test create mode 100644 mysql-test/suite/galera/t/galera_gcache_recover_manytrx.cnf create mode 100644 mysql-test/suite/galera/t/galera_gcache_recover_manytrx.test diff --git a/mysql-test/suite/galera/r/galera_defaults.result b/mysql-test/suite/galera/r/galera_defaults.result index a9bec4fc1dc..a06e6229f1d 100644 --- a/mysql-test/suite/galera/r/galera_defaults.result +++ b/mysql-test/suite/galera/r/galera_defaults.result @@ -47,7 +47,7 @@ WSREP_SST_DONOR WSREP_SST_DONOR_REJECTS_QUERIES OFF WSREP_SST_METHOD rsync WSREP_SYNC_WAIT 7 -; ; ; cert.log_conflicts = no; debug = no; evs.auto_evict = 0; evs.causal_keepalive_period = PT1S; evs.debug_log_mask = 0x1; evs.delay_margin = PT1S; evs.delayed_keep_period = PT30S; evs.inactive_check_period = PT0.5S; evs.inactive_timeout = PT30S; evs.info_log_mask = 0; evs.install_timeout = PT15S; evs.join_retrans_period = PT1S; evs.keepalive_period = PT1S; evs.max_install_timeouts = 3; evs.send_window = 4; evs.stats_report_period = PT1M; evs.suspect_timeout = PT10S; evs.use_aggregate = true; evs.user_send_window = 2; evs.version = 0; evs.view_forget_timeout = P1D; ; gcache.keep_pages_size = 0; gcache.mem_size = 0; ; gcache.page_size = 128M; gcache.size = 128M; gcomm.thread_prio = ; gcs.fc_debug = 0; gcs.fc_factor = 1.0; gcs.fc_limit = 16; gcs.fc_master_slave = no; gcs.max_packet_size = 64500; gcs.max_throttle = 0.25; ;gcs.recv_q_soft_limit = 0.25; gcs.sync_donor = no; ; gmcast.mcast_addr = ; gmcast.mcast_ttl = 1; gmcast.peer_timeout = PT3S; gmcast.segment = 0; gmcast.time_wait = PT5S; gmcast.version = 0; ; pc.announce_timeout = PT3S; pc.checksum = false; pc.ignore_quorum = false; pc.ignore_sb = false; pc.linger = PT20S; pc.npvo = false; pc.recovery = true; pc.version = 0; pc.wait_prim = true; pc.wait_prim_timeout = P30S; pc.weight = 1; protonet.backend = asio; protonet.version = 0; repl.causal_read_timeout = PT90S; repl.commit_order = 3; repl.key_format = FLAT8; repl.max_ws_size = 2147483647; repl.proto_max = 7; socket.checksum = 2; socket.recv_buf_size = 212992; +; ; ; cert.log_conflicts = no; debug = no; evs.auto_evict = 0; evs.causal_keepalive_period = PT1S; evs.debug_log_mask = 0x1; evs.delay_margin = PT1S; evs.delayed_keep_period = PT30S; evs.inactive_check_period = PT0.5S; evs.inactive_timeout = PT30S; evs.info_log_mask = 0; evs.install_timeout = PT15S; evs.join_retrans_period = PT1S; evs.keepalive_period = PT1S; evs.max_install_timeouts = 3; evs.send_window = 4; evs.stats_report_period = PT1M; evs.suspect_timeout = PT10S; evs.use_aggregate = true; evs.user_send_window = 2; evs.version = 0; evs.view_forget_timeout = P1D; ; gcache.keep_pages_size = 0; gcache.mem_size = 0; ; gcache.page_size = 128M; gcache.recover = no; gcache.size = 128M; gcomm.thread_prio = ; gcs.fc_debug = 0; gcs.fc_factor = 1.0; gcs.fc_limit = 16; gcs.fc_master_slave = no; gcs.max_packet_size = 64500; gcs.max_throttle = 0.25; ;gcs.recv_q_soft_limit = 0.25; gcs.sync_donor = no; ; gmcast.mcast_addr = ; gmcast.mcast_ttl = 1; gmcast.peer_timeout = PT3S; gmcast.segment = 0; gmcast.time_wait = PT5S; gmcast.version = 0; ; pc.announce_timeout = PT3S; pc.checksum = false; pc.ignore_quorum = false; pc.ignore_sb = false; pc.linger = PT20S; pc.npvo = false; pc.recovery = true; pc.version = 0; pc.wait_prim = true; pc.wait_prim_timeout = P30S; pc.weight = 1; protonet.backend = asio; protonet.version = 0; repl.causal_read_timeout = PT90S; repl.commit_order = 3; repl.key_format = FLAT8; repl.max_ws_size = 2147483647; repl.proto_max = 7; socket.checksum = 2; socket.recv_buf_size = 212992; SELECT COUNT(*) FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE 'wsrep_%' AND VARIABLE_NAME != 'wsrep_debug_sync_waiters'; diff --git a/mysql-test/suite/galera/r/galera_gcache_recover.result b/mysql-test/suite/galera/r/galera_gcache_recover.result new file mode 100644 index 00000000000..127bcba39d8 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_gcache_recover.result @@ -0,0 +1,18 @@ +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +SET SESSION wsrep_sync_wait = 0; +SET SESSION wsrep_sync_wait = 0; +Killing server ... +INSERT INTO t1 VALUES (2); +Killing server ... +Performing --wsrep-recover ... +Using --wsrep-start-position when starting mysqld ... +INSERT INTO t1 VALUES (3); +Performing --wsrep-recover ... +Using --wsrep-start-position when starting mysqld ... +include/diff_servers.inc [servers=1 2] +CALL mtr.add_suppression("Skipped GCache ring buffer recovery"); +include/assert_grep.inc [async IST sender starting to serve] +CALL mtr.add_suppression("Skipped GCache ring buffer recovery"); +include/assert_grep.inc [Recovering GCache ring buffer: found gapless sequence] +DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result b/mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result new file mode 100644 index 00000000000..30ee5772411 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result @@ -0,0 +1,19 @@ +SET SESSION wsrep_sync_wait = 0; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 LONGBLOB) ENGINE=InnoDB; +SET SESSION wsrep_sync_wait = 0; +Killing server ... +INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10)); +INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10)); +INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10)); +INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10)); +INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10)); +Killing server ... +Performing --wsrep-recover ... +Using --wsrep-start-position when starting mysqld ... +Performing --wsrep-recover ... +Using --wsrep-start-position when starting mysqld ... +include/diff_servers.inc [servers=1 2] +DROP TABLE t1; +CALL mtr.add_suppression("Skipped GCache ring buffer recovery"); +include/assert_grep.inc [IST first seqno 2 not found from cache, falling back to SST] +CALL mtr.add_suppression("Skipped GCache ring buffer recovery"); diff --git a/mysql-test/suite/galera/r/galera_gcache_recover_manytrx.result b/mysql-test/suite/galera/r/galera_gcache_recover_manytrx.result new file mode 100644 index 00000000000..868b39bfbd6 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_gcache_recover_manytrx.result @@ -0,0 +1,107 @@ +SET SESSION wsrep_sync_wait = 0; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 LONGBLOB) ENGINE=InnoDB; +CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +CREATE PROCEDURE insert_simple () +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +SET SESSION wsrep_sync_wait = 0; +WHILE 1 DO +INSERT INTO t1 (f1, f2) VALUES (DEFAULT,'abcdef'); +END WHILE; +END| +CREATE PROCEDURE insert_multi () +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +SET SESSION wsrep_sync_wait = 0; +WHILE 1 DO +INSERT INTO t1 (f1) VALUES (DEFAULT),(DEFAULT),(DEFAULT),(DEFAULT),(DEFAULT),(DEFAULT),(DEFAULT),(DEFAULT),(DEFAULT),(DEFAULT); +END WHILE; +END| +CREATE PROCEDURE insert_transaction () +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +SET SESSION wsrep_sync_wait = 0; +SET AUTOCOMMIT = OFF; +WHILE 1 DO +START TRANSACTION; +INSERT INTO t1 (f1) VALUES (DEFAULT); +INSERT INTO t1 (f1) VALUES (DEFAULT); +INSERT INTO t1 (f1) VALUES (DEFAULT); +INSERT INTO t1 (f1) VALUES (DEFAULT); +INSERT INTO t1 (f1) VALUES (DEFAULT); +INSERT INTO t1 (f1) VALUES (DEFAULT); +INSERT INTO t1 (f1) VALUES (DEFAULT); +INSERT INTO t1 (f1) VALUES (DEFAULT); +INSERT INTO t1 (f1) VALUES (DEFAULT); +INSERT INTO t1 (f1) VALUES (DEFAULT); +COMMIT; +END WHILE; +END| +CREATE PROCEDURE update_simple () +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +SET SESSION wsrep_sync_wait = 0; +WHILE 1 DO +UPDATE t1 SET f2 = CONCAT(f2,f2); +END WHILE; +END| +CREATE PROCEDURE insert_1k () +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +SET SESSION wsrep_sync_wait = 0; +WHILE 1 DO +INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024)); +END WHILE; +END| +CREATE PROCEDURE insert_1m () +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +SET SESSION wsrep_sync_wait = 0; +WHILE 1 DO +INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024)); +END WHILE; +END| +CREATE PROCEDURE insert_10m () +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +SET SESSION wsrep_sync_wait = 0; +WHILE 1 DO +INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10)); +END WHILE; +END| +CALL insert_simple();; +CALL insert_multi();; +CALL insert_transaction ();; +CALL update_simple ();; +CALL insert_1k ();; +CALL insert_1m ();; +CALL insert_10m ();; +SET SESSION wsrep_sync_wait = 0; +Killing server ... +Killing server ... +ERROR HY000: Lost connection to MySQL server during query +ERROR HY000: Lost connection to MySQL server during query +ERROR HY000: Lost connection to MySQL server during query +ERROR HY000: Lost connection to MySQL server during query +ERROR HY000: Lost connection to MySQL server during query +ERROR HY000: Lost connection to MySQL server during query +ERROR HY000: Lost connection to MySQL server during query +Performing --wsrep-recover ... +Using --wsrep-start-position when starting mysqld ... +Performing --wsrep-recover ... +Using --wsrep-start-position when starting mysqld ... +include/diff_servers.inc [servers=1 2] +DROP TABLE t1; +DROP TABLE ten; +DROP PROCEDURE insert_simple; +DROP PROCEDURE insert_multi; +DROP PROCEDURE insert_transaction; +DROP PROCEDURE update_simple; +DROP PROCEDURE insert_1k; +DROP PROCEDURE insert_1m; +CALL mtr.add_suppression("conflict state 7 after post commit"); +CALL mtr.add_suppression("Skipped GCache ring buffer recovery"); +include/assert_grep.inc [async IST sender starting to serve] +CALL mtr.add_suppression("Skipped GCache ring buffer recovery"); +include/assert_grep.inc [Recovering GCache ring buffer: found gapless sequence] diff --git a/mysql-test/suite/galera/t/galera_gcache_recover.cnf b/mysql-test/suite/galera/t/galera_gcache_recover.cnf new file mode 100644 index 00000000000..c7b59b6a27e --- /dev/null +++ b/mysql-test/suite/galera/t/galera_gcache_recover.cnf @@ -0,0 +1,7 @@ +!include ../galera_2nodes.cnf + +[mysqld.1] +wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.recover=yes;pc.ignore_sb=true' + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.recover=yes;pc.ignore_sb=true' diff --git a/mysql-test/suite/galera/t/galera_gcache_recover.test b/mysql-test/suite/galera/t/galera_gcache_recover.test new file mode 100644 index 00000000000..e1bfe517d27 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_gcache_recover.test @@ -0,0 +1,77 @@ +# +# Kill entire cluster while gcache.recover=yes. Expect that node #2 will rejoin using IST +# + +--source include/galera_cluster.inc +--source include/big_test.inc + +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +SET SESSION wsrep_sync_wait = 0; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) > 0 FROM t1; +--source include/wait_condition.inc + +SET SESSION wsrep_sync_wait = 0; +--source include/kill_galera.inc + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +INSERT INTO t1 VALUES (2); + +--source include/kill_galera.inc + +--sleep 1 + +--connection node_1 +--let $galera_wsrep_recover_server_id=1 +--source suite/galera/include/galera_wsrep_recover.inc + +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/start_mysqld.inc + +INSERT INTO t1 VALUES (3); + +--connection node_2 +--let $galera_wsrep_recover_server_id=2 +--source suite/galera/include/galera_wsrep_recover.inc + +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--source include/start_mysqld.inc + +--connection node_1 +--source include/wait_until_connected_again.inc +--source include/galera_wait_ready.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; + +--let $diff_servers = 1 2 +--source include/diff_servers.inc + +--connection node_1 +# Warning happens when the cluster is started for the first time +CALL mtr.add_suppression("Skipped GCache ring buffer recovery"); + +# Confirm that IST took place +--let $assert_text = async IST sender starting to serve +--let $assert_select = async IST sender starting to serve +--let $assert_count = 1 +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_only_after = starting as process +--source include/assert_grep.inc + +--connection node_2 +CALL mtr.add_suppression("Skipped GCache ring buffer recovery"); + +# Confirm that gcache recovery took place + +--let $assert_text = Recovering GCache ring buffer: found gapless sequence +--let $assert_select = Recovering GCache ring buffer: found gapless sequence +--let $assert_count = 1 +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.2.err +--let $assert_only_after = starting as process +--source include/assert_grep.inc + +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_gcache_recover_full_gcache.cnf b/mysql-test/suite/galera/t/galera_gcache_recover_full_gcache.cnf new file mode 100644 index 00000000000..da74ea9fc5d --- /dev/null +++ b/mysql-test/suite/galera/t/galera_gcache_recover_full_gcache.cnf @@ -0,0 +1,9 @@ +!include ../galera_2nodes.cnf + +[mysqld.1] +max_allowed_packet=10M +innodb_log_file_size=110M +wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.recover=yes;pc.ignore_sb=true;gcache.size=10M' + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.recover=yes;pc.ignore_sb=true;gcache.size=10M' diff --git a/mysql-test/suite/galera/t/galera_gcache_recover_full_gcache.test b/mysql-test/suite/galera/t/galera_gcache_recover_full_gcache.test new file mode 100644 index 00000000000..b7fd9cf3aed --- /dev/null +++ b/mysql-test/suite/galera/t/galera_gcache_recover_full_gcache.test @@ -0,0 +1,59 @@ +# +# Attempt gcache recovery on a full gcache. Node will not be able to join via IST due to gcache rollover +# + +--source include/galera_cluster.inc +--source include/big_test.inc + +SET SESSION wsrep_sync_wait = 0; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 LONGBLOB) ENGINE=InnoDB; + +--connection node_2 +SET SESSION wsrep_sync_wait = 0; +--source include/kill_galera.inc + +--connection node_1 +INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10)); +INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10)); +INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10)); +INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10)); +INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10)); +--source include/kill_galera.inc + +--connection node_1 +--let $galera_wsrep_recover_server_id=1 +--source suite/galera/include/galera_wsrep_recover.inc + +--let $_expect_file_name = $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/start_mysqld.inc +--connection node_2 +--let $galera_wsrep_recover_server_id=2 +--source suite/galera/include/galera_wsrep_recover.inc + +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--source include/start_mysqld.inc + +--connection node_1 +--source include/wait_until_connected_again.inc +--source include/galera_wait_ready.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; + +--let $diff_servers = 1 2 +--source include/diff_servers.inc + +--connection node_1 +DROP TABLE t1; + +# Warning always happens when the cluster is started for the first time +CALL mtr.add_suppression("Skipped GCache ring buffer recovery"); + +# Confirm that IST did not take place +--let $assert_text = IST first seqno 2 not found from cache, falling back to SST +--let $assert_select = IST first seqno 2 not found from cache, falling back to SST +--let $assert_count = 1 +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_only_after = starting as process +--source include/assert_grep.inc + +--connection node_2 +CALL mtr.add_suppression("Skipped GCache ring buffer recovery"); diff --git a/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.cnf b/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.cnf new file mode 100644 index 00000000000..39af0e94b94 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.cnf @@ -0,0 +1,8 @@ +!include ../galera_2nodes.cnf + +[mysqld.1] +innodb_log_file_size=110M +wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.recover=yes;pc.ignore_sb=true;' + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.recover=yes;pc.ignore_sb=true;' diff --git a/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.test b/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.test new file mode 100644 index 00000000000..3bfcdc9f117 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.test @@ -0,0 +1,216 @@ +# +# Kill entire cluster while various transactions are in progress +# restore the cluster and expect that node #2 will rejoin using IST +# + +--source include/galera_cluster.inc +--source include/big_test.inc + +SET SESSION wsrep_sync_wait = 0; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 LONGBLOB) ENGINE=InnoDB; +CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); + +DELIMITER |; +CREATE PROCEDURE insert_simple () +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + SET SESSION wsrep_sync_wait = 0; + WHILE 1 DO + INSERT INTO t1 (f1, f2) VALUES (DEFAULT,'abcdef'); + END WHILE; +END| + +CREATE PROCEDURE insert_multi () +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + SET SESSION wsrep_sync_wait = 0; + WHILE 1 DO + INSERT INTO t1 (f1) VALUES (DEFAULT),(DEFAULT),(DEFAULT),(DEFAULT),(DEFAULT),(DEFAULT),(DEFAULT),(DEFAULT),(DEFAULT),(DEFAULT); + END WHILE; +END| + +CREATE PROCEDURE insert_transaction () +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + SET SESSION wsrep_sync_wait = 0; + SET AUTOCOMMIT = OFF; + WHILE 1 DO + START TRANSACTION; + INSERT INTO t1 (f1) VALUES (DEFAULT); + INSERT INTO t1 (f1) VALUES (DEFAULT); + INSERT INTO t1 (f1) VALUES (DEFAULT); + INSERT INTO t1 (f1) VALUES (DEFAULT); + INSERT INTO t1 (f1) VALUES (DEFAULT); + + INSERT INTO t1 (f1) VALUES (DEFAULT); + INSERT INTO t1 (f1) VALUES (DEFAULT); + INSERT INTO t1 (f1) VALUES (DEFAULT); + INSERT INTO t1 (f1) VALUES (DEFAULT); + INSERT INTO t1 (f1) VALUES (DEFAULT); + COMMIT; + END WHILE; +END| + +DELIMITER ;| +DELIMITER |; + +CREATE PROCEDURE update_simple () +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + SET SESSION wsrep_sync_wait = 0; + WHILE 1 DO + UPDATE t1 SET f2 = CONCAT(f2,f2); + END WHILE; +END| + +CREATE PROCEDURE insert_1k () +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + SET SESSION wsrep_sync_wait = 0; + WHILE 1 DO + INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024)); + END WHILE; +END| + +CREATE PROCEDURE insert_1m () +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + SET SESSION wsrep_sync_wait = 0; + WHILE 1 DO + INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024)); + END WHILE; +END| + +CREATE PROCEDURE insert_10m () +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + SET SESSION wsrep_sync_wait = 0; + WHILE 1 DO + INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10)); + END WHILE; +END| + +DELIMITER ;| + +--connect node_1_insert_simple, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connect node_1_insert_multi, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connect node_1_insert_transaction, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connect node_1_update_simple, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connect node_1_insert_1k, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connect node_1_insert_1m, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connect node_1_insert_10m, 127.0.0.1, root, , test, $NODE_MYPORT_1 + +--connection node_1_insert_simple +--send CALL insert_simple(); + +--connection node_1_insert_multi +--send CALL insert_multi(); + +--connection node_1_insert_transaction +--send CALL insert_transaction (); + +--connection node_1_update_simple +--send CALL update_simple (); + +--connection node_1_insert_1k +--send CALL insert_1k (); + +--connection node_1_insert_1m +--send CALL insert_1m (); + +--connection node_1_insert_10m +--send CALL insert_10m (); + +--connection node_2 +SET SESSION wsrep_sync_wait = 0; +--source include/kill_galera.inc + +--sleep 10 +--connection node_1 +--source include/kill_galera.inc + +--connection node_1_insert_simple +--error 2013 +--reap + +--connection node_1_insert_multi +--error 2013 +--reap + +--connection node_1_insert_transaction +--error 2013 +--reap + +--connection node_1_update_simple +--error 2013 +--reap + +--connection node_1_insert_1k +--error 2013 +--reap + +--connection node_1_insert_1m +--error 2013 +--reap + +--connection node_1_insert_10m +--error 2013 +--reap + +--connection node_1 +--let $galera_wsrep_recover_server_id=1 +--source suite/galera/include/galera_wsrep_recover.inc + +--let $_expect_file_name = $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/start_mysqld.inc +--connection node_2 +--let $galera_wsrep_recover_server_id=2 +--source suite/galera/include/galera_wsrep_recover.inc + +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--source include/start_mysqld.inc + +--connection node_1 +--source include/wait_until_connected_again.inc +--source include/galera_wait_ready.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; + +--let $diff_servers = 1 2 +--source include/diff_servers.inc + +--connection node_1 +DROP TABLE t1; +DROP TABLE ten; +DROP PROCEDURE insert_simple; +DROP PROCEDURE insert_multi; +DROP PROCEDURE insert_transaction; +DROP PROCEDURE update_simple; +DROP PROCEDURE insert_1k; +DROP PROCEDURE insert_1m; + +--connection node_1 +CALL mtr.add_suppression("conflict state 7 after post commit"); + +# Warning happens when the cluster is started for the first time +CALL mtr.add_suppression("Skipped GCache ring buffer recovery"); + +# Confirm that IST took place +--let $assert_text = async IST sender starting to serve +--let $assert_select = async IST sender starting to serve +--let $assert_count = 1 +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_only_after = starting as process +--source include/assert_grep.inc + +--connection node_2 +CALL mtr.add_suppression("Skipped GCache ring buffer recovery"); + +# Confirm that gcache recovery took place + +--let $assert_text = Recovering GCache ring buffer: found gapless sequence +--let $assert_select = Recovering GCache ring buffer: found gapless sequence +--let $assert_count = 1 +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.2.err +--let $assert_only_after = starting as process +--source include/assert_grep.inc From 16e683fdad2595b37388f9320d76930cbe425a52 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Tue, 14 Mar 2017 07:11:17 +0530 Subject: [PATCH 09/66] Galera MTR Tests: Tests for GAL-419 Respect safe_to_bootstrap flag also with gcomm:// Signed-off-by: Sachin Setiya --- mysql-test/suite/galera/r/GAL-419.result | 4 ++ .../r/galera_var_cluster_address.result | 23 ++++++++++++ mysql-test/suite/galera/t/GAL-419.test | 35 ++++++++++++++++++ .../galera/t/galera_var_cluster_address.test | 37 ++++++++++++++++++- 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/galera/r/GAL-419.result create mode 100644 mysql-test/suite/galera/t/GAL-419.test diff --git a/mysql-test/suite/galera/r/GAL-419.result b/mysql-test/suite/galera/r/GAL-419.result new file mode 100644 index 00000000000..410c91b4f98 --- /dev/null +++ b/mysql-test/suite/galera/r/GAL-419.result @@ -0,0 +1,4 @@ +SET SESSION wsrep_sync_wait = 0; +Killing server ... +SET SESSION wsrep_sync_wait = 0; +Killing server ... diff --git a/mysql-test/suite/galera/r/galera_var_cluster_address.result b/mysql-test/suite/galera/r/galera_var_cluster_address.result index 17b5a7bca37..bb3ea8e3a53 100644 --- a/mysql-test/suite/galera/r/galera_var_cluster_address.result +++ b/mysql-test/suite/galera/r/galera_var_cluster_address.result @@ -26,6 +26,28 @@ VARIABLE_VALUE = 'Primary' SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 2 1 +SET GLOBAL wsrep_cluster_address = 'gcomm://192.0.2.1'; +SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS; +COUNT(*) > 0 +1 +SHOW STATUS LIKE 'wsrep_ready'; +Variable_name Value +wsrep_ready ON +SHOW STATUS LIKE 'wsrep_cluster_status'; +Variable_name Value +wsrep_cluster_status Primary +SHOW STATUS LIKE 'wsrep_local_state'; +Variable_name Value +wsrep_local_state 4 +SHOW STATUS LIKE 'wsrep_local_state_comment'; +Variable_name Value +wsrep_local_state_comment Synced +SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +VARIABLE_VALUE = 'Primary' +1 +SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +VARIABLE_VALUE = 2 +1 CALL mtr.add_suppression("Backend not supported: foo"); CALL mtr.add_suppression("Failed to initialize backend using 'foo"); CALL mtr.add_suppression("Failed to open channel 'my_wsrep_cluster' at 'foo"); @@ -36,4 +58,5 @@ CALL mtr.add_suppression("failed to open gcomm backend connection: 110: failed t CALL mtr.add_suppression("Failed to open backend connection: -110 \\(Connection timed out\\)"); CALL mtr.add_suppression("gcs connect failed: Connection timed out"); CALL mtr.add_suppression("WSREP: wsrep::connect\\(foo://\\) failed: 7"); +CALL mtr.add_suppression("WSREP: wsrep::connect\\(gcomm://192.0.2.1\\) failed: 7"); # End of test diff --git a/mysql-test/suite/galera/t/GAL-419.test b/mysql-test/suite/galera/t/GAL-419.test new file mode 100644 index 00000000000..e50b948bf35 --- /dev/null +++ b/mysql-test/suite/galera/t/GAL-419.test @@ -0,0 +1,35 @@ +# +# GAL-419 safe_to_bootstrap: boostrap using wsrep_cluster_address=gcomm:// not prevented +# + +--source include/galera_cluster.inc +--source include/big_test.inc + +--connection node_2 +SET SESSION wsrep_sync_wait = 0; +--source include/kill_galera.inc + +--connection node_1 +SET SESSION wsrep_sync_wait = 0; +--source include/kill_galera.inc + +--sleep 2 + +# Node #1 has wsrep_cluster_address=gcomm:// in my.cnf, so should fail to bootstrap + +--error 1 +--exec $MYSQLD --defaults-group-suffix=.1 --defaults-file=$MYSQLTEST_VARDIR/my.cnf | grep 'This node is not safe to bootstrap the cluster' + +# Unless we remove grastate.dat + +--remove_file $MYSQLTEST_VARDIR/mysqld.1/data/grastate.dat +--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat + +--connection node_1 +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/start_mysqld.inc +--source include/wait_until_connected_again.inc + +--connection node_2 +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--source include/start_mysqld.inc diff --git a/mysql-test/suite/galera/t/galera_var_cluster_address.test b/mysql-test/suite/galera/t/galera_var_cluster_address.test index 740c38765f6..5328b5e7a94 100644 --- a/mysql-test/suite/galera/t/galera_var_cluster_address.test +++ b/mysql-test/suite/galera/t/galera_var_cluster_address.test @@ -58,6 +58,41 @@ SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VA SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +# +# Set to invalid host +# + +--connection node_2 +SET GLOBAL wsrep_cluster_address = 'gcomm://192.0.2.1'; +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +--error 0 +SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS; + +# Must return 'OFF' +SHOW STATUS LIKE 'wsrep_ready'; + +# Must return 'Non-primary' +SHOW STATUS LIKE 'wsrep_cluster_status'; + +# Must return 0 = 'Initialized' +SHOW STATUS LIKE 'wsrep_local_state'; +SHOW STATUS LIKE 'wsrep_local_state_comment'; + +# +# Reset everything as it was +# + +--connection node_2 +--disable_query_log +--eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_node2'; +--enable_query_log + +--connection node_1 +SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; + --connection node_2 CALL mtr.add_suppression("Backend not supported: foo"); CALL mtr.add_suppression("Failed to initialize backend using 'foo"); @@ -69,7 +104,7 @@ CALL mtr.add_suppression("failed to open gcomm backend connection: 110: failed t CALL mtr.add_suppression("Failed to open backend connection: -110 \\(Connection timed out\\)"); CALL mtr.add_suppression("gcs connect failed: Connection timed out"); CALL mtr.add_suppression("WSREP: wsrep::connect\\(foo://\\) failed: 7"); - +CALL mtr.add_suppression("WSREP: wsrep::connect\\(gcomm://192.0.2.1\\) failed: 7"); # Restore original auto_increment_offset values. --source include/auto_increment_offset_restore.inc From 5d9c74719383b280f3d960c4d21bed238bfdbb38 Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Wed, 2 Nov 2016 07:04:34 -0700 Subject: [PATCH 10/66] Galera MTR tests: Update galera_defaults.result for GAL-360 --- mysql-test/suite/galera/r/galera_defaults.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/galera/r/galera_defaults.result b/mysql-test/suite/galera/r/galera_defaults.result index a06e6229f1d..b5b94ad317b 100644 --- a/mysql-test/suite/galera/r/galera_defaults.result +++ b/mysql-test/suite/galera/r/galera_defaults.result @@ -47,7 +47,7 @@ WSREP_SST_DONOR WSREP_SST_DONOR_REJECTS_QUERIES OFF WSREP_SST_METHOD rsync WSREP_SYNC_WAIT 7 -; ; ; cert.log_conflicts = no; debug = no; evs.auto_evict = 0; evs.causal_keepalive_period = PT1S; evs.debug_log_mask = 0x1; evs.delay_margin = PT1S; evs.delayed_keep_period = PT30S; evs.inactive_check_period = PT0.5S; evs.inactive_timeout = PT30S; evs.info_log_mask = 0; evs.install_timeout = PT15S; evs.join_retrans_period = PT1S; evs.keepalive_period = PT1S; evs.max_install_timeouts = 3; evs.send_window = 4; evs.stats_report_period = PT1M; evs.suspect_timeout = PT10S; evs.use_aggregate = true; evs.user_send_window = 2; evs.version = 0; evs.view_forget_timeout = P1D; ; gcache.keep_pages_size = 0; gcache.mem_size = 0; ; gcache.page_size = 128M; gcache.recover = no; gcache.size = 128M; gcomm.thread_prio = ; gcs.fc_debug = 0; gcs.fc_factor = 1.0; gcs.fc_limit = 16; gcs.fc_master_slave = no; gcs.max_packet_size = 64500; gcs.max_throttle = 0.25; ;gcs.recv_q_soft_limit = 0.25; gcs.sync_donor = no; ; gmcast.mcast_addr = ; gmcast.mcast_ttl = 1; gmcast.peer_timeout = PT3S; gmcast.segment = 0; gmcast.time_wait = PT5S; gmcast.version = 0; ; pc.announce_timeout = PT3S; pc.checksum = false; pc.ignore_quorum = false; pc.ignore_sb = false; pc.linger = PT20S; pc.npvo = false; pc.recovery = true; pc.version = 0; pc.wait_prim = true; pc.wait_prim_timeout = P30S; pc.weight = 1; protonet.backend = asio; protonet.version = 0; repl.causal_read_timeout = PT90S; repl.commit_order = 3; repl.key_format = FLAT8; repl.max_ws_size = 2147483647; repl.proto_max = 7; socket.checksum = 2; socket.recv_buf_size = 212992; +; ; ; cert.log_conflicts = no; debug = no; evs.auto_evict = 0; evs.causal_keepalive_period = PT1S; evs.debug_log_mask = 0x1; evs.delay_margin = PT1S; evs.delayed_keep_period = PT30S; evs.inactive_check_period = PT0.5S; evs.inactive_timeout = PT30S; evs.info_log_mask = 0; evs.install_timeout = PT15S; evs.join_retrans_period = PT1S; evs.keepalive_period = PT1S; evs.max_install_timeouts = 3; evs.send_window = 4; evs.stats_report_period = PT1M; evs.suspect_timeout = PT10S; evs.use_aggregate = true; evs.user_send_window = 2; evs.version = 0; evs.view_forget_timeout = P1D; ; gcache.keep_pages_size = 0; gcache.mem_size = 0; ; gcache.page_size = 128M; gcache.recover = no; gcache.size = 128M; gcomm.thread_prio = ; gcs.fc_debug = 0; gcs.fc_factor = 1.0; gcs.fc_limit = 16; gcs.fc_master_slave = no; gcs.max_packet_size = 64500; gcs.max_throttle = 0.25; ;gcs.recv_q_soft_limit = 0.25; gcs.sync_donor = no; ; gmcast.mcast_addr = ; gmcast.mcast_ttl = 1; gmcast.peer_timeout = PT3S; gmcast.segment = 0; gmcast.time_wait = PT5S; gmcast.version = 0; ; pc.announce_timeout = PT3S; pc.checksum = false; pc.ignore_quorum = false; pc.ignore_sb = false; pc.linger = PT20S; pc.npvo = false; pc.recovery = true; pc.version = 0; pc.wait_prim = true; pc.wait_prim_timeout = PT30S; pc.weight = 1; protonet.backend = asio; protonet.version = 0; repl.causal_read_timeout = PT90S; repl.commit_order = 3; repl.key_format = FLAT8; repl.max_ws_size = 2147483647; repl.proto_max = 7; socket.checksum = 2; socket.recv_buf_size = 212992; SELECT COUNT(*) FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE 'wsrep_%' AND VARIABLE_NAME != 'wsrep_debug_sync_waiters'; From 0a06347333092b54a5545f1c3ce51cd527f7571d Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Thu, 3 Nov 2016 00:49:20 -0700 Subject: [PATCH 11/66] Galera MTR Tests: Test for MW-309 - Fix wsrep_max_ws_rows so that it does not affect SELECT queries --- mysql-test/suite/galera/r/MW-309.result | 22 ++++++++++++++++++ mysql-test/suite/galera/t/MW-309.test | 31 +++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 mysql-test/suite/galera/r/MW-309.result create mode 100644 mysql-test/suite/galera/t/MW-309.test diff --git a/mysql-test/suite/galera/r/MW-309.result b/mysql-test/suite/galera/r/MW-309.result new file mode 100644 index 00000000000..3dd49a041ee --- /dev/null +++ b/mysql-test/suite/galera/r/MW-309.result @@ -0,0 +1,22 @@ +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +SET GLOBAL wsrep_max_ws_rows = 2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +SELECT * FROM t1 GROUP BY f1; +f1 +1 +SELECT * FROM t1 GROUP BY f1; +f1 +1 +SELECT * FROM t1 GROUP BY f1; +f1 +1 +SHOW STATUS LIKE '%wsrep%'; +SET GLOBAL wsrep_max_ws_rows = 0; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/MW-309.test b/mysql-test/suite/galera/t/MW-309.test new file mode 100644 index 00000000000..d4939f2745f --- /dev/null +++ b/mysql-test/suite/galera/t/MW-309.test @@ -0,0 +1,31 @@ +# +# MW-309 Regression: wsrep_max_ws_rows limit also applies to certain SELECT queries +# + +--source include/galera_cluster.inc + +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; + +SET GLOBAL wsrep_max_ws_rows = 2; + +SET AUTOCOMMIT=OFF; +START TRANSACTION; +SELECT * FROM t1 GROUP BY f1; +SELECT * FROM t1 GROUP BY f1; + +--error 0 +SELECT * FROM t1 GROUP BY f1; + +--disable_result_log +--error 0 +SHOW STATUS LIKE '%wsrep%'; +--enable_result_log + +SET GLOBAL wsrep_max_ws_rows = 0; +DROP TABLE t1; From 395c420f0fbbd675d2bc32f195bfc2ce7b730d5e Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Thu, 3 Nov 2016 04:05:05 -0700 Subject: [PATCH 12/66] Galera MTR Tests: MW-305 , re-enable the test for ALTER USER --- .../galera/r/galera_account_management.result | 7 +++++++ .../suite/galera/t/galera_account_management.test | 14 ++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_account_management.result b/mysql-test/suite/galera/r/galera_account_management.result index 9b3ae9ba46e..4fa33a63064 100644 --- a/mysql-test/suite/galera/r/galera_account_management.result +++ b/mysql-test/suite/galera/r/galera_account_management.result @@ -2,6 +2,13 @@ CREATE USER user1, user2 IDENTIFIED BY 'password'; SELECT COUNT(*) = 2 FROM mysql.user WHERE user IN ('user1', 'user2'); COUNT(*) = 2 1 +ALTER USER user1 PASSWORD EXPIRE; +SELECT password_expired = 'Y' FROM mysql.user WHERE user = 'user1'; +password_expired = 'Y' +1 +SELECT password_expired = 'Y' FROM mysql.user WHERE user = 'user1'; +password_expired = 'Y' +1 RENAME USER user2 TO user3; SELECT COUNT(*) = 0 FROM mysql.user WHERE user = 'user2'; COUNT(*) = 0 diff --git a/mysql-test/suite/galera/t/galera_account_management.test b/mysql-test/suite/galera/t/galera_account_management.test index 357319ad106..6dea0fcfa9e 100644 --- a/mysql-test/suite/galera/t/galera_account_management.test +++ b/mysql-test/suite/galera/t/galera_account_management.test @@ -18,14 +18,12 @@ SELECT COUNT(*) = 2 FROM mysql.user WHERE user IN ('user1', 'user2'); # ALTER USER # -# LP bug 1376269 -# -#--connection node_1 -#ALTER USER user1 PASSWORD EXPIRE; -#SELECT password_expired = 'Y' FROM mysql.user WHERE user = 'user1'; -# -#--connection node_2 -#SELECT password_expired = 'Y' FROM mysql.user WHERE user = 'user1'; +--connection node_1 +ALTER USER user1 PASSWORD EXPIRE; +SELECT password_expired = 'Y' FROM mysql.user WHERE user = 'user1'; + +--connection node_2 +SELECT password_expired = 'Y' FROM mysql.user WHERE user = 'user1'; # # RENAME USER From 9dda6cb08d3509a83a0897f890e48d7e5a98fdf7 Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Thu, 3 Nov 2016 16:04:22 +0100 Subject: [PATCH 13/66] MW-313 Enforce wsrep_max_ws_rows also when binlog is enabled --- sql/handler.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 2aaaff3500c..f920686231b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5933,16 +5933,18 @@ static int binlog_log_row(TABLE* table, THD *const thd= table->in_use; #ifdef WITH_WSREP - if (WSREP_EMULATE_BINLOG(thd)) + /* only InnoDB tables will be replicated through binlog emulation */ + if (WSREP_EMULATE_BINLOG(thd) && + table->file->ht->db_type != DB_TYPE_INNODB && + !(table->file->ht->db_type == DB_TYPE_PARTITION_DB && + (((ha_partition*)(table->file))->wsrep_db_type() == DB_TYPE_INNODB))) { - /* only InnoDB tables will be replicated through binlog emulation */ - if (table->file->ht->db_type != DB_TYPE_INNODB && - !(table->file->ht->db_type == DB_TYPE_PARTITION_DB && - (((ha_partition*)(table->file))->wsrep_db_type() == DB_TYPE_INNODB))) - { return 0; - } + } + /* enforce wsrep_max_ws_rows */ + if (table->s->tmp_table == NO_TMP_TABLE) + { thd->wsrep_affected_rows++; if (wsrep_max_ws_rows && thd->wsrep_exec_mode != REPL_RECV && From 451bf7243ac9a634593fbca006354d8dae59f34c Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Fri, 4 Nov 2016 01:33:54 -0700 Subject: [PATCH 14/66] Galera MTR Tests: Test for MW-313 Enforce wsrep_max_ws_rows also when binlog is enabled --- mysql-test/suite/galera/r/MW-313.result | 32 +++++++++++++ mysql-test/suite/galera/t/MW-313-master.opt | 1 + mysql-test/suite/galera/t/MW-313.test | 50 +++++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 mysql-test/suite/galera/r/MW-313.result create mode 100644 mysql-test/suite/galera/t/MW-313-master.opt create mode 100644 mysql-test/suite/galera/t/MW-313.test diff --git a/mysql-test/suite/galera/r/MW-313.result b/mysql-test/suite/galera/r/MW-313.result new file mode 100644 index 00000000000..dc605ffc370 --- /dev/null +++ b/mysql-test/suite/galera/r/MW-313.result @@ -0,0 +1,32 @@ +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +SET GLOBAL wsrep_max_ws_rows = 2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +SELECT * FROM t1 GROUP BY f1; +f1 +1 +SELECT * FROM t1 GROUP BY f1; +f1 +1 +SELECT * FROM t1 GROUP BY f1; +f1 +1 +SHOW STATUS LIKE '%wsrep%'; +INSERT INTO t1 SELECT * FROM t1; +ERROR HY000: wsrep_max_ws_rows exceeded +START TRANSACTION; +INSERT INTO t1 (f1) VALUES (1); +INSERT INTO t1 (f1) VALUES (2),(3),(4); +ERROR HY000: wsrep_max_ws_rows exceeded +ROLLBACK; +START TRANSACTION; +DELETE FROM t1; +ERROR HY000: wsrep_max_ws_rows exceeded +DROP TABLE t1; +SET GLOBAL wsrep_max_ws_rows = 0; diff --git a/mysql-test/suite/galera/t/MW-313-master.opt b/mysql-test/suite/galera/t/MW-313-master.opt new file mode 100644 index 00000000000..8a755e98b00 --- /dev/null +++ b/mysql-test/suite/galera/t/MW-313-master.opt @@ -0,0 +1 @@ +--log-bin --log-slave-updates diff --git a/mysql-test/suite/galera/t/MW-313.test b/mysql-test/suite/galera/t/MW-313.test new file mode 100644 index 00000000000..d697cb2cfcd --- /dev/null +++ b/mysql-test/suite/galera/t/MW-313.test @@ -0,0 +1,50 @@ +# +# MW-313 Enforce wsrep_max_ws_rows also when binlog is enabled +# + +--source include/galera_cluster.inc +--source include/have_binlog_format_row.inc + +# No error expected for SELECT and SHOW + +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; + +SET GLOBAL wsrep_max_ws_rows = 2; + +SET AUTOCOMMIT=OFF; +START TRANSACTION; +SELECT * FROM t1 GROUP BY f1; +SELECT * FROM t1 GROUP BY f1; + +--error 0 +SELECT * FROM t1 GROUP BY f1; + +--disable_result_log +--error 0 +SHOW STATUS LIKE '%wsrep%'; +--enable_result_log + +# Error expected for DML + +--error ER_ERROR_DURING_COMMIT +INSERT INTO t1 SELECT * FROM t1; + +START TRANSACTION; +INSERT INTO t1 (f1) VALUES (1); + +--error ER_ERROR_DURING_COMMIT +INSERT INTO t1 (f1) VALUES (2),(3),(4); + +ROLLBACK; +START TRANSACTION; +--error ER_ERROR_DURING_COMMIT +DELETE FROM t1; + +DROP TABLE t1; +SET GLOBAL wsrep_max_ws_rows = 0; From 64bb59fce9278e6e5c4128c636b7e0f5f3cebe16 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Tue, 14 Mar 2017 11:19:03 +0530 Subject: [PATCH 15/66] Galera MTR Tests: stability fixes * remove part of galera_var_cluster_address.test that can not be tested reliably * reduce running time for galera_gcache_recover_manytrx.test * Additional wait_conditions for GAL-401.test Signed-off-by: Sachin Setiya --- mysql-test/suite/galera/galera_2nodes.cnf | 2 +- mysql-test/suite/galera/r/GAL-401.result | 1 + .../galera/r/galera_many_tables_pk.result | 11 +++--- .../r/galera_var_cluster_address.result | 23 ------------ mysql-test/suite/galera/t/GAL-401.test | 5 +++ .../t/galera_gcache_recover_manytrx.cnf | 1 + .../suite/galera/t/galera_many_tables_pk.test | 21 ++++++----- .../galera/t/galera_var_cluster_address.test | 36 ------------------- 8 files changed, 26 insertions(+), 74 deletions(-) diff --git a/mysql-test/suite/galera/galera_2nodes.cnf b/mysql-test/suite/galera/galera_2nodes.cnf index 36630f718c4..0dc22ee4a81 100644 --- a/mysql-test/suite/galera/galera_2nodes.cnf +++ b/mysql-test/suite/galera/galera_2nodes.cnf @@ -8,7 +8,7 @@ default-storage-engine=innodb wsrep-provider=@ENV.WSREP_PROVIDER wsrep_node_address=127.0.0.1 wsrep_cluster_address='gcomm://' -wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S' +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;gcache.size=10M' # enforce read-committed characteristics across the cluster wsrep-causal-reads=ON diff --git a/mysql-test/suite/galera/r/GAL-401.result b/mysql-test/suite/galera/r/GAL-401.result index e1da2b4cf1a..4de13cf142b 100644 --- a/mysql-test/suite/galera/r/GAL-401.result +++ b/mysql-test/suite/galera/r/GAL-401.result @@ -9,6 +9,7 @@ SHOW STATUS LIKE 'wsrep_desync_count'; Variable_name Value wsrep_desync_count 0 SET @@global.wsrep_desync = 0; +SET SESSION wsrep_sync_wait=7; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/suite/galera/r/galera_many_tables_pk.result b/mysql-test/suite/galera/r/galera_many_tables_pk.result index 6b6899d979d..37474797d74 100644 --- a/mysql-test/suite/galera/r/galera_many_tables_pk.result +++ b/mysql-test/suite/galera/r/galera_many_tables_pk.result @@ -1,20 +1,21 @@ -SELECT COUNT(*) = 1000 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME LIKE 't%'; -COUNT(*) = 1000 +SELECT COUNT(*) = 100 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME LIKE 't%'; +COUNT(*) = 100 1 SET AUTOCOMMIT=OFF; START TRANSACTION; COMMIT; CREATE TABLE sum_table (f1 INTEGER); -SELECT SUM(f1) = 1000 FROM sum_table; -SUM(f1) = 1000 +SELECT SUM(f1) = 100 FROM sum_table; +SUM(f1) = 100 1 SET AUTOCOMMIT=OFF; START TRANSACTION; SET AUTOCOMMIT=OFF; START TRANSACTION; -UPDATE t1000 SET f1 = 3; +UPDATE t100 SET f1 = 3; COMMIT; COMMIT; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +include/diff_servers.inc [servers=1 2] DROP SCHEMA test; CREATE SCHEMA test; diff --git a/mysql-test/suite/galera/r/galera_var_cluster_address.result b/mysql-test/suite/galera/r/galera_var_cluster_address.result index bb3ea8e3a53..17b5a7bca37 100644 --- a/mysql-test/suite/galera/r/galera_var_cluster_address.result +++ b/mysql-test/suite/galera/r/galera_var_cluster_address.result @@ -26,28 +26,6 @@ VARIABLE_VALUE = 'Primary' SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 2 1 -SET GLOBAL wsrep_cluster_address = 'gcomm://192.0.2.1'; -SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS; -COUNT(*) > 0 -1 -SHOW STATUS LIKE 'wsrep_ready'; -Variable_name Value -wsrep_ready ON -SHOW STATUS LIKE 'wsrep_cluster_status'; -Variable_name Value -wsrep_cluster_status Primary -SHOW STATUS LIKE 'wsrep_local_state'; -Variable_name Value -wsrep_local_state 4 -SHOW STATUS LIKE 'wsrep_local_state_comment'; -Variable_name Value -wsrep_local_state_comment Synced -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -VARIABLE_VALUE = 'Primary' -1 -SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; -VARIABLE_VALUE = 2 -1 CALL mtr.add_suppression("Backend not supported: foo"); CALL mtr.add_suppression("Failed to initialize backend using 'foo"); CALL mtr.add_suppression("Failed to open channel 'my_wsrep_cluster' at 'foo"); @@ -58,5 +36,4 @@ CALL mtr.add_suppression("failed to open gcomm backend connection: 110: failed t CALL mtr.add_suppression("Failed to open backend connection: -110 \\(Connection timed out\\)"); CALL mtr.add_suppression("gcs connect failed: Connection timed out"); CALL mtr.add_suppression("WSREP: wsrep::connect\\(foo://\\) failed: 7"); -CALL mtr.add_suppression("WSREP: wsrep::connect\\(gcomm://192.0.2.1\\) failed: 7"); # End of test diff --git a/mysql-test/suite/galera/t/GAL-401.test b/mysql-test/suite/galera/t/GAL-401.test index 1f7b493717f..05295d1b977 100644 --- a/mysql-test/suite/galera/t/GAL-401.test +++ b/mysql-test/suite/galera/t/GAL-401.test @@ -38,6 +38,11 @@ SHOW STATUS LIKE 'wsrep_desync_count'; # Resync node_2, should pass: SET @@global.wsrep_desync = 0; + +--let $wait_condition = SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +--source include/wait_condition.inc + +SET SESSION wsrep_sync_wait=7; SHOW CREATE TABLE t1; DROP TABLE t1; CALL mtr.add_suppression("WSREP: Protocol violation. JOIN message sender (.*) is not in state transfer \\(SYNCED\\). Message ignored."); diff --git a/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.cnf b/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.cnf index 39af0e94b94..c08551eae84 100644 --- a/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.cnf +++ b/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.cnf @@ -5,4 +5,5 @@ innodb_log_file_size=110M wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.recover=yes;pc.ignore_sb=true;' [mysqld.2] +innodb_log_file_size=110M wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.recover=yes;pc.ignore_sb=true;' diff --git a/mysql-test/suite/galera/t/galera_many_tables_pk.test b/mysql-test/suite/galera/t/galera_many_tables_pk.test index 886cb7c1a00..72c7e08bcc3 100644 --- a/mysql-test/suite/galera/t/galera_many_tables_pk.test +++ b/mysql-test/suite/galera/t/galera_many_tables_pk.test @@ -3,16 +3,16 @@ --source include/have_innodb.inc # -# This test forces 1K tables with a PK to participate in a single transaction +# This test forces 100 tables with a PK to participate in a single transaction # # -# First, create 1K tables and make sure the DDLs are all propagated +# First, create 100 tables and make sure the DDLs are all propagated # --connection node_1 ---let $count = 1000 +--let $count = 100 while ($count) { --disable_query_log @@ -23,7 +23,7 @@ while ($count) } --connection node_2 -SELECT COUNT(*) = 1000 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME LIKE 't%'; +SELECT COUNT(*) = 100 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME LIKE 't%'; # # Second, create a transaction that uses all those tables @@ -33,7 +33,7 @@ SELECT COUNT(*) = 1000 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test SET AUTOCOMMIT=OFF; START TRANSACTION; ---let $count = 1000 +--let $count = 100 while ($count) { --disable_query_log @@ -52,7 +52,7 @@ COMMIT; --connection node_2 CREATE TABLE sum_table (f1 INTEGER); ---let $count = 1000 +--let $count = 100 while ($count) { --disable_query_log @@ -62,7 +62,7 @@ while ($count) --dec $count } -SELECT SUM(f1) = 1000 FROM sum_table; +SELECT SUM(f1) = 100 FROM sum_table; # # Fourth, create a deadlock @@ -72,7 +72,7 @@ SELECT SUM(f1) = 1000 FROM sum_table; SET AUTOCOMMIT=OFF; START TRANSACTION; ---let $count = 1000 +--let $count = 100 while ($count) { --disable_query_log @@ -85,7 +85,7 @@ while ($count) --connection node_2 SET AUTOCOMMIT=OFF; START TRANSACTION; -UPDATE t1000 SET f1 = 3; +UPDATE t100 SET f1 = 3; --connection node_1 COMMIT; @@ -94,5 +94,8 @@ COMMIT; --error ER_LOCK_DEADLOCK COMMIT; +--let $diff_servers = 1 2 +--source include/diff_servers.inc + DROP SCHEMA test; CREATE SCHEMA test; diff --git a/mysql-test/suite/galera/t/galera_var_cluster_address.test b/mysql-test/suite/galera/t/galera_var_cluster_address.test index 5328b5e7a94..984a262c7bd 100644 --- a/mysql-test/suite/galera/t/galera_var_cluster_address.test +++ b/mysql-test/suite/galera/t/galera_var_cluster_address.test @@ -58,41 +58,6 @@ SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VA SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; -# -# Set to invalid host -# - ---connection node_2 -SET GLOBAL wsrep_cluster_address = 'gcomm://192.0.2.1'; ---let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; ---source include/wait_condition.inc - ---error 0 -SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS; - -# Must return 'OFF' -SHOW STATUS LIKE 'wsrep_ready'; - -# Must return 'Non-primary' -SHOW STATUS LIKE 'wsrep_cluster_status'; - -# Must return 0 = 'Initialized' -SHOW STATUS LIKE 'wsrep_local_state'; -SHOW STATUS LIKE 'wsrep_local_state_comment'; - -# -# Reset everything as it was -# - ---connection node_2 ---disable_query_log ---eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_node2'; ---enable_query_log - ---connection node_1 -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; - --connection node_2 CALL mtr.add_suppression("Backend not supported: foo"); CALL mtr.add_suppression("Failed to initialize backend using 'foo"); @@ -104,7 +69,6 @@ CALL mtr.add_suppression("failed to open gcomm backend connection: 110: failed t CALL mtr.add_suppression("Failed to open backend connection: -110 \\(Connection timed out\\)"); CALL mtr.add_suppression("gcs connect failed: Connection timed out"); CALL mtr.add_suppression("WSREP: wsrep::connect\\(foo://\\) failed: 7"); -CALL mtr.add_suppression("WSREP: wsrep::connect\\(gcomm://192.0.2.1\\) failed: 7"); # Restore original auto_increment_offset values. --source include/auto_increment_offset_restore.inc From f78332c5818d0ba0b145bb09aa0bd4eedade7397 Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Sat, 5 Nov 2016 09:15:14 -0700 Subject: [PATCH 16/66] Galera MTR Tests: stability fix for galera#414.test --- mysql-test/suite/galera/t/galera#414.test | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysql-test/suite/galera/t/galera#414.test b/mysql-test/suite/galera/t/galera#414.test index 0ee6dcac700..dccb28e4054 100644 --- a/mysql-test/suite/galera/t/galera#414.test +++ b/mysql-test/suite/galera/t/galera#414.test @@ -24,10 +24,14 @@ SET SESSION wsrep_on = OFF; SET SESSION wsrep_on = ON; --let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --source include/wait_condition.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +--source include/wait_condition.inc --connection node_1 CALL mtr.add_suppression("Failed to set packet size"); --connection node_2 +--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +--source include/wait_condition.inc CALL mtr.add_suppression("Failed to set packet size"); From e29d7b1d0b54b2013a5d960f7714aae3b6fa8475 Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Tue, 8 Nov 2016 15:19:37 +0200 Subject: [PATCH 17/66] Bump WSREP_PATCH_VERSION to 18 --- cmake/wsrep.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake index 7d6418e71f2..d483225d4e3 100644 --- a/cmake/wsrep.cmake +++ b/cmake/wsrep.cmake @@ -18,7 +18,7 @@ # so WSREP_VERSION is produced regardless # Set the patch version -SET(WSREP_PATCH_VERSION "17") +SET(WSREP_PATCH_VERSION "18") # MariaDB addition: Revision number of the last revision merged from # codership branch visible in @@visible_comment. From c49bfff9922970104163f028e099f3814d314866 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Tue, 14 Mar 2017 11:21:16 +0530 Subject: [PATCH 18/66] Galera MTR tests: Make the mysqlhotcopy tests pass on Ubuntu 16.04 Signed-off-by: Sachin Setiya --- mysql-test/include/mysqlhotcopy.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/include/mysqlhotcopy.inc b/mysql-test/include/mysqlhotcopy.inc index f775d782b28..883f472a8b2 100644 --- a/mysql-test/include/mysqlhotcopy.inc +++ b/mysql-test/include/mysqlhotcopy.inc @@ -109,7 +109,7 @@ DROP DATABASE hotcopy_save; --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --list_files $MYSQLD_DATADIR/hotcopy_save --replace_result $MASTER_MYSOCK MASTER_MYSOCK ---error 1 +--error 9,11,110,2304,255 --exec $MYSQLHOTCOPY --quiet -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save --replace_result $MASTER_MYSOCK MASTER_MYSOCK --exec $MYSQLHOTCOPY --quiet --allowold -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save From 471dd1138185210b47f11cf6333a989861254105 Mon Sep 17 00:00:00 2001 From: sjaakola Date: Mon, 21 Nov 2016 10:38:20 +0200 Subject: [PATCH 19/66] refs: MW-319 * silenced the WSREP_ERROR, this fires for all replication filtered DDL, and is false positive --- sql/wsrep_hton.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc index 9f8c328c353..78d189fbd61 100644 --- a/sql/wsrep_hton.cc +++ b/sql/wsrep_hton.cc @@ -313,7 +313,7 @@ wsrep_run_wsrep_commit(THD *thd, handlerton *hton, bool all) int replay_round= 0; if (thd->get_stmt_da()->is_error()) { - WSREP_ERROR("commit issue, error: %d %s", + WSREP_DEBUG("commit issue, error: %d %s", thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message()); } From 0e0ae0bb06f75d8d745d35b2470e01671ddbe7a8 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Tue, 14 Mar 2017 13:13:22 +0530 Subject: [PATCH 20/66] MW-28, codership/mysql-wsrep#28 Fix sync_thread_levels debug assert Introduced a new wsrep_trx_print_locking() which may be called under lock_sys->mutex if the trx has locks. Signed-off-by: Sachin Setiya --- storage/innobase/include/trx0trx.h | 17 +++++ storage/innobase/lock/lock0lock.cc | 15 ++-- storage/innobase/trx/trx0trx.cc | 112 +++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 10 deletions(-) diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 07123cd6d86..c7e0dc5a551 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -333,6 +333,23 @@ trx_print_latched( or 0 to use the default max length */ MY_ATTRIBUTE((nonnull)); +#ifdef WITH_WSREP +/**********************************************************************//** +Prints info about a transaction. +Transaction information may be retrieved without having trx_sys->mutex acquired +so it may not be completely accurate. The caller must own lock_sys->mutex +and the trx must have some locks to make sure that it does not escape +without locking lock_sys->mutex. */ +UNIV_INTERN +void +wsrep_trx_print_locking( +/*==============*/ + FILE* f, /*!< in: output stream */ + const trx_t* trx, /*!< in: transaction */ + ulint max_query_len) /*!< in: max query length to print, + or 0 to use the default max length */ + MY_ATTRIBUTE((nonnull)); +#endif /* WITH_WSREP */ /**********************************************************************//** Prints info about a transaction. Acquires and releases lock_sys->mutex and trx_sys->mutex. */ diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index c44aa490a81..c1f5d71e1b6 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1704,16 +1704,14 @@ wsrep_kill_victim( is in the queue*/ } else if (lock->trx != trx) { if (wsrep_log_conflicts) { - mutex_enter(&trx_sys->mutex); - if (bf_this) { - fputs("\n*** Priority TRANSACTION:\n", + if (bf_this) + fputs("\n*** Priority TRANSACTION:\n", stderr); - } else { + else { fputs("\n*** Victim TRANSACTION:\n", stderr); } - - trx_print_latched(stderr, trx, 3000); + wsrep_trx_print_locking(stderr, trx, 3000); if (bf_other) { fputs("\n*** Priority TRANSACTION:\n", @@ -1722,10 +1720,7 @@ wsrep_kill_victim( fputs("\n*** Victim TRANSACTION:\n", stderr); } - - trx_print_latched(stderr, lock->trx, 3000); - - mutex_exit(&trx_sys->mutex); + wsrep_trx_print_locking(stderr, lock->trx, 3000); fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n", stderr); diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index de3afcdd8b0..3b39f685e6d 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1876,6 +1876,118 @@ trx_print_latched( mem_heap_get_size(trx->lock.lock_heap)); } +#ifdef WITH_WSREP +/**********************************************************************//** +Prints info about a transaction. +Transaction information may be retrieved without having trx_sys->mutex acquired +so it may not be completely accurate. The caller must own lock_sys->mutex +and the trx must have some locks to make sure that it does not escape +without locking lock_sys->mutex. */ +UNIV_INTERN +void +wsrep_trx_print_locking( +/*==========*/ + FILE* f, + /*!< in: output stream */ + const trx_t* trx, + /*!< in: transaction */ + ulint max_query_len) + /*!< in: max query length to print, + or 0 to use the default max length */ +{ + ibool newline; + const char* op_info; + + ut_ad(lock_mutex_own()); + ut_ad(trx->lock.trx_locks.count > 0); + + fprintf(f, "TRANSACTION " TRX_ID_FMT, trx->id); + + /* trx->state may change since trx_sys->mutex is not required */ + switch (trx->state) { + case TRX_STATE_NOT_STARTED: + fputs(", not started", f); + goto state_ok; + case TRX_STATE_ACTIVE: + fprintf(f, ", ACTIVE %lu sec", + (ulong) difftime(time(NULL), trx->start_time)); + goto state_ok; + case TRX_STATE_PREPARED: + fprintf(f, ", ACTIVE (PREPARED) %lu sec", + (ulong) difftime(time(NULL), trx->start_time)); + goto state_ok; + case TRX_STATE_COMMITTED_IN_MEMORY: + fputs(", COMMITTED IN MEMORY", f); + goto state_ok; + } + fprintf(f, ", state %lu", (ulong) trx->state); + ut_ad(0); +state_ok: + + /* prevent a race condition */ + op_info = trx->op_info; + + if (*op_info) { + putc(' ', f); + fputs(op_info, f); + } + + if (trx->is_recovered) { + fputs(" recovered trx", f); + } + + if (trx->declared_to_be_inside_innodb) { + fprintf(f, ", thread declared inside InnoDB %lu", + (ulong) trx->n_tickets_to_enter_innodb); + } + + putc('\n', f); + + if (trx->n_mysql_tables_in_use > 0 || trx->mysql_n_tables_locked > 0) { + fprintf(f, "mysql tables in use %lu, locked %lu\n", + (ulong) trx->n_mysql_tables_in_use, + (ulong) trx->mysql_n_tables_locked); + } + + newline = TRUE; + + /* trx->lock.que_state of an ACTIVE transaction may change + while we are not holding trx->mutex. We perform a dirty read + for performance reasons. */ + + switch (trx->lock.que_state) { + case TRX_QUE_RUNNING: + newline = FALSE; break; + case TRX_QUE_LOCK_WAIT: + fputs("LOCK WAIT ", f); break; + case TRX_QUE_ROLLING_BACK: + fputs("ROLLING BACK ", f); break; + case TRX_QUE_COMMITTING: + fputs("COMMITTING ", f); break; + default: + fprintf(f, "que state %lu ", (ulong) trx->lock.que_state); + } + + if (trx->has_search_latch) { + newline = TRUE; + fputs(", holds adaptive hash latch", f); + } + + if (trx->undo_no != 0) { + newline = TRUE; + fprintf(f, ", undo log entries " TRX_ID_FMT, trx->undo_no); + } + + if (newline) { + putc('\n', f); + } + + if (trx->mysql_thd != NULL) { + innobase_mysql_print_thd( + f, trx->mysql_thd, static_cast(max_query_len)); + } +} +#endif /* WITH_WSREP */ /**********************************************************************//** Prints info about a transaction. Acquires and releases lock_sys->mutex and trx_sys->mutex. */ From 6fabf12ba0c13c023451a8f4d9d0de95f44d38aa Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Wed, 23 Nov 2016 02:55:36 -0800 Subject: [PATCH 21/66] Galera MTR Test: Test for MW-28 : Assertion with --wsrep-log-conflicts --- .../galera/r/galera_wsrep_log_conficts.result | 18 ++++++ .../t/galera_wsrep_log_conficts-master.opt | 1 + .../galera/t/galera_wsrep_log_conficts.test | 55 +++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 mysql-test/suite/galera/r/galera_wsrep_log_conficts.result create mode 100644 mysql-test/suite/galera/t/galera_wsrep_log_conficts-master.opt create mode 100644 mysql-test/suite/galera/t/galera_wsrep_log_conficts.test diff --git a/mysql-test/suite/galera/r/galera_wsrep_log_conficts.result b/mysql-test/suite/galera/r/galera_wsrep_log_conficts.result new file mode 100644 index 00000000000..b535c6477b7 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_wsrep_log_conficts.result @@ -0,0 +1,18 @@ +CREATE TABLE t1 ( +f1 VARCHAR(255) PRIMARY KEY +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO t1 VALUES ('abc'); +SELECT f1 = 'abc' FROM t1; +f1 = 'abc' +1 +SET AUTOCOMMIT=OFF; +START TRANSACTION; +UPDATE t1 SET f1 = 'klm'; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +UPDATE t1 SET f1 = 'xyz'; +COMMIT; +COMMIT; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +include/assert_grep.inc [cluster conflict due to high priority abort for threads] +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_wsrep_log_conficts-master.opt b/mysql-test/suite/galera/t/galera_wsrep_log_conficts-master.opt new file mode 100644 index 00000000000..930c483bd64 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_wsrep_log_conficts-master.opt @@ -0,0 +1 @@ +--wsrep_log_conflicts=ON diff --git a/mysql-test/suite/galera/t/galera_wsrep_log_conficts.test b/mysql-test/suite/galera/t/galera_wsrep_log_conficts.test new file mode 100644 index 00000000000..3af08cbf637 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_wsrep_log_conficts.test @@ -0,0 +1,55 @@ +# +# Test --wsrep_log_conflicts=ON +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc + +CREATE TABLE t1 ( + f1 VARCHAR(255) PRIMARY KEY +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO t1 VALUES ('abc'); + +--connection node_2 +SELECT f1 = 'abc' FROM t1; + +# +# Provoke a conflict +# + +--connection node_1 +SET AUTOCOMMIT=OFF; +START TRANSACTION; +UPDATE t1 SET f1 = 'klm'; + +--connection node_2 +SET AUTOCOMMIT=OFF; +START TRANSACTION; +UPDATE t1 SET f1 = 'xyz'; + +--connection node_1 +COMMIT; + +--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 +--connection node_2a +--let $wait_condition = SELECT f1 = 'klm' FROM t1; +--source include/wait_condition.inc + +--connection node_2 +--error ER_LOCK_DEADLOCK +COMMIT; + +# +# We can not really check the log output very much because it is quite variable +# + +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.2.err +--let $assert_only_after = CURRENT_TEST + +--let $assert_text = cluster conflict due to high priority abort for threads +--let $assert_select = cluster conflict due to high priority abort for threads +--let $assert_match = cluster conflict due to high priority abort for threads +--source include/assert_grep.inc + +DROP TABLE t1; From f29c40d0a5d84a23500df4bac1657dce64bd3d9a Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Tue, 14 Mar 2017 14:31:13 +0530 Subject: [PATCH 22/66] GAL-480 MTR test --- mysql-test/suite/galera/r/GAL-480.result | 39 ++++++++++++++++++++ mysql-test/suite/galera/t/GAL-480.test | 47 ++++++++++++++++++++++++ mysql-test/suite/galera/t/MW-309.test | 1 + 3 files changed, 87 insertions(+) create mode 100644 mysql-test/suite/galera/r/GAL-480.result create mode 100644 mysql-test/suite/galera/t/GAL-480.test diff --git a/mysql-test/suite/galera/r/GAL-480.result b/mysql-test/suite/galera/r/GAL-480.result new file mode 100644 index 00000000000..b762e07423e --- /dev/null +++ b/mysql-test/suite/galera/r/GAL-480.result @@ -0,0 +1,39 @@ +CREATE TABLE t1 (f1 CHAR(10), f0 integer) ENGINE=InnoDB; +FLUSH TABLE t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE t1 DROP COLUMN f1; +SET SESSION wsrep_osu_method='RSU'; +ALTER TABLE t1 ADD COLUMN f1 CHAR(10); +ALTER TABLE t1 DROP COLUMN f1; +ALTER TABLE t1 ADD COLUMN f2 CHAR(10); +ALTER TABLE t1 DROP COLUMN f2; +ALTER TABLE t1 ADD COLUMN f3 CHAR(10); +ALTER TABLE t1 DROP COLUMN f3; +ALTER TABLE t1 ADD COLUMN f4 CHAR(10); +ALTER TABLE t1 DROP COLUMN f4; +ALTER TABLE t1 ADD COLUMN f5 CHAR(10); +ALTER TABLE t1 DROP COLUMN f5; +ALTER TABLE t1 ADD COLUMN f6 CHAR(10); +ALTER TABLE t1 DROP COLUMN f6; +ALTER TABLE t1 ADD COLUMN f7 CHAR(10); +ALTER TABLE t1 DROP COLUMN f7; +ALTER TABLE t1 ADD COLUMN f8 CHAR(10); +ALTER TABLE t1 DROP COLUMN f8; +ALTER TABLE t1 ADD COLUMN f9 CHAR(10); +ALTER TABLE t1 DROP COLUMN f9; +ALTER TABLE t1 ADD COLUMN f10 CHAR(10); +ALTER TABLE t1 DROP COLUMN f10; +ALTER TABLE t1 ADD COLUMN f11 CHAR(10); +ALTER TABLE t1 DROP COLUMN f11; +ALTER TABLE t1 ADD COLUMN f12 CHAR(10); +ALTER TABLE t1 DROP COLUMN f12; +ALTER TABLE t1 ADD COLUMN f13 CHAR(10); +ALTER TABLE t1 DROP COLUMN f13; +ALTER TABLE t1 ADD COLUMN f14 CHAR(10); +ALTER TABLE t1 DROP COLUMN f14; +ALTER TABLE t1 ADD COLUMN f15 CHAR(10); +ALTER TABLE t1 DROP COLUMN f15; +ALTER TABLE t1 ADD COLUMN f16 CHAR(10); +ALTER TABLE t1 DROP COLUMN f16; +SET SESSION wsrep_osu_method='TOI'; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/GAL-480.test b/mysql-test/suite/galera/t/GAL-480.test new file mode 100644 index 00000000000..142772fd8f9 --- /dev/null +++ b/mysql-test/suite/galera/t/GAL-480.test @@ -0,0 +1,47 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--connection node_1 +CREATE TABLE t1 (f1 CHAR(10), f0 integer) ENGINE=InnoDB; + +FLUSH TABLE t1 FOR EXPORT; +UNLOCK TABLES; + +ALTER TABLE t1 DROP COLUMN f1; + +SET SESSION wsrep_osu_method='RSU'; +ALTER TABLE t1 ADD COLUMN f1 CHAR(10); +ALTER TABLE t1 DROP COLUMN f1; +ALTER TABLE t1 ADD COLUMN f2 CHAR(10); +ALTER TABLE t1 DROP COLUMN f2; +ALTER TABLE t1 ADD COLUMN f3 CHAR(10); +ALTER TABLE t1 DROP COLUMN f3; +ALTER TABLE t1 ADD COLUMN f4 CHAR(10); +ALTER TABLE t1 DROP COLUMN f4; +ALTER TABLE t1 ADD COLUMN f5 CHAR(10); +ALTER TABLE t1 DROP COLUMN f5; +ALTER TABLE t1 ADD COLUMN f6 CHAR(10); +ALTER TABLE t1 DROP COLUMN f6; +ALTER TABLE t1 ADD COLUMN f7 CHAR(10); +ALTER TABLE t1 DROP COLUMN f7; +ALTER TABLE t1 ADD COLUMN f8 CHAR(10); +ALTER TABLE t1 DROP COLUMN f8; +ALTER TABLE t1 ADD COLUMN f9 CHAR(10); +ALTER TABLE t1 DROP COLUMN f9; +ALTER TABLE t1 ADD COLUMN f10 CHAR(10); +ALTER TABLE t1 DROP COLUMN f10; +ALTER TABLE t1 ADD COLUMN f11 CHAR(10); +ALTER TABLE t1 DROP COLUMN f11; +ALTER TABLE t1 ADD COLUMN f12 CHAR(10); +ALTER TABLE t1 DROP COLUMN f12; +ALTER TABLE t1 ADD COLUMN f13 CHAR(10); +ALTER TABLE t1 DROP COLUMN f13; +ALTER TABLE t1 ADD COLUMN f14 CHAR(10); +ALTER TABLE t1 DROP COLUMN f14; +ALTER TABLE t1 ADD COLUMN f15 CHAR(10); +ALTER TABLE t1 DROP COLUMN f15; +ALTER TABLE t1 ADD COLUMN f16 CHAR(10); +ALTER TABLE t1 DROP COLUMN f16; + +SET SESSION wsrep_osu_method='TOI'; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/MW-309.test b/mysql-test/suite/galera/t/MW-309.test index d4939f2745f..351a508ecec 100644 --- a/mysql-test/suite/galera/t/MW-309.test +++ b/mysql-test/suite/galera/t/MW-309.test @@ -3,6 +3,7 @@ # --source include/galera_cluster.inc +--source include/have_innodb.inc CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); From 00f1ed6655b51b8cb496a452471c76b16d50e8e7 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Tue, 14 Mar 2017 14:42:52 +0530 Subject: [PATCH 23/66] Galera MTR Tests: fix variable output in galera_as_slave_gtid_replicate_do_db.result Signed-off-by: Sachin Setiya --- sql/sql_class.h | 1 + sql/wsrep_thd.cc | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/sql/sql_class.h b/sql/sql_class.h index 56ae659797c..aed75d94972 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -69,6 +69,7 @@ struct wsrep_thd_shadow { char *db; size_t db_length; my_hrtime_t user_time; + longlong row_count_func; }; #endif class Reprepare_observer; diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index 5e530e84d43..307745ff1b0 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -164,6 +164,7 @@ static void wsrep_prepare_bf_thd(THD *thd, struct wsrep_thd_shadow* shadow) shadow->db = thd->db; shadow->db_length = thd->db_length; shadow->user_time = thd->user_time; + shadow->row_count_func= thd->get_row_count_func(); thd->reset_db(NULL, 0); } @@ -184,6 +185,7 @@ static void wsrep_return_from_bf_mode(THD *thd, struct wsrep_thd_shadow* shadow) thd->wsrep_rgi->cleanup_after_session(); delete thd->wsrep_rgi; thd->wsrep_rgi = NULL; + thd->set_row_count_func(shadow->row_count_func); } void wsrep_replay_transaction(THD *thd) @@ -198,12 +200,31 @@ void wsrep_replay_transaction(THD *thd) WSREP_ERROR("replay issue, thd has reported status already"); } + /* PS reprepare observer should have been removed already. open_table() will fail if we have dangling observer here. */ DBUG_ASSERT(thd->m_reprepare_observer == NULL); + struct da_shadow + { + enum Diagnostics_area::enum_diagnostics_status status; + ulonglong affected_rows; + ulonglong last_insert_id; + char message[MYSQL_ERRMSG_SIZE]; + }; + struct da_shadow da_status; + da_status.status= thd->get_stmt_da()->status(); + if (da_status.status == Diagnostics_area::DA_OK) + { + da_status.affected_rows= thd->get_stmt_da()->affected_rows(); + da_status.last_insert_id= thd->get_stmt_da()->last_insert_id(); + strmake(da_status.message, + thd->get_stmt_da()->message(), + sizeof(da_status.message)-1); + } + thd->get_stmt_da()->reset_diagnostics_area(); thd->wsrep_conflict_state= REPLAYING; @@ -270,7 +291,17 @@ void wsrep_replay_transaction(THD *thd) } else { - my_ok(thd); + if (da_status.status == Diagnostics_area::DA_OK) + { + my_ok(thd, + da_status.affected_rows, + da_status.last_insert_id, + da_status.message); + } + else + { + my_ok(thd); + } } break; case WSREP_TRX_FAIL: From 17f716062d51a1a8023c9e0ea2a483d651555fce Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Thu, 8 Dec 2016 00:17:28 -0800 Subject: [PATCH 24/66] Galera MTR Tests: Test for MW-329 Fix incorrect affected rows count after replay --- mysql-test/suite/galera/r/MW-329.result | 80 +++++++++++++++++++++++++ mysql-test/suite/galera/t/MW-329.test | 61 +++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 mysql-test/suite/galera/r/MW-329.result create mode 100644 mysql-test/suite/galera/t/MW-329.test diff --git a/mysql-test/suite/galera/r/MW-329.result b/mysql-test/suite/galera/r/MW-329.result new file mode 100644 index 00000000000..c782bf38f48 --- /dev/null +++ b/mysql-test/suite/galera/r/MW-329.result @@ -0,0 +1,80 @@ +CREATE TABLE t1 (f1 INTEGER, f2 CHAR(20) DEFAULT 'abc') ENGINE=InnoDB; +INSERT INTO t1 (f1) VALUES (1),(65535); +FLUSH STATUS; +SELECT VARIABLE_VALUE = 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'; +VARIABLE_VALUE = 0 +1 +CREATE PROCEDURE proc_insert () +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +SET SESSION wsrep_sync_wait = 0; +WHILE 1 DO +INSERT INTO t1 (f1) VALUES (FLOOR( 1 + RAND( ) * 65535 )); +END WHILE; +END| +CALL proc_insert();; +SELECT ROW_COUNT() > 0; +ROW_COUNT() > 0 +1 +SELECT FOUND_ROWS() > 0; +FOUND_ROWS() > 0 +1 +SELECT ROW_COUNT() > 0; +ROW_COUNT() > 0 +1 +SELECT FOUND_ROWS() > 0; +FOUND_ROWS() > 0 +1 +SELECT ROW_COUNT() > 0; +ROW_COUNT() > 0 +1 +SELECT FOUND_ROWS() > 0; +FOUND_ROWS() > 0 +1 +SELECT ROW_COUNT() > 0; +ROW_COUNT() > 0 +1 +SELECT FOUND_ROWS() > 0; +FOUND_ROWS() > 0 +1 +SELECT ROW_COUNT() > 0; +ROW_COUNT() > 0 +1 +SELECT FOUND_ROWS() > 0; +FOUND_ROWS() > 0 +1 +SELECT ROW_COUNT() > 0; +ROW_COUNT() > 0 +1 +SELECT FOUND_ROWS() > 0; +FOUND_ROWS() > 0 +1 +SELECT ROW_COUNT() > 0; +ROW_COUNT() > 0 +1 +SELECT FOUND_ROWS() > 0; +FOUND_ROWS() > 0 +1 +SELECT ROW_COUNT() > 0; +ROW_COUNT() > 0 +1 +SELECT FOUND_ROWS() > 0; +FOUND_ROWS() > 0 +1 +SELECT ROW_COUNT() > 0; +ROW_COUNT() > 0 +1 +SELECT FOUND_ROWS() > 0; +FOUND_ROWS() > 0 +1 +SELECT ROW_COUNT() > 0; +ROW_COUNT() > 0 +1 +SELECT FOUND_ROWS() > 0; +FOUND_ROWS() > 0 +1 +SELECT VARIABLE_VALUE > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'; +VARIABLE_VALUE > 0 +1 +DROP PROCEDURE proc_insert; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/MW-329.test b/mysql-test/suite/galera/t/MW-329.test new file mode 100644 index 00000000000..d22eb4d6a79 --- /dev/null +++ b/mysql-test/suite/galera/t/MW-329.test @@ -0,0 +1,61 @@ +# +# #MW-329 Fix incorrect affected rows count after replay +# + +--source include/galera_cluster.inc + +CREATE TABLE t1 (f1 INTEGER, f2 CHAR(20) DEFAULT 'abc') ENGINE=InnoDB; + +# We start with a populated table +INSERT INTO t1 (f1) VALUES (1),(65535); + +# Clear the wsrep_local_replays counter + +FLUSH STATUS; +SELECT VARIABLE_VALUE = 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'; + +# +# Run concurrent INSERTs +# + +DELIMITER |; +CREATE PROCEDURE proc_insert () +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + SET SESSION wsrep_sync_wait = 0; + WHILE 1 DO + INSERT INTO t1 (f1) VALUES (FLOOR( 1 + RAND( ) * 65535 )); + END WHILE; +END| +DELIMITER ;| + +--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1b +--send CALL proc_insert(); + +# +# Run concurrent UPDATEs. We expect that each UPDATE will report that +# some rows were matched and updated +# + +--connection node_2 +--let $count = 10 +while ($count) +{ + --let $signature = `SELECT LEFT(MD5(RAND()), 10)` + --disable_query_log + --eval UPDATE t1 SET f2 = '$signature' + --enable_query_log + SELECT ROW_COUNT() > 0; + SELECT FOUND_ROWS() > 0; + --dec $count +} + +# +# Confirm that some transaction replays occurred +# + +SELECT VARIABLE_VALUE > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'; + +DROP PROCEDURE proc_insert; +DROP TABLE t1; From 5ac0d5fc24d6d7bfc8c8f634749b303072edf7d9 Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Thu, 8 Dec 2016 05:15:31 -0800 Subject: [PATCH 25/66] Galera MTR Tests: Stability fix for MW-329 --- mysql-test/suite/galera/r/MW-329.result | 60 --------------------- mysql-test/suite/galera/t/MW-329-master.opt | 1 + mysql-test/suite/galera/t/MW-329.test | 24 ++++++++- 3 files changed, 23 insertions(+), 62 deletions(-) create mode 100644 mysql-test/suite/galera/t/MW-329-master.opt diff --git a/mysql-test/suite/galera/r/MW-329.result b/mysql-test/suite/galera/r/MW-329.result index c782bf38f48..655d8e9e291 100644 --- a/mysql-test/suite/galera/r/MW-329.result +++ b/mysql-test/suite/galera/r/MW-329.result @@ -13,66 +13,6 @@ INSERT INTO t1 (f1) VALUES (FLOOR( 1 + RAND( ) * 65535 )); END WHILE; END| CALL proc_insert();; -SELECT ROW_COUNT() > 0; -ROW_COUNT() > 0 -1 -SELECT FOUND_ROWS() > 0; -FOUND_ROWS() > 0 -1 -SELECT ROW_COUNT() > 0; -ROW_COUNT() > 0 -1 -SELECT FOUND_ROWS() > 0; -FOUND_ROWS() > 0 -1 -SELECT ROW_COUNT() > 0; -ROW_COUNT() > 0 -1 -SELECT FOUND_ROWS() > 0; -FOUND_ROWS() > 0 -1 -SELECT ROW_COUNT() > 0; -ROW_COUNT() > 0 -1 -SELECT FOUND_ROWS() > 0; -FOUND_ROWS() > 0 -1 -SELECT ROW_COUNT() > 0; -ROW_COUNT() > 0 -1 -SELECT FOUND_ROWS() > 0; -FOUND_ROWS() > 0 -1 -SELECT ROW_COUNT() > 0; -ROW_COUNT() > 0 -1 -SELECT FOUND_ROWS() > 0; -FOUND_ROWS() > 0 -1 -SELECT ROW_COUNT() > 0; -ROW_COUNT() > 0 -1 -SELECT FOUND_ROWS() > 0; -FOUND_ROWS() > 0 -1 -SELECT ROW_COUNT() > 0; -ROW_COUNT() > 0 -1 -SELECT FOUND_ROWS() > 0; -FOUND_ROWS() > 0 -1 -SELECT ROW_COUNT() > 0; -ROW_COUNT() > 0 -1 -SELECT FOUND_ROWS() > 0; -FOUND_ROWS() > 0 -1 -SELECT ROW_COUNT() > 0; -ROW_COUNT() > 0 -1 -SELECT FOUND_ROWS() > 0; -FOUND_ROWS() > 0 -1 SELECT VARIABLE_VALUE > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'; VARIABLE_VALUE > 0 1 diff --git a/mysql-test/suite/galera/t/MW-329-master.opt b/mysql-test/suite/galera/t/MW-329-master.opt new file mode 100644 index 00000000000..6565a6af3c4 --- /dev/null +++ b/mysql-test/suite/galera/t/MW-329-master.opt @@ -0,0 +1 @@ +--wsrep-retry-autocommit=0 diff --git a/mysql-test/suite/galera/t/MW-329.test b/mysql-test/suite/galera/t/MW-329.test index d22eb4d6a79..445f8795dff 100644 --- a/mysql-test/suite/galera/t/MW-329.test +++ b/mysql-test/suite/galera/t/MW-329.test @@ -31,6 +31,7 @@ DELIMITER ;| --connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1 --connection node_1b +--let $connection_id = `SELECT CONNECTION_ID()` --send CALL proc_insert(); # @@ -44,10 +45,15 @@ while ($count) { --let $signature = `SELECT LEFT(MD5(RAND()), 10)` --disable_query_log + --error 0,ER_LOCK_DEADLOCK --eval UPDATE t1 SET f2 = '$signature' --enable_query_log - SELECT ROW_COUNT() > 0; - SELECT FOUND_ROWS() > 0; + --let $row_count = `SELECT ROW_COUNT()` + if (`SELECT @@error_count = 0`) { + if (`SELECT $row_count = 0`) { + --die ROW_COUNT() = 0 + } + } --dec $count } @@ -57,5 +63,19 @@ while ($count) SELECT VARIABLE_VALUE > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'; +# +# Terminate the stored procedure +# + +--connection node_1 +--disable_query_log +--eval KILL CONNECTION $connection_id +--enable_query_log + +--connection node_1b +--error 0,2013,1317 +--reap + +--connection node_1 DROP PROCEDURE proc_insert; DROP TABLE t1; From dd2f023427a7125dda307d6e5ca5ec42c6fd741b Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Thu, 15 Dec 2016 01:22:44 -0800 Subject: [PATCH 26/66] Galera MTR Tests: restore galera_autoinc_sst_xtrabackup.test to use xtrabackup SST --- mysql-test/suite/galera/t/galera_autoinc_sst_xtrabackup.cnf | 5 ++--- mysql-test/suite/galera/t/galera_autoinc_sst_xtrabackup.test | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/galera/t/galera_autoinc_sst_xtrabackup.cnf b/mysql-test/suite/galera/t/galera_autoinc_sst_xtrabackup.cnf index 7d684cef67d..b4bf5f02171 100644 --- a/mysql-test/suite/galera/t/galera_autoinc_sst_xtrabackup.cnf +++ b/mysql-test/suite/galera/t/galera_autoinc_sst_xtrabackup.cnf @@ -1,9 +1,8 @@ !include ../galera_2nodes.cnf [mysqld] -#wsrep_sst_method=xtrabackup-v2 -#wsrep_sst_auth="root:" -#wsrep_debug=ON +wsrep_sst_method=xtrabackup-v2 +wsrep_sst_auth="root:" [mysqld.1] wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' diff --git a/mysql-test/suite/galera/t/galera_autoinc_sst_xtrabackup.test b/mysql-test/suite/galera/t/galera_autoinc_sst_xtrabackup.test index 251450f7099..30ce9bc4ceb 100644 --- a/mysql-test/suite/galera/t/galera_autoinc_sst_xtrabackup.test +++ b/mysql-test/suite/galera/t/galera_autoinc_sst_xtrabackup.test @@ -1,6 +1,6 @@ # # Test that autoincrement works correctly while the cluster membership -# is changing and IST takes place. +# is changing and SST takes place. # --source include/big_test.inc From 69b5bd7ae3ac8e4f3021fc28e01aa3aaa1b0e3bd Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Fri, 16 Dec 2016 02:30:09 -0800 Subject: [PATCH 27/66] Galera MTR Tests: Tests for MW-328 Fix unnecessary/silent BF aborts --- mysql-test/suite/galera/r/MW-328A.result | 21 ++++++++ mysql-test/suite/galera/r/MW-328B.result | 17 +++++++ mysql-test/suite/galera/r/MW-328C.result | 17 +++++++ mysql-test/suite/galera/r/MW-328D.result | 15 ++++++ mysql-test/suite/galera/r/MW-328E.result | 15 ++++++ mysql-test/suite/galera/t/MW-328-footer.inc | 18 +++++++ mysql-test/suite/galera/t/MW-328-header.inc | 29 +++++++++++ mysql-test/suite/galera/t/MW-328A.test | 55 +++++++++++++++++++++ mysql-test/suite/galera/t/MW-328B.test | 35 +++++++++++++ mysql-test/suite/galera/t/MW-328C.test | 35 +++++++++++++ mysql-test/suite/galera/t/MW-328D.test | 39 +++++++++++++++ mysql-test/suite/galera/t/MW-328E.test | 40 +++++++++++++++ 12 files changed, 336 insertions(+) create mode 100644 mysql-test/suite/galera/r/MW-328A.result create mode 100644 mysql-test/suite/galera/r/MW-328B.result create mode 100644 mysql-test/suite/galera/r/MW-328C.result create mode 100644 mysql-test/suite/galera/r/MW-328D.result create mode 100644 mysql-test/suite/galera/r/MW-328E.result create mode 100644 mysql-test/suite/galera/t/MW-328-footer.inc create mode 100644 mysql-test/suite/galera/t/MW-328-header.inc create mode 100644 mysql-test/suite/galera/t/MW-328A.test create mode 100644 mysql-test/suite/galera/t/MW-328B.test create mode 100644 mysql-test/suite/galera/t/MW-328C.test create mode 100644 mysql-test/suite/galera/t/MW-328D.test create mode 100644 mysql-test/suite/galera/t/MW-328E.test diff --git a/mysql-test/suite/galera/r/MW-328A.result b/mysql-test/suite/galera/r/MW-328A.result new file mode 100644 index 00000000000..daed2469f11 --- /dev/null +++ b/mysql-test/suite/galera/r/MW-328A.result @@ -0,0 +1,21 @@ +CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT PRIMARY KEY, f2 CHAR(20) DEFAULT 'abc') ENGINE=InnoDB; +INSERT INTO t1 (f1) VALUES (1); +CREATE TABLE t2 (f1 CHAR(20)) ENGINE=InnoDB; +CREATE PROCEDURE proc_update () +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +SET SESSION wsrep_sync_wait = 0; +WHILE 1 DO +UPDATE t1 SET f2 = LEFT(MD5(RAND()), 4); +END WHILE; +END| +CALL proc_update();; +SET SESSION wsrep_retry_autocommit = 0; +have_successes +1 +have_deadlocks +1 +Got one of the listed errors +DROP PROCEDURE proc_update; +DROP TABLE t1, t2; +CALL mtr.add_suppression("conflict state 3 after post commit"); diff --git a/mysql-test/suite/galera/r/MW-328B.result b/mysql-test/suite/galera/r/MW-328B.result new file mode 100644 index 00000000000..780988938f6 --- /dev/null +++ b/mysql-test/suite/galera/r/MW-328B.result @@ -0,0 +1,17 @@ +CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT PRIMARY KEY, f2 CHAR(20) DEFAULT 'abc') ENGINE=InnoDB; +INSERT INTO t1 (f1) VALUES (1); +CREATE TABLE t2 (f1 CHAR(20)) ENGINE=InnoDB; +CREATE PROCEDURE proc_update () +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +SET SESSION wsrep_sync_wait = 0; +WHILE 1 DO +UPDATE t1 SET f2 = LEFT(MD5(RAND()), 4); +END WHILE; +END| +CALL proc_update();; +SET SESSION wsrep_retry_autocommit = 0; +Got one of the listed errors +DROP PROCEDURE proc_update; +DROP TABLE t1, t2; +CALL mtr.add_suppression("conflict state 3 after post commit"); diff --git a/mysql-test/suite/galera/r/MW-328C.result b/mysql-test/suite/galera/r/MW-328C.result new file mode 100644 index 00000000000..5cd74f05171 --- /dev/null +++ b/mysql-test/suite/galera/r/MW-328C.result @@ -0,0 +1,17 @@ +CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT PRIMARY KEY, f2 CHAR(20) DEFAULT 'abc') ENGINE=InnoDB; +INSERT INTO t1 (f1) VALUES (1); +CREATE TABLE t2 (f1 CHAR(20)) ENGINE=InnoDB; +CREATE PROCEDURE proc_update () +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +SET SESSION wsrep_sync_wait = 0; +WHILE 1 DO +UPDATE t1 SET f2 = LEFT(MD5(RAND()), 4); +END WHILE; +END| +CALL proc_update();; +SET SESSION wsrep_retry_autocommit = 10000; +Got one of the listed errors +DROP PROCEDURE proc_update; +DROP TABLE t1, t2; +CALL mtr.add_suppression("conflict state 3 after post commit"); diff --git a/mysql-test/suite/galera/r/MW-328D.result b/mysql-test/suite/galera/r/MW-328D.result new file mode 100644 index 00000000000..f6d055def93 --- /dev/null +++ b/mysql-test/suite/galera/r/MW-328D.result @@ -0,0 +1,15 @@ +CREATE TABLE t1 (i INT) ENGINE = InnoDB; +INSERT INTO t1 (i) VALUES(1); +CREATE TABLE t2 (i INT) ENGINE = InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +SELECT * FROM t1 WHERE i = 1 LOCK IN SHARE MODE; +i +1 +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT IGNORE INTO t2 SELECT * FROM t1 WHERE i = 1 FOR UPDATE;; +DELETE FROM t1 WHERE i = 1; +COMMIT; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +DROP TABLE t1, t2; diff --git a/mysql-test/suite/galera/r/MW-328E.result b/mysql-test/suite/galera/r/MW-328E.result new file mode 100644 index 00000000000..5829559fa4d --- /dev/null +++ b/mysql-test/suite/galera/r/MW-328E.result @@ -0,0 +1,15 @@ +create table t1 (i int primary key, j int) engine=innodb; +create table t2 (i int primary key, j int) engine=innodb; +insert into t1 values (1,0); +insert into t2 values (2,0); +set autocommit=off; +start transaction; +update t1 set j=1 where i=1; +set autocommit=off; +start transaction; +begin; +update t2 set j=1 where i=2; +insert into t1 select * from t2;; +insert into t2 select * from t1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +DROP TABLE t1, t2; diff --git a/mysql-test/suite/galera/t/MW-328-footer.inc b/mysql-test/suite/galera/t/MW-328-footer.inc new file mode 100644 index 00000000000..5b736df220f --- /dev/null +++ b/mysql-test/suite/galera/t/MW-328-footer.inc @@ -0,0 +1,18 @@ +# +# Cleanup for MW-328 tests +# + +--connection node_1 +--disable_query_log +--eval KILL CONNECTION $sp_connection_id +--enable_query_log + +--connection node_1X +--error 2013,1317 +--reap + +--connection node_1 +DROP PROCEDURE proc_update; +DROP TABLE t1, t2; + +CALL mtr.add_suppression("conflict state 3 after post commit"); diff --git a/mysql-test/suite/galera/t/MW-328-header.inc b/mysql-test/suite/galera/t/MW-328-header.inc new file mode 100644 index 00000000000..f0a6ccaccc6 --- /dev/null +++ b/mysql-test/suite/galera/t/MW-328-header.inc @@ -0,0 +1,29 @@ +# +# Initialization for MW-328 tests +# + +CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT PRIMARY KEY, f2 CHAR(20) DEFAULT 'abc') ENGINE=InnoDB; +INSERT INTO t1 (f1) VALUES (1); + +CREATE TABLE t2 (f1 CHAR(20)) ENGINE=InnoDB; + +# +# Have some random updates going on against t1 +# + +DELIMITER |; +CREATE PROCEDURE proc_update () +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + SET SESSION wsrep_sync_wait = 0; + WHILE 1 DO + UPDATE t1 SET f2 = LEFT(MD5(RAND()), 4); + END WHILE; +END| + +DELIMITER ;| + +--connect node_1X, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1X +--let $sp_connection_id = `SELECT CONNECTION_ID()` +--send CALL proc_update(); diff --git a/mysql-test/suite/galera/t/MW-328A.test b/mysql-test/suite/galera/t/MW-328A.test new file mode 100644 index 00000000000..836dd088749 --- /dev/null +++ b/mysql-test/suite/galera/t/MW-328A.test @@ -0,0 +1,55 @@ +# +# MW-328 Fix unnecessary/silent BF aborts +# + +# +# Attempt to insert into t2 and check if insert actually inserted rows if +# a success was reported. +# + +--source include/galera_cluster.inc +--source suite/galera/t/MW-328-header.inc + +--connection node_2 +--let $count = 100 +--let $successes = 0 +--let $deadlocks = 0 + +SET SESSION wsrep_retry_autocommit = 0; + +--disable_query_log + +while ($count) +{ + TRUNCATE TABLE t2; + + --error 0,1213 + INSERT IGNORE INTO t2 SELECT f2 FROM t1; + if ($mysql_errno != 1213) { + --inc $successes + if (`SELECT COUNT(*) = 0 FROM t2`) { + --die No rows arrived in table t2 + } + } + + if ($mysql_errno == 1213) { + --inc $deadlocks + + } + + --dec $count +} + +--enable_query_log + +# +# Check that the test produced both deadlocks and successes +# + +--disable_query_log +--eval SELECT $successes > 0 AS have_successes +--eval SELECT $deadlocks > 0 AS have_deadlocks +--enable_query_log + + +--source suite/galera/t/MW-328-footer.inc diff --git a/mysql-test/suite/galera/t/MW-328B.test b/mysql-test/suite/galera/t/MW-328B.test new file mode 100644 index 00000000000..11969dd0b47 --- /dev/null +++ b/mysql-test/suite/galera/t/MW-328B.test @@ -0,0 +1,35 @@ +# +# MW-328 Fix unnecessary/silent BF aborts +# + +# +# Make sure an unrelated SELECT following a BF-aborted query never +# gets the deadlock error +# + +--source include/galera_cluster.inc +--source suite/galera/t/MW-328-header.inc + +--connection node_2 +--let $count = 100 + +SET SESSION wsrep_retry_autocommit = 0; + +--disable_query_log + +while ($count) +{ + --error 0,1213 + INSERT IGNORE INTO t2 SELECT f2 FROM t1; + + --disable_result_log + --error 0 + SELECT 1 FROM DUAL; + --enable_result_log + + --dec $count +} + +--enable_query_log + +--source suite/galera/t/MW-328-footer.inc diff --git a/mysql-test/suite/galera/t/MW-328C.test b/mysql-test/suite/galera/t/MW-328C.test new file mode 100644 index 00000000000..7241dfbdbca --- /dev/null +++ b/mysql-test/suite/galera/t/MW-328C.test @@ -0,0 +1,35 @@ +# +# MW-328 Fix unnecessary/silent BF aborts +# + +# +# Make sure that a high value of wsrep_retry_autocommit +# masks all deadlock errors +# + +--source include/galera_cluster.inc +--source suite/galera/t/MW-328-header.inc + +--connection node_2 +--let $count = 100 + +SET SESSION wsrep_retry_autocommit = 10000; + +--disable_query_log + +while ($count) +{ + --error 0 + INSERT IGNORE INTO t2 SELECT f2 FROM t1; + + --disable_result_log + --error 0 + SELECT 1 FROM DUAL; + --enable_result_log + + --dec $count +} + +--enable_query_log + +--source suite/galera/t/MW-328-footer.inc diff --git a/mysql-test/suite/galera/t/MW-328D.test b/mysql-test/suite/galera/t/MW-328D.test new file mode 100644 index 00000000000..e8a22f22a99 --- /dev/null +++ b/mysql-test/suite/galera/t/MW-328D.test @@ -0,0 +1,39 @@ +# +# MW-328 Fix unnecessary/silent BF aborts +# + +# +# Test that non-Galera deadlock error still behaves as expected +# + +--source include/galera_cluster.inc + +CREATE TABLE t1 (i INT) ENGINE = InnoDB; +INSERT INTO t1 (i) VALUES(1); + +CREATE TABLE t2 (i INT) ENGINE = InnoDB; + +# Create a deadlock situation + +--connection node_1 +SET AUTOCOMMIT=OFF; +START TRANSACTION; +SELECT * FROM t1 WHERE i = 1 LOCK IN SHARE MODE; + +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1a +SET AUTOCOMMIT=OFF; +START TRANSACTION; +--send INSERT IGNORE INTO t2 SELECT * FROM t1 WHERE i = 1 FOR UPDATE; + +--connection node_1 +--sleep 2 +DELETE FROM t1 WHERE i = 1; +COMMIT; + +# We expect that ER_LOCK_DEADLOCK will be delivered even though it was a INSERT INGORE statement +--connection node_1a +--error ER_LOCK_DEADLOCK +--reap + +DROP TABLE t1, t2; diff --git a/mysql-test/suite/galera/t/MW-328E.test b/mysql-test/suite/galera/t/MW-328E.test new file mode 100644 index 00000000000..34b17be7b08 --- /dev/null +++ b/mysql-test/suite/galera/t/MW-328E.test @@ -0,0 +1,40 @@ +# +# MW-328 Fix unnecessary/silent BF aborts +# + +# +# Test that non-Galera deadlock error still behaves as expected (case #2) +# + +--source include/galera_cluster.inc + +create table t1 (i int primary key, j int) engine=innodb; +create table t2 (i int primary key, j int) engine=innodb; + +insert into t1 values (1,0); +insert into t2 values (2,0); + +set autocommit=off; +start transaction; +update t1 set j=1 where i=1; + +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1a +set autocommit=off; +start transaction; +begin; +update t2 set j=1 where i=2; + +--connection node_1 +# Hang expected here +--send insert into t1 select * from t2; + +--sleep 2 +--connection node_1a +--error ER_LOCK_DEADLOCK +insert into t2 select * from t1; + +--connection node_1 +--reap + +DROP TABLE t1, t2; From ad7b00fb90fc954e782eff57e54ae25fe4e439eb Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Tue, 14 Mar 2017 16:17:28 +0530 Subject: [PATCH 28/66] Galera MTR Tests: do not run innodb.innodb_stats_del_mark and some other tests with Galera, as it produces warnings Signed-off-by: Sachin Setiya --- mysql-test/suite/innodb/t/galera.skip | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mysql-test/suite/innodb/t/galera.skip b/mysql-test/suite/innodb/t/galera.skip index 5b6aeb13c32..fbc9e466ddb 100644 --- a/mysql-test/suite/innodb/t/galera.skip +++ b/mysql-test/suite/innodb/t/galera.skip @@ -41,4 +41,9 @@ innodb-table-online : ALTER succeeds as it is given a higher priority innodb-index-online-purge : ALTER succeeds as it is given a higher priority innodb-wl5522-debug : Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. innodb_stats_table_flag_auto_recalc : Performs multiple restarts in a row which causes '1047: Unknown command' errors +innodb-lock-inherit-read_commited : Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT +innodb-index-debug : Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT +flush-hang : Unsafe statement written to the binary log +innodb_deadlock_with_autoinc : Test uses autoinc_lock_mode = 0 +innodb_stats_del_mark : Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. From 25070d2a2c47c418e4f7ccefc0d909ddc426acc5 Mon Sep 17 00:00:00 2001 From: Philip Stoev Date: Wed, 25 Jan 2017 09:58:07 +0200 Subject: [PATCH 29/66] Bump WSREP_PATCH_VERSION to 19 --- cmake/wsrep.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake index d483225d4e3..a8b1bea3bbb 100644 --- a/cmake/wsrep.cmake +++ b/cmake/wsrep.cmake @@ -18,7 +18,7 @@ # so WSREP_VERSION is produced regardless # Set the patch version -SET(WSREP_PATCH_VERSION "18") +SET(WSREP_PATCH_VERSION "19") # MariaDB addition: Revision number of the last revision merged from # codership branch visible in @@visible_comment. From 1743d68868a1c5ddbd21c82b9e99541c08ee0361 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Tue, 14 Mar 2017 18:41:38 +0530 Subject: [PATCH 30/66] Fix Some failing tests Signed-off-by: Sachin Setiya --- mysql-test/suite/galera/t/MW-258.test | 1 + mysql-test/suite/galera/t/MW-313.test | 1 + mysql-test/suite/galera/t/MW-328A.test | 1 + mysql-test/suite/galera/t/MW-328B.test | 1 + mysql-test/suite/galera/t/MW-328C.test | 1 + mysql-test/suite/galera/t/MW-328D.test | 1 + mysql-test/suite/galera/t/MW-328E.test | 1 + mysql-test/suite/galera/t/MW-329.test | 1 + mysql-test/suite/galera/t/galera_var_retry_autocommit.test | 1 + 9 files changed, 9 insertions(+) diff --git a/mysql-test/suite/galera/t/MW-258.test b/mysql-test/suite/galera/t/MW-258.test index f5519f8a081..174dd2c02c6 100644 --- a/mysql-test/suite/galera/t/MW-258.test +++ b/mysql-test/suite/galera/t/MW-258.test @@ -34,6 +34,7 @@ UNLOCK TABLES; --connection node_1 --echo value after RSU: +--sleep 3 SHOW STATUS LIKE 'wsrep_desync_count'; SHOW VARIABLES LIKE 'wsrep_desync'; SET GLOBAL wsrep_desync=0; diff --git a/mysql-test/suite/galera/t/MW-313.test b/mysql-test/suite/galera/t/MW-313.test index d697cb2cfcd..92fd835c615 100644 --- a/mysql-test/suite/galera/t/MW-313.test +++ b/mysql-test/suite/galera/t/MW-313.test @@ -3,6 +3,7 @@ # --source include/galera_cluster.inc +--source include/have_innodb.inc --source include/have_binlog_format_row.inc # No error expected for SELECT and SHOW diff --git a/mysql-test/suite/galera/t/MW-328A.test b/mysql-test/suite/galera/t/MW-328A.test index 836dd088749..4d6e1ea3625 100644 --- a/mysql-test/suite/galera/t/MW-328A.test +++ b/mysql-test/suite/galera/t/MW-328A.test @@ -8,6 +8,7 @@ # --source include/galera_cluster.inc +--source include/have_innodb.inc --source suite/galera/t/MW-328-header.inc --connection node_2 diff --git a/mysql-test/suite/galera/t/MW-328B.test b/mysql-test/suite/galera/t/MW-328B.test index 11969dd0b47..a7b4053ab0c 100644 --- a/mysql-test/suite/galera/t/MW-328B.test +++ b/mysql-test/suite/galera/t/MW-328B.test @@ -8,6 +8,7 @@ # --source include/galera_cluster.inc +--source include/have_innodb.inc --source suite/galera/t/MW-328-header.inc --connection node_2 diff --git a/mysql-test/suite/galera/t/MW-328C.test b/mysql-test/suite/galera/t/MW-328C.test index 7241dfbdbca..b681e743ab3 100644 --- a/mysql-test/suite/galera/t/MW-328C.test +++ b/mysql-test/suite/galera/t/MW-328C.test @@ -8,6 +8,7 @@ # --source include/galera_cluster.inc +--source include/have_innodb.inc --source suite/galera/t/MW-328-header.inc --connection node_2 diff --git a/mysql-test/suite/galera/t/MW-328D.test b/mysql-test/suite/galera/t/MW-328D.test index e8a22f22a99..d5cffdb8f47 100644 --- a/mysql-test/suite/galera/t/MW-328D.test +++ b/mysql-test/suite/galera/t/MW-328D.test @@ -7,6 +7,7 @@ # --source include/galera_cluster.inc +--source include/have_innodb.inc CREATE TABLE t1 (i INT) ENGINE = InnoDB; INSERT INTO t1 (i) VALUES(1); diff --git a/mysql-test/suite/galera/t/MW-328E.test b/mysql-test/suite/galera/t/MW-328E.test index 34b17be7b08..fd4b0bf9039 100644 --- a/mysql-test/suite/galera/t/MW-328E.test +++ b/mysql-test/suite/galera/t/MW-328E.test @@ -7,6 +7,7 @@ # --source include/galera_cluster.inc +--source include/have_innodb.inc create table t1 (i int primary key, j int) engine=innodb; create table t2 (i int primary key, j int) engine=innodb; diff --git a/mysql-test/suite/galera/t/MW-329.test b/mysql-test/suite/galera/t/MW-329.test index 445f8795dff..acf6763b396 100644 --- a/mysql-test/suite/galera/t/MW-329.test +++ b/mysql-test/suite/galera/t/MW-329.test @@ -3,6 +3,7 @@ # --source include/galera_cluster.inc +--source include/have_innodb.inc CREATE TABLE t1 (f1 INTEGER, f2 CHAR(20) DEFAULT 'abc') ENGINE=InnoDB; diff --git a/mysql-test/suite/galera/t/galera_var_retry_autocommit.test b/mysql-test/suite/galera/t/galera_var_retry_autocommit.test index 6ef647b24e1..bf4da3234c5 100644 --- a/mysql-test/suite/galera/t/galera_var_retry_autocommit.test +++ b/mysql-test/suite/galera/t/galera_var_retry_autocommit.test @@ -4,6 +4,7 @@ # --source include/galera_cluster.inc +--source include/have_innodb.inc --connection node_1 CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=InnoDB; From 5bb765366710848e8cda3f7cca6bd50467b9b947 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Thu, 16 Mar 2017 02:13:31 +0530 Subject: [PATCH 31/66] Fix wsrep_affected_rows. The value of wsrep_affected_rows were not reseted properly for slave. Now we also wsrep_affected_rows in Xid_log_event::do_apply_event also , apart from THD::cleanup_after_query(). Signed-off-by: Sachin Setiya --- mysql-test/suite/wsrep/r/wsrep_rpl.result | 4 ++-- mysql-test/suite/wsrep/t/wsrep_rpl.test | 10 ++-------- sql/handler.cc | 2 +- sql/log_event.cc | 4 ++++ 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/mysql-test/suite/wsrep/r/wsrep_rpl.result b/mysql-test/suite/wsrep/r/wsrep_rpl.result index fd792c215b3..a5db3b28ec0 100644 --- a/mysql-test/suite/wsrep/r/wsrep_rpl.result +++ b/mysql-test/suite/wsrep/r/wsrep_rpl.result @@ -5,12 +5,12 @@ include/master-slave.inc # wsrep_max_ws_rows exceeded. Error_Code 1180 # CREATE TABLE t1(i INT) ENGINE = INNODB; -SET @@GLOBAL.wsrep_max_ws_rows = 1; +SET @@GLOBAL.wsrep_max_ws_rows = 2; INSERT INTO t1 VALUES(1), (2); SELECT COUNT(*) = 2 FROM t1; COUNT(*) = 2 1 -SET @@GLOBAL.wsrep_max_ws_rows = 1; +SET @@GLOBAL.wsrep_max_ws_rows = 2; DELETE FROM t1; SELECT COUNT(*) = 0 FROM t1; COUNT(*) = 0 diff --git a/mysql-test/suite/wsrep/t/wsrep_rpl.test b/mysql-test/suite/wsrep/t/wsrep_rpl.test index 1cc7214325d..4f34aadc365 100644 --- a/mysql-test/suite/wsrep/t/wsrep_rpl.test +++ b/mysql-test/suite/wsrep/t/wsrep_rpl.test @@ -15,18 +15,13 @@ let $wsrep_max_ws_rows_slave = `SELECT @@GLOBAL.wsrep_max_ws_rows`; connection master; CREATE TABLE t1(i INT) ENGINE = INNODB; -# Setting wsrep_max_ws_rows should have no impact on replication master -# unless its a cluster node. -SET @@GLOBAL.wsrep_max_ws_rows = 1; +SET @@GLOBAL.wsrep_max_ws_rows = 2; INSERT INTO t1 VALUES(1), (2); - sync_slave_with_master; SELECT COUNT(*) = 2 FROM t1; connection slave; -# Setting wsrep_max_ws_rows should have no impact on replication slave -# unless its a cluster node. -SET @@GLOBAL.wsrep_max_ws_rows = 1; +SET @@GLOBAL.wsrep_max_ws_rows = 2; connection master; DELETE FROM t1; @@ -38,7 +33,6 @@ connection master; DROP TABLE t1; sync_slave_with_master; - # Restore wsrep_max_ws_rows on master and slave connection master; eval SET @@GLOBAL.wsrep_max_ws_rows = $wsrep_max_ws_rows_master; diff --git a/sql/handler.cc b/sql/handler.cc index f920686231b..79649316e73 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5943,7 +5943,7 @@ static int binlog_log_row(TABLE* table, } /* enforce wsrep_max_ws_rows */ - if (table->s->tmp_table == NO_TMP_TABLE) + if (table->s->tmp_table == NO_TMP_TABLE && WSREP(thd)) { thd->wsrep_affected_rows++; if (wsrep_max_ws_rows && diff --git a/sql/log_event.cc b/sql/log_event.cc index ba1981d3318..d2f3b2c60f6 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -7422,6 +7422,10 @@ int Xid_log_event::do_apply_event(rpl_group_info *rgi) Record any GTID in the same transaction, so slave state is transactionally consistent. */ + + /*Set wsrep_affected_rows = 0 */ + thd->wsrep_affected_rows= 0; + if (rgi->gtid_pending) { sub_id= rgi->gtid_sub_id; From c401773c8dd97bd9f6bf6cff9fcafdf24fbd0ee1 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Thu, 16 Mar 2017 08:07:58 +0530 Subject: [PATCH 32/66] Fix test cases Signed-off-by: Sachin Setiya --- mysql-test/include/diff_servers.inc | 67 +++++++++++++++++++++ mysql-test/suite/galera/disabled.def | 3 + mysql-test/suite/galera/t/galera_roles.test | 2 + 3 files changed, 72 insertions(+) create mode 100644 mysql-test/include/diff_servers.inc diff --git a/mysql-test/include/diff_servers.inc b/mysql-test/include/diff_servers.inc new file mode 100644 index 00000000000..5ec7efc38b9 --- /dev/null +++ b/mysql-test/include/diff_servers.inc @@ -0,0 +1,67 @@ +# ==== Purpose ==== +# +# Check that two or more servers have identical databases; fail if not. +# +# ==== Usage ==== +# +# --let $diff_servers= 1 2 +# [--let $databases= db1 db2 ...] +# [--let $rpl_debug= 1] +# --source include/diff_servers.inc + +# pretty-print header +--let $_ds_info= servers=$diff_servers +if ($databases != '') +{ + --let $_ds_info= $_ds_info databases=$databases +} +--let $include_filename= diff_servers.inc [$_ds_info] +--source include/begin_include_file.inc + +# get databases +--let $_ds_databases= $diff_database +if ($_ds_databases == '') +{ + --let $_ds_databases= `SELECT GROUP_CONCAT(SCHEMA_NAME SEPARATOR ' ') FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('information_schema', 'mtr', 'mysql', 'performance_schema')` +} + +# generate command line +--let $_ds_arg= --defaults-group-suffix=. +--let $_ds_number_pos= `SELECT LOCATE('$_ds_arg', '$MYSQL_DUMP') + LENGTH('$_ds_arg')` +--let $_ds_pre_command= `SELECT SUBSTR('$MYSQL_DUMP', 1, $_ds_number_pos - 1)` +--let $_ds_post_command= `SELECT SUBSTR('$MYSQL_DUMP', $_ds_number_pos + 1)` +--let $_ds_post_command= $_ds_post_command --compact --order-by-primary --skip-extended-insert --no-create-info --databases $_ds_databases +--let $_ds_prev_outfile= + +# iterate over servers +--let $_ds_servers= $diff_servers +while ($_ds_servers != '') +{ + --let $_ds_server_number= `SELECT SUBSTRING_INDEX('$_ds_servers', ' ', 1)` + --let $_ds_servers= `SELECT TRIM(SUBSTRING('$_ds_servers', 1 + LENGTH('_$ds_server_number')))` + --let $_ds_outfile= $MYSQLTEST_VARDIR/tmp/diff_servers_$_ds_server_number + + if ($rpl_debug) + { + --echo generating dump from server '$_ds_server_number' using command '$_ds_pre_command$_ds_server_number $_ds_post_command > $_ds_outfile' + --echo remaining servers: '$_ds_servers' + } + --exec $_ds_pre_command$_ds_server_number $_ds_post_command > $_ds_outfile + + if ($_ds_prev_outfile != '') + { + if ($rpl_debug) + { + --echo diffing files '$_ds_prev_outfile' and '$_ds_outfile' + } + --diff_files $_ds_prev_outfile $_ds_outfile + + --remove_file $_ds_prev_outfile + } + --let $_ds_prev_outfile= $_ds_outfile +} + +--remove_file $_ds_prev_outfile + +--let $include_filename= diff_servers.inc [servers=$_ds_info] +--source include/end_include_file.inc diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 907f7931483..0129e430ed7 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -32,3 +32,6 @@ galera_binlog_stmt_autoinc : TODO: investigate galera_concurrent_ctas : Test times out, investigate galera_sst_xtrabackup-v2-options : TODO: Fix test case mysql-wsrep#33 : TODO: investigate +GAL-480 : Investigate +galera_fk_no_pk :Investigate +galera_account_management : Investigate diff --git a/mysql-test/suite/galera/t/galera_roles.test b/mysql-test/suite/galera/t/galera_roles.test index 16e417d1fdb..eea35762539 100644 --- a/mysql-test/suite/galera/t/galera_roles.test +++ b/mysql-test/suite/galera/t/galera_roles.test @@ -36,6 +36,7 @@ GRANT SELECT (a) ON test1.t2 TO role1; --connect(foo_node_1,127.0.0.1,foo,,test,$port_1,) --let $port_2= \$NODE_MYPORT_2 +--sleep 1 --connect(foo_node_2,127.0.0.1,foo,,test,$port_2,) --echo @@ -101,6 +102,7 @@ REVOKE EXECUTE ON PROCEDURE test1.pr1 FROM role1; --echo # Connect with foo_node_1 --connection foo_node_1 +--sleep 1 --error ER_PROCACCESS_DENIED_ERROR CALL test1.pr1(); From 53c6195eede2b9959331bf11fa7679a108896bde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 20 Mar 2017 10:17:13 +0200 Subject: [PATCH 33/66] Fixed test failure on galere_wsrep_log_conflicts on XtraDB. Problem was that trx_sys->mutex was acquired to print trx info even when we already hold trx_sys->mutex. Fixed similarly as in InnoDB, i.e. with wsrep_trx_print_locking() function that does not acquire trx_sys->mutex. --- storage/innobase/include/trx0trx.h | 1 + storage/innobase/lock/lock0lock.cc | 10 ++- storage/innobase/trx/trx0trx.cc | 1 + storage/xtradb/include/trx0trx.h | 20 ++++- storage/xtradb/lock/lock0lock.cc | 9 +-- storage/xtradb/trx/trx0trx.cc | 114 +++++++++++++++++++++++++++++ 6 files changed, 144 insertions(+), 11 deletions(-) diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index c7e0dc5a551..6db87efaf91 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2015, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index c1f5d71e1b6..b927efaa286 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2016, MariaDB Corporation +Copyright (c) 2014, 2017, MariaDB Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1704,13 +1704,14 @@ wsrep_kill_victim( is in the queue*/ } else if (lock->trx != trx) { if (wsrep_log_conflicts) { - if (bf_this) - fputs("\n*** Priority TRANSACTION:\n", + if (bf_this) { + fputs("\n*** Priority TRANSACTION:\n", stderr); - else { + } else { fputs("\n*** Victim TRANSACTION:\n", stderr); } + wsrep_trx_print_locking(stderr, trx, 3000); if (bf_other) { @@ -1720,6 +1721,7 @@ wsrep_kill_victim( fputs("\n*** Victim TRANSACTION:\n", stderr); } + wsrep_trx_print_locking(stderr, lock->trx, 3000); fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n", diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index bfc1c546510..5fa176d99e1 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2015, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h index f9917c8448d..1bc1e07f547 100644 --- a/storage/xtradb/include/trx0trx.h +++ b/storage/xtradb/include/trx0trx.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, MariaDB Corporation +Copyright (c) 2015, 2017, MariaDB Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -333,6 +333,24 @@ trx_print_low( /*!< in: mem_heap_get_size(trx->lock.lock_heap) */ MY_ATTRIBUTE((nonnull)); +#ifdef WITH_WSREP +/**********************************************************************//** +Prints info about a transaction. +Transaction information may be retrieved without having trx_sys->mutex acquired +so it may not be completely accurate. The caller must own lock_sys->mutex +and the trx must have some locks to make sure that it does not escape +without locking lock_sys->mutex. */ +UNIV_INTERN +void +wsrep_trx_print_locking( +/*==============*/ + FILE* f, /*!< in: output stream */ + const trx_t* trx, /*!< in: transaction */ + ulint max_query_len) /*!< in: max query length to print, + or 0 to use the default max length */ + MY_ATTRIBUTE((nonnull)); +#endif /* WITH_WSREP */ + /**********************************************************************//** Prints info about a transaction. The caller must hold lock_sys->mutex and trx_sys->mutex. diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index 9be03e78977..c09a3ac2550 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2015, MariaDB Corporation +Copyright (c) 2014, 2017, MariaDB Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1714,7 +1714,6 @@ wsrep_kill_victim( is in the queue*/ } else if (lock->trx != trx) { if (wsrep_log_conflicts) { - mutex_enter(&trx_sys->mutex); if (bf_this) { fputs("\n*** Priority TRANSACTION:\n", stderr); @@ -1723,7 +1722,7 @@ wsrep_kill_victim( stderr); } - trx_print_latched(stderr, trx, 3000); + wsrep_trx_print_locking(stderr, trx, 3000); if (bf_other) { fputs("\n*** Priority TRANSACTION:\n", @@ -1733,9 +1732,7 @@ wsrep_kill_victim( stderr); } - trx_print_latched(stderr, lock->trx, 3000); - - mutex_exit(&trx_sys->mutex); + wsrep_trx_print_locking(stderr, lock->trx, 3000); fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n", stderr); diff --git a/storage/xtradb/trx/trx0trx.cc b/storage/xtradb/trx/trx0trx.cc index 07e122e54ee..1670837df59 100644 --- a/storage/xtradb/trx/trx0trx.cc +++ b/storage/xtradb/trx/trx0trx.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2015, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -2156,6 +2157,119 @@ trx_print_latched( mem_heap_get_size(trx->lock.lock_heap)); } +#ifdef WITH_WSREP +/**********************************************************************//** +Prints info about a transaction. +Transaction information may be retrieved without having trx_sys->mutex acquired +so it may not be completely accurate. The caller must own lock_sys->mutex +and the trx must have some locks to make sure that it does not escape +without locking lock_sys->mutex. */ +UNIV_INTERN +void +wsrep_trx_print_locking( +/*==========*/ + FILE* f, + /*!< in: output stream */ + const trx_t* trx, + /*!< in: transaction */ + ulint max_query_len) + /*!< in: max query length to print, + or 0 to use the default max length */ +{ + ibool newline; + const char* op_info; + + ut_ad(lock_mutex_own()); + ut_ad(trx->lock.trx_locks.count > 0); + + fprintf(f, "TRANSACTION " TRX_ID_FMT, trx->id); + + /* trx->state may change since trx_sys->mutex is not required */ + switch (trx->state) { + case TRX_STATE_NOT_STARTED: + fputs(", not started", f); + goto state_ok; + case TRX_STATE_ACTIVE: + fprintf(f, ", ACTIVE %lu sec", + (ulong) difftime(time(NULL), trx->start_time)); + goto state_ok; + case TRX_STATE_PREPARED: + fprintf(f, ", ACTIVE (PREPARED) %lu sec", + (ulong) difftime(time(NULL), trx->start_time)); + goto state_ok; + case TRX_STATE_COMMITTED_IN_MEMORY: + fputs(", COMMITTED IN MEMORY", f); + goto state_ok; + } + fprintf(f, ", state %lu", (ulong) trx->state); + ut_ad(0); +state_ok: + + /* prevent a race condition */ + op_info = trx->op_info; + + if (*op_info) { + putc(' ', f); + fputs(op_info, f); + } + + if (trx->is_recovered) { + fputs(" recovered trx", f); + } + + if (trx->declared_to_be_inside_innodb) { + fprintf(f, ", thread declared inside InnoDB %lu", + (ulong) trx->n_tickets_to_enter_innodb); + } + + putc('\n', f); + + if (trx->n_mysql_tables_in_use > 0 || trx->mysql_n_tables_locked > 0) { + fprintf(f, "mysql tables in use %lu, locked %lu\n", + (ulong) trx->n_mysql_tables_in_use, + (ulong) trx->mysql_n_tables_locked); + } + + newline = TRUE; + + /* trx->lock.que_state of an ACTIVE transaction may change + while we are not holding trx->mutex. We perform a dirty read + for performance reasons. */ + + switch (trx->lock.que_state) { + case TRX_QUE_RUNNING: + newline = FALSE; break; + case TRX_QUE_LOCK_WAIT: + fputs("LOCK WAIT ", f); break; + case TRX_QUE_ROLLING_BACK: + fputs("ROLLING BACK ", f); break; + case TRX_QUE_COMMITTING: + fputs("COMMITTING ", f); break; + default: + fprintf(f, "que state %lu ", (ulong) trx->lock.que_state); + } + + if (trx->has_search_latch) { + newline = TRUE; + fputs(", holds adaptive hash latch", f); + } + + if (trx->undo_no != 0) { + newline = TRUE; + fprintf(f, ", undo log entries " TRX_ID_FMT, trx->undo_no); + } + + if (newline) { + putc('\n', f); + } + + if (trx->mysql_thd != NULL) { + innobase_mysql_print_thd( + f, trx->mysql_thd, static_cast(max_query_len)); + } +} +#endif /* WITH_WSREP */ + /**********************************************************************//** Prints info about a transaction. Acquires and releases lock_sys->mutex and trx_sys->mutex. */ From 0b51dee0e3d79358120561fbedc5df2e80eb43b6 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Mon, 20 Mar 2017 18:52:18 +0530 Subject: [PATCH 34/66] Change VERSION no to 30 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 22d7ed0a903..5f666b9a57d 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=0 -MYSQL_VERSION_PATCH=31 +MYSQL_VERSION_PATCH=30 From 0759c9baf59b784b293b2141dac329aa6ff89f7f Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Tue, 21 Mar 2017 12:14:19 +0530 Subject: [PATCH 35/66] Fix mysqlhotcopy test failures Signed-off-by: Sachin Setiya --- mysql-test/include/mysqlhotcopy.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/include/mysqlhotcopy.inc b/mysql-test/include/mysqlhotcopy.inc index 883f472a8b2..2fc14d599d9 100644 --- a/mysql-test/include/mysqlhotcopy.inc +++ b/mysql-test/include/mysqlhotcopy.inc @@ -109,7 +109,7 @@ DROP DATABASE hotcopy_save; --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR --list_files $MYSQLD_DATADIR/hotcopy_save --replace_result $MASTER_MYSOCK MASTER_MYSOCK ---error 9,11,110,2304,255 +--error 1,9,11,110,2304,255 --exec $MYSQLHOTCOPY --quiet -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save --replace_result $MASTER_MYSOCK MASTER_MYSOCK --exec $MYSQLHOTCOPY --quiet --allowold -S $MASTER_MYSOCK -u root hotcopy_test hotcopy_save From b22026ddfd8c2b12e3793482c95c0977dd764b6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 21 Mar 2017 10:00:02 +0200 Subject: [PATCH 36/66] Fix failure on galera_toi_drop_database test. It is assumed that both insert..select statements take so long that drop database from node2 gets to abort them both but on fast machines it was too small. Increased the size of insert. --- mysql-test/suite/galera/r/galera_toi_drop_database.result | 4 ++-- mysql-test/suite/galera/t/galera_toi_drop_database.test | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_toi_drop_database.result b/mysql-test/suite/galera/r/galera_toi_drop_database.result index 8f4098419eb..d652a5154be 100644 --- a/mysql-test/suite/galera/r/galera_toi_drop_database.result +++ b/mysql-test/suite/galera/r/galera_toi_drop_database.result @@ -5,10 +5,10 @@ INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; CREATE TABLE t2 (f1 INTEGER) ENGINE=InnoDB; SET SESSION wsrep_retry_autocommit = 0; -INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;; +INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6;; USE database1; SET SESSION wsrep_retry_autocommit = 0; -INSERT INTO t2 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5;; +INSERT INTO t2 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6;; DROP DATABASE database1;; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction ERROR 40001: Deadlock found when trying to get lock; try restarting transaction diff --git a/mysql-test/suite/galera/t/galera_toi_drop_database.test b/mysql-test/suite/galera/t/galera_toi_drop_database.test index 0a37a4010ce..e790a0ba812 100644 --- a/mysql-test/suite/galera/t/galera_toi_drop_database.test +++ b/mysql-test/suite/galera/t/galera_toi_drop_database.test @@ -22,12 +22,12 @@ CREATE TABLE t2 (f1 INTEGER) ENGINE=InnoDB; # Make sure autocommit retrying does not kick in as this will mask the error we expect to get SET SESSION wsrep_retry_autocommit = 0; # Attemp to insert 1M rows ---send INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5; +--send INSERT INTO t1 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6; --connection node_1a USE database1; SET SESSION wsrep_retry_autocommit = 0; ---send INSERT INTO t2 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5; +--send INSERT INTO t2 (f1) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4, ten AS a5, ten AS a6; --connection node_2 --sleep 1 From 656d0f10e51a554ec2ff895c5e25e16a5da0d00e Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Tue, 21 Mar 2017 14:23:45 +0530 Subject: [PATCH 37/66] Fix galera_admin test Patch credit Jan --- mysql-test/suite/galera/t/galera_admin.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/galera/t/galera_admin.test b/mysql-test/suite/galera/t/galera_admin.test index d62c454bdfa..e3c43256ad5 100644 --- a/mysql-test/suite/galera/t/galera_admin.test +++ b/mysql-test/suite/galera/t/galera_admin.test @@ -56,7 +56,7 @@ ANALYZE TABLE t1, t2; OPTIMIZE TABLE t1, t2; --connection node_2 ---let $wait_condition = SELECT VARIABLE_VALUE = $wsrep_last_committed_before + 1 FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed' +--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 @@ -69,7 +69,7 @@ OPTIMIZE TABLE t1, t2; REPAIR TABLE x1, x2; --connection node_2 ---let $wait_condition = SELECT VARIABLE_VALUE = $wsrep_last_committed_before + 1 FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME = 'wsrep_last_committed' +--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 From 4eb29ecfab1522319d5b2494f60d7279f4522314 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Wed, 22 Mar 2017 09:40:57 +0530 Subject: [PATCH 38/66] MDEV-12319 Test added to disabled.def --- mysql-test/suite/galera/disabled.def | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 0129e430ed7..389ed86100a 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -35,3 +35,14 @@ mysql-wsrep#33 : TODO: investigate GAL-480 : Investigate galera_fk_no_pk :Investigate galera_account_management : Investigate +galera.galera_var_retry_autocommit : MDEV-12319 #Sparodic Faliure +galera.galera_gcs_fc_limit : MDEV-12319 #Sparodic Faliure +galera.galera_toi_ddl_nonconflicting : MDEV-12319 #Sparodic Faliure +galera.mysql-wsrep#198 : MDEV-12319 #Sparodic Faliure +galera.galera_pc_ignore_sb : MDEV-12319 #Sparodic Faliure +galera.MW-329 : MDEV-12319 #Sparodic Faliure +galera.galera_ist_recv_bind : MDEV-12319 #Failed to start mysqld +galera.galera_ist_restart_joiner : MDEV-12319 #Failed to start mysqld +galera.galera_ssl_compression : MDEV-12319 #Failed to start mysqld +galera.galera_wan : MDEV-12319 #Failed to start mysqld +galera.rpl_row_annotate : MDEV-12319 #Failed to start mysqld From a136c36781f3d70710ad50e86604c1bb649bbc91 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Wed, 22 Mar 2017 10:19:06 -0400 Subject: [PATCH 39/66] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5f666b9a57d..22d7ed0a903 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=0 -MYSQL_VERSION_PATCH=30 +MYSQL_VERSION_PATCH=31 From bb20f6d9e29f68ad8c830bf83c971d2849dac24e Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Thu, 23 Mar 2017 10:26:55 +0530 Subject: [PATCH 40/66] MDEV-12319 Part 2 Add more tests to disabled.diff Signed-off-by: Sachin Setiya --- mysql-test/suite/galera/disabled.def | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 389ed86100a..d96eb005eed 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -46,3 +46,5 @@ galera.galera_ist_restart_joiner : MDEV-12319 #Failed to start mysqld galera.galera_ssl_compression : MDEV-12319 #Failed to start mysqld galera.galera_wan : MDEV-12319 #Failed to start mysqld galera.rpl_row_annotate : MDEV-12319 #Failed to start mysqld +galera.MW-44 : MDEV-12319 +galera.galera_var_slave_threads : MDEV-12319 From d95dc57e751b00e1f8dc3fadaf29c3e06c499419 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Thu, 23 Mar 2017 13:18:29 +0530 Subject: [PATCH 41/66] Fix galera.galera_gcs_fc_limit --- mysql-test/suite/galera/t/galera_gcs_fc_limit.test | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/galera/t/galera_gcs_fc_limit.test b/mysql-test/suite/galera/t/galera_gcs_fc_limit.test index 721d84ecb05..dc65a452d7c 100644 --- a/mysql-test/suite/galera/t/galera_gcs_fc_limit.test +++ b/mysql-test/suite/galera/t/galera_gcs_fc_limit.test @@ -19,10 +19,13 @@ SET GLOBAL wsrep_provider_options = 'gcs.fc_limit=1'; LOCK TABLE t1 WRITE; --connection node_1 - +--sleep 1 INSERT INTO t1 VALUES (2); +--sleep 1 INSERT INTO t1 VALUES (3); +--sleep 1 INSERT INTO t1 VALUES (4); +--sleep 1 # This query will hang because flow control will kick in --send From 5dca5b8007c285f893221d3cb874c8f413da8155 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 30 Mar 2017 15:02:30 +1100 Subject: [PATCH 42/66] MDEV-7560: check_galera_version to account for greater version than specified Signed-off-by: Daniel Black --- .../wsrep/include/check_galera_version.inc | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/wsrep/include/check_galera_version.inc b/mysql-test/suite/wsrep/include/check_galera_version.inc index 38b4ada98b9..cb35269249b 100644 --- a/mysql-test/suite/wsrep/include/check_galera_version.inc +++ b/mysql-test/suite/wsrep/include/check_galera_version.inc @@ -12,11 +12,29 @@ --disable_query_log -eval SET @GALERA_VERSION=(SELECT CONCAT('$galera_version', '%')); +# Required Version -if (!`SELECT COUNT(*) FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE - VARIABLE_NAME LIKE 'wsrep_provider_version' AND - VARIABLE_VALUE LIKE @GALERA_VERSION`) +eval SET @GALERA_VERSION='$galera_version'; +SELECT CAST(REGEXP_REPLACE(@GALERA_VERSION,'^(\\d+)\\.(\\d+)\\.(\\d+).*','\\1') AS UNSIGNED) INTO @GALERA_MAJOR_VERSION; +SELECT CAST(REGEXP_REPLACE(@GALERA_VERSION,'^(\\d+)\\.(\\d+)\\.(\\d+).*','\\2') AS UNSIGNED) INTO @GALERA_MID_VERSION; +SELECT CAST(REGEXP_REPLACE(@GALERA_VERSION,'^(\\d+)\\.(\\d+)\\.(\\d+).*','\\3') AS UNSIGNED) INTO @GALERA_MINOR_VERSION; + +# Actual +SELECT VARIABLE_VALUE INTO @ACTUAL_GALERA_VERSION FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE 'wsrep_provider_version'; + +SELECT CAST(REGEXP_REPLACE(@ACTUAL_GALERA_VERSION,'^(\\d+)\\.(\\d+)\\.(\\d+).*','\\1') AS UNSIGNED) INTO @ACTUAL_GALERA_MAJOR_VERSION; +SELECT CAST(REGEXP_REPLACE(@ACTUAL_GALERA_VERSION,'^(\\d+)\\.(\\d+)\\.(\\d+).*','\\2') AS UNSIGNED) INTO @ACTUAL_GALERA_MID_VERSION; +SELECT CAST(REGEXP_REPLACE(@ACTUAL_GALERA_VERSION,'^(\\d+)\\.(\\d+)\\.(\\d+).*','\\3') AS UNSIGNED) INTO @ACTUAL_GALERA_MINOR_VERSION; + +# For testing +#SELECT @GALERA_MAJOR_VERSION, @GALERA_MID_VERSION, @GALERA_MINOR_VERSION; +#SELECT @ACTUAL_GALERA_VERSION; +#SELECT @ACTUAL_GALERA_MAJOR_VERSION, @ACTUAL_GALERA_MID_VERSION, @ACTUAL_GALERA_MINOR_VERSION; + +if (!`SELECT (@ACTUAL_GALERA_MAJOR_VERSION > @GALERA_MAJOR_VERSION) OR + (@ACTUAL_GALERA_MAJOR_VERSION = @GALERA_MAJOR_VERSION AND @ACTUAL_GALERA_MID_VERSION > @GALERA_MID_VERSION) OR + (@ACTUAL_GALERA_MAJOR_VERSION = @GALERA_MAJOR_VERSION AND @ACTUAL_GALERA_MID_VERSION = @GALERA_MID_VERSION AND @ACTUAL_GALERA_MINOR_VERSION >= @GALERA_MINOR_VERSION) + `) { skip Test requires Galera library version $galera_version; } From 09b28b3d10af1dfca7d9f97d7a11a44873a61e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 5 Apr 2017 14:35:41 +0300 Subject: [PATCH 43/66] Fix compiler warnings on gcc 6.x. --- sql/sql_class.cc | 2 +- sql/wsrep_mysqld.h | 2 +- sql/wsrep_sst.cc | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 57c228900fe..a8db8463e8e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2177,7 +2177,7 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use, #ifdef WITH_WSREP { signalled|= mysql_lock_abort_for_thread(this, thd_table); - if (this && WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE)) + if (WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE)) { WSREP_DEBUG("remove_table_from_cache: %llu", (unsigned long long) this->real_id); diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 5ec183f7186..7f574cb996a 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -207,7 +207,7 @@ extern wsrep_seqno_t wsrep_locked_seqno; strcmp(wsrep_provider, WSREP_NONE)) #define WSREP(thd) \ - (WSREP_ON && wsrep && (thd && thd->variables.wsrep_on)) + (WSREP_ON && wsrep && (thd->variables.wsrep_on)) #define WSREP_CLIENT(thd) \ (WSREP(thd) && thd->wsrep_client_thread) diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index 877a93eec44..11698089582 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -814,7 +814,7 @@ static int sst_donate_mysqldump (const char* addr, "%s", host, port, mysqld_port, mysqld_unix_port, wsrep_defaults_file, uuid_str, - (long long)seqno, bypass ? " "WSREP_SST_OPT_BYPASS : ""); + (long long)seqno, bypass ? " " WSREP_SST_OPT_BYPASS : ""); if (ret < 0 || ret >= cmd_len) { @@ -1125,7 +1125,7 @@ static int sst_donate_other (const char* method, wsrep_defaults_file, wsrep_defaults_group_suffix, binlog_opt, binlog_opt_val, uuid, (long long) seqno, - bypass ? " "WSREP_SST_OPT_BYPASS : ""); + bypass ? " " WSREP_SST_OPT_BYPASS : ""); my_free(binlog_opt_val); if (ret < 0 || ret >= cmd_len) From e4a52670f495c01307b124d729c29c7ef21be2ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 5 Apr 2017 08:54:20 +0300 Subject: [PATCH 44/66] fix warning "ignoring return value" of fwrite. Merge pull request https://github.com/MariaDB/server/pull/343 contributed by Eric Herman. --- sql/wsrep_binlog.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc index 5cb910248a2..5c5ebb9f780 100644 --- a/sql/wsrep_binlog.cc +++ b/sql/wsrep_binlog.cc @@ -309,9 +309,13 @@ void wsrep_dump_rbr_buf(THD *thd, const void* rbr_buf, size_t buf_len) } FILE *of= fopen(filename, "wb"); + if (of) { - fwrite (rbr_buf, buf_len, 1, of); + if (fwrite(rbr_buf, buf_len, 1, of) == 0) + WSREP_ERROR("Failed to write buffer of length %llu to '%s'", + (unsigned long long)buf_len, filename); + fclose(of); } else From 10d7a2f8e0e9076596ecbe9531d0448837cabf63 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Mon, 8 May 2017 16:00:23 +0530 Subject: [PATCH 45/66] Fix galera test failures. --- sql/sql_class.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a8db8463e8e..92bccadc84b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2177,7 +2177,7 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use, #ifdef WITH_WSREP { signalled|= mysql_lock_abort_for_thread(this, thd_table); - if (WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE)) + if (this && WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE)) { WSREP_DEBUG("remove_table_from_cache: %llu", (unsigned long long) this->real_id); From 0e3170e30d2a4e8f1ed6fd4bbe935355f7370a34 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Mon, 8 May 2017 16:29:41 +0530 Subject: [PATCH 46/66] Fix galera tests part II(Fix previous commit) --- sql/sql_class.cc | 2 +- sql/wsrep_mysqld.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 92bccadc84b..a8db8463e8e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2177,7 +2177,7 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use, #ifdef WITH_WSREP { signalled|= mysql_lock_abort_for_thread(this, thd_table); - if (this && WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE)) + if (WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE)) { WSREP_DEBUG("remove_table_from_cache: %llu", (unsigned long long) this->real_id); diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 7f574cb996a..5ec183f7186 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -207,7 +207,7 @@ extern wsrep_seqno_t wsrep_locked_seqno; strcmp(wsrep_provider, WSREP_NONE)) #define WSREP(thd) \ - (WSREP_ON && wsrep && (thd->variables.wsrep_on)) + (WSREP_ON && wsrep && (thd && thd->variables.wsrep_on)) #define WSREP_CLIENT(thd) \ (WSREP(thd) && thd->wsrep_client_thread) From b8405c853fa30002d164d5fe2b4f8ea8979c09b8 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 22 May 2017 07:09:49 +0200 Subject: [PATCH 47/66] MDEV-11958: LEFT JOIN with stored routine produces incorrect result Added forgoten method of Item_func_sp to make it correctly work with LEFT/RIGHT JOIN. Fixed inconsistency with the null table caches. --- mysql-test/r/join_outer.result | 95 +++++++++++++++++++++++++++++ mysql-test/r/join_outer_jcl6.result | 95 +++++++++++++++++++++++++++++ mysql-test/t/join_outer.test | 82 +++++++++++++++++++++++++ sql/item_func.h | 29 +++++++-- 4 files changed, 297 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 5dbb0f1d8b6..5611b61a7b0 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -2245,4 +2245,99 @@ SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a WHERE b IN (1,2,3) OR b = d; a b c d DROP TABLE t1,t2,t3; +# +# MDEV-11958: LEFT JOIN with stored routine produces incorrect result +# +CREATE TABLE t (x INT); +INSERT INTO t VALUES(1),(NULL); +CREATE FUNCTION f (val INT, ret INT) RETURNS INT DETERMINISTIC RETURN IFNULL(val, ret); +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) +FROM t t1 LEFT JOIN t t2 +ON t1.x = t2.x +WHERE IFNULL(t2.x,0)=0; +x x IFNULL(t2.x,0) f(t2.x,0) +NULL NULL 0 0 +explain extended +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) +FROM t t1 LEFT JOIN t t2 +ON t1.x = t2.x +WHERE IFNULL(t2.x,0)=0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t2`.`x` AS `x`,ifnull(`test`.`t2`.`x`,0) AS `IFNULL(t2.x,0)`,`f`(`test`.`t2`.`x`,0) AS `f(t2.x,0)` from `test`.`t` `t1` left join `test`.`t` `t2` on((`test`.`t2`.`x` = `test`.`t1`.`x`)) where (ifnull(`test`.`t2`.`x`,0) = 0) +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) +FROM t t1 LEFT JOIN t t2 +ON t1.x = t2.x +WHERE f(t2.x,0)=0; +x x IFNULL(t2.x,0) f(t2.x,0) +NULL NULL 0 0 +explain extended +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) +FROM t t1 LEFT JOIN t t2 +ON t1.x = t2.x +WHERE f(t2.x,0)=0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t2`.`x` AS `x`,ifnull(`test`.`t2`.`x`,0) AS `IFNULL(t2.x,0)`,`f`(`test`.`t2`.`x`,0) AS `f(t2.x,0)` from `test`.`t` `t1` left join `test`.`t` `t2` on((`test`.`t2`.`x` = `test`.`t1`.`x`)) where (`f`(`test`.`t2`.`x`,0) = 0) +drop function f; +drop table t; +CREATE TABLE t1 ( +col1 DECIMAL(33,5) NULL DEFAULT NULL, +col2 DECIMAL(33,5) NULL DEFAULT NULL +); +CREATE TABLE t2 ( +col1 DECIMAL(33,5) NULL DEFAULT NULL, +col2 DECIMAL(33,5) NULL DEFAULT NULL, +col3 DECIMAL(33,5) NULL DEFAULT NULL +); +INSERT INTO t1 VALUES (2, 1.1), (2, 2.1); +INSERT INTO t2 VALUES (3, 3.1, 4), (1, 1, NULL); +CREATE FUNCTION f1 ( p_num DECIMAL(45,15), p_return DECIMAL(45,15)) +RETURNS decimal(33,5) +LANGUAGE SQL +DETERMINISTIC +CONTAINS SQL +SQL SECURITY INVOKER +BEGIN +IF p_num IS NULL THEN +RETURN p_return; +ELSE +RETURN p_num; +END IF; +END | +SELECT t1.col1, t2.col1, t2.col3 +FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2 +WHERE IFNULL(t2.col3,0) = 0; +col1 col1 col3 +2.00000 NULL NULL +2.00000 NULL NULL +EXPLAIN EXTENDED SELECT t1.col1, t2.col1, t2.col3 +FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2 +WHERE IFNULL(t2.col3,0) = 0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`col2` = `test`.`t1`.`col1`)) where (ifnull(`test`.`t2`.`col3`,0) = 0) +SELECT t1.col1, t2.col1, t2.col3 +FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2 +WHERE f1(t2.col3,0) = 0; +col1 col1 col3 +2.00000 NULL NULL +2.00000 NULL NULL +EXPLAIN EXTENDED SELECT t1.col1, t2.col1, t2.col3 +FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2 +WHERE f1(t2.col3,0) = 0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`col2` = `test`.`t1`.`col1`)) where (`f1`(`test`.`t2`.`col3`,0) = 0) +DROP FUNCTION f1; +DROP TABLE t1,t2; +# end of 5.5 tests SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result index bdc4be0cb8c..8a1ccc7d5e5 100644 --- a/mysql-test/r/join_outer_jcl6.result +++ b/mysql-test/r/join_outer_jcl6.result @@ -2256,6 +2256,101 @@ SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a WHERE b IN (1,2,3) OR b = d; a b c d DROP TABLE t1,t2,t3; +# +# MDEV-11958: LEFT JOIN with stored routine produces incorrect result +# +CREATE TABLE t (x INT); +INSERT INTO t VALUES(1),(NULL); +CREATE FUNCTION f (val INT, ret INT) RETURNS INT DETERMINISTIC RETURN IFNULL(val, ret); +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) +FROM t t1 LEFT JOIN t t2 +ON t1.x = t2.x +WHERE IFNULL(t2.x,0)=0; +x x IFNULL(t2.x,0) f(t2.x,0) +NULL NULL 0 0 +explain extended +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) +FROM t t1 LEFT JOIN t t2 +ON t1.x = t2.x +WHERE IFNULL(t2.x,0)=0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t2`.`x` AS `x`,ifnull(`test`.`t2`.`x`,0) AS `IFNULL(t2.x,0)`,`f`(`test`.`t2`.`x`,0) AS `f(t2.x,0)` from `test`.`t` `t1` left join `test`.`t` `t2` on((`test`.`t2`.`x` = `test`.`t1`.`x`)) where (ifnull(`test`.`t2`.`x`,0) = 0) +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) +FROM t t1 LEFT JOIN t t2 +ON t1.x = t2.x +WHERE f(t2.x,0)=0; +x x IFNULL(t2.x,0) f(t2.x,0) +NULL NULL 0 0 +explain extended +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) +FROM t t1 LEFT JOIN t t2 +ON t1.x = t2.x +WHERE f(t2.x,0)=0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t2`.`x` AS `x`,ifnull(`test`.`t2`.`x`,0) AS `IFNULL(t2.x,0)`,`f`(`test`.`t2`.`x`,0) AS `f(t2.x,0)` from `test`.`t` `t1` left join `test`.`t` `t2` on((`test`.`t2`.`x` = `test`.`t1`.`x`)) where (`f`(`test`.`t2`.`x`,0) = 0) +drop function f; +drop table t; +CREATE TABLE t1 ( +col1 DECIMAL(33,5) NULL DEFAULT NULL, +col2 DECIMAL(33,5) NULL DEFAULT NULL +); +CREATE TABLE t2 ( +col1 DECIMAL(33,5) NULL DEFAULT NULL, +col2 DECIMAL(33,5) NULL DEFAULT NULL, +col3 DECIMAL(33,5) NULL DEFAULT NULL +); +INSERT INTO t1 VALUES (2, 1.1), (2, 2.1); +INSERT INTO t2 VALUES (3, 3.1, 4), (1, 1, NULL); +CREATE FUNCTION f1 ( p_num DECIMAL(45,15), p_return DECIMAL(45,15)) +RETURNS decimal(33,5) +LANGUAGE SQL +DETERMINISTIC +CONTAINS SQL +SQL SECURITY INVOKER +BEGIN +IF p_num IS NULL THEN +RETURN p_return; +ELSE +RETURN p_num; +END IF; +END | +SELECT t1.col1, t2.col1, t2.col3 +FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2 +WHERE IFNULL(t2.col3,0) = 0; +col1 col1 col3 +2.00000 NULL NULL +2.00000 NULL NULL +EXPLAIN EXTENDED SELECT t1.col1, t2.col1, t2.col3 +FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2 +WHERE IFNULL(t2.col3,0) = 0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`col2` = `test`.`t1`.`col1`)) where (ifnull(`test`.`t2`.`col3`,0) = 0) +SELECT t1.col1, t2.col1, t2.col3 +FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2 +WHERE f1(t2.col3,0) = 0; +col1 col1 col3 +2.00000 NULL NULL +2.00000 NULL NULL +EXPLAIN EXTENDED SELECT t1.col1, t2.col1, t2.col3 +FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2 +WHERE f1(t2.col3,0) = 0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`col2` = `test`.`t1`.`col1`)) where (`f1`(`test`.`t2`.`col3`,0) = 0) +DROP FUNCTION f1; +DROP TABLE t1,t2; +# end of 5.5 tests SET optimizer_switch=@save_optimizer_switch; set join_cache_level=default; show variables like 'join_cache_level'; diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index 19c5f64de78..9645d8ad82a 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -1801,4 +1801,86 @@ SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a DROP TABLE t1,t2,t3; +--echo # +--echo # MDEV-11958: LEFT JOIN with stored routine produces incorrect result +--echo # + +CREATE TABLE t (x INT); +INSERT INTO t VALUES(1),(NULL); +CREATE FUNCTION f (val INT, ret INT) RETURNS INT DETERMINISTIC RETURN IFNULL(val, ret); + +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) + FROM t t1 LEFT JOIN t t2 + ON t1.x = t2.x + WHERE IFNULL(t2.x,0)=0; +explain extended +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) + FROM t t1 LEFT JOIN t t2 + ON t1.x = t2.x + WHERE IFNULL(t2.x,0)=0; +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) + FROM t t1 LEFT JOIN t t2 + ON t1.x = t2.x + WHERE f(t2.x,0)=0; +explain extended +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) + FROM t t1 LEFT JOIN t t2 + ON t1.x = t2.x + WHERE f(t2.x,0)=0; + +drop function f; +drop table t; +CREATE TABLE t1 ( + col1 DECIMAL(33,5) NULL DEFAULT NULL, + col2 DECIMAL(33,5) NULL DEFAULT NULL +); + +CREATE TABLE t2 ( + col1 DECIMAL(33,5) NULL DEFAULT NULL, + col2 DECIMAL(33,5) NULL DEFAULT NULL, + col3 DECIMAL(33,5) NULL DEFAULT NULL +); + +INSERT INTO t1 VALUES (2, 1.1), (2, 2.1); +INSERT INTO t2 VALUES (3, 3.1, 4), (1, 1, NULL); + +DELIMITER |; + +CREATE FUNCTION f1 ( p_num DECIMAL(45,15), p_return DECIMAL(45,15)) +RETURNS decimal(33,5) +LANGUAGE SQL +DETERMINISTIC +CONTAINS SQL +SQL SECURITY INVOKER +BEGIN + IF p_num IS NULL THEN + RETURN p_return; + ELSE + RETURN p_num; + END IF; +END | + +DELIMITER ;| + +let $q1= +SELECT t1.col1, t2.col1, t2.col3 +FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2 +WHERE IFNULL(t2.col3,0) = 0; + +eval $q1; +eval EXPLAIN EXTENDED $q1; + +let $q2= +SELECT t1.col1, t2.col1, t2.col3 +FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2 +WHERE f1(t2.col3,0) = 0; +eval $q2; +eval EXPLAIN EXTENDED $q2; + +DROP FUNCTION f1; + +DROP TABLE t1,t2; + +--echo # end of 5.5 tests + SET optimizer_switch=@save_optimizer_switch; diff --git a/sql/item_func.h b/sql/item_func.h index d60801745fe..2157c6b6b6d 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1165,7 +1165,11 @@ public: longlong val_int(); const char *func_name() const { return "coercibility"; } void fix_length_and_dec() { max_length=10; maybe_null= 0; } - table_map not_null_tables() const { return 0; } + bool eval_not_null_tables(uchar *opt_arg) + { + not_null_tables_cache= 0; + return 0; + } }; class Item_func_locate :public Item_int_func @@ -1433,7 +1437,11 @@ public: } void cleanup(); Item_result result_type () const { return udf.result_type(); } - table_map not_null_tables() const { return 0; } + bool eval_not_null_tables(uchar *opt_arg) + { + not_null_tables_cache= 0; + return 0; + } bool is_expensive() { return 1; } virtual void print(String *str, enum_query_type query_type); }; @@ -1889,7 +1897,11 @@ public: bool is_expensive_processor(uchar *arg) { return TRUE; } enum Functype functype() const { return FT_FUNC; } const char *func_name() const { return "match"; } - table_map not_null_tables() const { return 0; } + bool eval_not_null_tables(uchar *opt_arg) + { + not_null_tables_cache= 0; + return 0; + } bool fix_fields(THD *thd, Item **ref); bool eq(const Item *, bool binary_cmp) const; /* The following should be safe, even if we compare doubles */ @@ -2091,6 +2103,11 @@ public: { return TRUE; } + bool eval_not_null_tables(uchar *opt_arg) + { + not_null_tables_cache= 0; + return 0; + } }; @@ -2138,7 +2155,11 @@ public: void fix_length_and_dec(); enum Item_result result_type () const { return last_value->result_type(); } const char *func_name() const { return "last_value"; } - table_map not_null_tables() const { return 0; } + bool eval_not_null_tables(uchar *opt_arg) + { + not_null_tables_cache= 0; + return 0; + } enum_field_types field_type() const { return last_value->field_type(); } bool const_item() const { return 0; } void evaluate_sideeffects(); From 994a5f29f104124c54f0e5995036d6d4f970a3ca Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Fri, 26 May 2017 19:53:29 +0300 Subject: [PATCH 48/66] On a build without performance schema the test failed performance-schema options in option files should be loose. The tests will be skipped after have_perfschema.inc check, but if options aren't loose, the failure happens on server startup, before the check --- mysql-test/suite/perfschema/t/start_server_1_digest-master.opt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/perfschema/t/start_server_1_digest-master.opt b/mysql-test/suite/perfschema/t/start_server_1_digest-master.opt index e59be3eb02f..c3a6012fbac 100644 --- a/mysql-test/suite/perfschema/t/start_server_1_digest-master.opt +++ b/mysql-test/suite/perfschema/t/start_server_1_digest-master.opt @@ -1 +1 @@ ---performance-schema-digests-size=1 +--loose-performance-schema-digests-size=1 From 8c35f105d24a71fb34b83e38ed57ed02338be415 Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Fri, 26 May 2017 19:54:09 +0300 Subject: [PATCH 49/66] Latest additions to the list of unstable tests in 10.1.24 --- mysql-test/unstable-tests | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests index d1e9a81a226..d21035a868e 100644 --- a/mysql-test/unstable-tests +++ b/mysql-test/unstable-tests @@ -90,6 +90,7 @@ archive.mysqlhotcopy_archive : Uses mysqlhotcopy.inc modified in 10.1.23 #---------------------------------------------------------------- binlog.binlog_commit_wait : MDEV-10150 - Error: too much time elapsed +binlog.binlog_killed : MDEV-12925 - Wrong result binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint binlog.mysqladmin : Added in 10.1.24 @@ -115,7 +116,7 @@ csv.read_only : Added in 10.1.24 encryption.create_or_replace : MDEV-9359 - Assertion failure encryption.debug_key_management : Modified in 10.1.23 encryption.encrypt_and_grep : Modified in 10.1.23 -encryption.innodb-bad-key-change : Modified in 10.1.23 +encryption.innodb-bad-key-change : MDEV-12926 - Valgrind; modified in 10.1.23 encryption.innodb-bad-key-change2 : MDEV-12632 - Valgrind warnings, modified in 10.1.23 encryption.innodb-bad-key-change4 : Modified in 10.1.23 encryption.innodb-compressed-blob : Added in 10.1.23 @@ -130,7 +131,7 @@ encryption.innodb-force-corrupt : Added in 10.1.23 encryption.innodb-key-rotation-disable : Modified in 10.1.24 encryption.innodb_lotoftables : MDEV-11531 - InnoDB error encryption.innodb-missing-key : MDEV-9359 - assertion failure; also modified in 10.1.23 -encryption.innodb_onlinealter_encryption : Modified in 10.1.23 +encryption.innodb_onlinealter_encryption : MDEV-12926 - Valgrind; modified in 10.1.23 encryption.innodb-page_encryption : MDEV-10641 - mutex problem encryption.innodb-page_encryption_compression : Modified in 10.1.23 encryption.innodb-page_encryption_log_encryption : Modified in 10.1.23 @@ -169,11 +170,14 @@ galera.GAL-419 : Added in 10.1.23 galera.GAL-480 : Added in 10.1.23 galera.galera_account_management : Modified in 10.1.23 galera.galera_admin : Added in 10.1.23 +galera.galera_autoinc_sst_xtrabackup : Config modified in 10.1.24 galera.galera_bf_abort : Modified in 10.1.23 +galera.galera_defaults : Include file modified in 10.1.24 galera.galera_desync_overlapped : Added in 10.1.23 galera.galera_gcache_recover : Added in 10.1.23 galera.galera_gcache_recover_full_gcache : Added in 10.1.23 galera.galera_gcache_recover_manytrx : Added in 10.1.23 +galera.galera_gcs_fc_limit : Modified in 10.1.24 galera.galera_many_tables_pk : Modified in 10.1.23 galera.galera_restart_on_unknown_option : Added in 10.1.23 galera.galera_roles : Modified in 10.1.23 @@ -191,6 +195,7 @@ galera.lp1376747-2 : Added in 10.1.23 galera.lp1376747-3 : Added in 10.1.23 galera.lp1376747-4 : Added in 10.1.23 galera.MW-258 : Modified in 10.1.23 +galera.MW-309 : Added in 10.1.24 galera.MW-313 : Added in 10.1.23 galera.MW-328A : Added in 10.1.23 galera.MW-328B : Added in 10.1.23 @@ -200,7 +205,7 @@ galera.MW-328E : Added in 10.1.23 galera.MW-329 : Added in 10.1.23 galera.pxc-421 : Added in 10.1.23 -galera_3nodes.* : MDEV-11490 - Warnings not suppressed +galera_3nodes.* : MDEV-11490 - Warnings not suppressed; config files modified in 10.1.24 galera_3nodes.galera_safe_to_bootstrap : Added in 10.1.23 @@ -209,6 +214,7 @@ galera_3nodes.galera_safe_to_bootstrap : Added in 10.1.23 innodb.autoinc_debug : Added in 10.1.23 innodb.binlog_consistent : MDEV-10618 - Server fails to start innodb.doublewrite : MDEV-12905 - Lost connection to MySQL server +innodb.drop_table_background : Added in 10.1.24 innodb.innodb-alter-debug : Added in 10.1.23 innodb.innodb-alter-nullable : Added in 10.1.23 innodb.innodb-alter-table : MDEV-10619 - Testcase timeout @@ -330,8 +336,10 @@ rpl.rpl_temporary_error2 : MDEV-10634 - Wrong number of retries spider.* : MDEV-9329 - tests are too memory-consuming +spider.spider_fixes : MDEV-12900 - Valgrind spider.spider_fixes_part : MDEV-12900 - Valgrind +spider/bg.basic_sql : MDEV-12900 - Valgrind spider/bg.direct_aggregate : MDEV-7098 - Trying to unlock mutex that wasn't locked spider/bg.direct_aggregate_part : MDEV-7098 - Trying to unlock mutex that wasn't locked spider/bg.function : MDEV-12900 - Valgrind @@ -415,6 +423,7 @@ vcol.vcol_keys_innodb : MDEV-10639 - Testcase timeout wsrep.binlog_format : MDEV-11532 - WSREP has not yet prepared node wsrep.pool_of_threads : MDEV-12234 - Library problem on Power +wsrep.variables : Include file modified in 10.1.24 wsrep.wsrep_rpl : Modified in 10.1.23 wsrep_info.plugin : MDEV-12909 - Wrong result From e4d10e09cf318aad237143254c45458d16009f70 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Sun, 28 May 2017 00:40:36 +0530 Subject: [PATCH 50/66] MDEV-11196: Error:Run-Time Check Failure #2 - Stack around the variable 'key_buff' was corrupted, server crashes in opt_sum_query Extended keys feature disabled if the length of extended key is longer than MAX_KEY_LEN --- mysql-test/r/innodb_ext_key.result | 81 ++++++++++++++++++++++++++++++ mysql-test/t/innodb_ext_key.test | 51 +++++++++++++++++++ sql/table.cc | 39 +++++++++++++- 3 files changed, 170 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/innodb_ext_key.result b/mysql-test/r/innodb_ext_key.result index 1305be86e5a..de1323e00f8 100644 --- a/mysql-test/r/innodb_ext_key.result +++ b/mysql-test/r/innodb_ext_key.result @@ -1133,5 +1133,86 @@ where index_date_updated= 10 and index_id < 800; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range index_date_updated index_date_updated 13 NULL # Using index condition drop table t0,t1,t2; +# +# MDEV-11196: Error:Run-Time Check Failure #2 - Stack around the variable 'key_buff' +# was corrupted, server crashes in opt_sum_query +set @save_innodb_file_format= @@innodb_file_format; +set @save_innodb_large_prefix= @@innodb_large_prefix; +set global innodb_file_format = BARRACUDA; +set global innodb_large_prefix = ON; +CREATE TABLE t1 ( +pk INT, +f1 VARCHAR(3), +f2 VARCHAR(1024), +PRIMARY KEY (pk), +KEY(f2) +) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC; +INSERT INTO t1 VALUES (1,'foo','abc'),(2,'bar','def'); +SELECT MAX(t2.pk) FROM t1 t2 INNER JOIN t1 t3 ON t2.f1 = t3.f1 WHERE t2.pk <= 4; +MAX(t2.pk) +2 +drop table t1; +CREATE TABLE t1 ( +pk1 INT, +pk2 INT, +f1 VARCHAR(3), +f2 VARCHAR(1021), +PRIMARY KEY (pk1,pk2), +KEY(f2) +) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC; +INSERT INTO t1 VALUES (1,2,'2','abc'),(2,3,'3','def'); +explain format= json +select * from t1 force index(f2) where pk1 <= 5 and pk2 <=5 and f2 = 'abc' and f1 <= '3'; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t1", + "access_type": "range", + "possible_keys": ["f2"], + "key": "f2", + "key_length": "3070", + "used_key_parts": ["f2", "pk1"], + "rows": 1, + "filtered": 100, + "index_condition": "((t1.pk1 <= 5) and (t1.pk2 <= 5) and (t1.f2 = 'abc'))", + "attached_condition": "(t1.f1 <= '3')" + } + } +} +drop table t1; +CREATE TABLE t1 ( +f2 INT, +pk2 INT, +f1 VARCHAR(3), +pk1 VARCHAR(1000), +PRIMARY KEY (pk1,pk2), +KEY k1(pk1,f2) +) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC; +INSERT INTO t1 VALUES (1,2,'2','abc'),(2,3,'3','def'); +explain format= json +select * from t1 force index(k1) where f2 <= 5 and pk2 <=5 and pk1 = 'abc' and f1 <= '3'; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t1", + "access_type": "range", + "possible_keys": ["k1"], + "key": "k1", + "key_length": "3011", + "used_key_parts": ["pk1", "f2", "pk2"], + "rows": 1, + "filtered": 100, + "index_condition": "((t1.f2 <= 5) and (t1.pk2 <= 5) and (t1.pk1 = 'abc'))", + "attached_condition": "(t1.f1 <= '3')" + } + } +} +drop table t1; set optimizer_switch=@save_ext_key_optimizer_switch; +set global innodb_file_format = @save_innodb_file_format; +set global innodb_large_prefix = @save_innodb_large_prefix; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/innodb_ext_key.test b/mysql-test/t/innodb_ext_key.test index bf94b7dd3d5..c8acfc5db2e 100644 --- a/mysql-test/t/innodb_ext_key.test +++ b/mysql-test/t/innodb_ext_key.test @@ -778,5 +778,56 @@ where index_date_updated= 10 and index_id < 800; drop table t0,t1,t2; + +--echo # +--echo # MDEV-11196: Error:Run-Time Check Failure #2 - Stack around the variable 'key_buff' +--echo # was corrupted, server crashes in opt_sum_query + +set @save_innodb_file_format= @@innodb_file_format; +set @save_innodb_large_prefix= @@innodb_large_prefix; +set global innodb_file_format = BARRACUDA; +set global innodb_large_prefix = ON; + +CREATE TABLE t1 ( + pk INT, + f1 VARCHAR(3), + f2 VARCHAR(1024), + PRIMARY KEY (pk), + KEY(f2) +) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC; + +INSERT INTO t1 VALUES (1,'foo','abc'),(2,'bar','def'); +SELECT MAX(t2.pk) FROM t1 t2 INNER JOIN t1 t3 ON t2.f1 = t3.f1 WHERE t2.pk <= 4; +drop table t1; + +CREATE TABLE t1 ( + pk1 INT, + pk2 INT, + f1 VARCHAR(3), + f2 VARCHAR(1021), + PRIMARY KEY (pk1,pk2), + KEY(f2) +) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC; + +INSERT INTO t1 VALUES (1,2,'2','abc'),(2,3,'3','def'); +explain format= json +select * from t1 force index(f2) where pk1 <= 5 and pk2 <=5 and f2 = 'abc' and f1 <= '3'; +drop table t1; + +CREATE TABLE t1 ( +f2 INT, +pk2 INT, +f1 VARCHAR(3), +pk1 VARCHAR(1000), +PRIMARY KEY (pk1,pk2), +KEY k1(pk1,f2) +) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC; +INSERT INTO t1 VALUES (1,2,'2','abc'),(2,3,'3','def'); +explain format= json +select * from t1 force index(k1) where f2 <= 5 and pk2 <=5 and pk1 = 'abc' and f1 <= '3'; +drop table t1; + set optimizer_switch=@save_ext_key_optimizer_switch; +set global innodb_file_format = @save_innodb_file_format; +set global innodb_large_prefix = @save_innodb_large_prefix; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/sql/table.cc b/sql/table.cc index 37c0b630efc..a1e9ebfc0cc 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1721,6 +1721,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, keyinfo= share->key_info; uint primary_key= my_strcasecmp(system_charset_info, share->keynames.type_names[0], primary_key_name) ? MAX_KEY : 0; + KEY* key_first_info; if (primary_key >= MAX_KEY && keyinfo->flags & HA_NOSAME) { @@ -1800,19 +1801,38 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, keyinfo->name_length+1); } + if (!key) + key_first_info= keyinfo; + if (ext_key_parts > share->key_parts && key) { KEY_PART_INFO *new_key_part= (keyinfo-1)->key_part + (keyinfo-1)->ext_key_parts; uint add_keyparts_for_this_key= add_first_key_parts; + uint length_bytes= 0, len_null_byte= 0, ext_key_length= 0; + Field *field; /* Do not extend the key that contains a component defined over the beginning of a field. */ for (i= 0; i < keyinfo->user_defined_key_parts; i++) - { + { uint fieldnr= keyinfo->key_part[i].fieldnr; + field= share->field[keyinfo->key_part[i].fieldnr-1]; + + if (field->null_ptr) + len_null_byte= HA_KEY_NULL_LENGTH; + + if (field->type() == MYSQL_TYPE_BLOB || + field->real_type() == MYSQL_TYPE_VARCHAR || + field->type() == MYSQL_TYPE_GEOMETRY) + { + length_bytes= HA_KEY_BLOB_LENGTH; + } + + ext_key_length+= keyinfo->key_part[i].length + len_null_byte + + length_bytes; if (share->field[fieldnr-1]->key_length() != keyinfo->key_part[i].length) { @@ -1821,6 +1841,23 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, } } + if (add_keyparts_for_this_key) + { + for (i= 0; i < add_keyparts_for_this_key; i++) + { + uint pk_part_length= key_first_info->key_part[i].store_length; + if (keyinfo->ext_key_part_map & 1< MAX_KEY_LENGTH) + { + add_keyparts_for_this_key= i; + break; + } + ext_key_length+= pk_part_length; + } + } + } + if (add_keyparts_for_this_key < (keyinfo->ext_key_parts - keyinfo->user_defined_key_parts)) { From af4421e82d3d458ea8f19cda6376503be6c49143 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 29 May 2017 00:27:14 -0700 Subject: [PATCH 51/66] Fixed the bug mdev-12931. This corrects the patch for mdev-10006. The current code supports only those semi-join nests that are placed at the join top level. So such nests cannot depend on other tables or nests. --- mysql-test/r/subselect_innodb.result | 39 ++++++++++++++++++++++++++++ mysql-test/t/subselect_innodb.test | 35 +++++++++++++++++++++++++ sql/sql_select.cc | 3 ++- 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result index 01257c33361..240a6ab47e4 100644 --- a/mysql-test/r/subselect_innodb.result +++ b/mysql-test/r/subselect_innodb.result @@ -576,3 +576,42 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL # 2 DEPENDENT SUBQUERY t2 ref key1 key1 5 test.t1.a # Using where; Using filesort drop table t1,t2; +# +# mdev-12931: semi-join in ON expression of STRAIGHT_JOIN +# joining a base table and a mergeable derived table +# +CREATE TABLE t1 (f1 int) ENGINE=InnoDB; +INSERT INTO t1 VALUES (3),(2); +CREATE TABLE t2 (f2 int) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1),(4); +CREATE TABLE t3 (f3 int) ENGINE=InnoDB; +INSERT INTO t3 VALUES (5),(6); +CREATE TABLE t4 (f4 int) ENGINE=InnoDB; +INSERT INTO t4 VALUES (1),(8); +SELECT * +FROM t1 +INNER JOIN +( t2 STRAIGHT_JOIN ( SELECT * FROM t3 ) AS sq +ON ( 1 IN ( SELECT f4 FROM t4 ) ) ) +ON ( f1 >= f2 ); +f1 f2 f3 +3 1 5 +2 1 5 +3 1 6 +2 1 6 +EXPLAIN EXTENDED +SELECT * +FROM t1 +INNER JOIN +( t2 STRAIGHT_JOIN ( SELECT * FROM t3 ) AS sq +ON ( 1 IN ( SELECT f4 FROM t4 ) ) ) +ON ( f1 >= f2 ); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (incremental, BNL join) +3 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t2`.`f2` AS `f2`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` join `test`.`t2` semi join (`test`.`t4`) join `test`.`t3` where ((`test`.`t4`.`f4` = 1) and (`test`.`t1`.`f1` >= `test`.`t2`.`f2`)) +DROP TABLE t1,t2,t3,t4; diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test index 2451bc60fee..544bcd994ed 100644 --- a/mysql-test/t/subselect_innodb.test +++ b/mysql-test/t/subselect_innodb.test @@ -576,3 +576,38 @@ from t1; drop table t1,t2; + +--echo # +--echo # mdev-12931: semi-join in ON expression of STRAIGHT_JOIN +--echo # joining a base table and a mergeable derived table +--echo # + +CREATE TABLE t1 (f1 int) ENGINE=InnoDB; +INSERT INTO t1 VALUES (3),(2); + +CREATE TABLE t2 (f2 int) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1),(4); + +CREATE TABLE t3 (f3 int) ENGINE=InnoDB; +INSERT INTO t3 VALUES (5),(6); + +CREATE TABLE t4 (f4 int) ENGINE=InnoDB; +INSERT INTO t4 VALUES (1),(8); + +SELECT * +FROM t1 + INNER JOIN + ( t2 STRAIGHT_JOIN ( SELECT * FROM t3 ) AS sq + ON ( 1 IN ( SELECT f4 FROM t4 ) ) ) + ON ( f1 >= f2 ); + +EXPLAIN EXTENDED +SELECT * +FROM t1 + INNER JOIN + ( t2 STRAIGHT_JOIN ( SELECT * FROM t3 ) AS sq + ON ( 1 IN ( SELECT f4 FROM t4 ) ) ) + ON ( f1 >= f2 ); + +DROP TABLE t1,t2,t3,t4; + diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 559473b8c19..50f121ce47f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14493,7 +14493,8 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top, table->table->maybe_null= FALSE; table->outer_join= 0; if (!(straight_join || table->straight)) - table->dep_tables= table->embedding? table->embedding->dep_tables: 0; + table->dep_tables= table->embedding && !table->embedding->sj_subq_pred ? + table->embedding->dep_tables : 0; if (table->on_expr) { /* Add ON expression to the WHERE or upper-level ON condition. */ From 2cb94aa1b70fa01d9e5c1d8a7625415a0220a3d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 29 May 2017 13:07:23 +0300 Subject: [PATCH 52/66] MDEV-11626 innodb.innodb-change-buffer-recovery fails for xtradb buf_page_get_gen(): Remove the error log messages about page flushing and eviction when innodb_change_buffering_debug=1 is in effect. --- storage/innobase/buf/buf0buf.c | 6 ------ storage/xtradb/buf/buf0buf.c | 6 ------ 2 files changed, 12 deletions(-) diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index a5e1c045b7b..80a15ffe0d5 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -2560,14 +2560,8 @@ wait_until_unfixed: } } buf_pool_mutex_exit(buf_pool); - fprintf(stderr, - "innodb_change_buffering_debug evict %u %u\n", - (unsigned) space, (unsigned) offset); return(NULL); } else if (buf_flush_page_try(buf_pool, block)) { - fprintf(stderr, - "innodb_change_buffering_debug flush %u %u\n", - (unsigned) space, (unsigned) offset); guess = block; goto loop; } diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c index e68b0526d42..0b0a00cd1ed 100644 --- a/storage/xtradb/buf/buf0buf.c +++ b/storage/xtradb/buf/buf0buf.c @@ -2852,9 +2852,6 @@ wait_until_unfixed: } } //buf_pool_mutex_exit(buf_pool); - fprintf(stderr, - "innodb_change_buffering_debug evict %u %u\n", - (unsigned) space, (unsigned) offset); return(NULL); } else if (UNIV_UNLIKELY(buf_block_get_state(block) @@ -2875,9 +2872,6 @@ wait_until_unfixed: ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); if (buf_flush_page_try(buf_pool, block)) { - fprintf(stderr, - "innodb_change_buffering_debug flush %u %u\n", - (unsigned) space, (unsigned) offset); guess = block; goto loop; } From 2372bfaa7b4b9a40e418cbfec480d30eb84eaf21 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 29 May 2017 20:49:36 +0200 Subject: [PATCH 53/66] MDEV-12942 REGEXP_INSTR returns 1 when using brackets always use full m_SubStrVec length in pcre_exec, we don't know how many subexpressions user's regexp will have --- mysql-test/r/func_regexp_pcre.result | 9 +++++++++ mysql-test/t/func_regexp_pcre.test | 7 +++++++ sql/item_cmpfunc.cc | 4 ++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_regexp_pcre.result b/mysql-test/r/func_regexp_pcre.result index 3430940401f..85822a16e15 100644 --- a/mysql-test/r/func_regexp_pcre.result +++ b/mysql-test/r/func_regexp_pcre.result @@ -883,3 +883,12 @@ SELECT 1 FROM dual WHERE ('Alpha,Bravo,Charlie,Delta,Echo,Foxtrot,StrataCentral, 1 Warnings: Warning 1139 Got error 'pcre_exec: recursion limit of NUM exceeded' from regexp +SELECT REGEXP_INSTR('a_kollision', 'oll'); +REGEXP_INSTR('a_kollision', 'oll') +4 +SELECT REGEXP_INSTR('a_kollision', '(oll)'); +REGEXP_INSTR('a_kollision', '(oll)') +4 +SELECT REGEXP_INSTR('a_kollision', 'o([lm])\\1'); +REGEXP_INSTR('a_kollision', 'o([lm])\\1') +4 diff --git a/mysql-test/t/func_regexp_pcre.test b/mysql-test/t/func_regexp_pcre.test index 8e3adad0037..a9895506975 100644 --- a/mysql-test/t/func_regexp_pcre.test +++ b/mysql-test/t/func_regexp_pcre.test @@ -430,3 +430,10 @@ SELECT CAST(0xE001 AS BINARY) REGEXP @regCheck; --echo # MDEV-12420: Testing recursion overflow --replace_regex /[0-9]+ exceeded/NUM exceeded/ SELECT 1 FROM dual WHERE ('Alpha,Bravo,Charlie,Delta,Echo,Foxtrot,StrataCentral,Golf,Hotel,India,Juliet,Kilo,Lima,Mike,StrataL3,November,Oscar,StrataL2,Sand,P3,P4SwitchTest,Arsys,Poppa,ExtensionMgr,Arp,Quebec,Romeo,StrataApiV2,PtReyes,Sierra,SandAcl,Arrow,Artools,BridgeTest,Tango,SandT,PAlaska,Namespace,Agent,Qos,PatchPanel,ProjectReport,Ark,Gimp,Agent,SliceAgent,Arnet,Bgp,Ale,Tommy,Central,AsicPktTestLib,Hsc,SandL3,Abuild,Pca9555,Standby,ControllerDut,CalSys,SandLib,Sb820,PointV2,BfnLib,Evpn,BfnSdk,Sflow,ManagementActive,AutoTest,GatedTest,Bgp,Sand,xinetd,BfnAgentLib,bf-utils,Hello,BfnState,Eos,Artest,Qos,Scd,ThermoMgr,Uniform,EosUtils,Eb,FanController,Central,BfnL3,BfnL2,tcp_wrappers,Victor,Environment,Route,Failover,Whiskey,Xray,Gimp,BfnFixed,Strata,SoCal,XApi,Msrp,XpProfile,tcpdump,PatchPanel,ArosTest,FhTest,Arbus,XpAcl,MacConc,XpApi,telnet,QosTest,Alpha2,BfnVlan,Stp,VxlanControllerTest,MplsAgent,Bravo2,Lanz,BfnMbb,Intf,XCtrl,Unicast,SandTunnel,L3Unicast,Ipsec,MplsTest,Rsvp,EthIntf,StageMgr,Sol,MplsUtils,Nat,Ira,P4NamespaceDut,Counters,Charlie2,Aqlc,Mlag,Power,OpenFlow,Lag,RestApi,BfdTest,strongs,Sfa,CEosUtils,Adt746,MaintenanceMode,MlagDut,EosImage,IpEth,MultiProtocol,Launcher,Max3179,Snmp,Acl,IpEthTest,PhyEee,bf-syslibs,tacc,XpL2,p4-ar-switch,p4-bf-switch,LdpTest,BfnPhy,Mirroring,Phy6,Ptp' REGEXP '^((?!\b(Strata|StrataApi|StrataApiV2)\b).)*$'); + +# +# MDEV-12942 REGEXP_INSTR returns 1 when using brackets +# +SELECT REGEXP_INSTR('a_kollision', 'oll'); +SELECT REGEXP_INSTR('a_kollision', '(oll)'); +SELECT REGEXP_INSTR('a_kollision', 'o([lm])\\1'); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 4c17da46e1e..369cdeda62d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5518,7 +5518,7 @@ int Regexp_processor_pcre::pcre_exec_with_warn(const pcre *code, bool Regexp_processor_pcre::exec(const char *str, int length, int offset) { m_pcre_exec_rc= pcre_exec_with_warn(m_pcre, &m_pcre_extra, str, length, offset, 0, - m_SubStrVec, m_subpatterns_needed * 3); + m_SubStrVec, array_elements(m_SubStrVec)); return false; } @@ -5531,7 +5531,7 @@ bool Regexp_processor_pcre::exec(String *str, int offset, m_pcre_exec_rc= pcre_exec_with_warn(m_pcre, &m_pcre_extra, str->c_ptr_safe(), str->length(), offset, 0, - m_SubStrVec, m_subpatterns_needed * 3); + m_SubStrVec, array_elements(m_SubStrVec)); if (m_pcre_exec_rc > 0) { uint i; From 5e0038b376b79ee5a2f47da1e0d71caa7d8fa99c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 29 May 2017 20:57:34 +0200 Subject: [PATCH 54/66] cleanup: remove Regexp_processor_pcre::m_subpatterns_needed it's unused now. --- sql/item_cmpfunc.cc | 4 ++-- sql/item_cmpfunc.h | 7 ++----- sql/item_strfunc.cc | 4 ++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 369cdeda62d..fe79e5f083d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5589,7 +5589,7 @@ Item_func_regex::fix_length_and_dec() if (agg_arg_charsets_for_comparison(cmp_collation, args, 2)) return; - re.init(cmp_collation.collation, 0, 0); + re.init(cmp_collation.collation, 0); re.fix_owner(this, args[0], args[1]); } @@ -5613,7 +5613,7 @@ Item_func_regexp_instr::fix_length_and_dec() if (agg_arg_charsets_for_comparison(cmp_collation, args, 2)) return; - re.init(cmp_collation.collation, 0, 1); + re.init(cmp_collation.collation, 0); re.fix_owner(this, args[0], args[1]); } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 964a174f330..56c5a4afe54 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1901,7 +1901,6 @@ class Regexp_processor_pcre String m_prev_pattern; int m_pcre_exec_rc; int m_SubStrVec[30]; - uint m_subpatterns_needed; void pcre_exec_warn(int rc) const; int pcre_exec_with_warn(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, @@ -1915,15 +1914,14 @@ public: m_pcre(NULL), m_conversion_is_needed(true), m_is_const(0), m_library_flags(0), m_data_charset(&my_charset_utf8_general_ci), - m_library_charset(&my_charset_utf8_general_ci), - m_subpatterns_needed(0) + m_library_charset(&my_charset_utf8_general_ci) { m_pcre_extra.flags= PCRE_EXTRA_MATCH_LIMIT_RECURSION; m_pcre_extra.match_limit_recursion= 100L; } int default_regex_flags(); void set_recursion_limit(THD *); - void init(CHARSET_INFO *data_charset, int extra_flags, uint nsubpatterns_arg) + void init(CHARSET_INFO *data_charset, int extra_flags) { m_library_flags= default_regex_flags() | extra_flags | (data_charset != &my_charset_bin ? @@ -1937,7 +1935,6 @@ public: m_conversion_is_needed= (data_charset != &my_charset_bin) && !my_charset_same(data_charset, m_library_charset); - m_subpatterns_needed= nsubpatterns_arg; } void fix_owner(Item_func *owner, Item *subject_arg, Item *pattern_arg); bool compile(String *pattern, bool send_error); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 40c2ab8f231..c54128db964 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1278,7 +1278,7 @@ void Item_func_regexp_replace::fix_length_and_dec() if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 3)) return; max_length= MAX_BLOB_WIDTH; - re.init(collation.collation, 0, 10); + re.init(collation.collation, 0); re.fix_owner(this, args[0], args[1]); } @@ -1413,7 +1413,7 @@ void Item_func_regexp_substr::fix_length_and_dec() if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 2)) return; fix_char_length(args[0]->max_char_length()); - re.init(collation.collation, 0, 10); + re.init(collation.collation, 0); re.fix_owner(this, args[0], args[1]); } From 473f4a65e185ac0b03b8689ec833abeecac0cb9d Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Wed, 31 May 2017 11:39:21 -0400 Subject: [PATCH 55/66] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c035ad734bc..aa7108a440a 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=1 -MYSQL_VERSION_PATCH=24 +MYSQL_VERSION_PATCH=25 From 1af8bf39ca2513bfdf43a55af0b6af10d32dcebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 30 May 2017 11:30:43 +0300 Subject: [PATCH 56/66] MDEV-12113: install_db shows corruption for rest encryption with innodb_data_file_path=ibdata1:3M; Problem was that FIL_PAGE_FLUSH_LSN_OR_KEY_VERSION field that for encrypted pages even in system datafiles should contain key_version except very first page (0:0) is after encryption overwritten with flush lsn. Ported WL#7990 Repurpose FIL_PAGE_FLUSH_LSN to 10.1 The field FIL_PAGE_FLUSH_LSN_OR_KEY_VERSION is consulted during InnoDB startup. At startup, InnoDB reads the FIL_PAGE_FLUSH_LSN_OR_KEY_VERSION from the first page of each file in the InnoDB system tablespace. If there are multiple files, the minimum and maximum LSN can differ. These numbers are passed to InnoDB startup. Having the number in other files than the first file of the InnoDB system tablespace is not providing much additional value. It is conflicting with other use of the field, such as on InnoDB R-tree index pages and encryption key_version. This worklog will stop writing FIL_PAGE_FLUSH_LSN_OR_KEY_VERSION to other files than the first file of the InnoDB system tablespace (page number 0:0) when system tablespace is encrypted. If tablespace is not encrypted we continue writing FIL_PAGE_FLUSH_LSN_OR_KEY_VERSION to all first pages of system tablespace to avoid unnecessary warnings on downgrade. open_or_create_data_files(): pass only one flushed_lsn parameter xb_load_tablespaces(): pass only one flushed_lsn parameter. buf_page_create(): Improve comment about where FIL_PAGE_FIL_FLUSH_LSN_OR_KEY_VERSION is set. fil_write_flushed_lsn(): A new function, merged from fil_write_lsn_and_arch_no_to_file() and fil_write_flushed_lsn_to_data_files(). Only write to the first page of the system tablespace (page 0:0) if tablespace is encrypted, or write all first pages of system tablespace and invoke fil_flush_file_spaces(FIL_TYPE_TABLESPACE) afterwards. fil_read_first_page(): read flush_lsn and crypt_data only from first datafile. fil_open_single_table_tablespace(): Remove output of LSN, because it was only valid for the system tablespace and the undo tablespaces, not user tablespaces. fil_validate_single_table_tablespace(): Remove output of LSN. checkpoint_now_set(): Use fil_write_flushed_lsn and output a error if operation fails. Remove lsn variable from fsp_open_info. recv_recovery_from_checkpoint_start(): Remove unnecessary second flush_lsn parameter. log_empty_and_mark_files_at_shutdown(): Use fil_writte_flushed_lsn and output error if it fails. open_or_create_data_files(): Pass only one flushed_lsn variable. --- extra/mariabackup/xb0xb.h | 7 +- extra/mariabackup/xtrabackup.cc | 13 +- storage/innobase/buf/buf0buf.cc | 10 +- storage/innobase/fil/fil0fil.cc | 269 ++++++++++++------------- storage/innobase/handler/ha_innodb.cc | 11 +- storage/innobase/include/fil0fil.h | 63 +++--- storage/innobase/include/log0recv.h | 36 ++-- storage/innobase/log/log0log.cc | 13 +- storage/innobase/log/log0recv.cc | 37 ++-- storage/innobase/srv/srv0start.cc | 134 ++++++------- storage/xtradb/buf/buf0buf.cc | 10 +- storage/xtradb/fil/fil0fil.cc | 276 ++++++++++++-------------- storage/xtradb/handler/ha_innodb.cc | 11 +- storage/xtradb/include/fil0fil.h | 51 +++-- storage/xtradb/include/log0recv.h | 36 ++-- storage/xtradb/log/log0log.cc | 9 +- storage/xtradb/log/log0recv.cc | 37 ++-- storage/xtradb/srv/srv0start.cc | 138 ++++++------- 18 files changed, 557 insertions(+), 604 deletions(-) diff --git a/extra/mariabackup/xb0xb.h b/extra/mariabackup/xb0xb.h index c6e4ae22de6..4aadee82b05 100644 --- a/extra/mariabackup/xb0xb.h +++ b/extra/mariabackup/xb0xb.h @@ -27,13 +27,12 @@ extern pfs_os_file_t files[1000]; extern const char *innodb_checksum_algorithm_names[]; extern TYPELIB innodb_checksum_algorithm_typelib; extern dberr_t open_or_create_data_files( - ibool* create_new_db, + bool* create_new_db, #ifdef UNIV_LOG_ARCHIVE lsn_t* min_arch_log_no, lsn_t* max_arch_log_no, -#endif - lsn_t* min_flushed_lsn, - lsn_t* max_flushed_lsn, +#endif + lsn_t* flushed_lsn, ulint* sum_of_new_sizes) ; int diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 16a39c58d5c..5b3f1527133 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -309,8 +309,7 @@ my_bool xtrabackup_rebuild_indexes = FALSE; my_bool xtrabackup_incremental_force_scan = FALSE; /* The flushed lsn which is read from data files */ -lsn_t min_flushed_lsn= 0; -lsn_t max_flushed_lsn= 0; +lsn_t flushed_lsn= 0; /* The size of archived log file */ ib_int64_t xtrabackup_arch_file_size = 0ULL; @@ -3249,7 +3248,7 @@ xb_load_tablespaces(void) /*=====================*/ { ulint i; - ibool create_new_db; + bool create_new_db; ulint err; ulint sum_of_new_sizes; lsn_t min_arch_logno, max_arch_logno; @@ -3265,7 +3264,7 @@ xb_load_tablespaces(void) err = open_or_create_data_files(&create_new_db, &min_arch_logno, &max_arch_logno, - &min_flushed_lsn, &max_flushed_lsn, + &flushed_lsn, &sum_of_new_sizes); if (err != DB_SUCCESS) { msg("xtrabackup: Could not open or create data files.\n" @@ -6475,13 +6474,13 @@ skip_check: metadata_last_lsn); xtrabackup_archived_to_lsn = metadata_last_lsn; } - if (xtrabackup_archived_to_lsn < min_flushed_lsn) { + if (xtrabackup_archived_to_lsn < flushed_lsn) { msg("xtrabackup: error: logs applying " "lsn limit " UINT64PF " is less than " "min_flushed_lsn " UINT64PF ", there is nothing to do\n", xtrabackup_archived_to_lsn, - min_flushed_lsn); + flushed_lsn); goto error_cleanup; } } @@ -6492,7 +6491,7 @@ skip_check: */ xtrabackup_apply_log_only = srv_apply_log_only = true; - if (!xtrabackup_arch_search_files(min_flushed_lsn)) { + if (!xtrabackup_arch_search_files(flushed_lsn)) { goto error_cleanup; } diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 5cc09287350..2cb2673f7fb 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -4291,11 +4291,11 @@ buf_page_create( memset(frame + FIL_PAGE_NEXT, 0xff, 4); mach_write_to_2(frame + FIL_PAGE_TYPE, FIL_PAGE_TYPE_ALLOCATED); - /* Reset to zero the file flush lsn field in the page; if the first - page of an ibdata file is 'created' in this function into the buffer - pool then we lose the original contents of the file flush lsn stamp. - Then InnoDB could in a crash recovery print a big, false, corruption - warning if the stamp contains an lsn bigger than the ib_logfile lsn. */ + /* FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION is only used on the + following pages: + (1) The first page of the InnoDB system tablespace (page 0:0) + (2) FIL_RTREE_SPLIT_SEQ_NUM on R-tree pages + (3) key_version on encrypted pages (not page 0:0) */ memset(frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8); diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index fa606e89828..9d4a464460f 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -2211,99 +2211,70 @@ fil_set_max_space_id_if_bigger( mutex_exit(&fil_system->mutex); } -/****************************************************************//** -Writes the flushed lsn and the latest archived log number to the page header -of the first page of a data file of the system tablespace (space 0), -which is uncompressed. */ -static MY_ATTRIBUTE((warn_unused_result)) +/** Write the flushed LSN to the page header of the first page in the +system tablespace. +@param[in] lsn flushed LSN +@return DB_SUCCESS or error number */ dberr_t -fil_write_lsn_and_arch_no_to_file( -/*==============================*/ - ulint space, /*!< in: space to write to */ - ulint sum_of_sizes, /*!< in: combined size of previous files - in space, in database pages */ - lsn_t lsn, /*!< in: lsn to write */ - ulint arch_log_no MY_ATTRIBUTE((unused))) - /*!< in: archived log number to write */ +fil_write_flushed_lsn( + lsn_t lsn) { byte* buf1; byte* buf; dberr_t err; - buf1 = static_cast(mem_alloc(2 * UNIV_PAGE_SIZE)); + buf1 = static_cast(ut_malloc(2 * UNIV_PAGE_SIZE)); buf = static_cast(ut_align(buf1, UNIV_PAGE_SIZE)); - err = fil_read(TRUE, space, 0, sum_of_sizes, 0, - UNIV_PAGE_SIZE, buf, NULL, 0); - if (err == DB_SUCCESS) { - mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, - lsn); + /* Acquire system tablespace */ + fil_space_t* space = fil_space_acquire(0); - err = fil_write(TRUE, space, 0, sum_of_sizes, 0, - UNIV_PAGE_SIZE, buf, NULL, 0); - } + /* If tablespace is not encrypted, stamp flush_lsn to + first page of all system tablespace datafiles to avoid + unnecessary error messages on possible downgrade. */ + if (space->crypt_data->min_key_version == 0) { + fil_node_t* node; + ulint sum_of_sizes = 0; - mem_free(buf1); + for (node = UT_LIST_GET_FIRST(space->chain); + node != NULL; + node = UT_LIST_GET_NEXT(chain, node)) { - return(err); -} + err = fil_read(TRUE, 0, 0, sum_of_sizes, 0, + UNIV_PAGE_SIZE, buf, NULL, 0); -/****************************************************************//** -Writes the flushed lsn and the latest archived log number to the page -header of the first page of each data file in the system tablespace. -@return DB_SUCCESS or error number */ -UNIV_INTERN -dberr_t -fil_write_flushed_lsn_to_data_files( -/*================================*/ - lsn_t lsn, /*!< in: lsn to write */ - ulint arch_log_no) /*!< in: latest archived log file number */ -{ - fil_space_t* space; - fil_node_t* node; - dberr_t err; + if (err == DB_SUCCESS) { + mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, + lsn); - mutex_enter(&fil_system->mutex); - - for (space = UT_LIST_GET_FIRST(fil_system->space_list); - space != NULL; - space = UT_LIST_GET_NEXT(space_list, space)) { - - /* We only write the lsn to all existing data files which have - been open during the lifetime of the mysqld process; they are - represented by the space objects in the tablespace memory - cache. Note that all data files in the system tablespace 0 - and the UNDO log tablespaces (if separate) are always open. */ - - if (space->purpose == FIL_TABLESPACE - && !fil_is_user_tablespace_id(space->id)) { - ulint sum_of_sizes = 0; - - for (node = UT_LIST_GET_FIRST(space->chain); - node != NULL; - node = UT_LIST_GET_NEXT(chain, node)) { - - mutex_exit(&fil_system->mutex); - - err = fil_write_lsn_and_arch_no_to_file( - space->id, sum_of_sizes, lsn, - arch_log_no); - - if (err != DB_SUCCESS) { - - return(err); - } - - mutex_enter(&fil_system->mutex); + err = fil_write(TRUE, 0, 0, sum_of_sizes, 0, + UNIV_PAGE_SIZE, buf, NULL, 0); sum_of_sizes += node->size; } } + } else { + /* When system tablespace is encrypted stamp flush_lsn to + only the first page of the first datafile (rest of pages + are encrypted). */ + err = fil_read(TRUE, 0, 0, 0, 0, + UNIV_PAGE_SIZE, buf, NULL, 0); + + if (err == DB_SUCCESS) { + mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, + lsn); + + err = fil_write(TRUE, 0, 0, 0, 0, + UNIV_PAGE_SIZE, buf, NULL, 0); + } } - mutex_exit(&fil_system->mutex); + fil_flush_file_spaces(FIL_TABLESPACE); + fil_space_release(space); - return(DB_SUCCESS); + ut_free(buf1); + + return(err); } /** Check the consistency of the first data page of a tablespace @@ -2356,36 +2327,37 @@ fil_check_first_page(const page_t* page, ulint space_id, ulint flags) return("inconsistent data in space header"); } -/*******************************************************************//** -Reads the flushed lsn, arch no, space_id and tablespace flag fields from -the first page of a data file at database startup. +/** Reads the flushed lsn, arch no, space_id and tablespace flag fields from +the first page of a first data file at database startup. +@param[in] data_file open data file +@param[in] one_read_only true if first datafile is already + read +@param[out] flags FSP_SPACE_FLAGS +@param[out] space_id tablepspace ID +@param[out] min_arch_log_no min of archived log numbers in + data files +@param[out] max_arch_log_no max of archived log numbers in + data files +@param[out] flushed_lsn flushed lsn value +@param[out] crypt_data encryption crypt data @retval NULL on success, or if innodb_force_recovery is set @return pointer to an error message string */ UNIV_INTERN const char* fil_read_first_page( -/*================*/ - pfs_os_file_t data_file, /*!< in: open data file */ - ibool one_read_already, /*!< in: TRUE if min and max - parameters below already - contain sensible data */ - ulint* flags, /*!< out: FSP_SPACE_FLAGS */ - ulint* space_id, /*!< out: tablespace ID */ + pfs_os_file_t data_file, + ibool one_read_already, + ulint* flags, + ulint* space_id, #ifdef UNIV_LOG_ARCHIVE - ulint* min_arch_log_no, /*!< out: min of archived - log numbers in data files */ - ulint* max_arch_log_no, /*!< out: max of archived - log numbers in data files */ + ulint* min_arch_log_no, + ulint* max_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - lsn_t* min_flushed_lsn, /*!< out: min of flushed - lsn values in data files */ - lsn_t* max_flushed_lsn, /*!< out: max of flushed - lsn values in data files */ - fil_space_crypt_t** crypt_data) /*< out: crypt data */ + lsn_t* flushed_lsn, + fil_space_crypt_t** crypt_data) { byte* buf; byte* page; - lsn_t flushed_lsn; const char* check_msg = NULL; fil_space_crypt_t* cdata; @@ -2407,6 +2379,11 @@ fil_read_first_page( *space_id = fsp_header_get_space_id(page); *flags = fsp_header_get_flags(page); + if (flushed_lsn) { + *flushed_lsn = mach_read_from_8(page + + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + } + if (!fsp_flags_is_valid(*flags)) { ulint cflags = fsp_flags_convert_from_101(*flags); if (cflags == ULINT_UNDEFINED) { @@ -2420,33 +2397,33 @@ fil_read_first_page( } check_msg = fil_check_first_page(page, *space_id, *flags); - } - flushed_lsn = mach_read_from_8(page + - FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + /* Possible encryption crypt data is also stored only to first page + of the first datafile. */ - ulint space = fsp_header_get_space_id(page); - ulint offset = fsp_header_get_crypt_offset( - fsp_flags_get_zip_size(*flags)); + ulint offset = fsp_header_get_crypt_offset( + fsp_flags_get_zip_size(*flags)); - cdata = fil_space_read_crypt_data(space, page, offset); + cdata = fil_space_read_crypt_data(*space_id, page, offset); - if (crypt_data) { - *crypt_data = cdata; - } + if (crypt_data) { + *crypt_data = cdata; + } - /* If file space is encrypted we need to have at least some - encryption service available where to get keys */ - if (cdata && cdata->should_encrypt()) { + /* If file space is encrypted we need to have at least some + encryption service available where to get keys */ + if (cdata && cdata->should_encrypt()) { - if (!encryption_key_id_exists(cdata->key_id)) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Tablespace id %ld is encrypted but encryption service" - " or used key_id %u is not available. Can't continue opening tablespace.", - space, cdata->key_id); - - return ("table encrypted but encryption service not available."); + if (!encryption_key_id_exists(cdata->key_id)) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Tablespace id " ULINTPF + " is encrypted but encryption service" + " or used key_id %u is not available. " + "Can't continue opening tablespace.", + *space_id, cdata->key_id); + return ("table encrypted but encryption service not available."); + } } } @@ -2457,8 +2434,6 @@ fil_read_first_page( } if (!one_read_already) { - *min_flushed_lsn = flushed_lsn; - *max_flushed_lsn = flushed_lsn; #ifdef UNIV_LOG_ARCHIVE *min_arch_log_no = arch_log_no; *max_arch_log_no = arch_log_no; @@ -2466,16 +2441,11 @@ fil_read_first_page( return(NULL); } - if (*min_flushed_lsn > flushed_lsn) { - *min_flushed_lsn = flushed_lsn; - } - if (*max_flushed_lsn < flushed_lsn) { - *max_flushed_lsn = flushed_lsn; - } #ifdef UNIV_LOG_ARCHIVE if (*min_arch_log_no > arch_log_no) { *min_arch_log_no = arch_log_no; } + if (*max_arch_log_no < arch_log_no) { *max_arch_log_no = arch_log_no; } @@ -4173,6 +4143,7 @@ fil_open_single_table_tablespace( def.file = os_file_create_simple_no_error_handling( innodb_file_data_key, def.filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &def.success, atomic_writes); + if (def.success) { tablespaces_found++; } @@ -4187,11 +4158,11 @@ fil_open_single_table_tablespace( /* Read the first page of the datadir tablespace, if found. */ if (def.success) { def.check_msg = fil_read_first_page( - def.file, FALSE, &def.flags, &def.id, + def.file, false, &def.flags, &def.id, #ifdef UNIV_LOG_ARCHIVE &space_arch_log_no, &space_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - &def.lsn, &def.lsn, &def.crypt_data); + NULL, &def.crypt_data); if (table) { table->crypt_data = def.crypt_data; @@ -4200,6 +4171,7 @@ fil_open_single_table_tablespace( def.valid = !def.check_msg && def.id == id && fsp_flags_match(flags, def.flags); + if (def.valid) { valid_tablespaces_found++; } else { @@ -4213,11 +4185,11 @@ fil_open_single_table_tablespace( /* Read the first page of the remote tablespace */ if (remote.success) { remote.check_msg = fil_read_first_page( - remote.file, FALSE, &remote.flags, &remote.id, + remote.file, false, &remote.flags, &remote.id, #ifdef UNIV_LOG_ARCHIVE &remote.arch_log_no, &remote.arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - &remote.lsn, &remote.lsn, &remote.crypt_data); + NULL, &remote.crypt_data); if (table) { table->crypt_data = remote.crypt_data; @@ -4227,6 +4199,7 @@ fil_open_single_table_tablespace( /* Validate this single-table-tablespace with SYS_TABLES. */ remote.valid = !remote.check_msg && remote.id == id && fsp_flags_match(flags, remote.flags); + if (remote.valid) { valid_tablespaces_found++; } else { @@ -4241,11 +4214,11 @@ fil_open_single_table_tablespace( /* Read the first page of the datadir tablespace, if found. */ if (dict.success) { dict.check_msg = fil_read_first_page( - dict.file, FALSE, &dict.flags, &dict.id, + dict.file, false, &dict.flags, &dict.id, #ifdef UNIV_LOG_ARCHIVE &dict.arch_log_no, &dict.arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - &dict.lsn, &dict.lsn, &dict.crypt_data); + NULL, &dict.crypt_data); if (table) { table->crypt_data = dict.crypt_data; @@ -4289,26 +4262,32 @@ fil_open_single_table_tablespace( ib_logf(IB_LOG_LEVEL_ERROR, "A tablespace for %s has been found in " "multiple places;", tablename); + if (def.success) { ib_logf(IB_LOG_LEVEL_ERROR, - "Default location; %s, LSN=" LSN_PF - ", Space ID=%lu, Flags=%lu", - def.filepath, def.lsn, - (ulong) def.id, (ulong) def.flags); + "Default location; %s" + ", Space ID=" ULINTPF " , Flags=" ULINTPF " .", + def.filepath, + def.id, + def.flags); } + if (remote.success) { ib_logf(IB_LOG_LEVEL_ERROR, - "Remote location; %s, LSN=" LSN_PF - ", Space ID=%lu, Flags=%lu", - remote.filepath, remote.lsn, - (ulong) remote.id, (ulong) remote.flags); + "Remote location; %s" + ", Space ID=" ULINTPF " , Flags=" ULINTPF " .", + remote.filepath, + remote.id, + remote.flags); } + if (dict.success) { ib_logf(IB_LOG_LEVEL_ERROR, - "Dictionary location; %s, LSN=" LSN_PF - ", Space ID=%lu, Flags=%lu", - dict.filepath, dict.lsn, - (ulong) dict.id, (ulong) dict.flags); + "Dictionary location; %s" + ", Space ID=" ULINTPF " , Flags=" ULINTPF " .", + dict.filepath, + dict.id, + dict.flags); } /* Force-recovery will allow some tablespaces to be @@ -4341,6 +4320,7 @@ fil_open_single_table_tablespace( os_file_close(def.file); tablespaces_found--; } + if (dict.success && !dict.valid) { dict.success = false; os_file_close(dict.file); @@ -4348,6 +4328,7 @@ fil_open_single_table_tablespace( can be corrected below. */ tablespaces_found--; } + if (remote.success && !remote.valid) { remote.success = false; os_file_close(remote.file); @@ -4698,7 +4679,7 @@ check_first_page: #ifdef UNIV_LOG_ARCHIVE &fsp->arch_log_no, &fsp->arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - &fsp->lsn, &fsp->lsn, &fsp->crypt_data)) { + NULL, &fsp->crypt_data)) { ib_logf(IB_LOG_LEVEL_ERROR, "%s in tablespace %s (table %s)", check_msg, fsp->filepath, tablename); @@ -4928,11 +4909,11 @@ will_not_choose: if (def.success && remote.success) { ib_logf(IB_LOG_LEVEL_ERROR, "Tablespaces for %s have been found in two places;\n" - "Location 1: SpaceID: %lu LSN: %lu File: %s\n" - "Location 2: SpaceID: %lu LSN: %lu File: %s\n" + "Location 1: SpaceID: " ULINTPF " File: %s\n" + "Location 2: SpaceID: " ULINTPF " File: %s\n" "You must delete one of them.", - tablename, (ulong) def.id, (ulong) def.lsn, - def.filepath, (ulong) remote.id, (ulong) remote.lsn, + tablename, def.id, + def.filepath, remote.id, remote.filepath); def.success = FALSE; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 012d81380f1..012539d1ace 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -18221,8 +18221,15 @@ checkpoint_now_set( log_make_checkpoint_at(LSN_MAX, TRUE); fil_flush_file_spaces(FIL_LOG); } - fil_write_flushed_lsn_to_data_files(log_sys->lsn, 0); - fil_flush_file_spaces(FIL_TABLESPACE); + + dberr_t err = fil_write_flushed_lsn(log_sys->lsn); + + if (err != DB_SUCCESS) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Failed to write flush lsn to the " + "system tablespace at checkpoint err=%s", + ut_strerr(err)); + } } } diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index d546bab6862..ba440cb2a1c 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -215,7 +215,6 @@ struct fsp_open_info { ibool valid; /*!< Is the tablespace valid? */ pfs_os_file_t file; /*!< File handle */ char* filepath; /*!< File path to open */ - lsn_t lsn; /*!< Flushed LSN from header page */ ulint id; /*!< Space ID */ ulint flags; /*!< Tablespace flags */ ulint encryption_error; /*!< if an encryption error occurs */ @@ -637,17 +636,17 @@ void fil_set_max_space_id_if_bigger( /*===========================*/ ulint max_id);/*!< in: maximum known id */ + #ifndef UNIV_HOTBACKUP -/****************************************************************//** -Writes the flushed lsn and the latest archived log number to the page -header of the first page of each data file in the system tablespace. -@return DB_SUCCESS or error number */ -UNIV_INTERN + +/** Write the flushed LSN to the page header of the first page in the +system tablespace. +@param[in] lsn flushed LSN +@return DB_SUCCESS or error number */ dberr_t -fil_write_flushed_lsn_to_data_files( -/*================================*/ - lsn_t lsn, /*!< in: lsn to write */ - ulint arch_log_no); /*!< in: latest archived log file number */ +fil_write_flushed_lsn( + lsn_t lsn) + MY_ATTRIBUTE((warn_unused_result)); /** Acquire a tablespace when it could be dropped concurrently. Used by background threads that do not necessarily hold proper locks @@ -793,35 +792,37 @@ private: fil_space_t* m_space; }; -/*******************************************************************//** -Reads the flushed lsn, arch no, and tablespace flag fields from a data -file at database startup. +/** Reads the flushed lsn, arch no, space_id and tablespace flag fields from +the first page of a first data file at database startup. +@param[in] data_file open data file +@param[in] one_read_only true if first datafile is already + read +@param[out] flags FSP_SPACE_FLAGS +@param[out] space_id tablepspace ID +@param[out] min_arch_log_no min of archived log numbers in + data files +@param[out] max_arch_log_no max of archived log numbers in + data files +@param[out] flushed_lsn flushed lsn value +@param[out] crypt_data encryption crypt data @retval NULL on success, or if innodb_force_recovery is set @return pointer to an error message string */ UNIV_INTERN const char* fil_read_first_page( -/*================*/ - pfs_os_file_t data_file, /*!< in: open data file */ - ibool one_read_already, /*!< in: TRUE if min and max - parameters below already - contain sensible data */ - ulint* flags, /*!< out: FSP_SPACE_FLAGS */ - ulint* space_id, /*!< out: tablespace ID */ + pfs_os_file_t data_file, + ibool one_read_already, + ulint* flags, + ulint* space_id, #ifdef UNIV_LOG_ARCHIVE - ulint* min_arch_log_no, /*!< out: min of archived - log numbers in data files */ - ulint* max_arch_log_no, /*!< out: max of archived - log numbers in data files */ + ulint* min_arch_log_no, + ulint* max_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - lsn_t* min_flushed_lsn, /*!< out: min of flushed - lsn values in data files */ - lsn_t* max_flushed_lsn, /*!< out: max of flushed - lsn values in data files */ - fil_space_crypt_t** crypt_data) /*!< out: crypt data */ - - __attribute__((warn_unused_result)); + lsn_t* flushed_lsn, + fil_space_crypt_t** crypt_data) + MY_ATTRIBUTE((warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ + /*******************************************************************//** Parses the body of a log record written about an .ibd file operation. That is, the log record part after the standard (type, space id, page no) header of the diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h index 9ca1c46d72b..dca99f2a7a5 100644 --- a/storage/innobase/include/log0recv.h +++ b/storage/innobase/include/log0recv.h @@ -123,26 +123,25 @@ a freshly read page) */ # define recv_recover_page(jri, block) recv_recover_page_func(block) #endif /* !UNIV_HOTBACKUP */ -/********************************************************//** -Recovers from a checkpoint. When this function returns, the database is able + +/** Recovers from a checkpoint. When this function returns, the database is able to start processing of new user transactions, but the function recv_recovery_from_checkpoint_finish should be called later to complete the recovery and free the resources used in it. +@param[in] type LOG_CHECKPOINT or LOG_ARCHIVE +@param[in] limit_lsn recover up to this lsn if possible +@param[in] flushed_lsn flushed lsn from first data file @return error code or DB_SUCCESS */ UNIV_INTERN dberr_t recv_recovery_from_checkpoint_start_func( -/*=====================================*/ #ifdef UNIV_LOG_ARCHIVE - ulint type, /*!< in: LOG_CHECKPOINT or - LOG_ARCHIVE */ - lsn_t limit_lsn, /*!< in: recover up to this lsn - if possible */ + ulint type, + lsn_t limit_lsn, #endif /* UNIV_LOG_ARCHIVE */ - lsn_t min_flushed_lsn,/*!< in: min flushed lsn from - data files */ - lsn_t max_flushed_lsn);/*!< in: max flushed lsn from - data files */ + lsn_t flushed_lsn) + MY_ATTRIBUTE((warn_unused_result)); + #ifdef UNIV_LOG_ARCHIVE /** Wrapper for recv_recovery_from_checkpoint_start_func(). Recovers from a checkpoint. When this function returns, the database is able @@ -151,11 +150,10 @@ recv_recovery_from_checkpoint_finish should be called later to complete the recovery and free the resources used in it. @param type in: LOG_CHECKPOINT or LOG_ARCHIVE @param lim in: recover up to this log sequence number if possible -@param min in: minimum flushed log sequence number from data files -@param max in: maximum flushed log sequence number from data files +@param lsn in: flushed log sequence number from first data file @return error code or DB_SUCCESS */ -# define recv_recovery_from_checkpoint_start(type,lim,min,max) \ - recv_recovery_from_checkpoint_start_func(type,lim,min,max) +# define recv_recovery_from_checkpoint_start(type,lim,lsn) \ + recv_recovery_from_checkpoint_start_func(type,lim,lsn) #else /* UNIV_LOG_ARCHIVE */ /** Wrapper for recv_recovery_from_checkpoint_start_func(). Recovers from a checkpoint. When this function returns, the database is able @@ -164,12 +162,12 @@ recv_recovery_from_checkpoint_finish should be called later to complete the recovery and free the resources used in it. @param type ignored: LOG_CHECKPOINT or LOG_ARCHIVE @param lim ignored: recover up to this log sequence number if possible -@param min in: minimum flushed log sequence number from data files -@param max in: maximum flushed log sequence number from data files +@param lsn in: flushed log sequence number from first data file @return error code or DB_SUCCESS */ -# define recv_recovery_from_checkpoint_start(type,lim,min,max) \ - recv_recovery_from_checkpoint_start_func(min,max) +# define recv_recovery_from_checkpoint_start(type,lim,lsn) \ + recv_recovery_from_checkpoint_start_func(lsn) #endif /* UNIV_LOG_ARCHIVE */ + /********************************************************//** Completes recovery from a checkpoint. */ UNIV_INTERN diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 14d1f4544cd..0dc06fd4b1b 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -3246,7 +3246,9 @@ logs_empty_and_mark_files_at_shutdown(void) /*=======================================*/ { lsn_t lsn; +#ifdef UNIV_LOG_ARCHIVE ulint arch_log_no; +#endif ulint count = 0; ulint pending_io; ibool server_busy; @@ -3454,9 +3456,9 @@ wait_suspend_loop: goto loop; } +#ifdef UNIV_LOG_ARCHIVE arch_log_no = 0; -#ifdef UNIV_LOG_ARCHIVE UT_LIST_GET_FIRST(log_sys->log_groups)->archived_file_no; if (!UT_LIST_GET_FIRST(log_sys->log_groups)->archived_offset) { @@ -3511,9 +3513,14 @@ wait_suspend_loop: srv_shutdown_lsn = lsn; if (!srv_read_only_mode) { - fil_write_flushed_lsn_to_data_files(lsn, arch_log_no); + dberr_t err = fil_write_flushed_lsn(lsn); - fil_flush_file_spaces(FIL_TABLESPACE); + if (err != DB_SUCCESS) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Failed to write flush lsn to the " + "system tablespace at shutdown err=%s", + ut_strerr(err)); + } } fil_close_all_files(); diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 2dc2d419e3f..bf00cd8e8d9 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2929,22 +2929,22 @@ recv_init_crash_recovery(void) } } -/********************************************************//** -Recovers from a checkpoint. When this function returns, the database is able +/** Recovers from a checkpoint. When this function returns, the database is able to start processing of new user transactions, but the function recv_recovery_from_checkpoint_finish should be called later to complete the recovery and free the resources used in it. +@param[in] type LOG_CHECKPOINT or LOG_ARCHIVE +@param[in] limit_lsn recover up to this lsn if possible +@param[in] flushed_lsn flushed lsn from first data file @return error code or DB_SUCCESS */ UNIV_INTERN dberr_t recv_recovery_from_checkpoint_start_func( -/*=====================================*/ #ifdef UNIV_LOG_ARCHIVE - ulint type, /*!< in: LOG_CHECKPOINT or LOG_ARCHIVE */ - lsn_t limit_lsn, /*!< in: recover up to this lsn if possible */ + ulint type, + lsn_t limit_lsn, #endif /* UNIV_LOG_ARCHIVE */ - lsn_t min_flushed_lsn,/*!< in: min flushed lsn from data files */ - lsn_t max_flushed_lsn)/*!< in: max flushed lsn from data files */ + lsn_t flushed_lsn) { log_group_t* group; log_group_t* max_cp_group; @@ -3165,6 +3165,7 @@ recv_recovery_from_checkpoint_start_func( group = UT_LIST_GET_NEXT(log_groups, group); } + /* Done with startup scan. Clear the flag. */ recv_log_scan_is_startup_type = FALSE; @@ -3177,10 +3178,9 @@ recv_recovery_from_checkpoint_start_func( there is something wrong we will print a message to the user about recovery: */ - if (checkpoint_lsn != max_flushed_lsn - || checkpoint_lsn != min_flushed_lsn) { + if (checkpoint_lsn != flushed_lsn) { - if (checkpoint_lsn < max_flushed_lsn) { + if (checkpoint_lsn < flushed_lsn) { ib_logf(IB_LOG_LEVEL_WARN, "The log sequence number " @@ -3191,24 +3191,21 @@ recv_recovery_from_checkpoint_start_func( "ib_logfiles to start up the database. " "Log sequence number in the " "ib_logfiles is " LSN_PF ", log" - "sequence numbers stamped " - "to ibdata file headers are between " - "" LSN_PF " and " LSN_PF ".", + "sequence number stamped " + "to ibdata file header is " LSN_PF ".", checkpoint_lsn, - min_flushed_lsn, - max_flushed_lsn); + flushed_lsn); } if (!recv_needed_recovery) { ib_logf(IB_LOG_LEVEL_INFO, - "The log sequence numbers " - LSN_PF " and " LSN_PF - " in ibdata files do not match" + "The log sequence number " + LSN_PF + " in ibdata file do not match" " the log sequence number " LSN_PF " in the ib_logfiles!", - min_flushed_lsn, - max_flushed_lsn, + flushed_lsn, checkpoint_lsn); if (!srv_read_only_mode) { diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index be65e4a6d17..f601ff17ebc 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -786,27 +786,26 @@ open_log_file( return(DB_SUCCESS); } -/*********************************************************************//** -Creates or opens database data files and closes them. +/** Creates or opens database data files and closes them. +@param[out] create_new_db true = create new database +@param[out] min_arch_log_no min of archived log numbers in + data files +@param[out] max_arch_log_no max of archived log numbers in + data files +@param[out] flushed_lsn flushed lsn in fist datafile +@param[out] sum_of_new_sizes sum of sizes of the new files + added @return DB_SUCCESS or error code */ static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t open_or_create_data_files( -/*======================*/ - ibool* create_new_db, /*!< out: TRUE if new database should be - created */ + bool* create_new_db, #ifdef UNIV_LOG_ARCHIVE - ulint* min_arch_log_no,/*!< out: min of archived log - numbers in data files */ - ulint* max_arch_log_no,/*!< out: max of archived log - numbers in data files */ + ulint* min_arch_log_no, + ulint* max_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - lsn_t* min_flushed_lsn,/*!< out: min of flushed lsn - values in data files */ - lsn_t* max_flushed_lsn,/*!< out: max of flushed lsn - values in data files */ - ulint* sum_of_new_sizes)/*!< out: sum of sizes of the - new files added */ + lsn_t* flushed_lsn, + ulint* sum_of_new_sizes) { ibool ret; ulint i; @@ -830,7 +829,7 @@ open_or_create_data_files( *sum_of_new_sizes = 0; - *create_new_db = FALSE; + *create_new_db = false; srv_normalize_path_for_win(srv_data_home); @@ -918,12 +917,13 @@ open_or_create_data_files( } const char* check_msg; + check_msg = fil_read_first_page( files[i], FALSE, &flags, &space, #ifdef UNIV_LOG_ARCHIVE min_arch_log_no, max_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - min_flushed_lsn, max_flushed_lsn, NULL); + flushed_lsn, NULL); /* If first page is valid, don't overwrite DB. It prevents overwriting DB when mysql_install_db @@ -954,6 +954,7 @@ open_or_create_data_files( name); return(DB_ERROR); } + if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) { ut_a(!srv_read_only_mode); files[i] = os_file_create( @@ -973,7 +974,6 @@ open_or_create_data_files( } if (!ret) { - os_file_get_last_error(true); ib_logf(IB_LOG_LEVEL_ERROR, @@ -983,7 +983,6 @@ open_or_create_data_files( } if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) { - goto skip_size_check; } @@ -1010,16 +1009,15 @@ size_check: "auto-extending " "data file %s is " "of a different size " - "%lu pages (rounded " + ULINTPF " pages (rounded " "down to MB) than specified " "in the .cnf file: " - "initial %lu pages, " - "max %lu (relevant if " + "initial " ULINTPF " pages, " + "max " ULINTPF " (relevant if " "non-zero) pages!", name, - (ulong) rounded_size_pages, - (ulong) srv_data_file_sizes[i], - (ulong) + rounded_size_pages, + srv_data_file_sizes[i], srv_last_file_size_max); return(DB_ERROR); @@ -1032,12 +1030,12 @@ size_check: ib_logf(IB_LOG_LEVEL_ERROR, "Data file %s is of a different " - "size %lu pages (rounded down to MB) " + "size " ULINTPF " pages (rounded down to MB) " "than specified in the .cnf file " - "%lu pages!", + ULINTPF " pages!", name, - (ulong) rounded_size_pages, - (ulong) srv_data_file_sizes[i]); + rounded_size_pages, + srv_data_file_sizes[i]); return(DB_ERROR); } @@ -1057,7 +1055,7 @@ check_first_page: #ifdef UNIV_LOG_ARCHIVE min_arch_log_no, max_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - min_flushed_lsn, max_flushed_lsn, &crypt_data); + flushed_lsn, &crypt_data); if (check_msg) { @@ -1094,9 +1092,9 @@ check_first_page: != fsp_flags_get_page_size(flags)) { ib_logf(IB_LOG_LEVEL_ERROR, - "Data file \"%s\" uses page size %lu," + "Data file \"%s\" uses page size " ULINTPF " ," "but the start-up parameter " - "is --innodb-page-size=%lu", + "is --innodb-page-size=" ULINTPF " .", name, fsp_flags_get_page_size(flags), UNIV_PAGE_SIZE); @@ -1127,9 +1125,9 @@ check_first_page: } ib_logf(IB_LOG_LEVEL_INFO, - "Setting file %s size to %lu MB", + "Setting file %s size to " ULINTPF " MB", name, - (ulong) (srv_data_file_sizes[i] + (srv_data_file_sizes[i] >> (20 - UNIV_PAGE_SIZE_SHIFT))); ret = os_file_set_size( @@ -1592,9 +1590,8 @@ dberr_t innobase_start_or_create_for_mysql(void) /*====================================*/ { - ibool create_new_db; - lsn_t min_flushed_lsn; - lsn_t max_flushed_lsn; + bool create_new_db; + lsn_t flushed_lsn; #ifdef UNIV_LOG_ARCHIVE ulint min_arch_log_no; ulint max_arch_log_no; @@ -2152,7 +2149,7 @@ innobase_start_or_create_for_mysql(void) #ifdef UNIV_LOG_ARCHIVE &min_arch_log_no, &max_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - &min_flushed_lsn, &max_flushed_lsn, + &flushed_lsn, &sum_of_new_sizes); if (err == DB_FAIL) { @@ -2197,12 +2194,12 @@ innobase_start_or_create_for_mysql(void) bool success = buf_flush_list(ULINT_MAX, LSN_MAX, NULL); ut_a(success); - min_flushed_lsn = max_flushed_lsn = log_get_lsn(); + flushed_lsn = log_get_lsn(); buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); err = create_log_files(create_new_db, logfilename, dirnamelen, - max_flushed_lsn, logfile0); + flushed_lsn, logfile0); if (err != DB_SUCCESS) { return(err); @@ -2222,19 +2219,8 @@ innobase_start_or_create_for_mysql(void) if (err == DB_NOT_FOUND) { if (i == 0) { - if (max_flushed_lsn - != min_flushed_lsn) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Cannot create" - " log files because" - " data files are" - " corrupt or" - " not in sync" - " with each other"); - return(DB_ERROR); - } - if (max_flushed_lsn < (lsn_t) 1000) { + if (flushed_lsn < (lsn_t) 1000) { ib_logf(IB_LOG_LEVEL_ERROR, "Cannot create" " log files because" @@ -2249,14 +2235,14 @@ innobase_start_or_create_for_mysql(void) err = create_log_files( create_new_db, logfilename, - dirnamelen, max_flushed_lsn, + dirnamelen, flushed_lsn, logfile0); if (err == DB_SUCCESS) { err = create_log_files_rename( logfilename, dirnamelen, - max_flushed_lsn, + flushed_lsn, logfile0); } @@ -2266,8 +2252,7 @@ innobase_start_or_create_for_mysql(void) /* Suppress the message about crash recovery. */ - max_flushed_lsn = min_flushed_lsn - = log_get_lsn(); + flushed_lsn = log_get_lsn(); goto files_checked; } else if (i < 2) { /* must have at least 2 log files */ @@ -2422,17 +2407,19 @@ files_checked: bool success = buf_flush_list(ULINT_MAX, LSN_MAX, NULL); ut_a(success); - min_flushed_lsn = max_flushed_lsn = log_get_lsn(); + flushed_lsn = log_get_lsn(); buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); /* Stamp the LSN to the data files. */ - fil_write_flushed_lsn_to_data_files(max_flushed_lsn, 0); + err = fil_write_flushed_lsn(flushed_lsn); - fil_flush_file_spaces(FIL_TABLESPACE); + if (err != DB_SUCCESS) { + return(err); + } err = create_log_files_rename(logfilename, dirnamelen, - max_flushed_lsn, logfile0); + flushed_lsn, logfile0); if (err != DB_SUCCESS) { return(err); @@ -2504,7 +2491,7 @@ files_checked: err = recv_recovery_from_checkpoint_start( LOG_CHECKPOINT, LSN_MAX, - min_flushed_lsn, max_flushed_lsn); + flushed_lsn); if (err == DB_SUCCESS) { /* Initialize the change buffer. */ @@ -2672,7 +2659,7 @@ files_checked: DBUG_EXECUTE_IF("innodb_log_abort_1", return(DB_ERROR);); - min_flushed_lsn = max_flushed_lsn = log_get_lsn(); + flushed_lsn = log_get_lsn(); ib_logf(IB_LOG_LEVEL_WARN, "Resizing redo log from %u*%u to %u*%u pages" @@ -2681,7 +2668,7 @@ files_checked: (unsigned) srv_log_file_size, (unsigned) srv_n_log_files, (unsigned) srv_log_file_size_requested, - max_flushed_lsn); + flushed_lsn); buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); @@ -2691,7 +2678,7 @@ files_checked: we need to explicitly flush the log buffers. */ fil_flush(SRV_LOG_SPACE_FIRST_ID); - ut_ad(max_flushed_lsn == log_get_lsn()); + ut_ad(flushed_lsn == log_get_lsn()); /* Prohibit redo log writes from any other threads until creating a log checkpoint at the @@ -2703,8 +2690,7 @@ files_checked: return(DB_ERROR);); /* Stamp the LSN to the data files. */ - fil_write_flushed_lsn_to_data_files( - max_flushed_lsn, 0); + err = fil_write_flushed_lsn(flushed_lsn); DBUG_EXECUTE_IF("innodb_log_abort_4", err = DB_ERROR;); @@ -2712,8 +2698,6 @@ files_checked: return(err); } - fil_flush_file_spaces(FIL_TABLESPACE); - /* Close and free the redo log files, so that we can replace them. */ fil_close_log_files(true); @@ -2730,13 +2714,23 @@ files_checked: srv_log_file_size = srv_log_file_size_requested; err = create_log_files(create_new_db, logfilename, - dirnamelen, max_flushed_lsn, + dirnamelen, flushed_lsn, logfile0); + if (err != DB_SUCCESS) { + return(err); + } + + /* create_log_files() can increase system lsn that is + why FIL_PAGE_FILE_FLUSH_LSN have to be updated */ + flushed_lsn = log_get_lsn(); + + err = fil_write_flushed_lsn(flushed_lsn); + if (err == DB_SUCCESS) { err = create_log_files_rename( logfilename, dirnamelen, - max_flushed_lsn, logfile0); + flushed_lsn, logfile0); } if (err != DB_SUCCESS) { diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc index 8ee85d0ecd8..7c30ff92b69 100644 --- a/storage/xtradb/buf/buf0buf.cc +++ b/storage/xtradb/buf/buf0buf.cc @@ -4371,11 +4371,11 @@ buf_page_create( memset(frame + FIL_PAGE_NEXT, 0xff, 4); mach_write_to_2(frame + FIL_PAGE_TYPE, FIL_PAGE_TYPE_ALLOCATED); - /* Reset to zero the file flush lsn field in the page; if the first - page of an ibdata file is 'created' in this function into the buffer - pool then we lose the original contents of the file flush lsn stamp. - Then InnoDB could in a crash recovery print a big, false, corruption - warning if the stamp contains an lsn bigger than the ib_logfile lsn. */ + /* FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION is only used on the + following pages: + (1) The first page of the InnoDB system tablespace (page 0:0) + (2) FIL_RTREE_SPLIT_SEQ_NUM on R-tree pages + (3) key_version on encrypted pages (not page 0:0) */ memset(frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8); diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index 09ba89459ad..17e9a1be973 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -2265,99 +2265,70 @@ fil_set_max_space_id_if_bigger( mutex_exit(&fil_system->mutex); } -/****************************************************************//** -Writes the flushed lsn and the latest archived log number to the page header -of the first page of a data file of the system tablespace (space 0), -which is uncompressed. */ -static MY_ATTRIBUTE((warn_unused_result)) +/** Write the flushed LSN to the page header of the first page in the +system tablespace. +@param[in] lsn flushed LSN +@return DB_SUCCESS or error number */ dberr_t -fil_write_lsn_and_arch_no_to_file( -/*==============================*/ - ulint space, /*!< in: space to write to */ - ulint sum_of_sizes, /*!< in: combined size of previous files - in space, in database pages */ - lsn_t lsn, /*!< in: lsn to write */ - ulint arch_log_no MY_ATTRIBUTE((unused))) - /*!< in: archived log number to write */ +fil_write_flushed_lsn( + lsn_t lsn) { byte* buf1; byte* buf; dberr_t err; - buf1 = static_cast(mem_alloc(2 * UNIV_PAGE_SIZE)); + buf1 = static_cast(ut_malloc(2 * UNIV_PAGE_SIZE)); buf = static_cast(ut_align(buf1, UNIV_PAGE_SIZE)); - err = fil_read(TRUE, space, 0, sum_of_sizes, 0, - UNIV_PAGE_SIZE, buf, NULL, 0); - if (err == DB_SUCCESS) { - mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, - lsn); + /* Acquire system tablespace */ + fil_space_t* space = fil_space_acquire(0); - err = fil_write(TRUE, space, 0, sum_of_sizes, 0, - UNIV_PAGE_SIZE, buf, NULL, 0); - } + /* If tablespace is not encrypted, stamp flush_lsn to + first page of all system tablespace datafiles to avoid + unnecessary error messages on possible downgrade. */ + if (space->crypt_data->min_key_version == 0) { + fil_node_t* node; + ulint sum_of_sizes = 0; - mem_free(buf1); + for (node = UT_LIST_GET_FIRST(space->chain); + node != NULL; + node = UT_LIST_GET_NEXT(chain, node)) { - return(err); -} + err = fil_read(TRUE, 0, 0, sum_of_sizes, 0, + UNIV_PAGE_SIZE, buf, NULL, 0); -/****************************************************************//** -Writes the flushed lsn and the latest archived log number to the page -header of the first page of each data file in the system tablespace. -@return DB_SUCCESS or error number */ -UNIV_INTERN -dberr_t -fil_write_flushed_lsn_to_data_files( -/*================================*/ - lsn_t lsn, /*!< in: lsn to write */ - ulint arch_log_no) /*!< in: latest archived log file number */ -{ - fil_space_t* space; - fil_node_t* node; - dberr_t err; + if (err == DB_SUCCESS) { + mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, + lsn); - mutex_enter(&fil_system->mutex); - - for (space = UT_LIST_GET_FIRST(fil_system->space_list); - space != NULL; - space = UT_LIST_GET_NEXT(space_list, space)) { - - /* We only write the lsn to all existing data files which have - been open during the lifetime of the mysqld process; they are - represented by the space objects in the tablespace memory - cache. Note that all data files in the system tablespace 0 - and the UNDO log tablespaces (if separate) are always open. */ - - if (space->purpose == FIL_TABLESPACE - && !fil_is_user_tablespace_id(space->id)) { - ulint sum_of_sizes = 0; - - for (node = UT_LIST_GET_FIRST(space->chain); - node != NULL; - node = UT_LIST_GET_NEXT(chain, node)) { - - mutex_exit(&fil_system->mutex); - - err = fil_write_lsn_and_arch_no_to_file( - space->id, sum_of_sizes, lsn, - arch_log_no); - - if (err != DB_SUCCESS) { - - return(err); - } - - mutex_enter(&fil_system->mutex); + err = fil_write(TRUE, 0, 0, sum_of_sizes, 0, + UNIV_PAGE_SIZE, buf, NULL, 0); sum_of_sizes += node->size; } } + } else { + /* When system tablespace is encrypted stamp flush_lsn to + only the first page of the first datafile (rest of pages + are encrypted). */ + err = fil_read(TRUE, 0, 0, 0, 0, + UNIV_PAGE_SIZE, buf, NULL, 0); + + if (err == DB_SUCCESS) { + mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, + lsn); + + err = fil_write(TRUE, 0, 0, 0, 0, + UNIV_PAGE_SIZE, buf, NULL, 0); + } } - mutex_exit(&fil_system->mutex); + fil_flush_file_spaces(FIL_TABLESPACE); + fil_space_release(space); - return(DB_SUCCESS); + ut_free(buf1); + + return(err); } /** Check the consistency of the first data page of a tablespace @@ -2410,30 +2381,29 @@ fil_check_first_page(const page_t* page, ulint space_id, ulint flags) return("inconsistent data in space header"); } -/*******************************************************************//** -Reads the flushed lsn, arch no, space_id and tablespace flag fields from -the first page of a data file at database startup. +/** Reads the flushed lsn, arch no, space_id and tablespace flag fields from +the first page of a first data file at database startup. +@param[in] data_file open data file +@param[in] one_read_only true if first datafile is already + read +@param[out] flags FSP_SPACE_FLAGS +@param[out] space_id tablepspace ID +@param[out] flushed_lsn flushed lsn value +@param[out] crypt_data encryption crypt data @retval NULL on success, or if innodb_force_recovery is set @return pointer to an error message string */ UNIV_INTERN const char* fil_read_first_page( -/*================*/ - pfs_os_file_t data_file, /*!< in: open data file */ - ibool one_read_already, /*!< in: TRUE if min and max - parameters below already - contain sensible data */ - ulint* flags, /*!< out: FSP_SPACE_FLAGS */ - ulint* space_id, /*!< out: tablespace ID */ - lsn_t* min_flushed_lsn, /*!< out: min of flushed - lsn values in data files */ - lsn_t* max_flushed_lsn, /*!< out: max of flushed - lsn values in data files */ - fil_space_crypt_t** crypt_data) /*< out: crypt data */ + pfs_os_file_t data_file, + ibool one_read_already, + ulint* flags, + ulint* space_id, + lsn_t* flushed_lsn, + fil_space_crypt_t** crypt_data) { byte* buf; byte* page; - lsn_t flushed_lsn; const char* check_msg = NULL; fil_space_crypt_t* cdata; @@ -2450,6 +2420,7 @@ fil_read_first_page( return "File size is less than minimum"; } } + buf = static_cast(ut_malloc(2 * UNIV_PAGE_SIZE)); /* Align the memory for a possible read from a raw device */ @@ -2468,6 +2439,11 @@ fil_read_first_page( *space_id = fsp_header_get_space_id(page); *flags = fsp_header_get_flags(page); + if (flushed_lsn) { + *flushed_lsn = mach_read_from_8(page + + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + } + if (!fsp_flags_is_valid(*flags)) { ulint cflags = fsp_flags_convert_from_101(*flags); if (cflags == ULINT_UNDEFINED) { @@ -2480,37 +2456,36 @@ fil_read_first_page( } } - if (!(IS_XTRABACKUP() && srv_backup_mode)) { - check_msg = fil_check_first_page(page, *space_id, *flags); + if (!(IS_XTRABACKUP() && srv_backup_mode)) { + check_msg = fil_check_first_page(page, *space_id, *flags); } - } - flushed_lsn = mach_read_from_8(page + - FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + /* Possible encryption crypt data is also stored only to first page + of the first datafile. */ + ulint offset = fsp_header_get_crypt_offset( + fsp_flags_get_zip_size(*flags)); - ulint space = fsp_header_get_space_id(page); - ulint offset = fsp_header_get_crypt_offset( - fsp_flags_get_zip_size(*flags)); + cdata = fil_space_read_crypt_data(*space_id, page, offset); - cdata = fil_space_read_crypt_data(space, page, offset); + if (crypt_data) { + *crypt_data = cdata; + } - if (crypt_data) { - *crypt_data = cdata; - } + /* If file space is encrypted we need to have at least some + encryption service available where to get keys */ + if (cdata && cdata->should_encrypt()) { - /* If file space is encrypted we need to have at least some - encryption service available where to get keys */ - if (cdata && cdata->should_encrypt()) { - - if (!encryption_key_id_exists(cdata->key_id)) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Tablespace id %ld is encrypted but encryption service" - " or used key_id %u is not available. Can't continue opening tablespace.", - space, cdata->key_id); - - return ("table encrypted but encryption service not available."); + if (!encryption_key_id_exists(cdata->key_id)) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Tablespace id " ULINTPF + " is encrypted but encryption service" + " or used key_id %u is not available. " + "Can't continue opening tablespace.", + *space_id, cdata->key_id); + return ("table encrypted but encryption service not available."); + } } } @@ -2520,20 +2495,6 @@ fil_read_first_page( return(check_msg); } - if (!one_read_already) { - *min_flushed_lsn = flushed_lsn; - *max_flushed_lsn = flushed_lsn; - - return(NULL); - } - - if (*min_flushed_lsn > flushed_lsn) { - *min_flushed_lsn = flushed_lsn; - } - if (*max_flushed_lsn < flushed_lsn) { - *max_flushed_lsn = flushed_lsn; - } - return(NULL); } @@ -4377,6 +4338,7 @@ fil_open_single_table_tablespace( def.file = os_file_create_simple_no_error_handling( innodb_file_data_key, def.filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &def.success, atomic_writes); + if (def.success) { tablespaces_found++; } @@ -4391,8 +4353,8 @@ fil_open_single_table_tablespace( /* Read the first page of the datadir tablespace, if found. */ if (def.success) { def.check_msg = fil_read_first_page( - def.file, FALSE, &def.flags, &def.id, - &def.lsn, &def.lsn, &def.crypt_data); + def.file, false, &def.flags, &def.id, + NULL, &def.crypt_data); if (table) { table->crypt_data = def.crypt_data; @@ -4401,6 +4363,7 @@ fil_open_single_table_tablespace( def.valid = !def.check_msg && def.id == id && fsp_flags_match(flags, def.flags); + if (def.valid) { valid_tablespaces_found++; } else { @@ -4414,8 +4377,8 @@ fil_open_single_table_tablespace( /* Read the first page of the remote tablespace */ if (remote.success) { remote.check_msg = fil_read_first_page( - remote.file, FALSE, &remote.flags, &remote.id, - &remote.lsn, &remote.lsn, &remote.crypt_data); + remote.file, false, &remote.flags, &remote.id, + NULL, &remote.crypt_data); if (table) { table->crypt_data = remote.crypt_data; @@ -4425,6 +4388,7 @@ fil_open_single_table_tablespace( /* Validate this single-table-tablespace with SYS_TABLES. */ remote.valid = !remote.check_msg && remote.id == id && fsp_flags_match(flags, remote.flags); + if (remote.valid) { valid_tablespaces_found++; } else { @@ -4439,8 +4403,8 @@ fil_open_single_table_tablespace( /* Read the first page of the datadir tablespace, if found. */ if (dict.success) { dict.check_msg = fil_read_first_page( - dict.file, FALSE, &dict.flags, &dict.id, - &dict.lsn, &dict.lsn, &dict.crypt_data); + dict.file, false, &dict.flags, &dict.id, + NULL, &dict.crypt_data); if (table) { table->crypt_data = dict.crypt_data; @@ -4472,14 +4436,16 @@ fil_open_single_table_tablespace( "See " REFMAN "innodb-troubleshooting-datadict.html " "for how to resolve the issue.", tablename); + if (IS_XTRABACKUP() && fix_dict) { ib_logf(IB_LOG_LEVEL_WARN, - "It will be removed from the data dictionary."); + "It will be removed from the data dictionary."); if (purge_sys) { fil_remove_invalid_table_from_data_dict(tablename); } } + err = DB_CORRUPTION; goto cleanup_and_exit; @@ -4491,26 +4457,32 @@ fil_open_single_table_tablespace( ib_logf(IB_LOG_LEVEL_ERROR, "A tablespace for %s has been found in " "multiple places;", tablename); + if (def.success) { ib_logf(IB_LOG_LEVEL_ERROR, - "Default location; %s, LSN=" LSN_PF - ", Space ID=%lu, Flags=%lu", - def.filepath, def.lsn, - (ulong) def.id, (ulong) def.flags); + "Default location; %s" + ", Space ID=" ULINTPF " , Flags=" ULINTPF " .", + def.filepath, + def.id, + def.flags); } + if (remote.success) { ib_logf(IB_LOG_LEVEL_ERROR, - "Remote location; %s, LSN=" LSN_PF - ", Space ID=%lu, Flags=%lu", - remote.filepath, remote.lsn, - (ulong) remote.id, (ulong) remote.flags); + "Remote location; %s" + ", Space ID=" ULINTPF " , Flags=" ULINTPF " .", + remote.filepath, + remote.id, + remote.flags); } + if (dict.success) { ib_logf(IB_LOG_LEVEL_ERROR, - "Dictionary location; %s, LSN=" LSN_PF - ", Space ID=%lu, Flags=%lu", - dict.filepath, dict.lsn, - (ulong) dict.id, (ulong) dict.flags); + "Dictionary location; %s" + ", Space ID=" ULINTPF " , Flags=" ULINTPF " .", + dict.filepath, + dict.id, + dict.flags); } /* Force-recovery will allow some tablespaces to be @@ -4543,6 +4515,7 @@ fil_open_single_table_tablespace( os_file_close(def.file); tablespaces_found--; } + if (dict.success && !dict.valid) { dict.success = false; os_file_close(dict.file); @@ -4895,8 +4868,8 @@ fil_validate_single_table_tablespace( check_first_page: fsp->success = TRUE; if (const char* check_msg = fil_read_first_page( - fsp->file, FALSE, &fsp->flags, &fsp->id, - &fsp->lsn, &fsp->lsn, &fsp->crypt_data)) { + fsp->file, false, &fsp->flags, &fsp->id, + NULL, &fsp->crypt_data)) { ib_logf(IB_LOG_LEVEL_ERROR, "%s in tablespace %s (table %s)", check_msg, fsp->filepath, tablename); @@ -4909,6 +4882,7 @@ check_first_page: in Xtrabackup, this does not work.*/ return; } + if (!restore_attempted) { if (!fil_user_tablespace_find_space_id(fsp)) { return; @@ -5152,11 +5126,11 @@ will_not_choose: if (def.success && remote.success) { ib_logf(IB_LOG_LEVEL_ERROR, "Tablespaces for %s have been found in two places;\n" - "Location 1: SpaceID: %lu LSN: %lu File: %s\n" - "Location 2: SpaceID: %lu LSN: %lu File: %s\n" + "Location 1: SpaceID: " ULINTPF " File: %s\n" + "Location 2: SpaceID: " ULINTPF " File: %s\n" "You must delete one of them.", - tablename, (ulong) def.id, (ulong) def.lsn, - def.filepath, (ulong) remote.id, (ulong) remote.lsn, + tablename, def.id, + def.filepath, remote.id, remote.filepath); def.success = FALSE; diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index f4576dac03a..dd5d041aed9 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -19238,8 +19238,15 @@ checkpoint_now_set( log_make_checkpoint_at(LSN_MAX, TRUE); fil_flush_file_spaces(FIL_LOG); } - fil_write_flushed_lsn_to_data_files(log_sys->lsn, 0); - fil_flush_file_spaces(FIL_TABLESPACE); + + dberr_t err = fil_write_flushed_lsn(log_sys->lsn); + + if (err != DB_SUCCESS) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Failed to write flush lsn to the " + "system tablespace at checkpoint err=%s", + ut_strerr(err)); + } } } diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index a4e147b9797..b861225f562 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -212,7 +212,6 @@ struct fsp_open_info { ibool valid; /*!< Is the tablespace valid? */ pfs_os_file_t file; /*!< File handle */ char* filepath; /*!< File path to open */ - lsn_t lsn; /*!< Flushed LSN from header page */ ulint id; /*!< Space ID */ ulint flags; /*!< Tablespace flags */ ulint encryption_error; /*!< if an encryption error occurs */ @@ -643,17 +642,17 @@ void fil_set_max_space_id_if_bigger( /*===========================*/ ulint max_id);/*!< in: maximum known id */ + #ifndef UNIV_HOTBACKUP -/****************************************************************//** -Writes the flushed lsn and the latest archived log number to the page -header of the first page of each data file in the system tablespace. -@return DB_SUCCESS or error number */ -UNIV_INTERN + +/** Write the flushed LSN to the page header of the first page in the +system tablespace. +@param[in] lsn flushed LSN +@return DB_SUCCESS or error number */ dberr_t -fil_write_flushed_lsn_to_data_files( -/*================================*/ - lsn_t lsn, /*!< in: lsn to write */ - ulint arch_log_no); /*!< in: latest archived log file number */ +fil_write_flushed_lsn( + lsn_t lsn) + MY_ATTRIBUTE((warn_unused_result)); /** Acquire a tablespace when it could be dropped concurrently. Used by background threads that do not necessarily hold proper locks @@ -799,28 +798,28 @@ private: fil_space_t* m_space; }; -/*******************************************************************//** -Reads the flushed lsn, arch no, and tablespace flag fields from a data -file at database startup. +/** Reads the flushed lsn, arch no, space_id and tablespace flag fields from +the first page of a first data file at database startup. +@param[in] data_file open data file +@param[in] one_read_only true if first datafile is already + read +@param[out] flags FSP_SPACE_FLAGS +@param[out] space_id tablepspace ID +@param[out] flushed_lsn flushed lsn value +@param[out] crypt_data encryption crypt data @retval NULL on success, or if innodb_force_recovery is set @return pointer to an error message string */ UNIV_INTERN const char* fil_read_first_page( -/*================*/ - pfs_os_file_t data_file, /*!< in: open data file */ - ibool one_read_already, /*!< in: TRUE if min and max - parameters below already - contain sensible data */ - ulint* flags, /*!< out: FSP_SPACE_FLAGS */ - ulint* space_id, /*!< out: tablespace ID */ - lsn_t* min_flushed_lsn, /*!< out: min of flushed - lsn values in data files */ - lsn_t* max_flushed_lsn, /*!< out: max of flushed - lsn values in data files */ - fil_space_crypt_t** crypt_data) /*!< out: crypt data */ + pfs_os_file_t data_file, + ibool one_read_already, + ulint* flags, + ulint* space_id, + lsn_t* flushed_lsn, + fil_space_crypt_t** crypt_data) + MY_ATTRIBUTE((warn_unused_result)); - __attribute__((warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ /*******************************************************************//** Parses the body of a log record written about an .ibd file operation. That is, diff --git a/storage/xtradb/include/log0recv.h b/storage/xtradb/include/log0recv.h index e7b6a937f01..73d53d2ddab 100644 --- a/storage/xtradb/include/log0recv.h +++ b/storage/xtradb/include/log0recv.h @@ -137,26 +137,25 @@ a freshly read page) */ # define recv_recover_page(jri, block) recv_recover_page_func(block) #endif /* !UNIV_HOTBACKUP */ -/********************************************************//** -Recovers from a checkpoint. When this function returns, the database is able + +/** Recovers from a checkpoint. When this function returns, the database is able to start processing of new user transactions, but the function recv_recovery_from_checkpoint_finish should be called later to complete the recovery and free the resources used in it. +@param[in] type LOG_CHECKPOINT or LOG_ARCHIVE +@param[in] limit_lsn recover up to this lsn if possible +@param[in] flushed_lsn flushed lsn from first data file @return error code or DB_SUCCESS */ UNIV_INTERN dberr_t recv_recovery_from_checkpoint_start_func( -/*=====================================*/ #ifdef UNIV_LOG_ARCHIVE - ulint type, /*!< in: LOG_CHECKPOINT or - LOG_ARCHIVE */ - lsn_t limit_lsn, /*!< in: recover up to this lsn - if possible */ + ulint type, + lsn_t limit_lsn, #endif /* UNIV_LOG_ARCHIVE */ - lsn_t min_flushed_lsn,/*!< in: min flushed lsn from - data files */ - lsn_t max_flushed_lsn);/*!< in: max flushed lsn from - data files */ + lsn_t flushed_lsn) + MY_ATTRIBUTE((warn_unused_result)); + #ifdef UNIV_LOG_ARCHIVE /** Wrapper for recv_recovery_from_checkpoint_start_func(). Recovers from a checkpoint. When this function returns, the database is able @@ -165,11 +164,10 @@ recv_recovery_from_checkpoint_finish should be called later to complete the recovery and free the resources used in it. @param type in: LOG_CHECKPOINT or LOG_ARCHIVE @param lim in: recover up to this log sequence number if possible -@param min in: minimum flushed log sequence number from data files -@param max in: maximum flushed log sequence number from data files +@param lsn in: flushed log sequence number from first data file @return error code or DB_SUCCESS */ -# define recv_recovery_from_checkpoint_start(type,lim,min,max) \ - recv_recovery_from_checkpoint_start_func(type,lim,min,max) +# define recv_recovery_from_checkpoint_start(type,lim,lsn) \ + recv_recovery_from_checkpoint_start_func(type,lim,lsn) #else /* UNIV_LOG_ARCHIVE */ /** Wrapper for recv_recovery_from_checkpoint_start_func(). Recovers from a checkpoint. When this function returns, the database is able @@ -178,12 +176,12 @@ recv_recovery_from_checkpoint_finish should be called later to complete the recovery and free the resources used in it. @param type ignored: LOG_CHECKPOINT or LOG_ARCHIVE @param lim ignored: recover up to this log sequence number if possible -@param min in: minimum flushed log sequence number from data files -@param max in: maximum flushed log sequence number from data files +@param lsn in: flushed log sequence number from first data file @return error code or DB_SUCCESS */ -# define recv_recovery_from_checkpoint_start(type,lim,min,max) \ - recv_recovery_from_checkpoint_start_func(min,max) +# define recv_recovery_from_checkpoint_start(type,lim,lsn) \ + recv_recovery_from_checkpoint_start_func(lsn) #endif /* UNIV_LOG_ARCHIVE */ + /********************************************************//** Completes recovery from a checkpoint. */ UNIV_INTERN diff --git a/storage/xtradb/log/log0log.cc b/storage/xtradb/log/log0log.cc index eae7f2bb09b..3252cd793c9 100644 --- a/storage/xtradb/log/log0log.cc +++ b/storage/xtradb/log/log0log.cc @@ -3836,9 +3836,14 @@ wait_suspend_loop: srv_shutdown_lsn = lsn; if (!srv_read_only_mode) { - fil_write_flushed_lsn_to_data_files(lsn, 0); + dberr_t err = fil_write_flushed_lsn(lsn); - fil_flush_file_spaces(FIL_TABLESPACE); + if (err != DB_SUCCESS) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Failed to write flush lsn to the " + "system tablespace at shutdown err=%s", + ut_strerr(err)); + } } fil_close_all_files(); diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index 0b797fd6c23..037bc9d35d3 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -3019,22 +3019,22 @@ recv_init_crash_recovery(void) } } -/********************************************************//** -Recovers from a checkpoint. When this function returns, the database is able +/** Recovers from a checkpoint. When this function returns, the database is able to start processing of new user transactions, but the function recv_recovery_from_checkpoint_finish should be called later to complete the recovery and free the resources used in it. +@param[in] type LOG_CHECKPOINT or LOG_ARCHIVE +@param[in] limit_lsn recover up to this lsn if possible +@param[in] flushed_lsn flushed lsn from first data file @return error code or DB_SUCCESS */ UNIV_INTERN dberr_t recv_recovery_from_checkpoint_start_func( -/*=====================================*/ #ifdef UNIV_LOG_ARCHIVE - ulint type, /*!< in: LOG_CHECKPOINT or LOG_ARCHIVE */ - lsn_t limit_lsn, /*!< in: recover up to this lsn if possible */ + ulint type, + lsn_t limit_lsn, #endif /* UNIV_LOG_ARCHIVE */ - lsn_t min_flushed_lsn,/*!< in: min flushed lsn from data files */ - lsn_t max_flushed_lsn)/*!< in: max flushed lsn from data files */ + lsn_t flushed_lsn) { log_group_t* group; log_group_t* max_cp_group; @@ -3262,6 +3262,7 @@ recv_recovery_from_checkpoint_start_func( group = UT_LIST_GET_NEXT(log_groups, group); } + /* Done with startup scan. Clear the flag. */ recv_log_scan_is_startup_type = FALSE; @@ -3274,10 +3275,9 @@ recv_recovery_from_checkpoint_start_func( there is something wrong we will print a message to the user about recovery: */ - if (checkpoint_lsn != max_flushed_lsn - || checkpoint_lsn != min_flushed_lsn) { + if (checkpoint_lsn != flushed_lsn) { - if (checkpoint_lsn < max_flushed_lsn) { + if (checkpoint_lsn > (20 - UNIV_PAGE_SIZE_SHIFT))); ret = os_file_set_size( @@ -1655,9 +1654,8 @@ dberr_t innobase_start_or_create_for_mysql(void) /*====================================*/ { - ibool create_new_db; - lsn_t min_flushed_lsn; - lsn_t max_flushed_lsn; + bool create_new_db; + lsn_t flushed_lsn; #ifdef UNIV_LOG_ARCHIVE lsn_t min_arch_log_no = LSN_MAX; lsn_t max_arch_log_no = LSN_MAX; @@ -2237,7 +2235,7 @@ innobase_start_or_create_for_mysql(void) #ifdef UNIV_LOG_ARCHIVE &min_arch_log_no, &max_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - &min_flushed_lsn, &max_flushed_lsn, + &flushed_lsn, &sum_of_new_sizes); if (err == DB_FAIL) { @@ -2281,12 +2279,12 @@ innobase_start_or_create_for_mysql(void) bool success = buf_flush_list(ULINT_MAX, LSN_MAX, NULL); ut_a(success); - min_flushed_lsn = max_flushed_lsn = log_get_lsn(); + flushed_lsn = log_get_lsn(); buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); err = create_log_files(create_new_db, logfilename, dirnamelen, - max_flushed_lsn, logfile0); + flushed_lsn, logfile0); if (err != DB_SUCCESS) { return(err); @@ -2306,19 +2304,8 @@ innobase_start_or_create_for_mysql(void) if (err == DB_NOT_FOUND) { if (i == 0) { - if (max_flushed_lsn - != min_flushed_lsn) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Cannot create" - " log files because" - " data files are" - " corrupt or" - " not in sync" - " with each other"); - return(DB_ERROR); - } - if (max_flushed_lsn < (lsn_t) 1000) { + if (flushed_lsn < (lsn_t) 1000) { ib_logf(IB_LOG_LEVEL_ERROR, "Cannot create" " log files because" @@ -2333,14 +2320,14 @@ innobase_start_or_create_for_mysql(void) err = create_log_files( create_new_db, logfilename, - dirnamelen, max_flushed_lsn, + dirnamelen, flushed_lsn, logfile0); if (err == DB_SUCCESS) { err = create_log_files_rename( logfilename, dirnamelen, - max_flushed_lsn, + flushed_lsn, logfile0); } @@ -2350,8 +2337,7 @@ innobase_start_or_create_for_mysql(void) /* Suppress the message about crash recovery. */ - max_flushed_lsn = min_flushed_lsn - = log_get_lsn(); + flushed_lsn = log_get_lsn(); goto files_checked; } else if (i < 2 && !IS_XTRABACKUP()) { /* must have at least 2 log files */ @@ -2509,17 +2495,19 @@ files_checked: bool success = buf_flush_list(ULINT_MAX, LSN_MAX, NULL); ut_a(success); - min_flushed_lsn = max_flushed_lsn = log_get_lsn(); + flushed_lsn = log_get_lsn(); buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); /* Stamp the LSN to the data files. */ - fil_write_flushed_lsn_to_data_files(max_flushed_lsn, 0); + err = fil_write_flushed_lsn(flushed_lsn); - fil_flush_file_spaces(FIL_TABLESPACE); + if (err != DB_SUCCESS) { + return(err); + } err = create_log_files_rename(logfilename, dirnamelen, - max_flushed_lsn, logfile0); + flushed_lsn, logfile0); if (err != DB_SUCCESS) { return(err); @@ -2574,7 +2562,7 @@ files_checked: err = recv_recovery_from_checkpoint_start( LOG_CHECKPOINT, LSN_MAX, - min_flushed_lsn, max_flushed_lsn); + flushed_lsn); if (err != DB_SUCCESS) { return(err); @@ -2757,7 +2745,7 @@ files_checked: DBUG_EXECUTE_IF("innodb_log_abort_1", return(DB_ERROR);); - min_flushed_lsn = max_flushed_lsn = log_get_lsn(); + flushed_lsn = log_get_lsn(); ib_logf(IB_LOG_LEVEL_WARN, "Resizing redo log from %u*%u to %u*%u pages" @@ -2766,7 +2754,7 @@ files_checked: (unsigned) srv_log_file_size, (unsigned) srv_n_log_files, (unsigned) srv_log_file_size_requested, - max_flushed_lsn); + flushed_lsn); buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); @@ -2776,7 +2764,7 @@ files_checked: we need to explicitly flush the log buffers. */ fil_flush(SRV_LOG_SPACE_FIRST_ID); - ut_ad(max_flushed_lsn == log_get_lsn()); + ut_ad(flushed_lsn == log_get_lsn()); /* Prohibit redo log writes from any other threads until creating a log checkpoint at the @@ -2788,8 +2776,7 @@ files_checked: return(DB_ERROR);); /* Stamp the LSN to the data files. */ - fil_write_flushed_lsn_to_data_files( - max_flushed_lsn, 0); + err = fil_write_flushed_lsn(flushed_lsn); DBUG_EXECUTE_IF("innodb_log_abort_4", err = DB_ERROR;); @@ -2797,8 +2784,6 @@ files_checked: return(err); } - fil_flush_file_spaces(FIL_TABLESPACE); - /* Close and free the redo log files, so that we can replace them. */ fil_close_log_files(true); @@ -2815,7 +2800,7 @@ files_checked: srv_log_file_size = srv_log_file_size_requested; err = create_log_files(create_new_db, logfilename, - dirnamelen, max_flushed_lsn, + dirnamelen, flushed_lsn, logfile0); if (err != DB_SUCCESS) { @@ -2824,12 +2809,17 @@ files_checked: /* create_log_files() can increase system lsn that is why FIL_PAGE_FILE_FLUSH_LSN have to be updated */ - min_flushed_lsn = max_flushed_lsn = log_get_lsn(); - fil_write_flushed_lsn_to_data_files(min_flushed_lsn, 0); - fil_flush_file_spaces(FIL_TABLESPACE); + flushed_lsn = log_get_lsn(); + + err = fil_write_flushed_lsn(flushed_lsn); + + if (err != DB_SUCCESS) { + return(err); + } err = create_log_files_rename(logfilename, dirnamelen, log_get_lsn(), logfile0); + if (err != DB_SUCCESS) { return(err); } From 6b6987154a23a8eba72fd58cbff915ae6d17189f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 30 May 2017 12:02:42 +0300 Subject: [PATCH 57/66] MDEV-12114: install_db shows corruption for rest encryption and innodb_checksum_algorithm=strict_none Problem was that checksum check resulted false positives that page is both not encrypted and encryted when checksum_algorithm was strict_none. Encrypton checksum will use only crc32 regardless of setting. buf_zip_decompress: If compression fails report a error message containing the space name if available (not available during import). And note if space could be encrypted. buf_page_get_gen: Do not assert if decompression fails, instead unfix the page and return NULL to upper layer. fil_crypt_calculate_checksum: Use only crc32 method. fil_space_verify_crypt_checksum: Here we need to check crc32, innodb and none method for old datafiles. fil_space_release_for_io: Allow null space. encryption.innodb-compressed-blob is now run with crc32 and none combinations. Note that with none and strict_none method there is not really a way to detect page corruptions and page corruptions after decrypting the page with incorrect key. New test innodb-checksum-algorithm to test different checksum algorithms with encrypted, row compressed and page compressed tables. --- .../r/innodb-checksum-algorithm.result | 741 ++++++++++++++++++ .../r/innodb-compressed-blob.result | 5 +- .../t/innodb-checksum-algorithm.opt | 4 + .../t/innodb-checksum-algorithm.test | 652 +++++++++++++++ .../t/innodb-compressed-blob.combinations | 12 + .../encryption/t/innodb-compressed-blob.opt | 4 - .../encryption/t/innodb-compressed-blob.test | 6 +- storage/innobase/buf/buf0buf.cc | 101 ++- storage/innobase/fil/fil0crypt.cc | 34 +- storage/xtradb/buf/buf0buf.cc | 101 ++- storage/xtradb/fil/fil0crypt.cc | 34 +- 11 files changed, 1577 insertions(+), 117 deletions(-) create mode 100644 mysql-test/suite/encryption/r/innodb-checksum-algorithm.result create mode 100644 mysql-test/suite/encryption/t/innodb-checksum-algorithm.opt create mode 100644 mysql-test/suite/encryption/t/innodb-checksum-algorithm.test create mode 100644 mysql-test/suite/encryption/t/innodb-compressed-blob.combinations delete mode 100644 mysql-test/suite/encryption/t/innodb-compressed-blob.opt diff --git a/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result b/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result new file mode 100644 index 00000000000..09a61af2a2f --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result @@ -0,0 +1,741 @@ +SET GLOBAL innodb_file_format = `Barracuda`; +SET GLOBAL innodb_file_per_table = ON; +call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_crc32\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"innodb\". Accepting the page as valid. Change innodb_checksum_algorithm to \"crc32\" to silently accept such pages or rewrite all pages so that they contain \"crc32\" checksum."); +call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_none\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"innodb\". Accepting the page as valid. Change innodb_checksum_algorithm to \"none\" to silently accept such pages or rewrite all pages so that they contain \"none\" checksum."); +call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_crc32\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"none\". Accepting the page as valid. Change innodb_checksum_algorithm to \"crc32\" to silently accept such pages or rewrite all pages so that they contain \"crc32\" checksum."); +call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_innodb\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"none\". Accepting the page as valid. Change innodb_checksum_algorithm to \"innodb\" to silently accept such pages or rewrite all pages so that they contain \"innodb\" checksum."); +call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_innodb\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"crc32\". Accepting the page as valid. Change innodb_checksum_algorithm to \"innodb\" to silently accept such pages or rewrite all pages so that they contain \"innodb\" checksum."); +call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_none\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"crc32\". Accepting the page as valid. Change innodb_checksum_algorithm to \"none\" to silently accept such pages or rewrite all pages so that they contain \"none\" checksum."); +set GLOBAL innodb_default_encryption_key_id=4; +create table t1(a int not null auto_increment primary key, b blob, index(b(10))) engine=innodb row_format=compressed encrypted=yes; +create table t2(a int not null auto_increment primary key, b blob, index(b(10))) engine=innodb encrypted=yes; +create table t3(a int not null auto_increment primary key, b blob, index(b(10))) engine=innodb row_format=compressed encrypted=no; +create table t4(a int not null auto_increment primary key, b blob, index(b(10))) engine=innodb encrypted=no; +create table t5(a int not null auto_increment primary key, b blob, index(b(10))) engine=innodb encrypted=yes page_compressed=yes; +begin; +insert into t1(b) values (repeat('secret',20)); +insert into t1(b) select b from t1; +insert into t1(b) select b from t1; +insert into t1(b) select b from t1; +insert into t1(b) select b from t1; +insert into t1(b) select b from t1; +insert into t2(b) select b from t1; +insert into t3(b) select b from t1; +insert into t4(b) select b from t1; +insert into t5(b) select b from t1; +commit; +# 1 Restart mysqld --innodb-checksum-algorithm=crc32 +select count(*) from t1; +count(*) +32 +select count(*) from t2; +count(*) +32 +select count(*) from t3; +count(*) +32 +select count(*) from t4; +count(*) +32 +select count(*) from t5; +count(*) +32 +insert into t1(b) select b from t1; +insert into t2(b) select b from t1; +insert into t3(b) select b from t1; +insert into t4(b) select b from t1; +insert into t5(b) select b from t1; +# 2 Restart mysqld --innodb-checksum-algorithm=innodb +select count(*) from t1; +count(*) +64 +select count(*) from t2; +count(*) +96 +select count(*) from t3; +count(*) +96 +select count(*) from t4; +count(*) +96 +select count(*) from t5; +count(*) +96 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 3 Restart mysqld --innodb-checksum-algorithm=none +select count(*) from t1; +count(*) +128 +select count(*) from t2; +count(*) +196 +select count(*) from t3; +count(*) +196 +select count(*) from t4; +count(*) +196 +select count(*) from t5; +count(*) +196 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 4 Restart mysqld --innodb-checksum-algorithm=innodb +select count(*) from t1; +count(*) +228 +select count(*) from t2; +count(*) +296 +select count(*) from t3; +count(*) +296 +select count(*) from t4; +count(*) +296 +select count(*) from t5; +count(*) +296 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 5 Restart mysqld --innodb-checksum-algorithm=strict_innodb +select count(*) from t1; +count(*) +328 +select count(*) from t2; +count(*) +396 +select count(*) from t3; +count(*) +396 +select count(*) from t4; +count(*) +396 +select count(*) from t5; +count(*) +396 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 6 Restart mysqld --innodb-checksum-algorithm=innodb +select count(*) from t1; +count(*) +428 +select count(*) from t2; +count(*) +496 +select count(*) from t3; +count(*) +496 +select count(*) from t4; +count(*) +496 +select count(*) from t5; +count(*) +496 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 7 Restart mysqld --innodb-checksum-algorithm=strict_none +select count(*) from t1; +count(*) +528 +select count(*) from t2; +count(*) +596 +select count(*) from t3; +count(*) +596 +select count(*) from t4; +count(*) +596 +select count(*) from t5; +count(*) +596 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 8 Restart mysqld --innodb-checksum-algorithm=innodb +select count(*) from t1; +count(*) +628 +select count(*) from t2; +count(*) +696 +select count(*) from t3; +count(*) +696 +select count(*) from t4; +count(*) +696 +select count(*) from t5; +count(*) +696 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 9 Restart mysqld --innodb-checksum-algorithm=strict_crc32 +select count(*) from t1; +count(*) +728 +select count(*) from t2; +count(*) +796 +select count(*) from t3; +count(*) +796 +select count(*) from t4; +count(*) +796 +select count(*) from t5; +count(*) +796 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 10 Restart mysqld --innodb-checksum-algorithm=innodb +select count(*) from t1; +count(*) +828 +select count(*) from t2; +count(*) +896 +select count(*) from t3; +count(*) +896 +select count(*) from t4; +count(*) +896 +select count(*) from t5; +count(*) +896 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# Restart mysqld --innodb-checksum-algorithm=crc32 +select count(*) from t1; +count(*) +928 +select count(*) from t2; +count(*) +996 +select count(*) from t3; +count(*) +996 +select count(*) from t4; +count(*) +996 +select count(*) from t5; +count(*) +996 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 11 Restart mysqld --innodb-checksum-algorithm=strict_crc32 +select count(*) from t1; +count(*) +1028 +select count(*) from t2; +count(*) +1096 +select count(*) from t3; +count(*) +1096 +select count(*) from t4; +count(*) +1096 +select count(*) from t5; +count(*) +1096 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 12 Restart mysqld --innodb-checksum-algorithm=crc32 +select count(*) from t1; +count(*) +1128 +select count(*) from t2; +count(*) +1196 +select count(*) from t3; +count(*) +1196 +select count(*) from t4; +count(*) +1196 +select count(*) from t5; +count(*) +1196 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 13 Restart mysqld --innodb-checksum-algorithm=strict_none +select count(*) from t1; +count(*) +1228 +select count(*) from t2; +count(*) +1296 +select count(*) from t3; +count(*) +1296 +select count(*) from t4; +count(*) +1296 +select count(*) from t5; +count(*) +1296 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 14 Restart mysqld --innodb-checksum-algorithm=crc32 +select count(*) from t1; +count(*) +1328 +select count(*) from t2; +count(*) +1396 +select count(*) from t3; +count(*) +1396 +select count(*) from t4; +count(*) +1396 +select count(*) from t5; +count(*) +1396 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 15 Restart mysqld --innodb-checksum-algorithm=strict_innodb +select count(*) from t1; +count(*) +1428 +select count(*) from t2; +count(*) +1496 +select count(*) from t3; +count(*) +1496 +select count(*) from t4; +count(*) +1496 +select count(*) from t5; +count(*) +1496 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 16 Restart mysqld --innodb-checksum-algorithm=crc32 +select count(*) from t1; +count(*) +1528 +select count(*) from t2; +count(*) +1596 +select count(*) from t3; +count(*) +1596 +select count(*) from t4; +count(*) +1596 +select count(*) from t5; +count(*) +1596 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 17 Restart mysqld --innodb-checksum-algorithm=none +select count(*) from t1; +count(*) +1628 +select count(*) from t2; +count(*) +1696 +select count(*) from t3; +count(*) +1696 +select count(*) from t4; +count(*) +1696 +select count(*) from t5; +count(*) +1696 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 18 Restart mysqld --innodb-checksum-algorithm=crc32 +select count(*) from t1; +count(*) +1728 +select count(*) from t2; +count(*) +1796 +select count(*) from t3; +count(*) +1796 +select count(*) from t4; +count(*) +1796 +select count(*) from t5; +count(*) +1796 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# Restart mysqld --innodb-checksum-algorithm=strict_crc32 +select count(*) from t1; +count(*) +1828 +select count(*) from t2; +count(*) +1896 +select count(*) from t3; +count(*) +1896 +select count(*) from t4; +count(*) +1896 +select count(*) from t5; +count(*) +1896 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 19 Restart mysqld --innodb-checksum-algorithm=strict_none +select count(*) from t1; +count(*) +1928 +select count(*) from t2; +count(*) +1996 +select count(*) from t3; +count(*) +1996 +select count(*) from t4; +count(*) +1996 +select count(*) from t5; +count(*) +1996 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 20 Restart mysqld --innodb-checksum-algorithm=strict_crc32 +select count(*) from t1; +count(*) +2028 +select count(*) from t2; +count(*) +2096 +select count(*) from t3; +count(*) +2096 +select count(*) from t4; +count(*) +2096 +select count(*) from t5; +count(*) +2096 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 21 Restart mysqld --innodb-checksum-algorithm=strict_innodb +select count(*) from t1; +count(*) +2128 +select count(*) from t2; +count(*) +2196 +select count(*) from t3; +count(*) +2196 +select count(*) from t4; +count(*) +2196 +select count(*) from t5; +count(*) +2196 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 22 Restart mysqld --innodb-checksum-algorithm=strict_crc32 +select count(*) from t1; +count(*) +2228 +select count(*) from t2; +count(*) +2296 +select count(*) from t3; +count(*) +2296 +select count(*) from t4; +count(*) +2296 +select count(*) from t5; +count(*) +2296 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 23 Restart mysqld --innodb-checksum-algorithm=none +select count(*) from t1; +count(*) +2328 +select count(*) from t2; +count(*) +2396 +select count(*) from t3; +count(*) +2396 +select count(*) from t4; +count(*) +2396 +select count(*) from t5; +count(*) +2396 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 24 Restart mysqld --innodb-checksum-algorithm=strict_crc32 +select count(*) from t1; +count(*) +2428 +select count(*) from t2; +count(*) +2496 +select count(*) from t3; +count(*) +2496 +select count(*) from t4; +count(*) +2496 +select count(*) from t5; +count(*) +2496 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# Restart mysqld --innodb-checksum-algorithm=strict_none +select count(*) from t1; +count(*) +2528 +select count(*) from t2; +count(*) +2596 +select count(*) from t3; +count(*) +2596 +select count(*) from t4; +count(*) +2596 +select count(*) from t5; +count(*) +2596 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 25 Restart mysqld --innodb-checksum-algorithm=none +select count(*) from t1; +count(*) +2628 +select count(*) from t2; +count(*) +2696 +select count(*) from t3; +count(*) +2696 +select count(*) from t4; +count(*) +2696 +select count(*) from t5; +count(*) +2696 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 26 Restart mysqld --innodb-checksum-algorithm=strict_none +select count(*) from t1; +count(*) +2728 +select count(*) from t2; +count(*) +2796 +select count(*) from t3; +count(*) +2796 +select count(*) from t4; +count(*) +2796 +select count(*) from t5; +count(*) +2796 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 27 Restart mysqld --innodb-checksum-algorithm=strict_innodb +select count(*) from t1; +count(*) +2828 +select count(*) from t2; +count(*) +2896 +select count(*) from t3; +count(*) +2896 +select count(*) from t4; +count(*) +2896 +select count(*) from t5; +count(*) +2896 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 28 Restart mysqld --innodb-checksum-algorithm=strict_none +select count(*) from t1; +count(*) +2928 +select count(*) from t2; +count(*) +2996 +select count(*) from t3; +count(*) +2996 +select count(*) from t4; +count(*) +2996 +select count(*) from t5; +count(*) +2996 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# Restart mysqld --innodb-checksum-algorithm=none +select count(*) from t1; +count(*) +3028 +select count(*) from t2; +count(*) +3096 +select count(*) from t3; +count(*) +3096 +select count(*) from t4; +count(*) +3096 +select count(*) from t5; +count(*) +3096 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 29 Restart mysqld --innodb-checksum-algorithm=strict_innodb +select count(*) from t1; +count(*) +3128 +select count(*) from t2; +count(*) +3196 +select count(*) from t3; +count(*) +3196 +select count(*) from t4; +count(*) +3196 +select count(*) from t5; +count(*) +3196 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +# 30 Restart mysqld --innodb-checksum-algorithm=none +select count(*) from t1; +count(*) +3228 +select count(*) from t2; +count(*) +3296 +select count(*) from t3; +count(*) +3296 +select count(*) from t4; +count(*) +3296 +select count(*) from t5; +count(*) +3296 +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; +drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/suite/encryption/r/innodb-compressed-blob.result b/mysql-test/suite/encryption/r/innodb-compressed-blob.result index 43506092498..15c2a410948 100644 --- a/mysql-test/suite/encryption/r/innodb-compressed-blob.result +++ b/mysql-test/suite/encryption/r/innodb-compressed-blob.result @@ -1,7 +1,6 @@ call mtr.add_suppression("InnoDB: However key management plugin or used key_version .*"); -call mtr.add_suppression("InnoDB: The page \[page id: space=[0-9]+, page number=[0-9]+\] in file test/t1 cannot be decrypted."); -call mtr.add_suppression("InnoDB: The page \[page id: space=[0-9]+, page number=[0-9]+\] in file test/t2 cannot be decrypted."); -call mtr.add_suppression("InnoDB: The page \[page id: space=[0-9]+, page number=[0-9]+\] in file test/t3 cannot be decrypted."); +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[0-9]+\\] in file test/t[1-3] cannot be decrypted."); +call mtr.add_suppression("Unable to decompress space ..test.t[1-3].ibd \\[[1-9][0-9]*:[0-9]+\\]"); # Restart mysqld --file-key-management-filename=keys2.txt SET GLOBAL innodb_file_format = `Barracuda`; SET GLOBAL innodb_file_per_table = ON; diff --git a/mysql-test/suite/encryption/t/innodb-checksum-algorithm.opt b/mysql-test/suite/encryption/t/innodb-checksum-algorithm.opt new file mode 100644 index 00000000000..8a13b909879 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-checksum-algorithm.opt @@ -0,0 +1,4 @@ +--innodb_checksum_algorithm=innodb +--innodb-tablespaces-encryption +--innodb-encrypt-tables=on +--innodb-encryption-threads=4 diff --git a/mysql-test/suite/encryption/t/innodb-checksum-algorithm.test b/mysql-test/suite/encryption/t/innodb-checksum-algorithm.test new file mode 100644 index 00000000000..baea1b8a3eb --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-checksum-algorithm.test @@ -0,0 +1,652 @@ +-- source include/have_innodb.inc +-- source include/have_file_key_management_plugin.inc + +# embedded does not support restart +-- source include/not_embedded.inc + +# +# Tests: +# +# innodb +# 1) innodb => crc32 +# 2) crc32 => innodb +# 3) innodb => none +# 4) none => innodb +# 5) innodb => strict_innodb +# 6) strict_innodb => innodb +# 7) innodb => strict_none +# 8) strict_none => innodb +# 9) innodb => strict_crc32 +# 10) strict_crc32 => innodb +# +# crc32 +# 11) crc32 => strict_crc32 +# 12) strict_crc32 => crc32 +# 13) crc32 => strict_none +# 14) strict_none => crc32 +# 15) crc32 => strict_innodb +# 16) strict_innodb => crc32 +# 17) crc32 => none +# 18) none => crc32 +# (note that innodb is handled on 1 and 2) +# +# strict_crc32 +# 19) strict_crc32 => strict_none +# 20) strict_none => strict_crc32 +# 21) strict_crc32 => strict_innodb +# 22) strict_innodb => strict_crc32 +# 23) strict_crc32 => none +# 24) none => strict_crc32 +# (note that innodb is handled on 9 and 10) +# (note that crc32 is handled on 11 and 12) +# +# strict_none +# 25) strict_none => none +# 26) none => strict_none +# 27) strict_none = strict_innodb +# 28) strict_innodb => strict_none +# (note that innodb is handled on 7 and 8) +# (note that crc32 is handled on 13 and 14) +# (note that strict_crc32 is handled 19 and 20) +# +# none +# 29) none => strict_innodb +# 30) strict_innodb => none +# (note that innodb is handled on 3 and 4) +# (note that crc32 is handled on 17 and 18) +# (note that strict_crc32 is handled on 23 and 24) +# (note that strict_none is handled on 25 and 26) +# +# strict_innodb +# (note that innodb is handled on 5 and 6) +# (note that crc32 is handled on 15 and 16) +# (note that strict_crc32 is handled on 21 and 22) +# (note that strict_none is handled on 27 and 28) +# (note that none is handled on 29 and 30) +# +--disable_warnings +SET GLOBAL innodb_file_format = `Barracuda`; +SET GLOBAL innodb_file_per_table = ON; + +call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_crc32\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"innodb\". Accepting the page as valid. Change innodb_checksum_algorithm to \"crc32\" to silently accept such pages or rewrite all pages so that they contain \"crc32\" checksum."); + +call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_none\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"innodb\". Accepting the page as valid. Change innodb_checksum_algorithm to \"none\" to silently accept such pages or rewrite all pages so that they contain \"none\" checksum."); + +call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_crc32\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"none\". Accepting the page as valid. Change innodb_checksum_algorithm to \"crc32\" to silently accept such pages or rewrite all pages so that they contain \"crc32\" checksum."); + +call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_innodb\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"none\". Accepting the page as valid. Change innodb_checksum_algorithm to \"innodb\" to silently accept such pages or rewrite all pages so that they contain \"innodb\" checksum."); + +call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_innodb\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"crc32\". Accepting the page as valid. Change innodb_checksum_algorithm to \"innodb\" to silently accept such pages or rewrite all pages so that they contain \"innodb\" checksum."); + +call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_none\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"crc32\". Accepting the page as valid. Change innodb_checksum_algorithm to \"none\" to silently accept such pages or rewrite all pages so that they contain \"none\" checksum."); + +--enable_warnings + +set GLOBAL innodb_default_encryption_key_id=4; +create table t1(a int not null auto_increment primary key, b blob, index(b(10))) engine=innodb row_format=compressed encrypted=yes; +create table t2(a int not null auto_increment primary key, b blob, index(b(10))) engine=innodb encrypted=yes; +create table t3(a int not null auto_increment primary key, b blob, index(b(10))) engine=innodb row_format=compressed encrypted=no; +create table t4(a int not null auto_increment primary key, b blob, index(b(10))) engine=innodb encrypted=no; +create table t5(a int not null auto_increment primary key, b blob, index(b(10))) engine=innodb encrypted=yes page_compressed=yes; + +begin; +insert into t1(b) values (repeat('secret',20)); +insert into t1(b) select b from t1; +insert into t1(b) select b from t1; +insert into t1(b) select b from t1; +insert into t1(b) select b from t1; +insert into t1(b) select b from t1; +insert into t2(b) select b from t1; +insert into t3(b) select b from t1; +insert into t4(b) select b from t1; +insert into t5(b) select b from t1; +commit; + +--echo # 1 Restart mysqld --innodb-checksum-algorithm=crc32 +-- let $restart_parameters=--innodb-checksum-algorithm=crc32 +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1; +insert into t2(b) select b from t1; +insert into t3(b) select b from t1; +insert into t4(b) select b from t1; +insert into t5(b) select b from t1; + +--echo # 2 Restart mysqld --innodb-checksum-algorithm=innodb +-- let $restart_parameters=--innodb-checksum-algorithm=innodb +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 3 Restart mysqld --innodb-checksum-algorithm=none +-- let $restart_parameters=--innodb-checksum-algorithm=none +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 4 Restart mysqld --innodb-checksum-algorithm=innodb +-- let $restart_parameters=--innodb-checksum-algorithm=innodb +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 5 Restart mysqld --innodb-checksum-algorithm=strict_innodb +-- let $restart_parameters=--innodb-checksum-algorithm=strict_innodb +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 6 Restart mysqld --innodb-checksum-algorithm=innodb +-- let $restart_parameters=--innodb-checksum-algorithm=innodb +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 7 Restart mysqld --innodb-checksum-algorithm=strict_none +-- let $restart_parameters=--innodb-checksum-algorithm=strict_none +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 8 Restart mysqld --innodb-checksum-algorithm=innodb +-- let $restart_parameters=--innodb-checksum-algorithm=innodb +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 9 Restart mysqld --innodb-checksum-algorithm=strict_crc32 +-- let $restart_parameters=--innodb-checksum-algorithm=strict_crc32 +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 10 Restart mysqld --innodb-checksum-algorithm=innodb +-- let $restart_parameters=--innodb-checksum-algorithm=innodb +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # Restart mysqld --innodb-checksum-algorithm=crc32 +-- let $restart_parameters=--innodb-checksum-algorithm=crc32 +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 11 Restart mysqld --innodb-checksum-algorithm=strict_crc32 +-- let $restart_parameters=--innodb-checksum-algorithm=strict_crc32 +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 12 Restart mysqld --innodb-checksum-algorithm=crc32 +-- let $restart_parameters=--innodb-checksum-algorithm=crc32 +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 13 Restart mysqld --innodb-checksum-algorithm=strict_none +-- let $restart_parameters=--innodb-checksum-algorithm=strict_none +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 14 Restart mysqld --innodb-checksum-algorithm=crc32 +-- let $restart_parameters=--innodb-checksum-algorithm=crc32 +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 15 Restart mysqld --innodb-checksum-algorithm=strict_innodb +-- let $restart_parameters=--innodb-checksum-algorithm=strict_innodb +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 16 Restart mysqld --innodb-checksum-algorithm=crc32 +-- let $restart_parameters=--innodb-checksum-algorithm=crc32 +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 17 Restart mysqld --innodb-checksum-algorithm=none +-- let $restart_parameters=--innodb-checksum-algorithm=none +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 18 Restart mysqld --innodb-checksum-algorithm=crc32 +-- let $restart_parameters=--innodb-checksum-algorithm=crc32 +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # Restart mysqld --innodb-checksum-algorithm=strict_crc32 +-- let $restart_parameters=--innodb-checksum-algorithm=strict_crc32 +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 19 Restart mysqld --innodb-checksum-algorithm=strict_none +-- let $restart_parameters=--innodb-checksum-algorithm=strict_none +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 20 Restart mysqld --innodb-checksum-algorithm=strict_crc32 +-- let $restart_parameters=--innodb-checksum-algorithm=strict_crc32 +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 21 Restart mysqld --innodb-checksum-algorithm=strict_innodb +-- let $restart_parameters=--innodb-checksum-algorithm=strict_innodb +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 22 Restart mysqld --innodb-checksum-algorithm=strict_crc32 +-- let $restart_parameters=--innodb-checksum-algorithm=strict_crc32 +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 23 Restart mysqld --innodb-checksum-algorithm=none +-- let $restart_parameters=--innodb-checksum-algorithm=none +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 24 Restart mysqld --innodb-checksum-algorithm=strict_crc32 +-- let $restart_parameters=--innodb-checksum-algorithm=strict_crc32 +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # Restart mysqld --innodb-checksum-algorithm=strict_none +-- let $restart_parameters=--innodb-checksum-algorithm=strict_none +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 25 Restart mysqld --innodb-checksum-algorithm=none +-- let $restart_parameters=--innodb-checksum-algorithm=none +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 26 Restart mysqld --innodb-checksum-algorithm=strict_none +-- let $restart_parameters=--innodb-checksum-algorithm=strict_none +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 27 Restart mysqld --innodb-checksum-algorithm=strict_innodb +-- let $restart_parameters=--innodb-checksum-algorithm=strict_innodb +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 28 Restart mysqld --innodb-checksum-algorithm=strict_none +-- let $restart_parameters=--innodb-checksum-algorithm=strict_none +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # Restart mysqld --innodb-checksum-algorithm=none +-- let $restart_parameters=--innodb-checksum-algorithm=none +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 29 Restart mysqld --innodb-checksum-algorithm=strict_innodb +-- let $restart_parameters=--innodb-checksum-algorithm=strict_innodb +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +--echo # 30 Restart mysqld --innodb-checksum-algorithm=none +-- let $restart_parameters=--innodb-checksum-algorithm=none +-- source include/restart_mysqld.inc + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; + +insert into t1(b) select b from t1 limit 100; +insert into t2(b) select b from t1 limit 100; +insert into t3(b) select b from t1 limit 100; +insert into t4(b) select b from t1 limit 100; +insert into t5(b) select b from t1 limit 100; + +drop table t1,t2,t3,t4,t5; + + + diff --git a/mysql-test/suite/encryption/t/innodb-compressed-blob.combinations b/mysql-test/suite/encryption/t/innodb-compressed-blob.combinations new file mode 100644 index 00000000000..e096b023b52 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-compressed-blob.combinations @@ -0,0 +1,12 @@ +[crc32] +loose-innodb-tablespaces-encryption +loose-innodb-encrypt-tables=on +loose-innodb-encryption-threads=4 +max_allowed_packet=64K +loose-innodb-checksum-algorithm=crc32 +[none] +loose-innodb-tablespaces-encryption +loose-innodb-encrypt-tables=on +loose-innodb-encryption-threads=4 +max_allowed_packet=64K +loose-innodb-checksum-algorithm=none diff --git a/mysql-test/suite/encryption/t/innodb-compressed-blob.opt b/mysql-test/suite/encryption/t/innodb-compressed-blob.opt deleted file mode 100644 index 36dcb6c6f26..00000000000 --- a/mysql-test/suite/encryption/t/innodb-compressed-blob.opt +++ /dev/null @@ -1,4 +0,0 @@ ---innodb-tablespaces-encryption ---innodb-encrypt-tables=on ---innodb-encryption-threads=2 ---max_allowed_packet=64K diff --git a/mysql-test/suite/encryption/t/innodb-compressed-blob.test b/mysql-test/suite/encryption/t/innodb-compressed-blob.test index 4024c8fa641..cb69f22f745 100644 --- a/mysql-test/suite/encryption/t/innodb-compressed-blob.test +++ b/mysql-test/suite/encryption/t/innodb-compressed-blob.test @@ -5,10 +5,8 @@ -- source include/not_embedded.inc call mtr.add_suppression("InnoDB: However key management plugin or used key_version .*"); -call mtr.add_suppression("InnoDB: The page \[page id: space=[0-9]+, page number=[0-9]+\] in file test/t1 cannot be decrypted."); -call mtr.add_suppression("InnoDB: The page \[page id: space=[0-9]+, page number=[0-9]+\] in file test/t2 cannot be decrypted."); -call mtr.add_suppression("InnoDB: The page \[page id: space=[0-9]+, page number=[0-9]+\] in file test/t3 cannot be decrypted."); - +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[0-9]+\\] in file test/t[1-3] cannot be decrypted."); +call mtr.add_suppression("Unable to decompress space ..test.t[1-3].ibd \\[[1-9][0-9]*:[0-9]+\\]"); --echo # Restart mysqld --file-key-management-filename=keys2.txt -- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 2cb2673f7fb..9b9d0b37f13 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -354,6 +354,15 @@ bool buf_page_decrypt_after_read(buf_page_t* bpage, fil_space_t* space) MY_ATTRIBUTE((nonnull)); +/********************************************************************//** +Mark a table with the specified space pointed by bpage->space corrupted. +Also remove the bpage from LRU list. +@param[in,out] bpage Block */ +static +void +buf_mark_space_corrupt( + buf_page_t* bpage); + /* prototypes for new functions added to ha_innodb.cc */ trx_t* innobase_get_trx(); @@ -2526,17 +2535,26 @@ buf_zip_decompress( { const byte* frame = block->page.zip.data; ulint size = page_zip_get_size(&block->page.zip); + /* Space is not found if this function is called during IMPORT */ + fil_space_t* space = fil_space_acquire_for_io(block->page.space); + const unsigned key_version = mach_read_from_4(frame + + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + fil_space_crypt_t* crypt_data = space ? space->crypt_data : NULL; + const bool encrypted = crypt_data + && crypt_data->type != CRYPT_SCHEME_UNENCRYPTED + && (!crypt_data->is_default_encryption() + || srv_encrypt_tables); ut_ad(buf_block_get_zip_size(block)); ut_a(buf_block_get_space(block) != 0); if (UNIV_UNLIKELY(check && !page_zip_verify_checksum(frame, size))) { - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: compressed page checksum mismatch" - " (space %u page %u): stored: %lu, crc32: %lu " - "innodb: %lu, none: %lu\n", + ib_logf(IB_LOG_LEVEL_ERROR, + "Compressed page checksum mismatch" + " for %s [%u:%u]: stored: " ULINTPF ", crc32: " ULINTPF + " innodb: " ULINTPF ", none: " ULINTPF ".", + space ? space->chain.start->name : "N/A", block->page.space, block->page.offset, mach_read_from_4(frame + FIL_PAGE_SPACE_OR_CHKSUM), page_zip_calc_checksum(frame, size, @@ -2545,22 +2563,28 @@ buf_zip_decompress( SRV_CHECKSUM_ALGORITHM_INNODB), page_zip_calc_checksum(frame, size, SRV_CHECKSUM_ALGORITHM_NONE)); - return(FALSE); + goto err_exit; } switch (fil_page_get_type(frame)) { - case FIL_PAGE_INDEX: + case FIL_PAGE_INDEX: { + if (page_zip_decompress(&block->page.zip, block->frame, TRUE)) { + if (space) { + fil_space_release_for_io(space); + } return(TRUE); } - fprintf(stderr, - "InnoDB: unable to decompress space %u page %u\n", + ib_logf(IB_LOG_LEVEL_ERROR, + "Unable to decompress space %s [%u:%u]", + space ? space->chain.start->name : "N/A", block->page.space, block->page.offset); - return(FALSE); + goto err_exit; + } case FIL_PAGE_TYPE_ALLOCATED: case FIL_PAGE_INODE: case FIL_PAGE_IBUF_BITMAP: @@ -2571,14 +2595,36 @@ buf_zip_decompress( /* Copy to uncompressed storage. */ memcpy(block->frame, frame, buf_block_get_zip_size(block)); + + if (space) { + fil_space_release_for_io(space); + } + return(TRUE); } - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: unknown compressed page" - " type %lu\n", - fil_page_get_type(frame)); + ib_logf(IB_LOG_LEVEL_ERROR, + "Unknown compressed page in %s [%u:%u]" + " type %s [" ULINTPF "].", + space ? space->chain.start->name : "N/A", + block->page.space, block->page.offset, + fil_get_page_type_name(fil_page_get_type(frame)), fil_page_get_type(frame)); + +err_exit: + if (encrypted) { + ib_logf(IB_LOG_LEVEL_INFO, + "Row compressed page could be encrypted with key_version %u.", + key_version); + block->page.encrypted = true; + dict_set_encrypted_by_space(block->page.space); + } else { + dict_set_corrupted_by_space(block->page.space); + } + + if (space) { + fil_space_release_for_io(space); + } + return(FALSE); } @@ -3031,9 +3077,9 @@ loop: } ib_logf(IB_LOG_LEVEL_FATAL, "Unable" - " to read tablespace %lu page no" - " %lu into the buffer pool after" - " %lu attempts" + " to read tablespace " ULINTPF " page no " + ULINTPF " into the buffer pool after " + ULINTPF " attempts." " The most probable cause" " of this error may be that the" " table has been corrupted." @@ -3232,12 +3278,21 @@ got_block: /* Decompress the page while not holding buf_pool->mutex or block->mutex. */ - /* Page checksum verification is already done when - the page is read from disk. Hence page checksum - verification is not necessary when decompressing the page. */ { - bool success = buf_zip_decompress(block, FALSE); - ut_a(success); + bool success = buf_zip_decompress(block, TRUE); + + if (!success) { + buf_pool_mutex_enter(buf_pool); + buf_block_mutex_enter(fix_block); + buf_block_set_io_fix(fix_block, BUF_IO_NONE); + buf_block_mutex_exit(fix_block); + + --buf_pool->n_pend_unzip; + buf_block_unfix(fix_block); + buf_pool_mutex_exit(buf_pool); + rw_lock_x_unlock(&fix_block->lock); + return NULL; + } } if (!recv_no_ibuf_operations) { diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index a6d85fb89bf..2131a936656 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -887,7 +887,7 @@ fil_space_decrypt( Calculate post encryption checksum @param[in] zip_size zip_size or 0 @param[in] dst_frame Block where checksum is calculated -@return page checksum or BUF_NO_CHECKSUM_MAGIC +@return page checksum not needed. */ UNIV_INTERN ulint @@ -896,30 +896,13 @@ fil_crypt_calculate_checksum( const byte* dst_frame) { ib_uint32_t checksum = 0; - srv_checksum_algorithm_t algorithm = - static_cast(srv_checksum_algorithm); + /* For encrypted tables we use only crc32 and strict_crc32 */ if (zip_size == 0) { - switch (algorithm) { - case SRV_CHECKSUM_ALGORITHM_CRC32: - case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: - checksum = buf_calc_page_crc32(dst_frame); - break; - case SRV_CHECKSUM_ALGORITHM_INNODB: - case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB: - checksum = (ib_uint32_t) buf_calc_page_new_checksum( - dst_frame); - break; - case SRV_CHECKSUM_ALGORITHM_NONE: - case SRV_CHECKSUM_ALGORITHM_STRICT_NONE: - checksum = BUF_NO_CHECKSUM_MAGIC; - break; - /* no default so the compiler will emit a warning - * if new enum is added and not handled here */ - } + checksum = buf_calc_page_crc32(dst_frame); } else { checksum = page_zip_calc_checksum(dst_frame, zip_size, - algorithm); + SRV_CHECKSUM_ALGORITHM_CRC32); } return checksum; @@ -953,14 +936,6 @@ fil_space_verify_crypt_checksum( return(false); } - srv_checksum_algorithm_t algorithm = - static_cast(srv_checksum_algorithm); - - /* If no checksum is used, can't continue checking. */ - if (algorithm == SRV_CHECKSUM_ALGORITHM_NONE) { - return(true); - } - /* Read stored post encryption checksum. */ ib_uint32_t checksum = mach_read_from_4( page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4); @@ -1044,7 +1019,6 @@ fil_space_verify_crypt_checksum( checksum2 = mach_read_from_4( page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM); valid = (buf_page_is_checksum_valid_crc32(page,checksum1,checksum2) - || buf_page_is_checksum_valid_none(page,checksum1,checksum2) || buf_page_is_checksum_valid_innodb(page,checksum1, checksum2)); } diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc index 7c30ff92b69..da4ab059d07 100644 --- a/storage/xtradb/buf/buf0buf.cc +++ b/storage/xtradb/buf/buf0buf.cc @@ -86,6 +86,15 @@ bool buf_page_decrypt_after_read(buf_page_t* bpage, fil_space_t* space) MY_ATTRIBUTE((nonnull)); +/********************************************************************//** +Mark a table with the specified space pointed by bpage->space corrupted. +Also remove the bpage from LRU list. +@param[in,out] bpage Block */ +static +void +buf_mark_space_corrupt( + buf_page_t* bpage); + /* prototypes for new functions added to ha_innodb.cc */ trx_t* innobase_get_trx(); @@ -2538,17 +2547,26 @@ buf_zip_decompress( { const byte* frame = block->page.zip.data; ulint size = page_zip_get_size(&block->page.zip); + /* Space is not found if this function is called during IMPORT */ + fil_space_t* space = fil_space_acquire_for_io(block->page.space); + const unsigned key_version = mach_read_from_4(frame + + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); + fil_space_crypt_t* crypt_data = space ? space->crypt_data : NULL; + const bool encrypted = crypt_data + && crypt_data->type != CRYPT_SCHEME_UNENCRYPTED + && (!crypt_data->is_default_encryption() + || srv_encrypt_tables); ut_ad(buf_block_get_zip_size(block)); ut_a(buf_block_get_space(block) != 0); if (UNIV_UNLIKELY(check && !page_zip_verify_checksum(frame, size))) { - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: compressed page checksum mismatch" - " (space %u page %u): stored: %lu, crc32: %lu " - "innodb: %lu, none: %lu\n", + ib_logf(IB_LOG_LEVEL_ERROR, + "Compressed page checksum mismatch" + " for %s [%u:%u]: stored: " ULINTPF ", crc32: " ULINTPF + " innodb: " ULINTPF ", none: " ULINTPF ".", + space ? space->chain.start->name : "N/A", block->page.space, block->page.offset, mach_read_from_4(frame + FIL_PAGE_SPACE_OR_CHKSUM), page_zip_calc_checksum(frame, size, @@ -2557,22 +2575,28 @@ buf_zip_decompress( SRV_CHECKSUM_ALGORITHM_INNODB), page_zip_calc_checksum(frame, size, SRV_CHECKSUM_ALGORITHM_NONE)); - return(FALSE); + goto err_exit; } switch (fil_page_get_type(frame)) { - case FIL_PAGE_INDEX: + case FIL_PAGE_INDEX: { + if (page_zip_decompress(&block->page.zip, block->frame, TRUE)) { + if (space) { + fil_space_release_for_io(space); + } return(TRUE); } - fprintf(stderr, - "InnoDB: unable to decompress space %u page %u\n", + ib_logf(IB_LOG_LEVEL_ERROR, + "Unable to decompress space %s [%u:%u]", + space ? space->chain.start->name : "N/A", block->page.space, block->page.offset); - return(FALSE); + goto err_exit; + } case FIL_PAGE_TYPE_ALLOCATED: case FIL_PAGE_INODE: case FIL_PAGE_IBUF_BITMAP: @@ -2583,14 +2607,36 @@ buf_zip_decompress( /* Copy to uncompressed storage. */ memcpy(block->frame, frame, buf_block_get_zip_size(block)); + + if (space) { + fil_space_release_for_io(space); + } + return(TRUE); } - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: unknown compressed page" - " type %lu\n", - fil_page_get_type(frame)); + ib_logf(IB_LOG_LEVEL_ERROR, + "Unknown compressed page in %s [%u:%u]" + " type %s [" ULINTPF "].", + space ? space->chain.start->name : "N/A", + block->page.space, block->page.offset, + fil_get_page_type_name(fil_page_get_type(frame)), fil_page_get_type(frame)); + +err_exit: + if (encrypted) { + ib_logf(IB_LOG_LEVEL_INFO, + "Row compressed page could be encrypted with key_version %u.", + key_version); + block->page.encrypted = true; + dict_set_encrypted_by_space(block->page.space); + } else { + dict_set_corrupted_by_space(block->page.space); + } + + if (space) { + fil_space_release_for_io(space); + } + return(FALSE); } @@ -3073,9 +3119,9 @@ loop: } ib_logf(IB_LOG_LEVEL_FATAL, "Unable" - " to read tablespace %lu page no" - " %lu into the buffer pool after" - " %lu attempts" + " to read tablespace " ULINTPF " page no " + ULINTPF " into the buffer pool after " + ULINTPF " attempts." " The most probable cause" " of this error may be that the" " table has been corrupted." @@ -3288,12 +3334,21 @@ got_block: /* Decompress the page while not holding any buf_pool or block->mutex. */ - /* Page checksum verification is already done when - the page is read from disk. Hence page checksum - verification is not necessary when decompressing the page. */ { - bool success = buf_zip_decompress(block, FALSE); - ut_a(success); + bool success = buf_zip_decompress(block, TRUE); + + if (!success) { + buf_block_mutex_enter(fix_block); + buf_block_set_io_fix(fix_block, BUF_IO_NONE); + buf_block_mutex_exit(fix_block); + + os_atomic_decrement_ulint(&buf_pool->n_pend_unzip, 1); + rw_lock_x_unlock(&fix_block->lock); + mutex_enter(&buf_pool->LRU_list_mutex); + buf_block_unfix(fix_block); + mutex_exit(&buf_pool->LRU_list_mutex); + return NULL; + } } if (!recv_no_ibuf_operations) { diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc index da78d4dd85d..21c1e3b730e 100644 --- a/storage/xtradb/fil/fil0crypt.cc +++ b/storage/xtradb/fil/fil0crypt.cc @@ -887,7 +887,7 @@ fil_space_decrypt( Calculate post encryption checksum @param[in] zip_size zip_size or 0 @param[in] dst_frame Block where checksum is calculated -@return page checksum or BUF_NO_CHECKSUM_MAGIC +@return page checksum not needed. */ UNIV_INTERN ulint @@ -896,30 +896,13 @@ fil_crypt_calculate_checksum( const byte* dst_frame) { ib_uint32_t checksum = 0; - srv_checksum_algorithm_t algorithm = - static_cast(srv_checksum_algorithm); + /* For encrypted tables we use only crc32 and strict_crc32 */ if (zip_size == 0) { - switch (algorithm) { - case SRV_CHECKSUM_ALGORITHM_CRC32: - case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: - checksum = buf_calc_page_crc32(dst_frame); - break; - case SRV_CHECKSUM_ALGORITHM_INNODB: - case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB: - checksum = (ib_uint32_t) buf_calc_page_new_checksum( - dst_frame); - break; - case SRV_CHECKSUM_ALGORITHM_NONE: - case SRV_CHECKSUM_ALGORITHM_STRICT_NONE: - checksum = BUF_NO_CHECKSUM_MAGIC; - break; - /* no default so the compiler will emit a warning - * if new enum is added and not handled here */ - } + checksum = buf_calc_page_crc32(dst_frame); } else { checksum = page_zip_calc_checksum(dst_frame, zip_size, - algorithm); + SRV_CHECKSUM_ALGORITHM_CRC32); } return checksum; @@ -953,14 +936,6 @@ fil_space_verify_crypt_checksum( return(false); } - srv_checksum_algorithm_t algorithm = - static_cast(srv_checksum_algorithm); - - /* If no checksum is used, can't continue checking. */ - if (algorithm == SRV_CHECKSUM_ALGORITHM_NONE) { - return(true); - } - /* Read stored post encryption checksum. */ ib_uint32_t checksum = mach_read_from_4( page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4); @@ -1044,7 +1019,6 @@ fil_space_verify_crypt_checksum( checksum1 = mach_read_from_4( page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM); valid = (buf_page_is_checksum_valid_crc32(page,checksum1,checksum2) - || buf_page_is_checksum_valid_none(page,checksum1,checksum2) || buf_page_is_checksum_valid_innodb(page,checksum1, checksum2)); } From 112b21da37dad0fbb28bc65f9ab5a3ba6c0c2186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 30 May 2017 11:55:11 +0300 Subject: [PATCH 58/66] MDEV-12600: crash during install_db with innodb_page_size=32K and ibdata1=3M; Problem was that all doublewrite buffer pages must fit to first system datafile. Ported commit 27a34df7882b1f8ed283f22bf83e8bfc523cbfde Author: Shaohua Wang Date: Wed Aug 12 15:55:19 2015 +0800 BUG#21551464 - SEGFAULT WHILE INITIALIZING DATABASE WHEN INNODB_DATA_FILE SIZE IS SMALL To 10.1 (with extended error printout). btr_create(): If ibuf header page allocation fails report error and return FIL_NULL. Similarly if root page allocation fails return a error. dict_build_table_def_step: If fsp_header_init fails return error code. fsp_header_init: returns true if header initialization succeeds and false if not. fseg_create_general: report error if segment or page allocation fails. innobase_init: If first datafile is smaller than 3M and could not contain all doublewrite buffer pages report error and fail to initialize InnoDB plugin. row_truncate_table_for_mysql: report error if fsp header init fails. srv_init_abort: New function to report database initialization errors. srv_undo_tablespaces_init, innobase_start_or_create_for_mysql: If database initialization fails report error and abort. trx_rseg_create: If segment header creation fails return. --- .../suite/innodb/t/log_data_file_size.opt | 2 +- storage/innobase/btr/btr0btr.cc | 19 +++++++ storage/innobase/dict/dict0crea.cc | 6 ++- storage/innobase/fil/fil0fil.cc | 42 +++++++-------- storage/innobase/fsp/fsp0fsp.cc | 37 +++++++++---- storage/innobase/handler/ha_innodb.cc | 14 +++++ storage/innobase/include/fsp0fsp.h | 20 ++++--- storage/innobase/row/row0mysql.cc | 8 ++- storage/innobase/srv/srv0start.cc | 52 ++++++++++++++++++- storage/innobase/trx/trx0rseg.cc | 5 +- storage/xtradb/btr/btr0btr.cc | 19 +++++++ storage/xtradb/dict/dict0crea.cc | 6 ++- storage/xtradb/fil/fil0fil.cc | 42 +++++++-------- storage/xtradb/fsp/fsp0fsp.cc | 37 +++++++++---- storage/xtradb/handler/ha_innodb.cc | 14 +++++ storage/xtradb/include/fsp0fsp.h | 20 ++++--- storage/xtradb/row/row0mysql.cc | 8 ++- storage/xtradb/srv/srv0start.cc | 52 ++++++++++++++++++- storage/xtradb/trx/trx0rseg.cc | 5 +- 19 files changed, 319 insertions(+), 89 deletions(-) diff --git a/mysql-test/suite/innodb/t/log_data_file_size.opt b/mysql-test/suite/innodb/t/log_data_file_size.opt index d9a364a3287..fe36abe4701 100644 --- a/mysql-test/suite/innodb/t/log_data_file_size.opt +++ b/mysql-test/suite/innodb/t/log_data_file_size.opt @@ -1,2 +1,2 @@ --loose-innodb-sys-indexes ---innodb-data-file-path=ibdata1:1M:autoextend +--innodb-data-file-path=ibdata1:3M:autoextend diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index cccae031b88..e200a2b9677 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -1701,6 +1701,12 @@ btr_create( space, 0, IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr); + if (ibuf_hdr_block == NULL) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Allocation of the first ibuf header page failed."); + return (FIL_NULL); + } + buf_block_dbg_add_level( ibuf_hdr_block, SYNC_IBUF_TREE_NODE_NEW); @@ -1714,6 +1720,11 @@ btr_create( + IBUF_HEADER + IBUF_TREE_SEG_HEADER, IBUF_TREE_ROOT_PAGE_NO, FSP_UP, mtr); + + if (!block) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Allocation of the tree root page segment failed."); + } ut_ad(buf_block_get_page_no(block) == IBUF_TREE_ROOT_PAGE_NO); } else { #ifdef UNIV_BLOB_DEBUG @@ -1726,6 +1737,12 @@ btr_create( #endif /* UNIV_BLOB_DEBUG */ block = fseg_create(space, 0, PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr); + + if (!block) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Allocation of the btree segment failed."); + } + } if (block == NULL) { @@ -1754,6 +1771,8 @@ btr_create( segment before return. */ btr_free_root(space, zip_size, page_no, mtr); + ib_logf(IB_LOG_LEVEL_ERROR, + "Allocation of the non-ibuf tree segment for leaf pages failed."); return(FIL_NULL); } diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index f6cd294884b..1ec7123bbc2 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -321,9 +321,13 @@ dict_build_table_def_step( mtr_start(&mtr); - fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr); + bool res = fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr); mtr_commit(&mtr); + + if (!res) { + return (DB_ERROR); + } } else { /* Create in the system tablespace: disallow Barracuda features by keeping only the first bit which says whether diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 9d4a464460f..e19ef110b4f 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -5812,19 +5812,21 @@ fil_report_invalid_page_access( ulint len, /*!< in: I/O length */ ulint type) /*!< in: I/O type */ { - fprintf(stderr, - "InnoDB: Error: trying to access page number %lu" - " in space %lu,\n" - "InnoDB: space name %s,\n" - "InnoDB: which is outside the tablespace bounds.\n" - "InnoDB: Byte offset %lu, len %lu, i/o type %lu.\n" - "InnoDB: If you get this error at mysqld startup," - " please check that\n" - "InnoDB: your my.cnf matches the ibdata files" - " that you have in the\n" - "InnoDB: MySQL server.\n", - (ulong) block_offset, (ulong) space_id, space_name, - (ulong) byte_offset, (ulong) len, (ulong) type); + ib_logf(IB_LOG_LEVEL_ERROR, + "Trying to access page number " ULINTPF + " in space " ULINTPF + " space name %s," + " which is outside the tablespace bounds." + " Byte offset " ULINTPF ", len " ULINTPF " i/o type " ULINTPF ".", + block_offset, space_id, space_name, + byte_offset, len, type); + + ib_logf(IB_LOG_LEVEL_FATAL, + "If you get this error at mysqld startup," + " please check that" + " your my.cnf matches the ibdata files" + " that you have in the" + " MySQL server."); } /********************************************************************//** @@ -6043,11 +6045,10 @@ fil_io( mutex_exit(&fil_system->mutex); return(DB_ERROR); } + fil_report_invalid_page_access( block_offset, space_id, space->name, byte_offset, len, type); - - ut_error; } /* Open file if closed */ @@ -6059,10 +6060,11 @@ fil_io( ib_logf(IB_LOG_LEVEL_ERROR, "Trying to do i/o to a tablespace which " "exists without .ibd data file. " - "i/o type %lu, space id %lu, page no %lu, " - "i/o length %lu bytes", - (ulong) type, (ulong) space_id, - (ulong) block_offset, (ulong) len); + "i/o type " ULINTPF ", space id " + ULINTPF ", page no " ULINTPF ", " + "i/o length " ULINTPF " bytes", + type, space_id, + block_offset, len); return(DB_TABLESPACE_DELETED); } @@ -6082,8 +6084,6 @@ fil_io( fil_report_invalid_page_access( block_offset, space_id, space->name, byte_offset, len, type); - - ut_error; } /* Now we have made the changes in the data structures of fil_system */ diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index a40283412e2..98cd11f3369 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -670,16 +670,18 @@ fsp_header_init_fields( } #ifndef UNIV_HOTBACKUP -/**********************************************************************//** -Initializes the space header of a new created space and creates also the -insert buffer tree root if space == 0. */ +/** Initializes the space header of a new created space and creates also the +insert buffer tree root if space == 0. +@param[in] space_id space id +@param[in] size current size in blocks +@param[in,out] mtr min-transaction +@return true on success, otherwise false. */ UNIV_INTERN -void +bool fsp_header_init( -/*============*/ - ulint space_id, /*!< in: space id */ - ulint size, /*!< in: current size in blocks */ - mtr_t* mtr) /*!< in/out: mini-transaction */ + ulint space_id, + ulint size, + mtr_t* mtr) { fsp_header_t* header; buf_block_t* block; @@ -722,11 +724,15 @@ fsp_header_init( flst_init(header + FSP_SEG_INODES_FREE, mtr); mlog_write_ull(header + FSP_SEG_ID, 1, mtr); + if (space_id == 0) { fsp_fill_free_list(FALSE, space_id, header, mtr); - btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, + + if (btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, 0, 0, DICT_IBUF_ID_MIN + space_id, - dict_ind_redundant, mtr); + dict_ind_redundant, mtr) == FIL_NULL) { + return (false); + } } else { fsp_fill_free_list(TRUE, space_id, header, mtr); } @@ -739,6 +745,8 @@ fsp_header_init( } fil_space_release(space); + + return (true); } #endif /* !UNIV_HOTBACKUP */ @@ -2057,6 +2065,10 @@ fseg_create_general( success = fsp_reserve_free_extents(&n_reserved, space, 2, FSP_NORMAL, mtr); if (!success) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Reserving %d free extents failed" + " could reserve only " ULINTPF " extents.", + 2, n_reserved); return(NULL); } } @@ -2066,6 +2078,8 @@ fseg_create_general( inode = fsp_alloc_seg_inode(space_header, mtr); if (inode == NULL) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Allocation of a new file segment inode page failed."); goto funct_exit; } @@ -2095,6 +2109,9 @@ fseg_create_general( inode, 0, FSP_UP, mtr, mtr); if (block == NULL) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Allocation of a free page from space " ULINTPF " failed.", + space); fsp_free_seg_inode(space, zip_size, inode, mtr); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 012539d1ace..b68a96c8846 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3353,6 +3353,7 @@ innobase_init( char *default_path; uint format_id; ulong num_pll_degree; + ulint min_size = 0; DBUG_ENTER("innobase_init"); handlerton *innobase_hton= (handlerton*) p; @@ -3563,6 +3564,19 @@ mem_free_and_error: goto error; } + /* All doublewrite buffer pages must fit to first system + datafile and first datafile must be at least 3M. */ + min_size = ut_max((3*1024*1024U), (192U*UNIV_PAGE_SIZE)); + + if ((srv_data_file_sizes[0]*1024*1024) < min_size) { + sql_print_error( + "InnoDB: first datafile is too small current=" ULINTPF + "M it should be at least " ULINTPF "M.", + srv_data_file_sizes[0], + min_size / (1024 * 1024)); + goto mem_free_and_error; + } + /* -------------- All log files ---------------------------*/ /* The default dir for log files is the datadir of MySQL */ diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h index 2a162100dc1..905e98cc1e6 100644 --- a/storage/innobase/include/fsp0fsp.h +++ b/storage/innobase/include/fsp0fsp.h @@ -520,16 +520,20 @@ fsp_header_init_fields( ulint space_id, /*!< in: space id */ ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS): 0, or table->flags if newer than COMPACT */ -/**********************************************************************//** -Initializes the space header of a new created space and creates also the -insert buffer tree root if space == 0. */ +/** Initializes the space header of a new created space and creates also the +insert buffer tree root if space == 0. +@param[in] space_id space id +@param[in] size current size in blocks +@param[in,out] mtr min-transaction +@return true on success, otherwise false. */ UNIV_INTERN -void +bool fsp_header_init( -/*============*/ - ulint space, /*!< in: space id */ - ulint size, /*!< in: current size in blocks */ - mtr_t* mtr); /*!< in/out: mini-transaction */ + ulint space_id, + ulint size, + mtr_t* mtr) + MY_ATTRIBUTE((warn_unused_result)); + /**********************************************************************//** Increases the space size field of a space. */ UNIV_INTERN diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 82938995e93..6ca9443dc7d 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -3590,9 +3590,15 @@ row_truncate_table_for_mysql( } while (index); mtr_start_trx(&mtr, trx); - fsp_header_init(space_id, + bool ret = fsp_header_init(space_id, FIL_IBD_FILE_INITIAL_SIZE, &mtr); mtr_commit(&mtr); + + if (!ret) { + table->file_unreadable = true; + err = DB_ERROR; + goto funct_exit; + } } } else { /* Lock all index trees for this table, as we will diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index f601ff17ebc..032b902c633 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -188,6 +188,39 @@ UNIV_INTERN mysql_pfs_key_t srv_master_thread_key; UNIV_INTERN mysql_pfs_key_t srv_purge_thread_key; #endif /* UNIV_PFS_THREAD */ +/** Innobase start-up aborted. Perform cleanup actions. +@param[in] create_new_db TRUE if new db is being created +@param[in] file File name +@param[in] line Line number +@param[in] err Reason for aborting InnoDB startup +@return DB_SUCCESS or error code. */ +static +dberr_t +srv_init_abort( + bool create_new_db, + const char* file, + ulint line, + dberr_t err) +{ + if (create_new_db) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Database creation was aborted" + " at %s [" ULINTPF "]" + " with error %s. You may need" + " to delete the ibdata1 file before trying to start" + " up again.", + file, line, ut_strerr(err)); + } else { + ib_logf(IB_LOG_LEVEL_ERROR, + "Plugin initialization aborted" + " at %s [" ULINTPF "]" + " with error %s.", + file, line, ut_strerr(err)); + } + + return(err); +} + /*********************************************************************//** Convert a numeric string that optionally ends in G or M or K, to a number containing megabytes. @@ -1528,18 +1561,26 @@ srv_undo_tablespaces_init( if (create_new_db) { mtr_t mtr; + bool ret=true; mtr_start(&mtr); /* The undo log tablespace */ for (i = 0; i < n_undo_tablespaces; ++i) { - fsp_header_init( + ret = fsp_header_init( undo_tablespace_ids[i], SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr); + if (!ret) { + break; + } } mtr_commit(&mtr); + + if (!ret) { + return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR)); + } } return(DB_SUCCESS); @@ -2378,10 +2419,14 @@ files_checked: mtr_start(&mtr); - fsp_header_init(0, sum_of_new_sizes, &mtr); + bool ret = fsp_header_init(0, sum_of_new_sizes, &mtr); mtr_commit(&mtr); + if (!ret) { + return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR)); + } + /* To maintain backward compatibility we create only the first rollback segment before the double write buffer. All the remaining rollback segments will be created later, @@ -2809,6 +2854,9 @@ files_checked: /* Can only happen if server is read only. */ ut_a(srv_read_only_mode); srv_undo_logs = ULONG_UNDEFINED; + } else if (srv_available_undo_logs < srv_undo_logs) { + /* Should due to out of file space. */ + return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR)); } if (!srv_read_only_mode) { diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc index 003d1036a8c..21dbab98e48 100644 --- a/storage/innobase/trx/trx0rseg.cc +++ b/storage/innobase/trx/trx0rseg.cc @@ -323,7 +323,10 @@ trx_rseg_create( page_no = trx_rseg_header_create( space, 0, ULINT_MAX, slot_no, &mtr); - ut_a(page_no != FIL_NULL); + if (page_no == FIL_NULL) { + mtr_commit(&mtr); + return (rseg); + } sys_header = trx_sysf_get(&mtr); diff --git a/storage/xtradb/btr/btr0btr.cc b/storage/xtradb/btr/btr0btr.cc index d84c93f8b3e..7b5b3bb6cba 100644 --- a/storage/xtradb/btr/btr0btr.cc +++ b/storage/xtradb/btr/btr0btr.cc @@ -1720,6 +1720,12 @@ btr_create( space, 0, IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr); + if (ibuf_hdr_block == NULL) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Allocation of the first ibuf header page failed."); + return (FIL_NULL); + } + buf_block_dbg_add_level( ibuf_hdr_block, SYNC_IBUF_TREE_NODE_NEW); @@ -1733,6 +1739,11 @@ btr_create( + IBUF_HEADER + IBUF_TREE_SEG_HEADER, IBUF_TREE_ROOT_PAGE_NO, FSP_UP, mtr); + + if (!block) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Allocation of the tree root page segment failed."); + } ut_ad(buf_block_get_page_no(block) == IBUF_TREE_ROOT_PAGE_NO); } else { #ifdef UNIV_BLOB_DEBUG @@ -1745,6 +1756,12 @@ btr_create( #endif /* UNIV_BLOB_DEBUG */ block = fseg_create(space, 0, PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr); + + if (!block) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Allocation of the btree segment failed."); + } + } if (block == NULL) { @@ -1773,6 +1790,8 @@ btr_create( segment before return. */ btr_free_root(space, zip_size, page_no, mtr); + ib_logf(IB_LOG_LEVEL_ERROR, + "Allocation of the non-ibuf tree segment for leaf pages failed."); return(FIL_NULL); } diff --git a/storage/xtradb/dict/dict0crea.cc b/storage/xtradb/dict/dict0crea.cc index 6d5b12474eb..faaa6d1bdc7 100644 --- a/storage/xtradb/dict/dict0crea.cc +++ b/storage/xtradb/dict/dict0crea.cc @@ -323,9 +323,13 @@ dict_build_table_def_step( mtr_start(&mtr); - fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr); + bool res = fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr); mtr_commit(&mtr); + + if(!res) { + return (DB_ERROR); + } } else { /* Create in the system tablespace: disallow Barracuda features by keeping only the first bit which says whether diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index 17e9a1be973..b669d35ff15 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -6115,19 +6115,21 @@ fil_report_invalid_page_access( ulint len, /*!< in: I/O length */ ulint type) /*!< in: I/O type */ { - fprintf(stderr, - "InnoDB: Error: trying to access page number %lu" - " in space %lu,\n" - "InnoDB: space name %s,\n" - "InnoDB: which is outside the tablespace bounds.\n" - "InnoDB: Byte offset %lu, len %lu, i/o type %lu.\n" - "InnoDB: If you get this error at mysqld startup," - " please check that\n" - "InnoDB: your my.cnf matches the ibdata files" - " that you have in the\n" - "InnoDB: MySQL server.\n", - (ulong) block_offset, (ulong) space_id, space_name, - (ulong) byte_offset, (ulong) len, (ulong) type); + ib_logf(IB_LOG_LEVEL_ERROR, + "Trying to access page number " ULINTPF + " in space " ULINTPF + " space name %s," + " which is outside the tablespace bounds." + " Byte offset " ULINTPF ", len " ULINTPF " i/o type " ULINTPF ".", + block_offset, space_id, space_name, + byte_offset, len, type); + + ib_logf(IB_LOG_LEVEL_FATAL, + "If you get this error at mysqld startup," + " please check that" + " your my.cnf matches the ibdata files" + " that you have in the" + " MySQL server."); } /********************************************************************//** @@ -6347,11 +6349,10 @@ _fil_io( mutex_exit(&fil_system->mutex); return(DB_ERROR); } + fil_report_invalid_page_access( block_offset, space_id, space->name, byte_offset, len, type); - - ut_error; } /* Open file if closed */ @@ -6363,10 +6364,11 @@ _fil_io( ib_logf(IB_LOG_LEVEL_ERROR, "Trying to do i/o to a tablespace which " "exists without .ibd data file. " - "i/o type %lu, space id %lu, page no %lu, " - "i/o length %lu bytes", - (ulong) type, (ulong) space_id, - (ulong) block_offset, (ulong) len); + "i/o type " ULINTPF ", space id " + ULINTPF ", page no " ULINTPF ", " + "i/o length " ULINTPF " bytes", + type, space_id, + block_offset, len); return(DB_TABLESPACE_DELETED); } @@ -6386,8 +6388,6 @@ _fil_io( fil_report_invalid_page_access( block_offset, space_id, space->name, byte_offset, len, type); - - ut_error; } /* Now we have made the changes in the data structures of fil_system */ diff --git a/storage/xtradb/fsp/fsp0fsp.cc b/storage/xtradb/fsp/fsp0fsp.cc index 934824c6462..7929372ae6c 100644 --- a/storage/xtradb/fsp/fsp0fsp.cc +++ b/storage/xtradb/fsp/fsp0fsp.cc @@ -673,16 +673,18 @@ fsp_header_init_fields( } #ifndef UNIV_HOTBACKUP -/**********************************************************************//** -Initializes the space header of a new created space and creates also the -insert buffer tree root if space == 0. */ +/** Initializes the space header of a new created space and creates also the +insert buffer tree root if space == 0. +@param[in] space_id space id +@param[in] size current size in blocks +@param[in,out] mtr min-transaction +@return true on success, otherwise false. */ UNIV_INTERN -void +bool fsp_header_init( -/*============*/ - ulint space_id, /*!< in: space id */ - ulint size, /*!< in: current size in blocks */ - mtr_t* mtr) /*!< in/out: mini-transaction */ + ulint space_id, + ulint size, + mtr_t* mtr) { fsp_header_t* header; buf_block_t* block; @@ -725,11 +727,15 @@ fsp_header_init( flst_init(header + FSP_SEG_INODES_FREE, mtr); mlog_write_ull(header + FSP_SEG_ID, 1, mtr); + if (space_id == 0) { fsp_fill_free_list(FALSE, space_id, header, mtr); - btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, + + if (btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, 0, 0, DICT_IBUF_ID_MIN + space_id, - dict_ind_redundant, mtr); + dict_ind_redundant, mtr) == FIL_NULL) { + return (false); + } } else { fsp_fill_free_list(TRUE, space_id, header, mtr); } @@ -742,6 +748,8 @@ fsp_header_init( } fil_space_release(space); + + return (true); } #endif /* !UNIV_HOTBACKUP */ @@ -2066,6 +2074,10 @@ fseg_create_general( success = fsp_reserve_free_extents(&n_reserved, space, 2, FSP_NORMAL, mtr); if (!success) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Reserving %d free extents failed" + " could reserve only " ULINTPF " extents.", + 2, n_reserved); return(NULL); } } @@ -2075,6 +2087,8 @@ fseg_create_general( inode = fsp_alloc_seg_inode(space_header, mtr); if (inode == NULL) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Allocation of a new file segment inode page failed."); goto funct_exit; } @@ -2104,6 +2118,9 @@ fseg_create_general( inode, 0, FSP_UP, mtr, mtr); if (block == NULL) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Allocation of a free page from space " ULINTPF " failed.", + space); fsp_free_seg_inode(space, zip_size, inode, mtr); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index dd5d041aed9..7be6c64407b 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -3770,6 +3770,7 @@ innobase_init( char *default_path; uint format_id; ulong num_pll_degree; + ulint min_size = 0; DBUG_ENTER("innobase_init"); handlerton *innobase_hton= (handlerton*) p; @@ -4020,6 +4021,19 @@ mem_free_and_error: goto error; } + /* All doublewrite buffer pages must fit to first system + datafile and first datafile must be at least 3M. */ + min_size = ut_max((3*1024*1024U), (192U*UNIV_PAGE_SIZE)); + + if ((srv_data_file_sizes[0]*1024*1024) < min_size) { + sql_print_error( + "InnoDB: first datafile is too small current=" ULINTPF + "M it should be at least " ULINTPF "M.", + srv_data_file_sizes[0], + min_size / (1024 * 1024)); + goto mem_free_and_error; + } + /* -------------- All log files ---------------------------*/ /* The default dir for log files is the datadir of MySQL */ diff --git a/storage/xtradb/include/fsp0fsp.h b/storage/xtradb/include/fsp0fsp.h index 6ed78eba6f9..d8f851a0846 100644 --- a/storage/xtradb/include/fsp0fsp.h +++ b/storage/xtradb/include/fsp0fsp.h @@ -519,16 +519,20 @@ fsp_header_init_fields( ulint space_id, /*!< in: space id */ ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS): 0, or table->flags if newer than COMPACT */ -/**********************************************************************//** -Initializes the space header of a new created space and creates also the -insert buffer tree root if space == 0. */ +/** Initializes the space header of a new created space and creates also the +insert buffer tree root if space == 0. +@param[in] space_id space id +@param[in] size current size in blocks +@param[in,out] mtr min-transaction +@return true on success, otherwise false. */ UNIV_INTERN -void +bool fsp_header_init( -/*============*/ - ulint space, /*!< in: space id */ - ulint size, /*!< in: current size in blocks */ - mtr_t* mtr); /*!< in/out: mini-transaction */ + ulint space_id, + ulint size, + mtr_t* mtr) + MY_ATTRIBUTE((warn_unused_result)); + /**********************************************************************//** Increases the space size field of a space. */ UNIV_INTERN diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 59568f5c91b..9f1f216bccb 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -3614,9 +3614,15 @@ row_truncate_table_for_mysql( } while (index); mtr_start_trx(&mtr, trx); - fsp_header_init(space_id, + bool ret = fsp_header_init(space_id, FIL_IBD_FILE_INITIAL_SIZE, &mtr); mtr_commit(&mtr); + + if (!ret) { + table->file_unreadable = true; + err = DB_ERROR; + goto funct_exit; + } } } else { /* Lock all index trees for this table, as we will diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index 9e2bd483511..9491d5328e7 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -206,6 +206,39 @@ UNIV_INTERN mysql_pfs_key_t srv_purge_thread_key; UNIV_INTERN mysql_pfs_key_t srv_log_tracking_thread_key; #endif /* UNIV_PFS_THREAD */ +/** Innobase start-up aborted. Perform cleanup actions. +@param[in] create_new_db TRUE if new db is being created +@param[in] file File name +@param[in] line Line number +@param[in] err Reason for aborting InnoDB startup +@return DB_SUCCESS or error code. */ +static +dberr_t +srv_init_abort( + bool create_new_db, + const char* file, + ulint line, + dberr_t err) +{ + if (create_new_db) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Database creation was aborted" + " at %s [" ULINTPF "]" + " with error %s. You may need" + " to delete the ibdata1 file before trying to start" + " up again.", + file, line, ut_strerr(err)); + } else { + ib_logf(IB_LOG_LEVEL_ERROR, + "Plugin initialization aborted" + " at %s [" ULINTPF "]" + " with error %s.", + file, line, ut_strerr(err)); + } + + return(err); +} + /*********************************************************************//** Convert a numeric string that optionally ends in G or M or K, to a number containing megabytes. @@ -1568,18 +1601,26 @@ srv_undo_tablespaces_init( if (create_new_db) { mtr_t mtr; + bool ret=true; mtr_start(&mtr); /* The undo log tablespace */ for (i = 0; i < n_undo_tablespaces; ++i) { - fsp_header_init( + ret = fsp_header_init( undo_tablespace_ids[i], SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr); + if (!ret) { + break; + } } mtr_commit(&mtr); + + if (!ret) { + return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR)); + } } return(DB_SUCCESS); @@ -2466,10 +2507,14 @@ files_checked: mtr_start(&mtr); - fsp_header_init(0, sum_of_new_sizes, &mtr); + bool ret = fsp_header_init(0, sum_of_new_sizes, &mtr); mtr_commit(&mtr); + if (!ret) { + return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR)); + } + /* To maintain backward compatibility we create only the first rollback segment before the double write buffer. All the remaining rollback segments will be created later, @@ -2899,6 +2944,9 @@ files_checked: /* Can only happen if server is read only. */ ut_a(srv_read_only_mode); srv_undo_logs = ULONG_UNDEFINED; + } else if (srv_available_undo_logs < srv_undo_logs) { + /* Should due to out of file space. */ + return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR)); } if (!srv_read_only_mode) { diff --git a/storage/xtradb/trx/trx0rseg.cc b/storage/xtradb/trx/trx0rseg.cc index 003d1036a8c..21dbab98e48 100644 --- a/storage/xtradb/trx/trx0rseg.cc +++ b/storage/xtradb/trx/trx0rseg.cc @@ -323,7 +323,10 @@ trx_rseg_create( page_no = trx_rseg_header_create( space, 0, ULINT_MAX, slot_no, &mtr); - ut_a(page_no != FIL_NULL); + if (page_no == FIL_NULL) { + mtr_commit(&mtr); + return (rseg); + } sys_header = trx_sysf_get(&mtr); From ab62b7538f2eab43943da56c3a6d74cd85dfa877 Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Fri, 2 Jun 2017 01:46:25 +0300 Subject: [PATCH 59/66] MDEV-12042 Re-bootstrap the server if InnoDB options are incompatible --- .../include/innodb_page_size.combinations | 8 +++++ mysql-test/include/innodb_page_size.inc | 4 +++ mysql-test/mysql-test-run.pl | 31 ++++++++++++++----- 3 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 mysql-test/include/innodb_page_size.combinations create mode 100644 mysql-test/include/innodb_page_size.inc diff --git a/mysql-test/include/innodb_page_size.combinations b/mysql-test/include/innodb_page_size.combinations new file mode 100644 index 00000000000..a9b7c7ce14d --- /dev/null +++ b/mysql-test/include/innodb_page_size.combinations @@ -0,0 +1,8 @@ +[16k] +innodb-page-size=16K + +[8k] +innodb-page-size=8K + +[4k] +innodb-page-size=4K diff --git a/mysql-test/include/innodb_page_size.inc b/mysql-test/include/innodb_page_size.inc new file mode 100644 index 00000000000..754b640da86 --- /dev/null +++ b/mysql-test/include/innodb_page_size.inc @@ -0,0 +1,4 @@ +# The goal of including this file is to enable innodb_page_size combinations +# (see include/innodb_page_size.combinations) + +--source include/have_innodb.inc diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 6f9481c7491..47c4f6ca737 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3217,15 +3217,26 @@ sub mysql_server_start($) { } my $mysqld_basedir= $mysqld->value('basedir'); + my $extra_opts= get_extra_opts($mysqld, $tinfo); + if ( $basedir eq $mysqld_basedir ) { if (! $opt_start_dirty) # If dirty, keep possibly grown system db { - # Copy datadir from installed system db - my $path= ($opt_parallel == 1) ? "$opt_vardir" : "$opt_vardir/.."; - my $install_db= "$path/install.db"; - copytree($install_db, $datadir) if -d $install_db; - mtr_error("Failed to copy system db to '$datadir'") unless -d $datadir; + # Some InnoDB options are incompatible with the default bootstrap. + # If they are used, re-bootstrap + if ( $extra_opts and + "@$extra_opts" =~ /--innodb[-_](?:page[-_]size|checksum[-_]algorithm|undo[-_]tablespaces|log[-_]group[-_]home[-_]dir|data[-_]home[-_]dir)/ ) + { + mysql_install_db($mysqld, undef, $extra_opts); + } + else { + # Copy datadir from installed system db + my $path= ($opt_parallel == 1) ? "$opt_vardir" : "$opt_vardir/.."; + my $install_db= "$path/install.db"; + copytree($install_db, $datadir) if -d $install_db; + mtr_error("Failed to copy system db to '$datadir'") unless -d $datadir; + } } } else @@ -3264,7 +3275,6 @@ sub mysql_server_start($) { if (!$opt_embedded_server) { - my $extra_opts= get_extra_opts($mysqld, $tinfo); mysqld_start($mysqld,$extra_opts); # Save this test case information, so next can examine it @@ -3488,7 +3498,7 @@ sub default_mysqld { sub mysql_install_db { - my ($mysqld, $datadir)= @_; + my ($mysqld, $datadir, $extra_opts)= @_; my $install_datadir= $datadir || $mysqld->value('datadir'); my $install_basedir= $mysqld->value('basedir'); @@ -3529,6 +3539,13 @@ sub mysql_install_db { mtr_add_arg($args, $extra_opt); } } + # InnoDB options can come not only from the command line, but also + # from option files or combinations + foreach my $extra_opt ( @$extra_opts ) { + if ($extra_opt =~ /--innodb/) { + mtr_add_arg($args, $extra_opt); + } + } # If DISABLE_GRANT_OPTIONS is defined when the server is compiled (e.g., # configure --disable-grant-options), mysqld will not recognize the From da61107fc8481b03ae858188dd03b3114e7aa084 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Mon, 5 Jun 2017 13:10:24 +0530 Subject: [PATCH 60/66] MDEV-9544 FLUSH [RELAY] LOGS does not rotate logs for a named slave Problem:- In the case of multisource replication/named slave when we run "FLUSH LOGS" , it does not flush logs. Solution:- A new function Master_info_index->flush_all_relay_logs() is created which will rotate relay logs for all named slave. This will be called in reload_acl_and_cache function when connection_name.length == 0 --- mysql-test/suite/multi_source/mdev-9544.cnf | 22 ++++ .../suite/multi_source/mdev-9544.result | 78 ++++++++++++ mysql-test/suite/multi_source/mdev-9544.test | 116 ++++++++++++++++++ sql/rpl_mi.cc | 51 +++++++- sql/rpl_mi.h | 2 + sql/sql_reload.cc | 8 +- 6 files changed, 274 insertions(+), 3 deletions(-) create mode 100644 mysql-test/suite/multi_source/mdev-9544.cnf create mode 100644 mysql-test/suite/multi_source/mdev-9544.result create mode 100644 mysql-test/suite/multi_source/mdev-9544.test diff --git a/mysql-test/suite/multi_source/mdev-9544.cnf b/mysql-test/suite/multi_source/mdev-9544.cnf new file mode 100644 index 00000000000..b43aca5370d --- /dev/null +++ b/mysql-test/suite/multi_source/mdev-9544.cnf @@ -0,0 +1,22 @@ +!include my.cnf + +[mysqld.1] +log-bin +log-slave-updates + +[mysqld.2] +log-bin +log-slave-updates + +[mysqld.3] +log-bin +log-slave-updates + +[mysqld.4] +server-id=4 +log-bin=server4-bin +log-slave-updates + +[ENV] +SERVER_MYPORT_4= @mysqld.4.port +SERVER_MYSOCK_4= @mysqld.4.socket diff --git a/mysql-test/suite/multi_source/mdev-9544.result b/mysql-test/suite/multi_source/mdev-9544.result new file mode 100644 index 00000000000..e7e4bcda8ff --- /dev/null +++ b/mysql-test/suite/multi_source/mdev-9544.result @@ -0,0 +1,78 @@ +create database a; +use a; +create table t1(a int); +insert into t1 values(1); +create table t2(a int); +insert into t2 values(1); +create database b; +use b; +create table t1(a int); +insert into t1 values(1); +create table t2(a int); +insert into t2 values(1); +create database c; +use c; +create table t1(a int); +insert into t1 values(1); +create table t2(a int); +insert into t2 values(1); +change master 'm1' to master_port=MYPORT_1 , master_host='127.0.0.1', master_user='root'; +change master 'm2' to master_port=MYPORT_2 , master_host='127.0.0.1', master_user='root'; +change master to master_port=MYPORT_3 , master_host='127.0.0.1', master_user='root'; +start all slaves; +set default_master_connection = 'm1'; +include/wait_for_slave_to_start.inc +set default_master_connection = 'm2'; +include/wait_for_slave_to_start.inc +set default_master_connection = ''; +include/wait_for_slave_to_start.inc +use a; +show tables; +Tables_in_a +t1 +t2 +use b; +show tables; +Tables_in_b +t1 +t2 +use c; +show tables; +Tables_in_c +t1 +t2 +#TEST +SET default_master_connection = "m1"; +SET default_master_connection = "m2"; +SET default_master_connection = ""; +flush logs; +SET default_master_connection = "m1"; +#log Rotated +mysqld-relay-bin.000002 +mysqld-relay-bin.000003 +mysqld-relay-bin.index +SET default_master_connection = "m2"; +#log Rotated +mysqld-relay-bin-m1.000002 +mysqld-relay-bin-m1.000003 +mysqld-relay-bin-m1.index +SET default_master_connection = ""; +#log Rotated +mysqld-relay-bin-m2.000002 +mysqld-relay-bin-m2.000003 +mysqld-relay-bin-m2.index +#CleanUp +drop database a; +drop database b; +drop database c; +stop all slaves; +Warnings: +Note 1938 SLAVE 'm2' stopped +Note 1938 SLAVE '' stopped +Note 1938 SLAVE 'm1' stopped +SET default_master_connection = "m1"; +include/wait_for_slave_to_stop.inc +SET default_master_connection = "m2"; +include/wait_for_slave_to_stop.inc +SET default_master_connection = ""; +include/wait_for_slave_to_stop.inc diff --git a/mysql-test/suite/multi_source/mdev-9544.test b/mysql-test/suite/multi_source/mdev-9544.test new file mode 100644 index 00000000000..f532a63a585 --- /dev/null +++ b/mysql-test/suite/multi_source/mdev-9544.test @@ -0,0 +1,116 @@ +--source include/not_embedded.inc +--source include/have_innodb.inc +--source include/have_debug.inc + +--connect (server_1,127.0.0.1,root,,,$SERVER_MYPORT_1) +--connect (server_2,127.0.0.1,root,,,$SERVER_MYPORT_2) +--connect (server_3,127.0.0.1,root,,,$SERVER_MYPORT_3) +--connect (server_4,127.0.0.1,root,,,$SERVER_MYPORT_4) + +--connection server_1 +create database a; +use a; +create table t1(a int); +insert into t1 values(1); +create table t2(a int); +insert into t2 values(1); +--save_master_pos + +--connection server_2 +create database b; +use b; +create table t1(a int); +insert into t1 values(1); +create table t2(a int); +insert into t2 values(1); +--save_master_pos + +--connection server_3 +create database c; +use c; +create table t1(a int); +insert into t1 values(1); +create table t2(a int); +insert into t2 values(1); +--save_master_pos + +--connection server_4 +--disable_warnings +--replace_result $SERVER_MYPORT_1 MYPORT_1 +eval change master 'm1' to master_port=$SERVER_MYPORT_1 , master_host='127.0.0.1', master_user='root'; +--replace_result $SERVER_MYPORT_2 MYPORT_2 +eval change master 'm2' to master_port=$SERVER_MYPORT_2 , master_host='127.0.0.1', master_user='root'; +--replace_result $SERVER_MYPORT_3 MYPORT_3 +eval change master to master_port=$SERVER_MYPORT_3 , master_host='127.0.0.1', master_user='root'; +start all slaves; +set default_master_connection = 'm1'; +--source include/wait_for_slave_to_start.inc +set default_master_connection = 'm2'; +--source include/wait_for_slave_to_start.inc +set default_master_connection = ''; +--source include/wait_for_slave_to_start.inc + +--enable_warnings +--sync_with_master 0,'m1' +--sync_with_master 0,'m2' +--sync_with_master 0,'' +use a; +show tables; +use b; +show tables; +use c; +show tables; +--echo #TEST +SET default_master_connection = "m1"; +--let $old_m1 = query_get_value("show relaylog events;", "Log_name",1) +SET default_master_connection = "m2"; +--let $old_m2 = query_get_value("show relaylog events;", "Log_name",1) +SET default_master_connection = ""; +--let $old__ = query_get_value("show relaylog events;", "Log_name",1) +flush logs; +--sleep 2 +--let $MYSQLD_DATADIR = `select @@datadir` +SET default_master_connection = "m1"; +--let $new_m1 = query_get_value("show relaylog events;", "Log_name",1) +--if ($new_m1 != $old_m1) { + --echo #log Rotated + --exec ls $MYSQLD_DATADIR | grep "mysqld-relay-bin\." +} +SET default_master_connection = "m2"; +--let $new_m2 = query_get_value("show relaylog events;", "Log_name",1) +--if ($new_m2 != $old_m2) { + --echo #log Rotated + --exec ls $MYSQLD_DATADIR | grep "mysqld-relay-bin-m1" +} +SET default_master_connection = ""; +--let $new__ = query_get_value("show relaylog events;", "Log_name",1) +--if ($new__ != $old__) { + --echo #log Rotated + --exec ls $MYSQLD_DATADIR | grep "mysqld-relay-bin-m2" +} + +--echo #CleanUp +--connection server_1 +drop database a; +--save_master_pos + +--connection server_2 +drop database b; +--save_master_pos + +--connection server_3 +drop database c; +--save_master_pos + +--connection server_4 +--sync_with_master 0,'m1' +--sync_with_master 0,'m2' +--sync_with_master 0,'' +stop all slaves; +SET default_master_connection = "m1"; +--source include/wait_for_slave_to_stop.inc +SET default_master_connection = "m2"; +--source include/wait_for_slave_to_stop.inc +SET default_master_connection = ""; +--source include/wait_for_slave_to_stop.inc + diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index c9dcf7b8fd7..ed756a996ca 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -41,7 +41,7 @@ Master_info::Master_info(LEX_STRING *connection_name_arg, master_id(0), prev_master_id(0), using_gtid(USE_GTID_NO), events_queued_since_last_gtid(0), gtid_reconnect_event_skip_count(0), gtid_event_seen(false), - in_start_all_slaves(0), in_stop_all_slaves(0), + in_start_all_slaves(0), in_stop_all_slaves(0), in_flush_all_relay_logs(0), users(0), killed(0) { host[0] = 0; user[0] = 0; password[0] = 0; @@ -1980,4 +1980,53 @@ void prot_store_ids(THD *thd, DYNAMIC_ARRAY *ids) return; } +bool Master_info_index::flush_all_relay_logs() +{ + DBUG_ENTER("flush_all_relay_logs"); + bool result= false; + int error= 0; + mysql_mutex_lock(&LOCK_active_mi); + for (uint i= 0; i< master_info_hash.records; i++) + { + Master_info *mi; + mi= (Master_info *) my_hash_element(&master_info_hash, i); + mi->in_flush_all_relay_logs= 0; + } + for (uint i=0; i < master_info_hash.records;) + { + Master_info *mi; + mi= (Master_info *)my_hash_element(&master_info_hash, i); + DBUG_ASSERT(mi); + + if (mi->in_flush_all_relay_logs) + { + i++; + continue; + } + mi->in_flush_all_relay_logs= 1; + + mysql_mutex_lock(&mi->sleep_lock); + mi->users++; // Mark used + mysql_mutex_unlock(&mi->sleep_lock); + mysql_mutex_unlock(&LOCK_active_mi); + + mysql_mutex_lock(&mi->data_lock); + error= rotate_relay_log(mi); + mysql_mutex_unlock(&mi->data_lock); + mi->release(); + mysql_mutex_lock(&LOCK_active_mi); + + if (error) + { + result= true; + break; + } + /* Restart from first element as master_info_hash may have changed */ + i= 0; + continue; + } + mysql_mutex_unlock(&LOCK_active_mi); + DBUG_RETURN(result); +} + #endif /* HAVE_REPLICATION */ diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 31c0f280ac1..d0f6171815c 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -302,6 +302,7 @@ class Master_info : public Slave_reporting_capability /* gtid_event_seen is false until we receive first GTID event from master. */ bool gtid_event_seen; bool in_start_all_slaves, in_stop_all_slaves; + bool in_flush_all_relay_logs; uint users; /* Active user for object */ uint killed; @@ -354,6 +355,7 @@ public: bool start_all_slaves(THD *thd); bool stop_all_slaves(THD *thd); void free_connections(); + bool flush_all_relay_logs(); }; diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 995c4c0a838..376dfeb1542 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -181,8 +181,12 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, slave is not likely to have the same connection names. */ tmp_write_to_binlog= 0; - - if (!(mi= (get_master_info(&connection_name, + if (connection_name.length == 0) + { + if (master_info_index->flush_all_relay_logs()) + *write_to_binlog= -1; + } + else if (!(mi= (get_master_info(&connection_name, Sql_condition::WARN_LEVEL_ERROR)))) { result= 1; From 151daaf4805d4e8ed30d2d871ac99ff1c1873bdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 5 Jun 2017 15:16:15 +0300 Subject: [PATCH 61/66] MDEV-12994 innodb_fast_shutdown=0 skips change buffer merge; fast shutdown does it srv_master_thread(): Pass the correct parameter to srv_shutdown(). This bug was introduced in MDEV-12052, and it affects the MariaDB 10.1.24 release. --- storage/innobase/srv/srv0srv.cc | 2 +- storage/xtradb/srv/srv0srv.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 93ed302a236..bad1579070c 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -2403,7 +2403,7 @@ suspend_thread: case SRV_SHUTDOWN_CLEANUP: if (srv_shutdown_state == SRV_SHUTDOWN_CLEANUP && srv_fast_shutdown < 2) { - srv_shutdown(srv_fast_shutdown == 1); + srv_shutdown(srv_fast_shutdown == 0); } srv_suspend_thread(slot); my_thread_end(); diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc index d18abbe0574..2fa3be014a5 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -3076,7 +3076,7 @@ suspend_thread: case SRV_SHUTDOWN_CLEANUP: if (srv_shutdown_state == SRV_SHUTDOWN_CLEANUP && srv_fast_shutdown < 2) { - srv_shutdown(srv_fast_shutdown == 1); + srv_shutdown(srv_fast_shutdown == 0); } srv_suspend_thread(slot); my_thread_end(); From d8d39721dfef6b965d782e6099493c36150585cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 6 Jun 2017 09:34:09 +0300 Subject: [PATCH 62/66] Follow-up to MDEV-12042 (test innodb_page_size variants) innodb_page_size_small: A new set of combinations, for innodb_page_size up to 16k. In MariaDB 10.0, this does not make a difference, but in 10.1 and later, innodb_page_size would cover 32k and 64k, for which ROW_FORMAT=COMPRESSED is not available. Enable these combinations in a few InnoDB tests. --- .../include/innodb_page_size_small.combinations | 8 ++++++++ mysql-test/include/innodb_page_size_small.inc | 4 ++++ mysql-test/suite/innodb/t/innodb-alter-debug.test | 2 +- mysql-test/suite/innodb/t/innodb-alter-discard.test | 2 +- mysql-test/suite/innodb/t/innodb-alter-nullable.test | 2 +- mysql-test/suite/innodb/t/innodb-alter-table.test | 2 +- mysql-test/suite/innodb/t/innodb-alter-tempfile.test | 3 +-- mysql-test/suite/innodb_zip/r/innodb-zip.result | 2 -- .../suite/innodb_zip/t/innodb-create-options.test | 2 +- mysql-test/suite/innodb_zip/t/innodb-zip.test | 11 +---------- mysql-test/suite/innodb_zip/t/innodb_bug36169.test | 2 +- mysql-test/suite/innodb_zip/t/innodb_bug36172.test | 2 +- mysql-test/suite/innodb_zip/t/innodb_bug52745.test | 2 +- mysql-test/suite/innodb_zip/t/innodb_bug53591.test | 2 +- mysql-test/suite/innodb_zip/t/innodb_bug56680.test | 2 +- 15 files changed, 24 insertions(+), 24 deletions(-) create mode 100644 mysql-test/include/innodb_page_size_small.combinations create mode 100644 mysql-test/include/innodb_page_size_small.inc diff --git a/mysql-test/include/innodb_page_size_small.combinations b/mysql-test/include/innodb_page_size_small.combinations new file mode 100644 index 00000000000..a9b7c7ce14d --- /dev/null +++ b/mysql-test/include/innodb_page_size_small.combinations @@ -0,0 +1,8 @@ +[16k] +innodb-page-size=16K + +[8k] +innodb-page-size=8K + +[4k] +innodb-page-size=4K diff --git a/mysql-test/include/innodb_page_size_small.inc b/mysql-test/include/innodb_page_size_small.inc new file mode 100644 index 00000000000..754b640da86 --- /dev/null +++ b/mysql-test/include/innodb_page_size_small.inc @@ -0,0 +1,4 @@ +# The goal of including this file is to enable innodb_page_size combinations +# (see include/innodb_page_size.combinations) + +--source include/have_innodb.inc diff --git a/mysql-test/suite/innodb/t/innodb-alter-debug.test b/mysql-test/suite/innodb/t/innodb-alter-debug.test index 70017ffba35..f4996916e9f 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-debug.test +++ b/mysql-test/suite/innodb/t/innodb-alter-debug.test @@ -1,4 +1,4 @@ ---source include/have_innodb.inc +--source include/innodb_page_size.inc --source include/have_debug.inc --source include/have_debug_sync.inc diff --git a/mysql-test/suite/innodb/t/innodb-alter-discard.test b/mysql-test/suite/innodb/t/innodb-alter-discard.test index 80678cef0a6..c90992e58a3 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-discard.test +++ b/mysql-test/suite/innodb/t/innodb-alter-discard.test @@ -1,7 +1,7 @@ #Bug#13955083 ALLOW IN-PLACE DDL OPERATIONS ON MISSING OR DISCARDED TABLESPACES --source include/not_embedded.inc ---source include/have_innodb.inc +--source include/innodb_page_size.inc let $MYSQLD_DATADIR=`select @@datadir`; SET GLOBAL innodb_file_per_table=1; diff --git a/mysql-test/suite/innodb/t/innodb-alter-nullable.test b/mysql-test/suite/innodb/t/innodb-alter-nullable.test index 3f1e82b3183..bb5cdee000a 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-nullable.test +++ b/mysql-test/suite/innodb/t/innodb-alter-nullable.test @@ -1,4 +1,4 @@ ---source include/have_innodb.inc +--source include/innodb_page_size.inc # Save the initial number of concurrent sessions. --source include/count_sessions.inc diff --git a/mysql-test/suite/innodb/t/innodb-alter-table.test b/mysql-test/suite/innodb/t/innodb-alter-table.test index 45342b4a218..97f0075f344 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-table.test +++ b/mysql-test/suite/innodb/t/innodb-alter-table.test @@ -1,4 +1,4 @@ ---source include/have_innodb.inc +--source include/innodb_page_size.inc # # MMDEV-8386: MariaDB creates very big tmp file and hangs on xtradb diff --git a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test index e1e736fc678..8813e50f24a 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test +++ b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test @@ -10,8 +10,7 @@ # Avoid CrashReporter popup on Mac --source include/not_crashrep.inc -# InnoDB is required ---source include/have_innodb.inc +--source include/innodb_page_size.inc --echo # --echo # Bug #18734396 INNODB IN-PLACE ALTER FAILURES BLOCK FUTURE ALTERS diff --git a/mysql-test/suite/innodb_zip/r/innodb-zip.result b/mysql-test/suite/innodb_zip/r/innodb-zip.result index dbfae3c0630..584a8a5d647 100644 --- a/mysql-test/suite/innodb_zip/r/innodb-zip.result +++ b/mysql-test/suite/innodb_zip/r/innodb-zip.result @@ -1,4 +1,3 @@ -DROP DATABASE IF EXISTS mysqltest_innodb_zip; CREATE DATABASE mysqltest_innodb_zip; USE mysqltest_innodb_zip; SELECT table_name, row_format, data_length, index_length @@ -379,5 +378,4 @@ select @@innodb_file_format_max; @@innodb_file_format_max Barracuda drop table normal_table, zip_table; -USE test; DROP DATABASE mysqltest_innodb_zip; diff --git a/mysql-test/suite/innodb_zip/t/innodb-create-options.test b/mysql-test/suite/innodb_zip/t/innodb-create-options.test index aeb22514bf6..53d739feccb 100644 --- a/mysql-test/suite/innodb_zip/t/innodb-create-options.test +++ b/mysql-test/suite/innodb_zip/t/innodb-create-options.test @@ -1,4 +1,4 @@ ---source include/have_innodb.inc +--source include/innodb_page_size_small.inc # Tests for various combinations of ROW_FORMAT and KEY_BLOCK_SIZE # Related bugs; # Bug#54679: ALTER TABLE causes compressed row_format to revert to compact diff --git a/mysql-test/suite/innodb_zip/t/innodb-zip.test b/mysql-test/suite/innodb_zip/t/innodb-zip.test index 1c7c7c8c419..e8ba98f14ce 100644 --- a/mysql-test/suite/innodb_zip/t/innodb-zip.test +++ b/mysql-test/suite/innodb_zip/t/innodb-zip.test @@ -1,9 +1,4 @@ --- source include/have_innodb.inc - - ---disable_warnings -DROP DATABASE IF EXISTS mysqltest_innodb_zip; ---enable_warnings +--source include/innodb_page_size_small.inc CREATE DATABASE mysqltest_innodb_zip; USE mysqltest_innodb_zip; @@ -13,7 +8,6 @@ SELECT table_name, row_format, data_length, index_length let $per_table=`select @@innodb_file_per_table`; let $format=`select @@innodb_file_format`; -let $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; let $innodb_file_format_orig=`select @@innodb_file_format`; let $innodb_file_format_max_orig=`select @@innodb_file_format_max`; SET @save_innodb_stats_on_metadata=@@global.innodb_stats_on_metadata; @@ -363,12 +357,9 @@ drop table normal_table, zip_table; -- disable_query_log eval set global innodb_file_format=$format; eval set global innodb_file_per_table=$per_table; -eval set session innodb_strict_mode=$innodb_strict_mode_orig; eval SET GLOBAL innodb_file_format=$innodb_file_format_orig; eval SET GLOBAL innodb_file_format_max=$innodb_file_format_max_orig; SET @@global.innodb_stats_on_metadata=@save_innodb_stats_on_metadata; --enable_query_log -USE test; DROP DATABASE mysqltest_innodb_zip; - diff --git a/mysql-test/suite/innodb_zip/t/innodb_bug36169.test b/mysql-test/suite/innodb_zip/t/innodb_bug36169.test index 6426bd683ae..ac1f0a3fe57 100644 --- a/mysql-test/suite/innodb_zip/t/innodb_bug36169.test +++ b/mysql-test/suite/innodb_zip/t/innodb_bug36169.test @@ -1,4 +1,4 @@ ---source include/have_innodb.inc +--source include/innodb_page_size_small.inc # # Bug#36169 create innodb compressed table with too large row size crashed # http://bugs.mysql.com/36169 diff --git a/mysql-test/suite/innodb_zip/t/innodb_bug36172.test b/mysql-test/suite/innodb_zip/t/innodb_bug36172.test index 015f461e532..7b82a7aba33 100644 --- a/mysql-test/suite/innodb_zip/t/innodb_bug36172.test +++ b/mysql-test/suite/innodb_zip/t/innodb_bug36172.test @@ -1,4 +1,4 @@ ---source include/have_innodb.inc +--source include/innodb_page_size_small.inc # # Test case for bug 36172 # diff --git a/mysql-test/suite/innodb_zip/t/innodb_bug52745.test b/mysql-test/suite/innodb_zip/t/innodb_bug52745.test index 3c5d79826f0..d84feb3b22d 100644 --- a/mysql-test/suite/innodb_zip/t/innodb_bug52745.test +++ b/mysql-test/suite/innodb_zip/t/innodb_bug52745.test @@ -1,4 +1,4 @@ --- source include/have_innodb.inc +--source include/innodb_page_size_small.inc let $file_format=`select @@innodb_file_format`; let $file_per_table=`select @@innodb_file_per_table`; diff --git a/mysql-test/suite/innodb_zip/t/innodb_bug53591.test b/mysql-test/suite/innodb_zip/t/innodb_bug53591.test index 8bc461719b8..ea1221dd711 100644 --- a/mysql-test/suite/innodb_zip/t/innodb_bug53591.test +++ b/mysql-test/suite/innodb_zip/t/innodb_bug53591.test @@ -1,4 +1,4 @@ --- source include/have_innodb.inc +--source include/innodb_page_size_small.inc let $file_format=`select @@innodb_file_format`; let $file_per_table=`select @@innodb_file_per_table`; diff --git a/mysql-test/suite/innodb_zip/t/innodb_bug56680.test b/mysql-test/suite/innodb_zip/t/innodb_bug56680.test index f592bd16942..700d7e6f0a8 100644 --- a/mysql-test/suite/innodb_zip/t/innodb_bug56680.test +++ b/mysql-test/suite/innodb_zip/t/innodb_bug56680.test @@ -1,4 +1,4 @@ ---source include/have_innodb.inc +--source include/innodb_page_size_small.inc # # Bug #56680 InnoDB may return wrong results from a case-insensitive index # From 6439238c539577588e36961aeb8005bb102a1fbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 6 Jun 2017 14:57:20 +0300 Subject: [PATCH 63/66] Correct a merge error --- storage/xtradb/buf/buf0buf.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc index 759e1441ee3..c72900bd082 100644 --- a/storage/xtradb/buf/buf0buf.cc +++ b/storage/xtradb/buf/buf0buf.cc @@ -3450,6 +3450,7 @@ got_block: } if (buf_flush_page_try(buf_pool, fix_block)) { + guess = fix_block; goto loop; } From d8515829ec821304c4e0fd00d2645b64568b9df3 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 8 Jun 2017 12:43:39 +1000 Subject: [PATCH 64/66] MDEV-13032: fix galera_new_cluster to be POSIX Signed-off-by: Daniel Black --- scripts/galera_new_cluster.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/galera_new_cluster.sh b/scripts/galera_new_cluster.sh index b873192cf31..8bf2fa35cec 100755 --- a/scripts/galera_new_cluster.sh +++ b/scripts/galera_new_cluster.sh @@ -5,7 +5,7 @@ # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. -if [ "${1}" == "-h" -o "${1}" == "--help" ]; then +if [ "${1}" = "-h" ] || [ "${1}" = "--help" ]; then cat < Date: Tue, 6 Jun 2017 15:24:43 +0300 Subject: [PATCH 65/66] Revert part of MDEV-12113 commit 1af8bf39ca2513bfdf43a55af0b6af10d32dcebb added unnecessary calls to fil_write_flushed_lsn() during redo log resizing at InnoDB server startup. Because fil_write_flushed_lsn() is neither redo-logged nor doublewrite buffered, the call is risky and should be avoided, because if the server killed during the write call, the whole InnoDB instance can become inaccessible (corrupted page 0 in the system tablespace). In the best case, this call might prevent a diagnostic message from being emitted to the error log on the next startup. --- storage/innobase/srv/srv0start.cc | 13 ++----------- storage/xtradb/srv/srv0start.cc | 10 ---------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 032b902c633..4e59ddd1f87 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -2766,17 +2766,8 @@ files_checked: return(err); } - /* create_log_files() can increase system lsn that is - why FIL_PAGE_FILE_FLUSH_LSN have to be updated */ - flushed_lsn = log_get_lsn(); - - err = fil_write_flushed_lsn(flushed_lsn); - - if (err == DB_SUCCESS) { - err = create_log_files_rename( - logfilename, dirnamelen, - flushed_lsn, logfile0); - } + err = create_log_files_rename(logfilename, dirnamelen, + log_get_lsn(), logfile0); if (err != DB_SUCCESS) { return(err); diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index 9491d5328e7..cbab9b2f8c4 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -2852,16 +2852,6 @@ files_checked: return(err); } - /* create_log_files() can increase system lsn that is - why FIL_PAGE_FILE_FLUSH_LSN have to be updated */ - flushed_lsn = log_get_lsn(); - - err = fil_write_flushed_lsn(flushed_lsn); - - if (err != DB_SUCCESS) { - return(err); - } - err = create_log_files_rename(logfilename, dirnamelen, log_get_lsn(), logfile0); From fbeb9489cd7d6ad859a49ae5ab8f876f3d988470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 6 Jun 2017 14:59:42 +0300 Subject: [PATCH 66/66] Cleanup of MDEV-12600: crash during install_db with innodb_page_size=32K and ibdata1=3M The doublewrite buffer pages must fit in the first InnoDB system tablespace data file. The checks that were added in the initial patch (commit 112b21da37dad0fbb28bc65f9ab5a3ba6c0c2186) were at too high level and did not cover all cases. innodb.log_data_file_size: Test all innodb_page_size combinations. fsp_header_init(): Never return an error. Move the change buffer creation to the only caller that needs to do it. btr_create(): Clean up the logic. Remove the error log messages. buf_dblwr_create(): Try to return an error on non-fatal failure. Check that the first data file is big enough for creating the doublewrite buffers. buf_dblwr_process(): Check if the doublewrite buffer is available. Display the message only if it is available. recv_recovery_from_checkpoint_start_func(): Remove a redundant message about FIL_PAGE_FILE_FLUSH_LSN mismatch when crash recovery has already been initiated. fil_report_invalid_page_access(): Simplify the message. fseg_create_general(): Do not emit messages to the error log. innobase_init(): Revert the changes. trx_rseg_create(): Refactor (no functional change). --- mysql-test/suite/innodb/r/doublewrite.result | 12 ++- mysql-test/suite/innodb/t/doublewrite.test | 44 +++++++++-- .../suite/innodb/t/log_data_file_size.opt | 2 +- .../suite/innodb/t/log_data_file_size.test | 2 +- storage/innobase/btr/btr0btr.cc | 54 ++++---------- storage/innobase/buf/buf0dblwr.cc | 74 +++++++++++++------ storage/innobase/dict/dict0crea.cc | 6 +- storage/innobase/fil/fil0fil.cc | 20 +++-- storage/innobase/fsp/fsp0fsp.cc | 37 ++-------- storage/innobase/handler/ha_innodb.cc | 14 ---- storage/innobase/include/buf0dblwr.h | 16 ++-- storage/innobase/include/fsp0fsp.h | 14 +--- storage/innobase/include/trx0rseg.h | 11 +-- storage/innobase/log/log0recv.cc | 23 ------ storage/innobase/row/row0mysql.cc | 8 +- storage/innobase/srv/srv0start.cc | 33 +++++---- storage/innobase/trx/trx0rseg.cc | 38 +++++----- storage/xtradb/btr/btr0btr.cc | 54 ++++---------- storage/xtradb/buf/buf0dblwr.cc | 74 +++++++++++++------ storage/xtradb/dict/dict0crea.cc | 6 +- storage/xtradb/fil/fil0fil.cc | 20 +++-- storage/xtradb/fsp/fsp0fsp.cc | 37 ++-------- storage/xtradb/handler/ha_innodb.cc | 14 ---- storage/xtradb/include/buf0dblwr.h | 16 ++-- storage/xtradb/include/fsp0fsp.h | 14 +--- storage/xtradb/include/trx0rseg.h | 11 +-- storage/xtradb/log/log0recv.cc | 23 ------ storage/xtradb/row/row0mysql.cc | 8 +- storage/xtradb/srv/srv0start.cc | 33 +++++---- storage/xtradb/trx/trx0rseg.cc | 38 +++++----- 30 files changed, 323 insertions(+), 433 deletions(-) diff --git a/mysql-test/suite/innodb/r/doublewrite.result b/mysql-test/suite/innodb/r/doublewrite.result index 6b913f49972..7cc4a436e5c 100644 --- a/mysql-test/suite/innodb/r/doublewrite.result +++ b/mysql-test/suite/innodb/r/doublewrite.result @@ -231,6 +231,7 @@ set global innodb_buf_flush_list_now = 1; check table t1; Table Op Msg_type Msg_text test.t1 check status OK +FOUND /\[ERROR\] InnoDB: .* in tablespace.*test.t1.*/ in mysqld.1.err select f1, f2 from t1; f1 f2 1 ############ @@ -238,6 +239,13 @@ f1 f2 3 //////////// 4 ------------ 5 ............ -# Test End -# --------------------------------------------------------------- drop table t1; +# +# MDEV-12600 crash during install_db with innodb_page_size=32K +# and ibdata1=3M +# +SELECT * FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND /\[ERROR\] InnoDB: Cannot create doublewrite buffer/ in mysqld.1.err diff --git a/mysql-test/suite/innodb/t/doublewrite.test b/mysql-test/suite/innodb/t/doublewrite.test index b4604a44731..aba3d6ecff5 100644 --- a/mysql-test/suite/innodb/t/doublewrite.test +++ b/mysql-test/suite/innodb/t/doublewrite.test @@ -4,7 +4,7 @@ --echo # PAGE OF SYSTEM TABLESPACE --echo # ---source include/have_innodb.inc +--source include/innodb_page_size.inc --source include/have_debug.inc --source include/not_embedded.inc @@ -15,12 +15,17 @@ call mtr.add_suppression("space header page consists of zero bytes.*test.t1"); call mtr.add_suppression("checksum mismatch in tablespace.*test.t1"); call mtr.add_suppression("Current page size .* != page size on page"); call mtr.add_suppression("innodb-page-size mismatch in tablespace.*test.t1"); -call mtr.add_suppression("Trying to recover page.*from the doublewrite buffer"); +call mtr.add_suppression("InnoDB: New log files created"); +call mtr.add_suppression("InnoDB: Cannot create doublewrite buffer: the first file in innodb_data_file_path must be at least (3|6|12)M\\."); +call mtr.add_suppression("InnoDB: Database creation was aborted"); +call mtr.add_suppression("Plugin 'InnoDB' (init function returned error|registration as a STORAGE ENGINE failed)"); --enable_query_log --source include/restart_mysqld.inc let INNODB_PAGE_SIZE=`select @@innodb_page_size`; let MYSQLD_DATADIR=`select @@datadir`; +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; +let SEARCH_RANGE= -50000; show variables like 'innodb_doublewrite'; show variables like 'innodb_fil_make_page_dirty_debug'; @@ -393,9 +398,38 @@ EOF --source include/start_mysqld.inc check table t1; +--let SEARCH_PATTERN= \[ERROR\] InnoDB: .* in tablespace.*test.t1.* +--source include/search_pattern_in_file.inc + select f1, f2 from t1; ---echo # Test End ---echo # --------------------------------------------------------------- - drop table t1; + +--echo # +--echo # MDEV-12600 crash during install_db with innodb_page_size=32K +--echo # and ibdata1=3M +--echo # +let bugdir= $MYSQLTEST_VARDIR/tmp/doublewrite; +--mkdir $bugdir + +let $check_no_innodb=SELECT * FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); + +--let $ibp=--innodb-log-group-home-dir=$bugdir --innodb-data-home-dir=$bugdir +--let $ibd=$ibp --innodb-undo-tablespaces=0 --innodb-log-files-in-group=2 +--let $ibp=$ibp --innodb-data-file-path=ibdata1:1M;ibdata2:1M:autoextend + +--let $restart_parameters= $ibp +--source include/restart_mysqld.inc +eval $check_no_innodb; +--let SEARCH_PATTERN= \[ERROR\] InnoDB: Cannot create doublewrite buffer +--source include/search_pattern_in_file.inc +--let $restart_parameters= +--source include/restart_mysqld.inc + +--remove_file $bugdir/ibdata1 +--remove_file $bugdir/ibdata2 +--remove_file $bugdir/ib_logfile0 +--remove_file $bugdir/ib_logfile1 +--rmdir $bugdir diff --git a/mysql-test/suite/innodb/t/log_data_file_size.opt b/mysql-test/suite/innodb/t/log_data_file_size.opt index fe36abe4701..d9a364a3287 100644 --- a/mysql-test/suite/innodb/t/log_data_file_size.opt +++ b/mysql-test/suite/innodb/t/log_data_file_size.opt @@ -1,2 +1,2 @@ --loose-innodb-sys-indexes ---innodb-data-file-path=ibdata1:3M:autoextend +--innodb-data-file-path=ibdata1:1M:autoextend diff --git a/mysql-test/suite/innodb/t/log_data_file_size.test b/mysql-test/suite/innodb/t/log_data_file_size.test index 9328f3bbe6d..2f1c497595b 100644 --- a/mysql-test/suite/innodb/t/log_data_file_size.test +++ b/mysql-test/suite/innodb/t/log_data_file_size.test @@ -1,4 +1,4 @@ ---source include/have_innodb.inc +--source include/innodb_page_size.inc --source include/not_embedded.inc let INNODB_PAGE_SIZE=`select @@innodb_page_size`; diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index e200a2b9677..b7afcf12b39 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -2,7 +2,7 @@ Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2014, 2017, MariaDB Corporation +Copyright (c) 2014, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1684,9 +1684,7 @@ btr_create( dict_index_t* index, /*!< in: index */ mtr_t* mtr) /*!< in: mini-transaction handle */ { - ulint page_no; buf_block_t* block; - buf_frame_t* frame; page_t* page; page_zip_des_t* page_zip; @@ -1702,9 +1700,7 @@ btr_create( IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr); if (ibuf_hdr_block == NULL) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Allocation of the first ibuf header page failed."); - return (FIL_NULL); + return(FIL_NULL); } buf_block_dbg_add_level( @@ -1721,11 +1717,16 @@ btr_create( IBUF_TREE_ROOT_PAGE_NO, FSP_UP, mtr); - if (!block) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Allocation of the tree root page segment failed."); + if (block == NULL) { + return(FIL_NULL); } + ut_ad(buf_block_get_page_no(block) == IBUF_TREE_ROOT_PAGE_NO); + + buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW); + + flst_init(block->frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, + mtr); } else { #ifdef UNIV_BLOB_DEBUG if ((type & DICT_CLUSTERED) && !index->blobs) { @@ -1738,41 +1739,18 @@ btr_create( block = fseg_create(space, 0, PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr); - if (!block) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Allocation of the btree segment failed."); + if (block == NULL) { + return(FIL_NULL); } - } - - if (block == NULL) { - - return(FIL_NULL); - } - - page_no = buf_block_get_page_no(block); - frame = buf_block_get_frame(block); - - if (type & DICT_IBUF) { - /* It is an insert buffer tree: initialize the free list */ - buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW); - - ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO); - - flst_init(frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, mtr); - } else { - /* It is a non-ibuf tree: create a file segment for leaf - pages */ buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW); - if (!fseg_create(space, page_no, + if (!fseg_create(space, buf_block_get_page_no(block), PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) { /* Not enough space for new segment, free root segment before return. */ - btr_free_root(space, zip_size, page_no, mtr); - - ib_logf(IB_LOG_LEVEL_ERROR, - "Allocation of the non-ibuf tree segment for leaf pages failed."); + btr_free_root(space, zip_size, + buf_block_get_page_no(block), mtr); return(FIL_NULL); } @@ -1816,7 +1794,7 @@ btr_create( ut_ad(page_get_max_insert_size(page, 2) > 2 * BTR_PAGE_MAX_REC_SIZE); - return(page_no); + return(buf_block_get_page_no(block)); } /************************************************************//** diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index e2c7ae9bae1..8ff5428d3a5 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -175,13 +175,14 @@ buf_dblwr_init( mem_zalloc(buf_size * sizeof(void*))); } -/****************************************************************//** -Creates the doublewrite buffer to a new InnoDB installation. The header of the -doublewrite buffer is placed on the trx system header page. */ +/** Create the doublewrite buffer if the doublewrite buffer header +is not present in the TRX_SYS page. +@return whether the operation succeeded +@retval true if the doublewrite buffer exists or was created +@retval false if the creation failed (too small first data file) */ UNIV_INTERN -void -buf_dblwr_create(void) -/*==================*/ +bool +buf_dblwr_create() { buf_block_t* block2; buf_block_t* new_block; @@ -194,8 +195,7 @@ buf_dblwr_create(void) if (buf_dblwr) { /* Already inited */ - - return; + return(true); } start_again: @@ -213,39 +213,59 @@ start_again: mtr_commit(&mtr); buf_dblwr_being_created = FALSE; - return; + return(true); } - ib_logf(IB_LOG_LEVEL_INFO, - "Doublewrite buffer not found: creating new"); - if (buf_pool_get_curr_size() < ((TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE + FSP_EXTENT_SIZE / 2 + 100) * UNIV_PAGE_SIZE)) { - ib_logf(IB_LOG_LEVEL_FATAL, - "Cannot create doublewrite buffer: you must " - "increase your buffer pool size. Cannot continue " - "operation."); + ib_logf(IB_LOG_LEVEL_ERROR, + "Cannot create doublewrite buffer: " + "innodb_buffer_pool_size is too small."); + mtr_commit(&mtr); + return(false); + } else { + fil_space_t* space = fil_space_acquire(TRX_SYS_SPACE); + const bool fail = UT_LIST_GET_FIRST(space->chain)->size + < 3 * FSP_EXTENT_SIZE; + fil_space_release(space); + + if (fail) { + goto too_small; + } } block2 = fseg_create(TRX_SYS_SPACE, TRX_SYS_PAGE_NO, TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_FSEG, &mtr); + if (block2 == NULL) { +too_small: + ib_logf(IB_LOG_LEVEL_ERROR, + "Cannot create doublewrite buffer: " + "the first file in innodb_data_file_path" + " must be at least %luM.", + 3 * (FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) >> 20); + mtr_commit(&mtr); + return(false); + } + + ib_logf(IB_LOG_LEVEL_INFO, + "Doublewrite buffer not found: creating new"); + + /* FIXME: After this point, the doublewrite buffer creation + is not atomic. The doublewrite buffer should not exist in + the InnoDB system tablespace file in the first place. + It could be located in separate optional file(s) in a + user-specified location. */ + /* fseg_create acquires a second latch on the page, therefore we must declare it: */ buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK); - if (block2 == NULL) { - ib_logf(IB_LOG_LEVEL_FATAL, - "Cannot create doublewrite buffer: you must " - "increase your tablespace size. " - "Cannot continue operation."); - } - fseg_header = doublewrite + TRX_SYS_DOUBLEWRITE_FSEG; prev_page_no = 0; @@ -482,6 +502,14 @@ buf_dblwr_process() byte* unaligned_read_buf; recv_dblwr_t& recv_dblwr = recv_sys->dblwr; + if (!buf_dblwr) { + return; + } + + ib_logf(IB_LOG_LEVEL_INFO, + "Restoring possible half-written data pages " + "from the doublewrite buffer..."); + unaligned_read_buf = static_cast(ut_malloc(2 * UNIV_PAGE_SIZE)); read_buf = static_cast( diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index 1ec7123bbc2..f6cd294884b 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -321,13 +321,9 @@ dict_build_table_def_step( mtr_start(&mtr); - bool res = fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr); + fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr); mtr_commit(&mtr); - - if (!res) { - return (DB_ERROR); - } } else { /* Create in the system tablespace: disallow Barracuda features by keeping only the first bit which says whether diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index e19ef110b4f..f88bb2add59 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2014, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -5812,21 +5812,19 @@ fil_report_invalid_page_access( ulint len, /*!< in: I/O length */ ulint type) /*!< in: I/O type */ { - ib_logf(IB_LOG_LEVEL_ERROR, + ib_logf(IB_LOG_LEVEL_FATAL, "Trying to access page number " ULINTPF " in space " ULINTPF " space name %s," " which is outside the tablespace bounds." - " Byte offset " ULINTPF ", len " ULINTPF " i/o type " ULINTPF ".", + " Byte offset " ULINTPF ", len " ULINTPF + " i/o type " ULINTPF ".%s", block_offset, space_id, space_name, - byte_offset, len, type); - - ib_logf(IB_LOG_LEVEL_FATAL, - "If you get this error at mysqld startup," - " please check that" - " your my.cnf matches the ibdata files" - " that you have in the" - " MySQL server."); + byte_offset, len, type, + space_id == 0 && !srv_was_started + ? "Please check that the configuration matches" + " the InnoDB system tablespace location (ibdata files)" + : ""); } /********************************************************************//** diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index 98cd11f3369..4f05549bc1c 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -670,18 +670,13 @@ fsp_header_init_fields( } #ifndef UNIV_HOTBACKUP -/** Initializes the space header of a new created space and creates also the -insert buffer tree root if space == 0. +/** Initialize a tablespace header. @param[in] space_id space id @param[in] size current size in blocks -@param[in,out] mtr min-transaction -@return true on success, otherwise false. */ +@param[in,out] mtr mini-transaction */ UNIV_INTERN -bool -fsp_header_init( - ulint space_id, - ulint size, - mtr_t* mtr) +void +fsp_header_init(ulint space_id, ulint size, mtr_t* mtr) { fsp_header_t* header; buf_block_t* block; @@ -725,17 +720,7 @@ fsp_header_init( mlog_write_ull(header + FSP_SEG_ID, 1, mtr); - if (space_id == 0) { - fsp_fill_free_list(FALSE, space_id, header, mtr); - - if (btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, - 0, 0, DICT_IBUF_ID_MIN + space_id, - dict_ind_redundant, mtr) == FIL_NULL) { - return (false); - } - } else { - fsp_fill_free_list(TRUE, space_id, header, mtr); - } + fsp_fill_free_list(space_id != TRX_SYS_SPACE, space_id, header, mtr); fil_space_t* space = fil_space_acquire(space_id); ut_ad(space); @@ -745,8 +730,6 @@ fsp_header_init( } fil_space_release(space); - - return (true); } #endif /* !UNIV_HOTBACKUP */ @@ -2065,10 +2048,6 @@ fseg_create_general( success = fsp_reserve_free_extents(&n_reserved, space, 2, FSP_NORMAL, mtr); if (!success) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Reserving %d free extents failed" - " could reserve only " ULINTPF " extents.", - 2, n_reserved); return(NULL); } } @@ -2078,9 +2057,6 @@ fseg_create_general( inode = fsp_alloc_seg_inode(space_header, mtr); if (inode == NULL) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Allocation of a new file segment inode page failed."); - goto funct_exit; } @@ -2109,9 +2085,6 @@ fseg_create_general( inode, 0, FSP_UP, mtr, mtr); if (block == NULL) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Allocation of a free page from space " ULINTPF " failed.", - space); fsp_free_seg_inode(space, zip_size, inode, mtr); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index b68a96c8846..012539d1ace 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3353,7 +3353,6 @@ innobase_init( char *default_path; uint format_id; ulong num_pll_degree; - ulint min_size = 0; DBUG_ENTER("innobase_init"); handlerton *innobase_hton= (handlerton*) p; @@ -3564,19 +3563,6 @@ mem_free_and_error: goto error; } - /* All doublewrite buffer pages must fit to first system - datafile and first datafile must be at least 3M. */ - min_size = ut_max((3*1024*1024U), (192U*UNIV_PAGE_SIZE)); - - if ((srv_data_file_sizes[0]*1024*1024) < min_size) { - sql_print_error( - "InnoDB: first datafile is too small current=" ULINTPF - "M it should be at least " ULINTPF "M.", - srv_data_file_sizes[0], - min_size / (1024 * 1024)); - goto mem_free_and_error; - } - /* -------------- All log files ---------------------------*/ /* The default dir for log files is the datadir of MySQL */ diff --git a/storage/innobase/include/buf0dblwr.h b/storage/innobase/include/buf0dblwr.h index 8e1b00db83c..7b7464761cc 100644 --- a/storage/innobase/include/buf0dblwr.h +++ b/storage/innobase/include/buf0dblwr.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -39,13 +39,15 @@ extern buf_dblwr_t* buf_dblwr; /** Set to TRUE when the doublewrite buffer is being created */ extern ibool buf_dblwr_being_created; -/****************************************************************//** -Creates the doublewrite buffer to a new InnoDB installation. The header of the -doublewrite buffer is placed on the trx system header page. */ +/** Create the doublewrite buffer if the doublewrite buffer header +is not present in the TRX_SYS page. +@return whether the operation succeeded +@retval true if the doublewrite buffer exists or was created +@retval false if the creation failed (too small first data file) */ UNIV_INTERN -void -buf_dblwr_create(void); -/*==================*/ +bool +buf_dblwr_create() + MY_ATTRIBUTE((warn_unused_result)); /****************************************************************//** At a database startup initializes the doublewrite buffer memory structure if diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h index 905e98cc1e6..d8d044ba2ec 100644 --- a/storage/innobase/include/fsp0fsp.h +++ b/storage/innobase/include/fsp0fsp.h @@ -520,19 +520,13 @@ fsp_header_init_fields( ulint space_id, /*!< in: space id */ ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS): 0, or table->flags if newer than COMPACT */ -/** Initializes the space header of a new created space and creates also the -insert buffer tree root if space == 0. +/** Initialize a tablespace header. @param[in] space_id space id @param[in] size current size in blocks -@param[in,out] mtr min-transaction -@return true on success, otherwise false. */ +@param[in,out] mtr mini-transaction */ UNIV_INTERN -bool -fsp_header_init( - ulint space_id, - ulint size, - mtr_t* mtr) - MY_ATTRIBUTE((warn_unused_result)); +void +fsp_header_init(ulint space_id, ulint size, mtr_t* mtr); /**********************************************************************//** Increases the space size field of a space. */ diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h index 185b05876b4..2fe5df14cee 100644 --- a/storage/innobase/include/trx0rseg.h +++ b/storage/innobase/include/trx0rseg.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -124,13 +125,13 @@ trx_rseg_mem_free( /*==============*/ trx_rseg_t* rseg); /*!< in, own: instance to free */ -/********************************************************************* -Creates a rollback segment. */ +/** Create a rollback segment. +@param[in] space undo tablespace ID +@return pointer to new rollback segment +@retval NULL on failure */ UNIV_INTERN trx_rseg_t* -trx_rseg_create( -/*============*/ - ulint space); /*!< in: id of UNDO tablespace */ +trx_rseg_create(ulint space); /******************************************************************** Get the number of unique rollback tablespaces in use except space id 0. diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index bf00cd8e8d9..4e6e66e808e 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2914,11 +2914,6 @@ recv_init_crash_recovery(void) possible */ if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) { - - ib_logf(IB_LOG_LEVEL_INFO, - "Restoring possible half-written data pages " - "from the doublewrite buffer..."); - buf_dblwr_process(); /* Spawn the background thread to flush dirty pages @@ -3179,24 +3174,6 @@ recv_recovery_from_checkpoint_start_func( user about recovery: */ if (checkpoint_lsn != flushed_lsn) { - - if (checkpoint_lsn < flushed_lsn) { - - ib_logf(IB_LOG_LEVEL_WARN, - "The log sequence number " - "in the ibdata files is higher " - "than the log sequence number " - "in the ib_logfiles! Are you sure " - "you are using the right " - "ib_logfiles to start up the database. " - "Log sequence number in the " - "ib_logfiles is " LSN_PF ", log" - "sequence number stamped " - "to ibdata file header is " LSN_PF ".", - checkpoint_lsn, - flushed_lsn); - } - if (!recv_needed_recovery) { ib_logf(IB_LOG_LEVEL_INFO, "The log sequence number " diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 6ca9443dc7d..82938995e93 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -3590,15 +3590,9 @@ row_truncate_table_for_mysql( } while (index); mtr_start_trx(&mtr, trx); - bool ret = fsp_header_init(space_id, + fsp_header_init(space_id, FIL_IBD_FILE_INITIAL_SIZE, &mtr); mtr_commit(&mtr); - - if (!ret) { - table->file_unreadable = true; - err = DB_ERROR; - goto funct_exit; - } } } else { /* Lock all index trees for this table, as we will diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 4e59ddd1f87..c7026b4f04a 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1561,26 +1561,18 @@ srv_undo_tablespaces_init( if (create_new_db) { mtr_t mtr; - bool ret=true; mtr_start(&mtr); /* The undo log tablespace */ for (i = 0; i < n_undo_tablespaces; ++i) { - ret = fsp_header_init( + fsp_header_init( undo_tablespace_ids[i], SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr); - if (!ret) { - break; - } } mtr_commit(&mtr); - - if (!ret) { - return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR)); - } } return(DB_SUCCESS); @@ -2419,14 +2411,24 @@ files_checked: mtr_start(&mtr); - bool ret = fsp_header_init(0, sum_of_new_sizes, &mtr); + fsp_header_init(0, sum_of_new_sizes, &mtr); + compile_time_assert(TRX_SYS_SPACE == 0); + compile_time_assert(IBUF_SPACE_ID == 0); + + ulint ibuf_root = btr_create( + DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, + 0, 0, DICT_IBUF_ID_MIN, + dict_ind_redundant, &mtr); mtr_commit(&mtr); - if (!ret) { - return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR)); + if (ibuf_root == FIL_NULL) { + return(srv_init_abort(true, __FILE__, __LINE__, + DB_ERROR)); } + ut_ad(ibuf_root == IBUF_TREE_ROOT_PAGE_NO); + /* To maintain backward compatibility we create only the first rollback segment before the double write buffer. All the remaining rollback segments will be created later, @@ -2812,10 +2814,9 @@ files_checked: /* fprintf(stderr, "Max allowed record size %lu\n", page_get_free_space_of_empty() / 2); */ - if (buf_dblwr == NULL) { - /* Create the doublewrite buffer to a new tablespace */ - - buf_dblwr_create(); + if (!buf_dblwr_create()) { + return(srv_init_abort(create_new_db, __FILE__, __LINE__, + DB_ERROR)); } /* Here the double write buffer has already been created and so diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc index 21dbab98e48..16fa334872b 100644 --- a/storage/innobase/trx/trx0rseg.cc +++ b/storage/innobase/trx/trx0rseg.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -293,14 +294,13 @@ trx_rseg_create_instance( } } -/********************************************************************* -Creates a rollback segment. -@return pointer to new rollback segment if create successful */ +/** Create a rollback segment. +@param[in] space undo tablespace ID +@return pointer to new rollback segment +@retval NULL on failure */ UNIV_INTERN trx_rseg_t* -trx_rseg_create( -/*============*/ - ulint space) /*!< in: id of UNDO tablespace */ +trx_rseg_create(ulint space) { mtr_t mtr; ulint slot_no; @@ -323,25 +323,21 @@ trx_rseg_create( page_no = trx_rseg_header_create( space, 0, ULINT_MAX, slot_no, &mtr); - if (page_no == FIL_NULL) { - mtr_commit(&mtr); - return (rseg); + if (page_no != FIL_NULL) { + sys_header = trx_sysf_get(&mtr); + + id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr); + ut_a(id == space); + + zip_size = space ? fil_space_get_zip_size(space) : 0; + + rseg = trx_rseg_mem_create( + slot_no, space, zip_size, page_no, + purge_sys->ib_bh, &mtr); } - - sys_header = trx_sysf_get(&mtr); - - id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr); - ut_a(id == space); - - zip_size = space ? fil_space_get_zip_size(space) : 0; - - rseg = trx_rseg_mem_create( - slot_no, space, zip_size, page_no, - purge_sys->ib_bh, &mtr); } mtr_commit(&mtr); - return(rseg); } diff --git a/storage/xtradb/btr/btr0btr.cc b/storage/xtradb/btr/btr0btr.cc index 7b5b3bb6cba..e66599e206d 100644 --- a/storage/xtradb/btr/btr0btr.cc +++ b/storage/xtradb/btr/btr0btr.cc @@ -2,7 +2,7 @@ Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2014, 2017, MariaDB Corporation +Copyright (c) 2014, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1703,9 +1703,7 @@ btr_create( dict_index_t* index, /*!< in: index */ mtr_t* mtr) /*!< in: mini-transaction handle */ { - ulint page_no; buf_block_t* block; - buf_frame_t* frame; page_t* page; page_zip_des_t* page_zip; @@ -1721,9 +1719,7 @@ btr_create( IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr); if (ibuf_hdr_block == NULL) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Allocation of the first ibuf header page failed."); - return (FIL_NULL); + return(FIL_NULL); } buf_block_dbg_add_level( @@ -1740,11 +1736,16 @@ btr_create( IBUF_TREE_ROOT_PAGE_NO, FSP_UP, mtr); - if (!block) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Allocation of the tree root page segment failed."); + if (block == NULL) { + return(FIL_NULL); } + ut_ad(buf_block_get_page_no(block) == IBUF_TREE_ROOT_PAGE_NO); + + buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW); + + flst_init(block->frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, + mtr); } else { #ifdef UNIV_BLOB_DEBUG if ((type & DICT_CLUSTERED) && !index->blobs) { @@ -1757,41 +1758,18 @@ btr_create( block = fseg_create(space, 0, PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr); - if (!block) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Allocation of the btree segment failed."); + if (block == NULL) { + return(FIL_NULL); } - } - - if (block == NULL) { - - return(FIL_NULL); - } - - page_no = buf_block_get_page_no(block); - frame = buf_block_get_frame(block); - - if (type & DICT_IBUF) { - /* It is an insert buffer tree: initialize the free list */ - buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW); - - ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO); - - flst_init(frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, mtr); - } else { - /* It is a non-ibuf tree: create a file segment for leaf - pages */ buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW); - if (!fseg_create(space, page_no, + if (!fseg_create(space, buf_block_get_page_no(block), PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) { /* Not enough space for new segment, free root segment before return. */ - btr_free_root(space, zip_size, page_no, mtr); - - ib_logf(IB_LOG_LEVEL_ERROR, - "Allocation of the non-ibuf tree segment for leaf pages failed."); + btr_free_root(space, zip_size, + buf_block_get_page_no(block), mtr); return(FIL_NULL); } @@ -1835,7 +1813,7 @@ btr_create( ut_ad(page_get_max_insert_size(page, 2) > 2 * BTR_PAGE_MAX_REC_SIZE); - return(page_no); + return(buf_block_get_page_no(block)); } /************************************************************//** diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc index c0c52deb57f..49371f9a6f1 100644 --- a/storage/xtradb/buf/buf0dblwr.cc +++ b/storage/xtradb/buf/buf0dblwr.cc @@ -175,13 +175,14 @@ buf_dblwr_init( mem_zalloc(buf_size * sizeof(void*))); } -/****************************************************************//** -Creates the doublewrite buffer to a new InnoDB installation. The header of the -doublewrite buffer is placed on the trx system header page. */ +/** Create the doublewrite buffer if the doublewrite buffer header +is not present in the TRX_SYS page. +@return whether the operation succeeded +@retval true if the doublewrite buffer exists or was created +@retval false if the creation failed (too small first data file) */ UNIV_INTERN -void -buf_dblwr_create(void) -/*==================*/ +bool +buf_dblwr_create() { buf_block_t* block2; buf_block_t* new_block; @@ -194,8 +195,7 @@ buf_dblwr_create(void) if (buf_dblwr) { /* Already inited */ - - return; + return(true); } start_again: @@ -213,39 +213,59 @@ start_again: mtr_commit(&mtr); buf_dblwr_being_created = FALSE; - return; + return(true); } - ib_logf(IB_LOG_LEVEL_INFO, - "Doublewrite buffer not found: creating new"); - if (buf_pool_get_curr_size() < ((TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE + FSP_EXTENT_SIZE / 2 + 100) * UNIV_PAGE_SIZE)) { - ib_logf(IB_LOG_LEVEL_FATAL, - "Cannot create doublewrite buffer: you must " - "increase your buffer pool size. Cannot continue " - "operation."); + ib_logf(IB_LOG_LEVEL_ERROR, + "Cannot create doublewrite buffer: " + "innodb_buffer_pool_size is too small."); + mtr_commit(&mtr); + return(false); + } else { + fil_space_t* space = fil_space_acquire(TRX_SYS_SPACE); + const bool fail = UT_LIST_GET_FIRST(space->chain)->size + < 3 * FSP_EXTENT_SIZE; + fil_space_release(space); + + if (fail) { + goto too_small; + } } block2 = fseg_create(TRX_SYS_SPACE, TRX_SYS_PAGE_NO, TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_FSEG, &mtr); + if (block2 == NULL) { +too_small: + ib_logf(IB_LOG_LEVEL_ERROR, + "Cannot create doublewrite buffer: " + "the first file in innodb_data_file_path" + " must be at least %luM.", + 3 * (FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) >> 20); + mtr_commit(&mtr); + return(false); + } + + ib_logf(IB_LOG_LEVEL_INFO, + "Doublewrite buffer not found: creating new"); + + /* FIXME: After this point, the doublewrite buffer creation + is not atomic. The doublewrite buffer should not exist in + the InnoDB system tablespace file in the first place. + It could be located in separate optional file(s) in a + user-specified location. */ + /* fseg_create acquires a second latch on the page, therefore we must declare it: */ buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK); - if (block2 == NULL) { - ib_logf(IB_LOG_LEVEL_FATAL, - "Cannot create doublewrite buffer: you must " - "increase your tablespace size. " - "Cannot continue operation."); - } - fseg_header = doublewrite + TRX_SYS_DOUBLEWRITE_FSEG; prev_page_no = 0; @@ -482,6 +502,14 @@ buf_dblwr_process() byte* unaligned_read_buf; recv_dblwr_t& recv_dblwr = recv_sys->dblwr; + if (!buf_dblwr) { + return; + } + + ib_logf(IB_LOG_LEVEL_INFO, + "Restoring possible half-written data pages " + "from the doublewrite buffer..."); + unaligned_read_buf = static_cast(ut_malloc(2 * UNIV_PAGE_SIZE)); read_buf = static_cast( diff --git a/storage/xtradb/dict/dict0crea.cc b/storage/xtradb/dict/dict0crea.cc index faaa6d1bdc7..6d5b12474eb 100644 --- a/storage/xtradb/dict/dict0crea.cc +++ b/storage/xtradb/dict/dict0crea.cc @@ -323,13 +323,9 @@ dict_build_table_def_step( mtr_start(&mtr); - bool res = fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr); + fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr); mtr_commit(&mtr); - - if(!res) { - return (DB_ERROR); - } } else { /* Create in the system tablespace: disallow Barracuda features by keeping only the first bit which says whether diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index b669d35ff15..d979c05c9a6 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2014, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -6115,21 +6115,19 @@ fil_report_invalid_page_access( ulint len, /*!< in: I/O length */ ulint type) /*!< in: I/O type */ { - ib_logf(IB_LOG_LEVEL_ERROR, + ib_logf(IB_LOG_LEVEL_FATAL, "Trying to access page number " ULINTPF " in space " ULINTPF " space name %s," " which is outside the tablespace bounds." - " Byte offset " ULINTPF ", len " ULINTPF " i/o type " ULINTPF ".", + " Byte offset " ULINTPF ", len " ULINTPF + " i/o type " ULINTPF ".%s", block_offset, space_id, space_name, - byte_offset, len, type); - - ib_logf(IB_LOG_LEVEL_FATAL, - "If you get this error at mysqld startup," - " please check that" - " your my.cnf matches the ibdata files" - " that you have in the" - " MySQL server."); + byte_offset, len, type, + space_id == 0 && !srv_was_started + ? "Please check that the configuration matches" + " the InnoDB system tablespace location (ibdata files)" + : ""); } /********************************************************************//** diff --git a/storage/xtradb/fsp/fsp0fsp.cc b/storage/xtradb/fsp/fsp0fsp.cc index 7929372ae6c..bd87b88f58d 100644 --- a/storage/xtradb/fsp/fsp0fsp.cc +++ b/storage/xtradb/fsp/fsp0fsp.cc @@ -673,18 +673,13 @@ fsp_header_init_fields( } #ifndef UNIV_HOTBACKUP -/** Initializes the space header of a new created space and creates also the -insert buffer tree root if space == 0. +/** Initialize a tablespace header. @param[in] space_id space id @param[in] size current size in blocks -@param[in,out] mtr min-transaction -@return true on success, otherwise false. */ +@param[in,out] mtr mini-transaction */ UNIV_INTERN -bool -fsp_header_init( - ulint space_id, - ulint size, - mtr_t* mtr) +void +fsp_header_init(ulint space_id, ulint size, mtr_t* mtr) { fsp_header_t* header; buf_block_t* block; @@ -728,17 +723,7 @@ fsp_header_init( mlog_write_ull(header + FSP_SEG_ID, 1, mtr); - if (space_id == 0) { - fsp_fill_free_list(FALSE, space_id, header, mtr); - - if (btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, - 0, 0, DICT_IBUF_ID_MIN + space_id, - dict_ind_redundant, mtr) == FIL_NULL) { - return (false); - } - } else { - fsp_fill_free_list(TRUE, space_id, header, mtr); - } + fsp_fill_free_list(space_id != TRX_SYS_SPACE, space_id, header, mtr); fil_space_t* space = fil_space_acquire(space_id); ut_ad(space); @@ -748,8 +733,6 @@ fsp_header_init( } fil_space_release(space); - - return (true); } #endif /* !UNIV_HOTBACKUP */ @@ -2074,10 +2057,6 @@ fseg_create_general( success = fsp_reserve_free_extents(&n_reserved, space, 2, FSP_NORMAL, mtr); if (!success) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Reserving %d free extents failed" - " could reserve only " ULINTPF " extents.", - 2, n_reserved); return(NULL); } } @@ -2087,9 +2066,6 @@ fseg_create_general( inode = fsp_alloc_seg_inode(space_header, mtr); if (inode == NULL) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Allocation of a new file segment inode page failed."); - goto funct_exit; } @@ -2118,9 +2094,6 @@ fseg_create_general( inode, 0, FSP_UP, mtr, mtr); if (block == NULL) { - ib_logf(IB_LOG_LEVEL_ERROR, - "Allocation of a free page from space " ULINTPF " failed.", - space); fsp_free_seg_inode(space, zip_size, inode, mtr); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 7be6c64407b..dd5d041aed9 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -3770,7 +3770,6 @@ innobase_init( char *default_path; uint format_id; ulong num_pll_degree; - ulint min_size = 0; DBUG_ENTER("innobase_init"); handlerton *innobase_hton= (handlerton*) p; @@ -4021,19 +4020,6 @@ mem_free_and_error: goto error; } - /* All doublewrite buffer pages must fit to first system - datafile and first datafile must be at least 3M. */ - min_size = ut_max((3*1024*1024U), (192U*UNIV_PAGE_SIZE)); - - if ((srv_data_file_sizes[0]*1024*1024) < min_size) { - sql_print_error( - "InnoDB: first datafile is too small current=" ULINTPF - "M it should be at least " ULINTPF "M.", - srv_data_file_sizes[0], - min_size / (1024 * 1024)); - goto mem_free_and_error; - } - /* -------------- All log files ---------------------------*/ /* The default dir for log files is the datadir of MySQL */ diff --git a/storage/xtradb/include/buf0dblwr.h b/storage/xtradb/include/buf0dblwr.h index 8e1b00db83c..7b7464761cc 100644 --- a/storage/xtradb/include/buf0dblwr.h +++ b/storage/xtradb/include/buf0dblwr.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -39,13 +39,15 @@ extern buf_dblwr_t* buf_dblwr; /** Set to TRUE when the doublewrite buffer is being created */ extern ibool buf_dblwr_being_created; -/****************************************************************//** -Creates the doublewrite buffer to a new InnoDB installation. The header of the -doublewrite buffer is placed on the trx system header page. */ +/** Create the doublewrite buffer if the doublewrite buffer header +is not present in the TRX_SYS page. +@return whether the operation succeeded +@retval true if the doublewrite buffer exists or was created +@retval false if the creation failed (too small first data file) */ UNIV_INTERN -void -buf_dblwr_create(void); -/*==================*/ +bool +buf_dblwr_create() + MY_ATTRIBUTE((warn_unused_result)); /****************************************************************//** At a database startup initializes the doublewrite buffer memory structure if diff --git a/storage/xtradb/include/fsp0fsp.h b/storage/xtradb/include/fsp0fsp.h index d8f851a0846..715572199ab 100644 --- a/storage/xtradb/include/fsp0fsp.h +++ b/storage/xtradb/include/fsp0fsp.h @@ -519,19 +519,13 @@ fsp_header_init_fields( ulint space_id, /*!< in: space id */ ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS): 0, or table->flags if newer than COMPACT */ -/** Initializes the space header of a new created space and creates also the -insert buffer tree root if space == 0. +/** Initialize a tablespace header. @param[in] space_id space id @param[in] size current size in blocks -@param[in,out] mtr min-transaction -@return true on success, otherwise false. */ +@param[in,out] mtr mini-transaction */ UNIV_INTERN -bool -fsp_header_init( - ulint space_id, - ulint size, - mtr_t* mtr) - MY_ATTRIBUTE((warn_unused_result)); +void +fsp_header_init(ulint space_id, ulint size, mtr_t* mtr); /**********************************************************************//** Increases the space size field of a space. */ diff --git a/storage/xtradb/include/trx0rseg.h b/storage/xtradb/include/trx0rseg.h index b9c84ef2b06..e2853df7045 100644 --- a/storage/xtradb/include/trx0rseg.h +++ b/storage/xtradb/include/trx0rseg.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -124,13 +125,13 @@ trx_rseg_mem_free( /*==============*/ trx_rseg_t* rseg); /*!< in, own: instance to free */ -/********************************************************************* -Creates a rollback segment. */ +/** Create a rollback segment. +@param[in] space undo tablespace ID +@return pointer to new rollback segment +@retval NULL on failure */ UNIV_INTERN trx_rseg_t* -trx_rseg_create( -/*============*/ - ulint space); /*!< in: id of UNDO tablespace */ +trx_rseg_create(ulint space); /******************************************************************** Get the number of unique rollback tablespaces in use except space id 0. diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index 037bc9d35d3..fb64309cee4 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -3004,11 +3004,6 @@ recv_init_crash_recovery(void) possible */ if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) { - - ib_logf(IB_LOG_LEVEL_INFO, - "Restoring possible half-written data pages " - "from the doublewrite buffer..."); - buf_dblwr_process(); /* Spawn the background thread to flush dirty pages @@ -3276,24 +3271,6 @@ recv_recovery_from_checkpoint_start_func( user about recovery: */ if (checkpoint_lsn != flushed_lsn) { - - if (checkpoint_lsn file_unreadable = true; - err = DB_ERROR; - goto funct_exit; - } } } else { /* Lock all index trees for this table, as we will diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index cbab9b2f8c4..6fd8e8944f5 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -1601,26 +1601,18 @@ srv_undo_tablespaces_init( if (create_new_db) { mtr_t mtr; - bool ret=true; mtr_start(&mtr); /* The undo log tablespace */ for (i = 0; i < n_undo_tablespaces; ++i) { - ret = fsp_header_init( + fsp_header_init( undo_tablespace_ids[i], SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr); - if (!ret) { - break; - } } mtr_commit(&mtr); - - if (!ret) { - return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR)); - } } return(DB_SUCCESS); @@ -2507,14 +2499,24 @@ files_checked: mtr_start(&mtr); - bool ret = fsp_header_init(0, sum_of_new_sizes, &mtr); + fsp_header_init(0, sum_of_new_sizes, &mtr); + compile_time_assert(TRX_SYS_SPACE == 0); + compile_time_assert(IBUF_SPACE_ID == 0); + + ulint ibuf_root = btr_create( + DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, + 0, 0, DICT_IBUF_ID_MIN, + dict_ind_redundant, &mtr); mtr_commit(&mtr); - if (!ret) { - return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR)); + if (ibuf_root == FIL_NULL) { + return(srv_init_abort(true, __FILE__, __LINE__, + DB_ERROR)); } + ut_ad(ibuf_root == IBUF_TREE_ROOT_PAGE_NO); + /* To maintain backward compatibility we create only the first rollback segment before the double write buffer. All the remaining rollback segments will be created later, @@ -2901,10 +2903,9 @@ files_checked: /* fprintf(stderr, "Max allowed record size %lu\n", page_get_free_space_of_empty() / 2); */ - if (buf_dblwr == NULL) { - /* Create the doublewrite buffer to a new tablespace */ - - buf_dblwr_create(); + if (!buf_dblwr_create()) { + return(srv_init_abort(create_new_db, __FILE__, __LINE__, + DB_ERROR)); } /* Here the double write buffer has already been created and so diff --git a/storage/xtradb/trx/trx0rseg.cc b/storage/xtradb/trx/trx0rseg.cc index 21dbab98e48..16fa334872b 100644 --- a/storage/xtradb/trx/trx0rseg.cc +++ b/storage/xtradb/trx/trx0rseg.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -293,14 +294,13 @@ trx_rseg_create_instance( } } -/********************************************************************* -Creates a rollback segment. -@return pointer to new rollback segment if create successful */ +/** Create a rollback segment. +@param[in] space undo tablespace ID +@return pointer to new rollback segment +@retval NULL on failure */ UNIV_INTERN trx_rseg_t* -trx_rseg_create( -/*============*/ - ulint space) /*!< in: id of UNDO tablespace */ +trx_rseg_create(ulint space) { mtr_t mtr; ulint slot_no; @@ -323,25 +323,21 @@ trx_rseg_create( page_no = trx_rseg_header_create( space, 0, ULINT_MAX, slot_no, &mtr); - if (page_no == FIL_NULL) { - mtr_commit(&mtr); - return (rseg); + if (page_no != FIL_NULL) { + sys_header = trx_sysf_get(&mtr); + + id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr); + ut_a(id == space); + + zip_size = space ? fil_space_get_zip_size(space) : 0; + + rseg = trx_rseg_mem_create( + slot_no, space, zip_size, page_no, + purge_sys->ib_bh, &mtr); } - - sys_header = trx_sysf_get(&mtr); - - id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr); - ut_a(id == space); - - zip_size = space ? fil_space_get_zip_size(space) : 0; - - rseg = trx_rseg_mem_create( - slot_no, space, zip_size, page_no, - purge_sys->ib_bh, &mtr); } mtr_commit(&mtr); - return(rseg); }