From 425ecc74f86b19d24e3392bae052a3a9f6b41926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 19 Dec 2023 15:14:28 +0200 Subject: [PATCH 01/14] MDEV-29882 : Galera test failure on galera_sr_cc_master Test case changes only to wait expected membership and streaming replication status. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera_sr/disabled.def | 1 - .../galera_sr/r/galera_sr_cc_master.result | 30 ++++++++++--------- .../galera_sr/t/galera_sr_cc_master.test | 26 +++++++++++----- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/mysql-test/suite/galera_sr/disabled.def b/mysql-test/suite/galera_sr/disabled.def index fa62168d474..0371f0f589f 100644 --- a/mysql-test/suite/galera_sr/disabled.def +++ b/mysql-test/suite/galera_sr/disabled.def @@ -11,4 +11,3 @@ ############################################################################## GCF-1060 : MDEV-32160 GCF-1060 test failure due to wsrep MDL conflict -galera_sr_cc_master : MDEV-29882 Galera test failure on galera_sr_cc_master diff --git a/mysql-test/suite/galera_sr/r/galera_sr_cc_master.result b/mysql-test/suite/galera_sr/r/galera_sr_cc_master.result index 9e223414fe4..654b86d56a8 100644 --- a/mysql-test/suite/galera_sr/r/galera_sr_cc_master.result +++ b/mysql-test/suite/galera_sr/r/galera_sr_cc_master.result @@ -13,12 +13,12 @@ INSERT INTO t1 VALUES (2); INSERT INTO t1 VALUES (3); INSERT INTO t1 VALUES (4); INSERT INTO t1 VALUES (5); -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; -COUNT(*) +SELECT COUNT(*) AS EXPECT_5 FROM mysql.wsrep_streaming_log; +EXPECT_5 5 connection node_1; -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; -COUNT(*) +SELECT COUNT(*) AS EXPECT_5 FROM mysql.wsrep_streaming_log; +EXPECT_5 5 connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; connection node_2a; @@ -29,8 +29,8 @@ connection node_2; INSERT INTO t1 VALUES (6); ERROR HY000: Lost connection to MySQL server during query connection node_1; -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; -COUNT(*) +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +EXPECT_0 0 connection node_2a; connection node_1; @@ -38,8 +38,8 @@ connect node_2b, 127.0.0.1, root, , test, $NODE_MYPORT_2; connection node_2b; SELECT * FROM mysql.wsrep_streaming_log; node_uuid trx_id seqno flags frag -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; -COUNT(*) +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +EXPECT_0 0 SET AUTOCOMMIT=OFF; START TRANSACTION; @@ -49,18 +49,20 @@ INSERT INTO t1 VALUES (3); INSERT INTO t1 VALUES (4); INSERT INTO t1 VALUES (5); COMMIT; -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; -COUNT(*) +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +EXPECT_0 0 connection node_1; -SELECT COUNT(*) FROM t1; -COUNT(*) +SELECT COUNT(*) AS EXPECT_5 FROM t1; +EXPECT_5 5 -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; -COUNT(*) +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +EXPECT_0 0 DROP TABLE t1; connection node_2b; CALL mtr.add_suppression("WSREP: Failed to replicate rollback fragment for"); disconnect node_2; connect node_2, 127.0.0.1, root, , test, $NODE_MYPORT_2; +disconnect node_2a; +disconnect node_2b; diff --git a/mysql-test/suite/galera_sr/t/galera_sr_cc_master.test b/mysql-test/suite/galera_sr/t/galera_sr_cc_master.test index da547c59626..f6a1b11cba9 100644 --- a/mysql-test/suite/galera_sr/t/galera_sr_cc_master.test +++ b/mysql-test/suite/galera_sr/t/galera_sr_cc_master.test @@ -28,10 +28,13 @@ INSERT INTO t1 VALUES (3); INSERT INTO t1 VALUES (4); INSERT INTO t1 VALUES (5); -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; +SELECT COUNT(*) AS EXPECT_5 FROM mysql.wsrep_streaming_log; --connection node_1 -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; +--let $wait_condition = SELECT COUNT(*) = 5 FROM mysql.wsrep_streaming_log +--source include/wait_condition.inc + +SELECT COUNT(*) AS EXPECT_5 FROM mysql.wsrep_streaming_log; # # Trigger CC . The transaction is aborted and we expect the SR tables to be cleaned up @@ -52,7 +55,9 @@ SET SESSION wsrep_sync_wait = DEFAULT; INSERT INTO t1 VALUES (6); --connection node_1 -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; +--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; # Restore cluster @@ -69,8 +74,10 @@ SELECT COUNT(*) FROM mysql.wsrep_streaming_log; --connect node_2b, 127.0.0.1, root, , test, $NODE_MYPORT_2 --connection node_2b --source include/galera_wait_ready.inc +--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log +--source include/wait_condition.inc SELECT * FROM mysql.wsrep_streaming_log; -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; # Repeat transaction to confirm no locks are left from previous transaction @@ -83,11 +90,13 @@ INSERT INTO t1 VALUES (4); INSERT INTO t1 VALUES (5); COMMIT; -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; --connection node_1 -SELECT COUNT(*) FROM t1; -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; +--let $wait_condition = SELECT COUNT(*) = 5 FROM t1 +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_5 FROM t1; +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; DROP TABLE t1; @@ -98,3 +107,6 @@ CALL mtr.add_suppression("WSREP: Failed to replicate rollback fragment for"); --connect node_2, 127.0.0.1, root, , test, $NODE_MYPORT_2 # Restore original auto_increment_offset values. --source ../galera/include/auto_increment_offset_restore.inc + +--disconnect node_2a +--disconnect node_2b From dfd2eb529a9f8bae0e02d57763d36128a0696fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 20 Dec 2023 09:36:37 +0200 Subject: [PATCH 02/14] MDEV-29892 : Galera test failure on galera_sr_kill_slave_after_apply_rollback2 Could not reproduce and bug report is incomplete i.e. there is no error logs to analyze and 10.4 branch commit where failure was seen is not mentioned. Enable test to get more information. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera_3nodes_sr/disabled.def | 2 -- 1 file changed, 2 deletions(-) diff --git a/mysql-test/suite/galera_3nodes_sr/disabled.def b/mysql-test/suite/galera_3nodes_sr/disabled.def index 4472d960d9f..fcaf38a3d7b 100644 --- a/mysql-test/suite/galera_3nodes_sr/disabled.def +++ b/mysql-test/suite/galera_3nodes_sr/disabled.def @@ -9,5 +9,3 @@ # Do not use any TAB characters for whitespace. # ############################################################################## - -galera_sr_kill_slave_after_apply_rollback2 : MDEV-29892 Galera test failure on galera_sr_kill_slave_after_apply_rollback2 From 630972825f7fc10697476799ec2e2a6df10b58ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 20 Dec 2023 08:16:50 +0200 Subject: [PATCH 03/14] MDEV-29876 : Galera test failure on galera_sst_encrypted AES block cipher mode CTR is available at the moment only from OpenSSL 1.0.1. Do not run this testcase using CTR combination if it is not available. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/disabled.def | 1 - mysql-test/suite/galera/suite.pm | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 72be88fd1a1..ce251bac7ce 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -12,7 +12,6 @@ galera_as_slave_ctas : MDEV-28378 timeout galera_pc_recovery : MDEV-25199 cluster fails to start up -galera_sst_encrypted : MDEV-29876 Galera test failure on galera_sst_encrypted galera_var_node_address : MDEV-20485 Galera test failure galera_sequences : MDEV-32561 WSREP FSM failure: no such a transition REPLICATING -> COMMITTED galera_shutdown_nonprim : MDEV-32635 galera_shutdown_nonprim: mysql_shutdown failed diff --git a/mysql-test/suite/galera/suite.pm b/mysql-test/suite/galera/suite.pm index 027100fdb30..55108f603d3 100644 --- a/mysql-test/suite/galera/suite.pm +++ b/mysql-test/suite/galera/suite.pm @@ -70,13 +70,17 @@ push @::global_suppressions, sub which($) { return `sh -c "command -v $_[0]"` } sub skip_combinations { - my %skip = (); + my @combinations; + $skip{'include/have_mariabackup.inc'} = 'Need socket statistics utility' unless which("lsof") || which("sockstat") || which("ss"); $skip{'include/have_stunnel.inc'} = "Need 'stunnel' utility" unless which("stunnel"); $skip{'include/have_qpress.inc'} = "Need 'qpress' utility" unless which("qpress"); + $skip{'../encryption/include/have_file_key_management_plugin.combinations'} = [ 'ctr' ] + unless $::mysqld_variables{'version-ssl-library'} =~ /OpenSSL (\S+)/ + and $1 ge "1.0.1"; %skip; } From 1dc6ded8b19bd99b6fc2252070f94b7603eb4117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 19 Dec 2023 08:29:27 +0200 Subject: [PATCH 04/14] MDEV-20485 : Galera test failure on galera.galera_var_node_address Loopback interface might not be configured, thus do not test it. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/disabled.def | 2 +- .../r/galera_var_node_address.result | 20 +++++++++---------- .../t/galera_var_node_address.cnf | 4 +--- .../t/galera_var_node_address.test | 20 +++++++++---------- 4 files changed, 22 insertions(+), 24 deletions(-) rename mysql-test/suite/{galera => galera_3nodes}/r/galera_var_node_address.result (54%) rename mysql-test/suite/{galera => galera_3nodes}/t/galera_var_node_address.cnf (56%) rename mysql-test/suite/{galera => galera_3nodes}/t/galera_var_node_address.test (61%) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index ce251bac7ce..a05ee3f8880 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -12,7 +12,6 @@ galera_as_slave_ctas : MDEV-28378 timeout galera_pc_recovery : MDEV-25199 cluster fails to start up -galera_var_node_address : MDEV-20485 Galera test failure galera_sequences : MDEV-32561 WSREP FSM failure: no such a transition REPLICATING -> COMMITTED galera_shutdown_nonprim : MDEV-32635 galera_shutdown_nonprim: mysql_shutdown failed versioning_trx_id : MDEV-18590 : galera.versioning_trx_id: Test failure: mysqltest: Result content mismatch @@ -22,5 +21,6 @@ galera_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep: galera_sst_mysqldump_with_key : MDEV-32782 galera_sst_mysqldump_with_key test failed mdev-31285 : MDEV-25089 Assertion `error.len > 0' failed in galera::ReplicatorSMM::handle_apply_error() galera_var_ignore_apply_errors : MENT-1997 galera_var_ignore_apply_errors test freezes +MDEV-22232 : temporarily disabled at the request of Codership MW-402 : temporarily disabled at the request of Codership galera_desync_overlapped : MDEV-21538 galera_desync_overlapped MTR failed: Result content mismatch diff --git a/mysql-test/suite/galera/r/galera_var_node_address.result b/mysql-test/suite/galera_3nodes/r/galera_var_node_address.result similarity index 54% rename from mysql-test/suite/galera/r/galera_var_node_address.result rename to mysql-test/suite/galera_3nodes/r/galera_var_node_address.result index 6b91a9f3ea3..fe6c2a001b2 100644 --- a/mysql-test/suite/galera/r/galera_var_node_address.result +++ b/mysql-test/suite/galera_3nodes/r/galera_var_node_address.result @@ -1,22 +1,22 @@ connection node_2; connection node_1; -call mtr.add_suppression("WSREP: Stray state UUID msg: .*"); -call mtr.add_suppression("WSREP: Protocol violation. JOIN message sender .*"); -call mtr.add_suppression("WSREP: Sending JOIN failed: .*"); -flush tables; +connection node_1; SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE -4 -connection node_1; +3 CREATE TABLE t1 (f1 INTEGER) ENGINE=INNODB; connection node_2; -set global wsrep_sync_wait=15; INSERT INTO t1 VALUES (1); +SELECT COUNT(*) AS EXPECT_1 FROM t1; +EXPECT_1 +1 connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; connection node_3; -set global wsrep_sync_wait=15; -SELECT COUNT(*) FROM t1; -COUNT(*) +SELECT COUNT(*) AS EXPECT_1 FROM t1; +EXPECT_1 1 connection node_1; +SELECT COUNT(*) AS EXPECT_1 FROM t1; +EXPECT_1 +1 DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_var_node_address.cnf b/mysql-test/suite/galera_3nodes/t/galera_var_node_address.cnf similarity index 56% rename from mysql-test/suite/galera/t/galera_var_node_address.cnf rename to mysql-test/suite/galera_3nodes/t/galera_var_node_address.cnf index 0de0edaa396..aa0c47f1e0f 100644 --- a/mysql-test/suite/galera/t/galera_var_node_address.cnf +++ b/mysql-test/suite/galera_3nodes/t/galera_var_node_address.cnf @@ -1,4 +1,4 @@ -!include ../galera_4nodes.cnf +!include ../galera_3nodes.cnf [mysqld.2] wsrep_node_address=127.0.0.1 @@ -6,5 +6,3 @@ wsrep_node_address=127.0.0.1 [mysqld.3] wsrep_node_address=localhost -[mysqld.4] -wsrep_node_address=lo diff --git a/mysql-test/suite/galera/t/galera_var_node_address.test b/mysql-test/suite/galera_3nodes/t/galera_var_node_address.test similarity index 61% rename from mysql-test/suite/galera/t/galera_var_node_address.test rename to mysql-test/suite/galera_3nodes/t/galera_var_node_address.test index 99cb30e7b91..08c0d2e4d6e 100644 --- a/mysql-test/suite/galera/t/galera_var_node_address.test +++ b/mysql-test/suite/galera_3nodes/t/galera_var_node_address.test @@ -6,27 +6,27 @@ --source include/galera_cluster.inc --source include/have_innodb.inc -call mtr.add_suppression("WSREP: Stray state UUID msg: .*"); -call mtr.add_suppression("WSREP: Protocol violation. JOIN message sender .*"); -call mtr.add_suppression("WSREP: Sending JOIN failed: .*"); -flush tables; - ---let $wait_condition = SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --source include/wait_condition.inc SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; ---connection node_1 CREATE TABLE t1 (f1 INTEGER) ENGINE=INNODB; --connection node_2 -set global wsrep_sync_wait=15; +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +--source include/wait_condition.inc + INSERT INTO t1 VALUES (1); +SELECT COUNT(*) AS EXPECT_1 FROM t1; --connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 --connection node_3 -set global wsrep_sync_wait=15; -SELECT COUNT(*) FROM t1; +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM t1; --connection node_1 +SELECT COUNT(*) AS EXPECT_1 FROM t1; DROP TABLE t1; From 00a81516b084e9aa6f71bbc30eae6f4d1bd2f7ae Mon Sep 17 00:00:00 2001 From: tommijkl Date: Mon, 20 Jun 2022 15:24:22 +0300 Subject: [PATCH 05/14] MDEV-28953 sporadic failures with galera_sr.mysql-wsrep-features#165 Modified galera_sr.mysql-wsrep-features#165 test to be deterministic: Added one wait condition to catch execution state after --send command. Changed another wait condition to better match the execution state of the test thread. Signed-off-by: Julius Goryavsky --- .../galera_sr/r/mysql-wsrep-features#165.result | 16 ++++++++++++++++ .../galera_sr/t/mysql-wsrep-features#165.inc | 6 +++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/galera_sr/r/mysql-wsrep-features#165.result b/mysql-test/suite/galera_sr/r/mysql-wsrep-features#165.result index 8ad3ac63438..353315d1dd6 100644 --- a/mysql-test/suite/galera_sr/r/mysql-wsrep-features#165.result +++ b/mysql-test/suite/galera_sr/r/mysql-wsrep-features#165.result @@ -26,6 +26,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -91,6 +92,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -156,6 +158,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -221,6 +224,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -286,6 +290,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -351,6 +356,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -416,6 +422,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -481,6 +488,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -546,6 +554,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -611,6 +620,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -676,6 +686,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -741,6 +752,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -806,6 +818,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -871,6 +884,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -936,6 +950,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 @@ -1001,6 +1016,7 @@ f1 f2 connection node_1c; SET AUTOCOMMIT=ON; INSERT INTO t1 VALUES (3, 'c'); +connection node_1; connection node_2; SELECT * FROM t1; f1 f2 diff --git a/mysql-test/suite/galera_sr/t/mysql-wsrep-features#165.inc b/mysql-test/suite/galera_sr/t/mysql-wsrep-features#165.inc index 7f13afa3c47..26cdd116c08 100644 --- a/mysql-test/suite/galera_sr/t/mysql-wsrep-features#165.inc +++ b/mysql-test/suite/galera_sr/t/mysql-wsrep-features#165.inc @@ -46,6 +46,10 @@ SELECT * FROM t1; SET AUTOCOMMIT=ON; --send INSERT INTO t1 VALUES (3, 'c') +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS; +--source include/wait_condition.inc + --connection node_2 SELECT * FROM t1; @@ -54,7 +58,7 @@ SELECT * FROM t1; --send UPDATE t1 SET f2 = 'a' WHERE f1 = 2 --connection node_1 ---let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER != 'system user' AND STATE = 'Updating'; +--let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS; --source include/wait_condition.inc # Will deadlock From c554f2683201df4731b1e3c61fb5011d7d8bbb86 Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Tue, 24 Oct 2023 16:04:47 +0200 Subject: [PATCH 06/14] Disable ps-protocol second execution on test that do not support it MDEV-31003 has introduced second execution for SELECTs that execute under ps-protocol. The following tests in galera suites do not support this mode of execution, disable it: galera.MDEV-27862 galera.galera_log_output_csv galera.galera_query_cache galera.galera_query_cache_sync_wait galera_3nodes_sr.GCF-336 galera_3nodes_sr.galera_sr_isolate_master galera_sr.galera_sr_large_fragment galera_sr.galera_sr_many_fragments Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/t/MDEV-27862.test | 3 +++ mysql-test/suite/galera/t/galera_log_output_csv.test | 4 ++++ mysql-test/suite/galera/t/galera_query_cache.test | 3 +++ mysql-test/suite/galera/t/galera_query_cache_sync_wait.test | 4 ++++ mysql-test/suite/galera_3nodes_sr/t/GCF-336.test | 5 +++++ .../suite/galera_3nodes_sr/t/galera_sr_isolate_master.test | 2 ++ mysql-test/suite/galera_sr/t/galera_sr_large_fragment.test | 3 +++ mysql-test/suite/galera_sr/t/galera_sr_many_fragments.test | 4 ++++ 8 files changed, 28 insertions(+) diff --git a/mysql-test/suite/galera/t/MDEV-27862.test b/mysql-test/suite/galera/t/MDEV-27862.test index d23ce95d47e..f19d6b5db42 100644 --- a/mysql-test/suite/galera/t/MDEV-27862.test +++ b/mysql-test/suite/galera/t/MDEV-27862.test @@ -1,6 +1,8 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +--disable_ps2_protocol + # NEXTVAL --connection node_1 @@ -54,3 +56,4 @@ SELECT NEXTVAL(seq_transaction) = 4; DROP SEQUENCE seq_transaction; DROP TABLE t1; +--enable_ps2_protocol diff --git a/mysql-test/suite/galera/t/galera_log_output_csv.test b/mysql-test/suite/galera/t/galera_log_output_csv.test index eeccc953187..43f4190c761 100644 --- a/mysql-test/suite/galera/t/galera_log_output_csv.test +++ b/mysql-test/suite/galera/t/galera_log_output_csv.test @@ -12,13 +12,17 @@ INSERT INTO t1 VALUES (1); SELECT COUNT(*) > 0 FROM mysql.general_log; +--disable_ps2_protocol SELECT 1 = 1 FROM t1; SELECT COUNT(*) = 1 FROM mysql.slow_log WHERE sql_text = 'SELECT 1 = 1 FROM t1'; +--enable_ps2_protocol --connection node_2 +--disable_ps2_protocol SELECT 2 = 2 FROM t1; SELECT COUNT(*) = 1 FROM mysql.slow_log WHERE sql_text = 'SELECT 2 = 2 FROM t1'; +--enable_ps2_protocol --connection node_1 DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_query_cache.test b/mysql-test/suite/galera/t/galera_query_cache.test index 900faba0e1b..ec7306e0188 100644 --- a/mysql-test/suite/galera/t/galera_query_cache.test +++ b/mysql-test/suite/galera/t/galera_query_cache.test @@ -2,6 +2,8 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +--disable_ps2_protocol + # # Ensure that the query cache behaves properly with respect to Galera # @@ -65,3 +67,4 @@ SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_ DROP TABLE t1; +--enable_ps2_protocol diff --git a/mysql-test/suite/galera/t/galera_query_cache_sync_wait.test b/mysql-test/suite/galera/t/galera_query_cache_sync_wait.test index 6d1e21fd94d..9a4b734e1d2 100644 --- a/mysql-test/suite/galera/t/galera_query_cache_sync_wait.test +++ b/mysql-test/suite/galera/t/galera_query_cache_sync_wait.test @@ -4,6 +4,8 @@ --source include/have_query_cache.inc --source include/galera_have_debug_sync.inc +--disable_ps2_protocol + CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); @@ -88,3 +90,5 @@ DROP TABLE t1; --connection node_2a SET DEBUG_SYNC = "RESET"; + +--enable_ps2_protocol diff --git a/mysql-test/suite/galera_3nodes_sr/t/GCF-336.test b/mysql-test/suite/galera_3nodes_sr/t/GCF-336.test index b8d46db74f1..ba85aa5291c 100644 --- a/mysql-test/suite/galera_3nodes_sr/t/GCF-336.test +++ b/mysql-test/suite/galera_3nodes_sr/t/GCF-336.test @@ -1,5 +1,7 @@ --source include/galera_cluster.inc +--disable_ps2_protocol + --connection node_2 CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; @@ -45,3 +47,6 @@ CALL mtr.add_suppression("WSREP: failed to send SR rollback for "); --connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 --connection node_3 --source include/galera_wait_ready.inc + + +--enable_ps2_protocol diff --git a/mysql-test/suite/galera_3nodes_sr/t/galera_sr_isolate_master.test b/mysql-test/suite/galera_3nodes_sr/t/galera_sr_isolate_master.test index 27674148f46..18e1f0023c3 100644 --- a/mysql-test/suite/galera_3nodes_sr/t/galera_sr_isolate_master.test +++ b/mysql-test/suite/galera_3nodes_sr/t/galera_sr_isolate_master.test @@ -1,6 +1,7 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +--disable_ps2_protocol # # Test the effect of gmcast.isolate on master during an SR transaction # @@ -133,3 +134,4 @@ CALL mtr.add_suppression("failed to send SR rollback for"); DROP TABLE t1; --source ../galera/include/auto_increment_offset_restore.inc +--enable_ps2_protocol diff --git a/mysql-test/suite/galera_sr/t/galera_sr_large_fragment.test b/mysql-test/suite/galera_sr/t/galera_sr_large_fragment.test index 63278555723..d08cab494b7 100644 --- a/mysql-test/suite/galera_sr/t/galera_sr_large_fragment.test +++ b/mysql-test/suite/galera_sr/t/galera_sr_large_fragment.test @@ -6,6 +6,8 @@ --source include/have_innodb.inc --source include/big_test.inc +--disable_ps2_protocol + CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB; INSERT INTO ten VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); @@ -56,3 +58,4 @@ CALL mtr.add_suppression('InnoDB: Resizing redo log from'); CALL mtr.add_suppression('InnoDB: Starting to delete and rewrite log files'); CALL mtr.add_suppression('InnoDB: New log files created, LSN='); +--enable_ps2_protocol diff --git a/mysql-test/suite/galera_sr/t/galera_sr_many_fragments.test b/mysql-test/suite/galera_sr/t/galera_sr_many_fragments.test index 9b8dae9d8e3..7a6c1bea4fb 100644 --- a/mysql-test/suite/galera_sr/t/galera_sr_many_fragments.test +++ b/mysql-test/suite/galera_sr/t/galera_sr_many_fragments.test @@ -6,6 +6,8 @@ --source include/have_innodb.inc --source include/big_test.inc +--disable_ps2_protocol + CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB; INSERT INTO ten VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); @@ -51,3 +53,5 @@ SELECT COUNT(*) = 0 FROM t1; DROP TABLE ten; DROP TABLE t1; + +--enable_ps2_protocol From 1b747ffd05dd524f8d43b35a2b583dc4c00d767b Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sat, 23 Dec 2023 09:13:07 +0100 Subject: [PATCH 07/14] MDEV-33115 Update HeidiSQL to 12.6 --- win/packaging/heidisql.cmake | 2 +- win/packaging/heidisql.wxi.in | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/win/packaging/heidisql.cmake b/win/packaging/heidisql.cmake index 45a407371ba..681a4250e65 100644 --- a/win/packaging/heidisql.cmake +++ b/win/packaging/heidisql.cmake @@ -1,4 +1,4 @@ -SET(HEIDISQL_BASE_NAME "HeidiSQL_12.3_32_Portable") +SET(HEIDISQL_BASE_NAME "HeidiSQL_12.6_32_Portable") SET(HEIDISQL_ZIP "${HEIDISQL_BASE_NAME}.zip") SET(HEIDISQL_URL "http://www.heidisql.com/downloads/releases/${HEIDISQL_ZIP}") SET(HEIDISQL_DOWNLOAD_DIR ${THIRD_PARTY_DOWNLOAD_LOCATION}/${HEIDISQL_BASE_NAME}) diff --git a/win/packaging/heidisql.wxi.in b/win/packaging/heidisql.wxi.in index 03d5b579651..45bd6c4b218 100644 --- a/win/packaging/heidisql.wxi.in +++ b/win/packaging/heidisql.wxi.in @@ -68,6 +68,12 @@ + + + + + + @@ -115,6 +121,8 @@ + + From 371bf4abc61fffd86a3f87a90cb89179f4df3bee Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 23 Aug 2023 12:25:24 +0400 Subject: [PATCH 08/14] A 11.3->10.4 backport for MDEV-31991 Split class Database_qualified_name This is a requirement step to fix and merge easier MDEV-33019 The database part is not case sensitive in SP names The original MDEV-31991 commit commend: - Moving some of Database_qualified_name methods into a new class Identifier_chain2. - Changing the data type of the following variables from Database_qualified_name to Identifier_chain2: * q_pkg_proc in LEX::call_statement_start() * q_pkg_func in LEX::make_item_func_call_generic() Rationale: The data type of Database_qualified_name::m_db will be changed to Lex_ident_db soon. So Database_qualified_name won't be able to store the `pkg.routine` part of `db.pkg.routine` any more, because `pkg` must not depend on lower-case-table-names. --- sql/item.cc | 8 ++--- sql/sql_class.h | 88 ++++++++++++++++++++++++++++++++----------------- sql/sql_lex.cc | 4 +-- 3 files changed, 64 insertions(+), 36 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index 259c4bf8f4d..21190b38e1a 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2710,11 +2710,11 @@ Item_sp::func_name(THD *thd, bool is_package_function) const quoted `pkg` and `func` separately, so the entire result looks like: `db`.`pkg`.`func` */ - Database_qualified_name tmp= Database_qualified_name::split(m_name->m_name); - DBUG_ASSERT(tmp.m_db.length); - append_identifier(thd, &qname, &tmp.m_db); + Identifier_chain2 tmp= Identifier_chain2::split(m_name->m_name); + DBUG_ASSERT(tmp[0].length); + append_identifier(thd, &qname, &tmp[0]); qname.append('.'); - append_identifier(thd, &qname, &tmp.m_name); + append_identifier(thd, &qname, &tmp[1]); } else append_identifier(thd, &qname, &m_name->m_name); diff --git a/sql/sql_class.h b/sql/sql_class.h index fa124d899dd..2c6cc96a134 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -7051,6 +7051,61 @@ public: }; +class Identifier_chain2 +{ + LEX_CSTRING m_name[2]; +public: + Identifier_chain2() + :m_name{Lex_cstring(), Lex_cstring()} + { } + Identifier_chain2(const LEX_CSTRING &a, const LEX_CSTRING &b) + :m_name{a, b} + { } + + const LEX_CSTRING& operator [] (size_t i) const + { + return m_name[i]; + } + + static Identifier_chain2 split(const LEX_CSTRING &txt) + { + DBUG_ASSERT(txt.str[txt.length] == '\0'); // Expect 0-terminated input + const char *dot= strchr(txt.str, '.'); + if (!dot) + return Identifier_chain2(Lex_cstring(), txt); + size_t length0= dot - txt.str; + Lex_cstring name0(txt.str, length0); + Lex_cstring name1(txt.str + length0 + 1, txt.length - length0 - 1); + return Identifier_chain2(name0, name1); + } + + // Export as a qualified name string: 'db.name' + size_t make_qname(char *dst, size_t dstlen) const + { + return my_snprintf(dst, dstlen, "%.*s.%.*s", + (int) m_name[0].length, m_name[0].str, + (int) m_name[1].length, m_name[1].str); + } + + // Export as a qualified name string, allocate on mem_root. + bool make_qname(MEM_ROOT *mem_root, LEX_CSTRING *dst) const + { + const uint dot= !!m_name[0].length; + char *tmp; + /* format: [pkg + dot] + name + '\0' */ + dst->length= m_name[0].length + dot + m_name[1].length; + if (unlikely(!(dst->str= tmp= (char*) alloc_root(mem_root, + dst->length + 1)))) + return true; + snprintf(tmp, dst->length + 1, "%.*s%.*s%.*s", + (int) m_name[0].length, (m_name[0].length ? m_name[0].str : ""), + dot, ".", + (int) m_name[1].length, m_name[1].str); + return false; + } +}; + + /** This class resembles the SQL Standard schema qualified object name: ::= [ ] @@ -7093,41 +7148,16 @@ public: void copy(MEM_ROOT *mem_root, const LEX_CSTRING &db, const LEX_CSTRING &name); - static Database_qualified_name split(const LEX_CSTRING &txt) - { - DBUG_ASSERT(txt.str[txt.length] == '\0'); // Expect 0-terminated input - const char *dot= strchr(txt.str, '.'); - if (!dot) - return Database_qualified_name(NULL, 0, txt.str, txt.length); - size_t dblen= dot - txt.str; - Lex_cstring db(txt.str, dblen); - Lex_cstring name(txt.str + dblen + 1, txt.length - dblen - 1); - return Database_qualified_name(db, name); - } - // Export db and name as a qualified name string: 'db.name' size_t make_qname(char *dst, size_t dstlen) const { - return my_snprintf(dst, dstlen, "%.*s.%.*s", - (int) m_db.length, m_db.str, - (int) m_name.length, m_name.str); + return Identifier_chain2(m_db, m_name).make_qname(dst, dstlen); } // Export db and name as a qualified name string, allocate on mem_root. bool make_qname(MEM_ROOT *mem_root, LEX_CSTRING *dst) const { - const uint dot= !!m_db.length; - char *tmp; - /* format: [database + dot] + name + '\0' */ - dst->length= m_db.length + dot + m_name.length; - if (unlikely(!(dst->str= tmp= (char*) alloc_root(mem_root, - dst->length + 1)))) - return true; - snprintf(tmp, dst->length + 1, "%.*s%.*s%.*s", - (int) m_db.length, (m_db.length ? m_db.str : ""), - dot, ".", - (int) m_name.length, m_name.str); DBUG_SLOW_ASSERT(ok_for_lower_case_names(m_db.str)); - return false; + return Identifier_chain2(m_db, m_name).make_qname(mem_root, dst); } bool make_package_routine_name(MEM_ROOT *mem_root, @@ -7138,9 +7168,7 @@ public: size_t length= package.length + 1 + routine.length + 1; if (unlikely(!(tmp= (char *) alloc_root(mem_root, length)))) return true; - m_name.length= my_snprintf(tmp, length, "%.*s.%.*s", - (int) package.length, package.str, - (int) routine.length, routine.str); + m_name.length= Identifier_chain2(package, routine).make_qname(tmp, length); m_name.str= tmp; return false; } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 127691997b0..4efa30c73c2 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -8616,7 +8616,7 @@ bool LEX::call_statement_start(THD *thd, const LEX_CSTRING &db, const LEX_CSTRING &proc) { Database_qualified_name q_db_pkg(db, pkg); - Database_qualified_name q_pkg_proc(pkg, proc); + Identifier_chain2 q_pkg_proc(pkg, proc); sp_name *spname; sql_command= SQLCOM_CALL; @@ -9026,7 +9026,7 @@ Item *LEX::make_item_func_call_generic(THD *thd, static Lex_cstring dot(".", 1); Lex_ident_sys db(thd, cdb), pkg(thd, cpkg), func(thd, cfunc); Database_qualified_name q_db_pkg(db, pkg); - Database_qualified_name q_pkg_func(pkg, func); + Identifier_chain2 q_pkg_func(pkg, func); sp_name *qname; if (db.is_null() || pkg.is_null() || func.is_null()) From 916caac2a52fd376bfb3b67d28a27c21f9d287e3 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 27 Dec 2023 13:22:49 +0400 Subject: [PATCH 09/14] MDEV-33019 The database part is not case sensitive in SP names Part#1 A non-functional change Changing the signature of Identifier_chain2::make_qname() from bool make_qname(MEM_ROOT *mem_root, LEX_CSTRING *dst) const; to LEX_CSTRING make_qname(MEM_ROOT *mem_root) const; Now the result is returned as LEX_CSTRING from the function rather than is passed as a parameter. The return value {NULL,0} means "EOM". --- sql/sql_class.h | 29 +++++++++++++++-------------- sql/sql_lex.cc | 10 ++++++---- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/sql/sql_class.h b/sql/sql_class.h index 2c6cc96a134..f8c8463265e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -7088,20 +7088,21 @@ public: } // Export as a qualified name string, allocate on mem_root. - bool make_qname(MEM_ROOT *mem_root, LEX_CSTRING *dst) const + LEX_CSTRING make_qname(MEM_ROOT *mem_root) const { - const uint dot= !!m_name[0].length; - char *tmp; + LEX_STRING dst; /* format: [pkg + dot] + name + '\0' */ - dst->length= m_name[0].length + dot + m_name[1].length; - if (unlikely(!(dst->str= tmp= (char*) alloc_root(mem_root, - dst->length + 1)))) - return true; - snprintf(tmp, dst->length + 1, "%.*s%.*s%.*s", - (int) m_name[0].length, (m_name[0].length ? m_name[0].str : ""), - dot, ".", - (int) m_name[1].length, m_name[1].str); - return false; + size_t dst_size= m_name[0].length + 1 /*dot*/ + m_name[1].length + 1/*\0*/; + if (unlikely(!(dst.str= (char*) alloc_root(mem_root, dst_size)))) + return {NULL, 0}; + if (!m_name[0].length) + { + dst.length= my_snprintf(dst.str, dst_size, "%.*s", + (int) m_name[1].length, m_name[1].str); + return {dst.str, dst.length}; + } + dst.length= make_qname(dst.str, dst_size); + return {dst.str, dst.length}; } }; @@ -7154,10 +7155,10 @@ public: return Identifier_chain2(m_db, m_name).make_qname(dst, dstlen); } // Export db and name as a qualified name string, allocate on mem_root. - bool make_qname(MEM_ROOT *mem_root, LEX_CSTRING *dst) const + LEX_CSTRING make_qname(MEM_ROOT *mem_root) const { DBUG_SLOW_ASSERT(ok_for_lower_case_names(m_db.str)); - return Identifier_chain2(m_db, m_name).make_qname(mem_root, dst); + return Identifier_chain2(m_db, m_name).make_qname(mem_root); } bool make_package_routine_name(MEM_ROOT *mem_root, diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 4efa30c73c2..21abdc290ee 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -6754,7 +6754,8 @@ sp_head *LEX::make_sp_head(THD *thd, const sp_name *name, name->m_name); else sp->init_sp_name(name); - sp->make_qname(sp->get_main_mem_root(), &sp->m_qname); + if (!(sp->m_qname= sp->make_qname(sp->get_main_mem_root())).str) + return NULL; } sphead= sp; } @@ -8632,7 +8633,7 @@ bool LEX::call_statement_start(THD *thd, const LEX_CSTRING &db, // Concat `pkg` and `name` to `pkg.name` LEX_CSTRING pkg_dot_proc; - if (q_pkg_proc.make_qname(thd->mem_root, &pkg_dot_proc) || + if (!(pkg_dot_proc= q_pkg_proc.make_qname(thd->mem_root)).str || check_ident_length(&pkg_dot_proc) || !(spname= new (thd->mem_root) sp_name(&db, &pkg_dot_proc, true))) return true; @@ -8698,7 +8699,8 @@ sp_package *LEX::create_package_start(THD *thd, return NULL; pkg->reset_thd_mem_root(thd); pkg->init(this); - pkg->make_qname(pkg->get_main_mem_root(), &pkg->m_qname); + if (!(pkg->m_qname= pkg->make_qname(pkg->get_main_mem_root())).str) + return NULL; sphead= pkg; return pkg; } @@ -9043,7 +9045,7 @@ Item *LEX::make_item_func_call_generic(THD *thd, // Concat `pkg` and `name` to `pkg.name` LEX_CSTRING pkg_dot_func; - if (q_pkg_func.make_qname(thd->mem_root, &pkg_dot_func) || + if (!(pkg_dot_func= q_pkg_func.make_qname(thd->mem_root)).str || check_ident_length(&pkg_dot_func) || !(qname= new (thd->mem_root) sp_name(&db, &pkg_dot_func, true))) return NULL; From 9695974e4b212aa4820e0ccfeb164f5444c0d58e Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 27 Dec 2023 13:41:42 +0400 Subject: [PATCH 10/14] MDEV-33019 The database part is not case sensitive in SP names Problem: sp_cache erroneously looked up fully qualified SP names (e.g. `DB`.`SP`), in case insensitive style. It was wrong, because only the "name" part is always case insensitive, while the "db" part should be compared according to lower_case_table_names (case sensitively for 0, case insensitively for 1 and 2). Fix: Adding a "casedn_name" parameter make_qname() to tell if the name part should be lower cased: `DB1`.`SP` -> "DB1.SP" (when casedn_name=false) `DB1`.`SP` -> "DB1.sp" (when casedn_name=true) and using make_qname() with casedn_name=true when creating sp_cache hash lookup keys. Details: As a result, it now works as follows: - sp_head::m_db is converted to lower case if lower_case_table_names>0 during the sp_name initialization phase. So when make_qname() is called, sp_head::m_db is already normalized. There are no changes in here. - The initialization phase of sp_head when creating sp_head::m_qname now calls make_qname() with casedn_name=true, so sp_head::m_name gets written to sp_head::m_qname in lower case. - sp_cache_lookup() now also calls make_qname() with casedn_name=true, so sp_head::m_name gets written to the temporary lookup key in lower case. - sp_cache::m_hashtable now uses case sensitive comparison --- mysql-test/main/lowercase_table5.result | 36 +++++++++++++++++++++++++ mysql-test/main/lowercase_table5.test | 31 +++++++++++++++++++++ sql/sp_cache.cc | 4 +-- sql/sql_class.h | 29 +++++++++++--------- sql/sql_lex.cc | 8 +++--- 5 files changed, 90 insertions(+), 18 deletions(-) diff --git a/mysql-test/main/lowercase_table5.result b/mysql-test/main/lowercase_table5.result index 7704e1fa658..7e78f71b75f 100644 --- a/mysql-test/main/lowercase_table5.result +++ b/mysql-test/main/lowercase_table5.result @@ -11,3 +11,39 @@ Database Create Database mysql_TEST CREATE DATABASE `mysql_TEST` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci */ DROP DATABASE mysql_test; DROP DATABASE mysql_TEST; +# +# Start of 10.4 tests +# +# +# MDEV-33019 The database part is not case sensitive in SP names +# +CREATE DATABASE DB1; +CREATE DATABASE db1; +CREATE PROCEDURE DB1.sp() SELECT 'This is DB1.sp' AS ret; +CREATE PROCEDURE db1.sp() SELECT 'This is db1.sp' AS ret; +CALL DB1.sp(); +ret +This is DB1.sp +CALL db1.sp(); +ret +This is db1.sp +DROP DATABASE DB1; +CALL DB1.sp(); +ERROR 42000: PROCEDURE DB1.sp does not exist +CALL db1.sp(); +ret +This is db1.sp +DROP DATABASE db1; +CREATE PROCEDURE SP() SELECT 'This is SP' AS ret; +CREATE PROCEDURE sp() SELECT 'This is sp' AS ret; +ERROR 42000: PROCEDURE sp already exists +CALL SP(); +ret +This is SP +CALL sp(); +ret +This is SP +DROP PROCEDURE SP; +# +# End of 10.4 tests +# diff --git a/mysql-test/main/lowercase_table5.test b/mysql-test/main/lowercase_table5.test index dfdfafcb3da..0103dbf5fd2 100644 --- a/mysql-test/main/lowercase_table5.test +++ b/mysql-test/main/lowercase_table5.test @@ -18,3 +18,34 @@ DROP DATABASE mysql_test; DROP DATABASE mysql_TEST; # End of 10.0 tests + +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-33019 The database part is not case sensitive in SP names +--echo # + +CREATE DATABASE DB1; +CREATE DATABASE db1; +CREATE PROCEDURE DB1.sp() SELECT 'This is DB1.sp' AS ret; +CREATE PROCEDURE db1.sp() SELECT 'This is db1.sp' AS ret; +CALL DB1.sp(); +CALL db1.sp(); +DROP DATABASE DB1; +--error ER_SP_DOES_NOT_EXIST +CALL DB1.sp(); +CALL db1.sp(); +DROP DATABASE db1; + +CREATE PROCEDURE SP() SELECT 'This is SP' AS ret; +--error ER_SP_ALREADY_EXISTS +CREATE PROCEDURE sp() SELECT 'This is sp' AS ret; +CALL SP(); +CALL sp(); +DROP PROCEDURE SP; + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index e97f24c5487..cfdfea9ae0a 100644 --- a/sql/sp_cache.cc +++ b/sql/sp_cache.cc @@ -195,7 +195,7 @@ sp_head *sp_cache_lookup(sp_cache **cp, const Database_qualified_name *name) sp_cache *c= *cp; if (! c) return NULL; - return c->lookup(buf, name->make_qname(buf, sizeof(buf))); + return c->lookup(buf, name->make_qname(buf, sizeof(buf), true)); } @@ -302,7 +302,7 @@ sp_cache::~sp_cache() void sp_cache::init() { - my_hash_init(&m_hashtable, system_charset_info, 0, 0, 0, + my_hash_init(&m_hashtable, &my_charset_bin, 0, 0, 0, hash_get_key_for_sp_head, hash_free_sp_head, 0); } diff --git a/sql/sql_class.h b/sql/sql_class.h index f8c8463265e..e849b21b95b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -7080,15 +7080,18 @@ public: } // Export as a qualified name string: 'db.name' - size_t make_qname(char *dst, size_t dstlen) const + size_t make_qname(char *dst, size_t dstlen, bool casedn_part1) const { - return my_snprintf(dst, dstlen, "%.*s.%.*s", - (int) m_name[0].length, m_name[0].str, - (int) m_name[1].length, m_name[1].str); + size_t res= my_snprintf(dst, dstlen, "%.*s.%.*s", + (int) m_name[0].length, m_name[0].str, + (int) m_name[1].length, m_name[1].str); + if (casedn_part1 && dstlen > m_name[0].length) + my_casedn_str(system_charset_info, dst + m_name[0].length + 1); + return res; } // Export as a qualified name string, allocate on mem_root. - LEX_CSTRING make_qname(MEM_ROOT *mem_root) const + LEX_CSTRING make_qname(MEM_ROOT *mem_root, bool casedn_part1) const { LEX_STRING dst; /* format: [pkg + dot] + name + '\0' */ @@ -7097,11 +7100,12 @@ public: return {NULL, 0}; if (!m_name[0].length) { + DBUG_ASSERT(!casedn_part1); // Should not be called this way dst.length= my_snprintf(dst.str, dst_size, "%.*s", (int) m_name[1].length, m_name[1].str); return {dst.str, dst.length}; } - dst.length= make_qname(dst.str, dst_size); + dst.length= make_qname(dst.str, dst_size, casedn_part1); return {dst.str, dst.length}; } }; @@ -7150,15 +7154,15 @@ public: const LEX_CSTRING &name); // Export db and name as a qualified name string: 'db.name' - size_t make_qname(char *dst, size_t dstlen) const + size_t make_qname(char *dst, size_t dstlen, bool casedn_name) const { - return Identifier_chain2(m_db, m_name).make_qname(dst, dstlen); + return Identifier_chain2(m_db, m_name).make_qname(dst, dstlen, casedn_name); } // Export db and name as a qualified name string, allocate on mem_root. - LEX_CSTRING make_qname(MEM_ROOT *mem_root) const + LEX_CSTRING make_qname(MEM_ROOT *mem_root, bool casedn_name) const { DBUG_SLOW_ASSERT(ok_for_lower_case_names(m_db.str)); - return Identifier_chain2(m_db, m_name).make_qname(mem_root); + return Identifier_chain2(m_db, m_name).make_qname(mem_root, casedn_name); } bool make_package_routine_name(MEM_ROOT *mem_root, @@ -7169,7 +7173,8 @@ public: size_t length= package.length + 1 + routine.length + 1; if (unlikely(!(tmp= (char *) alloc_root(mem_root, length)))) return true; - m_name.length= Identifier_chain2(package, routine).make_qname(tmp, length); + m_name.length= Identifier_chain2(package, routine).make_qname(tmp, length, + false); m_name.str= tmp; return false; } @@ -7198,7 +7203,7 @@ public: { } const char *ptr() const { - m_name->make_qname(err_buffer, sizeof(err_buffer)); + m_name->make_qname(err_buffer, sizeof(err_buffer), false); return err_buffer; } }; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 21abdc290ee..847bd1d72d2 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -6754,7 +6754,7 @@ sp_head *LEX::make_sp_head(THD *thd, const sp_name *name, name->m_name); else sp->init_sp_name(name); - if (!(sp->m_qname= sp->make_qname(sp->get_main_mem_root())).str) + if (!(sp->m_qname= sp->make_qname(sp->get_main_mem_root(), true)).str) return NULL; } sphead= sp; @@ -8633,7 +8633,7 @@ bool LEX::call_statement_start(THD *thd, const LEX_CSTRING &db, // Concat `pkg` and `name` to `pkg.name` LEX_CSTRING pkg_dot_proc; - if (!(pkg_dot_proc= q_pkg_proc.make_qname(thd->mem_root)).str || + if (!(pkg_dot_proc= q_pkg_proc.make_qname(thd->mem_root, false)).str || check_ident_length(&pkg_dot_proc) || !(spname= new (thd->mem_root) sp_name(&db, &pkg_dot_proc, true))) return true; @@ -8699,7 +8699,7 @@ sp_package *LEX::create_package_start(THD *thd, return NULL; pkg->reset_thd_mem_root(thd); pkg->init(this); - if (!(pkg->m_qname= pkg->make_qname(pkg->get_main_mem_root())).str) + if (!(pkg->m_qname= pkg->make_qname(pkg->get_main_mem_root(), true)).str) return NULL; sphead= pkg; return pkg; @@ -9045,7 +9045,7 @@ Item *LEX::make_item_func_call_generic(THD *thd, // Concat `pkg` and `name` to `pkg.name` LEX_CSTRING pkg_dot_func; - if (!(pkg_dot_func= q_pkg_func.make_qname(thd->mem_root)).str || + if (!(pkg_dot_func= q_pkg_func.make_qname(thd->mem_root, false)).str || check_ident_length(&pkg_dot_func) || !(qname= new (thd->mem_root) sp_name(&db, &pkg_dot_func, true))) return NULL; From 832e96deb6f368591dcb35a4fa33b2fd770aa17a Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 15 Dec 2023 11:00:15 -0800 Subject: [PATCH 11/14] MDEV-29362 Crash with query using constant subquery as left part of IN subquery If a query has a HAVING clause that contains a predicate with a constant IN subquery whose lef part in its turn is a subquery and the predicate is subject to pushdown from HAVING to WHERE then execution of the query could cause a crash of the server. The cause of the problem was the missing implementation of the walk() method for the class Item_in_optimizer. As a result in some cases the left operand of the Item_in_optimizer condition could be traversed twice by the walk procedure. For many call-back functions used as an argument of this procedure it does not matter. Yet it matters for the call-back function cleanup_excluding_immutables_processor() used in pushdown of predicates from HAVING to WHERE. If the processed item is marked with the IMMUTABLE_FL flag then the processor just removes this flag, otherwise it performs cleanup of the item making it unfixed. If an item is marked with an the IMMUTABLE_FL and it traversed with this processor twice then it becomes unfixed after the second traversal though the flag indicates that the item should not be cleaned up. Approved by Oleksandr Byelkin --- mysql-test/main/subselect4.result | 79 +++++++++++++++++++++++++++++++ mysql-test/main/subselect4.test | 36 ++++++++++++++ sql/item_cmpfunc.cc | 17 +++++++ sql/item_cmpfunc.h | 1 + 4 files changed, 133 insertions(+) diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result index 9f435146e0b..4edcffa0ee5 100644 --- a/mysql-test/main/subselect4.result +++ b/mysql-test/main/subselect4.result @@ -3213,4 +3213,83 @@ FROM x ) ); ERROR 21000: Operand should contain 2 column(s) +# +# MDEV-29362: Constant subquery used as left part of IN subquery +# +CREATE TABLE t1 (a int) ENGINE=MyISAM; +INSERT INTO t1 VALUES (15), (1), (2); +CREATE TABLE t2 (b int) ENGINE=MyISAM; +INSERT INTO t2 VALUES (15), (1); +CREATE TABLE t3 (c int) ENGINE=MyISAM; +INSERT INTO t3 VALUES (15), (1); +SET optimizer_switch='condition_pushdown_from_having=off'; +SELECT a FROM t1 GROUP BY a +HAVING a = ( (SELECT b FROM t2 where b=1) IN (SELECT c FROM t3) ) + 1; +a +2 +SELECT a FROM t1 GROUP BY a +HAVING a IN ( (SELECT b FROM t2 where b=1) IN (SELECT c FROM t3) ); +a +1 +SET optimizer_switch='condition_pushdown_from_having=on'; +SELECT a FROM t1 GROUP BY a +HAVING a = ( (SELECT b FROM t2 where b=1) IN (SELECT c FROM t3) ) + 1; +a +2 +SELECT a FROM t1 GROUP BY a +HAVING a IN ( (SELECT b FROM t2 where b=1) IN (SELECT c FROM t3) ); +a +1 +EXPLAIN FORMAT=JSON SELECT a FROM t1 GROUP BY a +HAVING a = ( (SELECT b FROM t2 where b=1) IN (SELECT c FROM t3) ) + 1; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 3, + "filtered": 100, + "attached_condition": "t1.a = (((subquery#2),(subquery#3)) + 1)" + }, + "subqueries": [ + { + "query_block": { + "select_id": 3, + "having_condition": "trigcond(t3.c is null)", + "table": { + "table_name": "t3", + "access_type": "ALL", + "rows": 2, + "filtered": 100, + "attached_condition": "trigcond(1 = t3.c or t3.c is null)" + } + } + }, + { + "query_block": { + "select_id": 2, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 2, + "filtered": 100, + "attached_condition": "t2.b = 1" + } + } + } + ] + } +} +PREPARE stmt FROM "SELECT a FROM t1 GROUP BY a +HAVING a = ( (SELECT b FROM t2 where b=1) IN (SELECT c FROM t3) ) + 1"; +EXECUTE stmt; +a +2 +EXECUTE stmt; +a +2 +DEALLOCATE PREPARE stmt; +DROP TABLE t1,t2,t3; # End of 10.4 tests diff --git a/mysql-test/main/subselect4.test b/mysql-test/main/subselect4.test index 23611e4ec0d..d5871f1202c 100644 --- a/mysql-test/main/subselect4.test +++ b/mysql-test/main/subselect4.test @@ -2629,5 +2629,41 @@ SELECT ) ); +--echo # +--echo # MDEV-29362: Constant subquery used as left part of IN subquery +--echo # + +CREATE TABLE t1 (a int) ENGINE=MyISAM; +INSERT INTO t1 VALUES (15), (1), (2); +CREATE TABLE t2 (b int) ENGINE=MyISAM; +INSERT INTO t2 VALUES (15), (1); +CREATE TABLE t3 (c int) ENGINE=MyISAM; +INSERT INTO t3 VALUES (15), (1); + +let $q1= +SELECT a FROM t1 GROUP BY a + HAVING a = ( (SELECT b FROM t2 where b=1) IN (SELECT c FROM t3) ) + 1; +let $q2= +SELECT a FROM t1 GROUP BY a + HAVING a IN ( (SELECT b FROM t2 where b=1) IN (SELECT c FROM t3) ); + +SET optimizer_switch='condition_pushdown_from_having=off'; + +eval $q1; +eval $q2; + +SET optimizer_switch='condition_pushdown_from_having=on'; + +eval $q1; +eval $q2; + +eval EXPLAIN FORMAT=JSON $q1; + +eval PREPARE stmt FROM "$q1"; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +DROP TABLE t1,t2,t3; --echo # End of 10.4 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 2a1fc3f90d3..cffd2e8add8 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1444,6 +1444,23 @@ bool Item_in_optimizer::invisible_mode() } +bool Item_in_optimizer::walk(Item_processor processor, + bool walk_subquery, + void *arg) +{ + bool res= FALSE; + if (args[1]->type() == Item::SUBSELECT_ITEM && + ((Item_subselect *)args[1])->substype() != Item_subselect::EXISTS_SUBS && + !(((Item_subselect *)args[1])->substype() == Item_subselect::IN_SUBS && + ((Item_in_subselect *)args[1])->test_strategy(SUBS_IN_TO_EXISTS))) + res= args[0]->walk(processor, walk_subquery, arg); + if (!res) + res= args[1]->walk(processor, walk_subquery, arg); + + return res || (this->*processor)(arg); +} + + /** Add an expression cache for this subquery if it is needed diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 9731eb7755d..1ae0e652e88 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -385,6 +385,7 @@ public: bool eval_not_null_tables(void *opt_arg); void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); bool invisible_mode(); + bool walk(Item_processor processor, bool walk_subquery, void *arg); void reset_cache() { cache= NULL; } virtual void print(String *str, enum_query_type query_type); void restore_first_argument(); From 96130b1898d34222d1f0543d75dc1acb6cdb8b09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 3 Jan 2024 08:52:50 +0200 Subject: [PATCH 12/14] MDEV-33157 WSREP: Fix function pointer mismatch wsrep_plugin_init(), wsrep_plugin_deinit(): Remove these dummy functions in order to fix an error that would be flagged by cmake -DWITH_UBSAN=ON when using clang. wsrep_show_ready(), wsrep_show_bf_aborts(): Correct the signature. --- sql/wsrep_mysqld.cc | 3 ++- sql/wsrep_mysqld.h | 3 ++- sql/wsrep_plugin.cc | 16 ++-------------- sql/wsrep_thd.cc | 2 +- sql/wsrep_thd.h | 2 +- 5 files changed, 8 insertions(+), 18 deletions(-) diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 7c8bb683aab..5ec96478e4a 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -512,7 +512,8 @@ my_bool wsrep_ready_get (void) return ret; } -int wsrep_show_ready(THD *thd, SHOW_VAR *var, char *buff) +int wsrep_show_ready(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type) { var->type= SHOW_MY_BOOL; var->value= buff; diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 921b75ae42d..62bab628e78 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -148,7 +148,8 @@ extern char* wsrep_cluster_capabilities; int wsrep_show_status(THD *thd, SHOW_VAR *var, void *buff, system_status_var *status_var, enum_var_type scope); -int wsrep_show_ready(THD *thd, SHOW_VAR *var, char *buff); +int wsrep_show_ready(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *, enum_var_type); void wsrep_free_status(THD *thd); void wsrep_update_cluster_state_uuid(const char* str); diff --git a/sql/wsrep_plugin.cc b/sql/wsrep_plugin.cc index 743b8a593b8..3fa5f7b7ef4 100644 --- a/sql/wsrep_plugin.cc +++ b/sql/wsrep_plugin.cc @@ -18,18 +18,6 @@ #include -static int wsrep_plugin_init(void *p) -{ - WSREP_DEBUG("wsrep_plugin_init()"); - return 0; -} - -static int wsrep_plugin_deinit(void *p) -{ - WSREP_DEBUG("wsrep_plugin_deinit()"); - return 0; -} - struct Mysql_replication wsrep_plugin= { MYSQL_REPLICATION_INTERFACE_VERSION }; @@ -42,8 +30,8 @@ maria_declare_plugin(wsrep) "Codership Oy", "Wsrep replication plugin", PLUGIN_LICENSE_GPL, - wsrep_plugin_init, - wsrep_plugin_deinit, + NULL, + NULL, 0x0100, NULL, /* Status variables */ NULL, /* System variables */ diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index 4a6f0736c76..243a3ccdd3e 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -36,7 +36,7 @@ static Wsrep_thd_queue* wsrep_rollback_queue= 0; static Atomic_counter wsrep_bf_aborts_counter; -int wsrep_show_bf_aborts (THD *thd, SHOW_VAR *var, char *buff, +int wsrep_show_bf_aborts (THD *thd, SHOW_VAR *var, void *, system_status_var *, enum enum_var_type scope) { wsrep_local_bf_aborts= wsrep_bf_aborts_counter; diff --git a/sql/wsrep_thd.h b/sql/wsrep_thd.h index 488268bde69..22596840296 100644 --- a/sql/wsrep_thd.h +++ b/sql/wsrep_thd.h @@ -82,7 +82,7 @@ private: mysql_cond_t COND_wsrep_thd_queue; }; -int wsrep_show_bf_aborts (THD *thd, SHOW_VAR *var, char *buff, +int wsrep_show_bf_aborts (THD *thd, SHOW_VAR *var, void *, system_status_var *, enum enum_var_type scope); bool wsrep_create_appliers(long threads, bool mutex_protected=false); void wsrep_create_rollbacker(); From 77b8bedf345384bb15f4b2ac53af3cea871f2df8 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 3 Jan 2024 15:08:22 +0530 Subject: [PATCH 13/14] MDEV-33098 The test innodb.doublewrite_debug occasionally fails to start up InnoDB - innodb.doublewrite_debug should avoid the checkpoint before killing the server. So used debug sync and innodb_flush_sync to avoid the checkpoint completely. Test case allowed to skip on MSAN builder due to extra checkpoint. --- .../suite/innodb/r/doublewrite_debug.result | 8 +++-- .../suite/innodb/t/doublewrite_debug.test | 30 +++++++++++++++---- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/mysql-test/suite/innodb/r/doublewrite_debug.result b/mysql-test/suite/innodb/r/doublewrite_debug.result index 960610a7091..08d9a2a92e8 100644 --- a/mysql-test/suite/innodb/r/doublewrite_debug.result +++ b/mysql-test/suite/innodb/r/doublewrite_debug.result @@ -23,7 +23,7 @@ commit work; # Test Begin: Test if recovery works if 1st page and 2nd page # of system tablespace is full of zeroes. SET GLOBAL innodb_fast_shutdown = 0; -# restart +# restart: --debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0 begin; insert into t1 values (6, repeat('%', 400)); # Make the first page dirty for system tablespace @@ -33,6 +33,7 @@ set global innodb_fil_make_page_dirty_debug = 0; set global innodb_saved_page_number_debug = 1; set global innodb_fil_make_page_dirty_debug = 0; set global innodb_buf_flush_list_now = 1; +# Kill the server # Make the 1st page (page_no=0) and 2nd page (page_no=1) # of the system tablespace all zeroes. # restart @@ -52,7 +53,7 @@ f1 f2 # --------------------------------------------------------------- # Test Begin: Test if recovery works if 1st page of # system tablespace is corrupted and 2nd page as corrupted. -set global innodb_log_checkpoint_now = 1; +# restart: --debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0 begin; insert into t1 values (6, repeat('%', 400)); # Make the first page dirty for system tablespace @@ -62,6 +63,7 @@ set global innodb_fil_make_page_dirty_debug = 0; set global innodb_saved_page_number_debug = 1; set global innodb_fil_make_page_dirty_debug = 0; set global innodb_buf_flush_list_now = 1; +# Kill the server # Corrupt the 1st page (page_no=0) and 2nd page of the system tablespace. # restart FOUND 2 /InnoDB: Restoring page \[page id: space=0, page number=0\] of datafile/ in mysqld.1.err @@ -83,7 +85,7 @@ drop table t1; # MDEV-12600 crash during install_db with innodb_page_size=32K # and ibdata1=3M # -# restart: --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/doublewrite --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/doublewrite --innodb-data-file-path=ibdata1:1M;ibdata2:1M:autoextend +# restart: --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/doublewrite --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/doublewrite --innodb-undo-tablespaces=0 --innodb-data-file-path=ibdata1:1M;ibdata2:1M:autoextend SELECT * FROM INFORMATION_SCHEMA.ENGINES WHERE engine = 'innodb' AND support IN ('YES', 'DEFAULT', 'ENABLED'); diff --git a/mysql-test/suite/innodb/t/doublewrite_debug.test b/mysql-test/suite/innodb/t/doublewrite_debug.test index 86809cc43c0..b8eb81c645c 100644 --- a/mysql-test/suite/innodb/t/doublewrite_debug.test +++ b/mysql-test/suite/innodb/t/doublewrite_debug.test @@ -44,7 +44,9 @@ commit work; # Slow shutdown and restart to make sure ibuf merge is finished SET GLOBAL innodb_fast_shutdown = 0; let $shutdown_timeout=; +let $restart_parameters="--debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0"; --source include/restart_mysqld.inc +--source ../include/no_checkpoint_start.inc begin; insert into t1 values (6, repeat('%', 400)); @@ -57,8 +59,20 @@ set global innodb_saved_page_number_debug = 1; set global innodb_fil_make_page_dirty_debug = 0; set global innodb_buf_flush_list_now = 1; -let $shutdown_timeout=0; ---source include/shutdown_mysqld.inc + +--let CLEANUP_IF_CHECKPOINT=drop table t1, unexpected_checkpoint; +# Occasionally, a checkpoint would occur on the MSAN builder. +# We do not know the reason, because the failure can only be reproduced if there is +# enough load in that environment. +# Therefore, we allow the test to be skipped when run on MSAN. +# In other environments, we want the test to fail if a checkpoint occurs, +# so that we would catch it if it starts to happen regularly. +if (`select count(*) from information_schema.system_variables where variable_name='have_sanitizer' and global_value like "MSAN%"`) +{ +--let CLEANUP_IF_CHECKPOINT=drop table t1; +} + +--source ../include/no_checkpoint_end.inc --echo # Make the 1st page (page_no=0) and 2nd page (page_no=1) --echo # of the system tablespace all zeroes. @@ -74,6 +88,7 @@ print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}); close FILE; EOF +let $restart_parameters=; --source include/start_mysqld.inc let SEARCH_PATTERN=InnoDB: Restoring page \[page id: space=0, page number=0\] of datafile; @@ -90,7 +105,9 @@ select f1, f2 from t1; --echo # Test Begin: Test if recovery works if 1st page of --echo # system tablespace is corrupted and 2nd page as corrupted. -set global innodb_log_checkpoint_now = 1; +let $restart_parameters="--debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0"; +--source include/restart_mysqld.inc +--source ../include/no_checkpoint_start.inc begin; insert into t1 values (6, repeat('%', 400)); @@ -103,8 +120,8 @@ set global innodb_saved_page_number_debug = 1; set global innodb_fil_make_page_dirty_debug = 0; set global innodb_buf_flush_list_now = 1; -let $shutdown_timeout=0; ---source include/shutdown_mysqld.inc + +--source ../include/no_checkpoint_end.inc --echo # Corrupt the 1st page (page_no=0) and 2nd page of the system tablespace. perl; @@ -119,6 +136,7 @@ print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2); close FILE; EOF +let $restart_parameters=; --source include/start_mysqld.inc let SEARCH_PATTERN=InnoDB: Restoring page \[page id: space=0, page number=0\] of datafile; @@ -145,7 +163,7 @@ 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 +--let $ibp=$ibp --innodb-undo-tablespaces=0 --let $ibp=$ibp --innodb-data-file-path=ibdata1:1M;ibdata2:1M:autoextend --let $restart_parameters= $ibp From cc5c0eda4c1a516753de238e02a024b0f044b738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 3 Jan 2024 12:08:21 +0200 Subject: [PATCH 14/14] MDEV-33156 Crash on innodb_buf_flush_list_now=ON and innodb_force_recovery=6 srv_start(): Move a read only mode startup tweak from innodb_init_params() to the correct location. Also if innodb_force_recovery=6 we will disable the doublewrite buffer, because InnoDB must run in read-only mode to prevent further corruption. This change only affects debug checks. Whenever srv_read_only_mode holds, the buf_pool.flush_list will be empty, that is, there will be no writes of persistent InnoDB data pages. Reviewed by: Thirunarayanan Balathandayuthapani --- mysql-test/suite/innodb/r/ibuf_not_empty.result | 1 + mysql-test/suite/innodb/t/ibuf_not_empty.test | 1 + storage/innobase/handler/ha_innodb.cc | 5 ----- storage/innobase/srv/srv0start.cc | 8 ++++++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/mysql-test/suite/innodb/r/ibuf_not_empty.result b/mysql-test/suite/innodb/r/ibuf_not_empty.result index f2da89990b0..f26ea7fb8c2 100644 --- a/mysql-test/suite/innodb/r/ibuf_not_empty.result +++ b/mysql-test/suite/innodb/r/ibuf_not_empty.result @@ -12,6 +12,7 @@ check table t1; Table Op Msg_type Msg_text test.t1 check Warning InnoDB: Index 'b' contains 990 entries, should be 1024. test.t1 check error Corrupt +SET GLOBAL innodb_buf_flush_list_now=ON; # restart SET GLOBAL innodb_fast_shutdown=0; # restart diff --git a/mysql-test/suite/innodb/t/ibuf_not_empty.test b/mysql-test/suite/innodb/t/ibuf_not_empty.test index 207427d9ab8..11606f2d925 100644 --- a/mysql-test/suite/innodb/t/ibuf_not_empty.test +++ b/mysql-test/suite/innodb/t/ibuf_not_empty.test @@ -72,6 +72,7 @@ EOF --replace_regex /contains \d+ entries/contains 990 entries/ check table t1; +SET GLOBAL innodb_buf_flush_list_now=ON; --source include/shutdown_mysqld.inc diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 026309d0ff6..777ea1ba86e 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3893,11 +3893,6 @@ static int innodb_init_params() } #endif - if (srv_read_only_mode) { - ib::info() << "Started in read only mode"; - srv_use_doublewrite_buf = FALSE; - } - #ifdef LINUX_NATIVE_AIO #elif !defined _WIN32 /* Currently native AIO is supported only on windows and linux diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 6f40df82f8f..56e41616d1d 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1073,10 +1073,14 @@ dberr_t srv_start(bool create_new_db) if (srv_force_recovery) { ib::info() << "!!! innodb_force_recovery is set to " << srv_force_recovery << " !!!"; + if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) { + srv_read_only_mode = true; + } } - if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) { - srv_read_only_mode = true; + if (srv_read_only_mode) { + sql_print_information("InnoDB: Started in read only mode"); + srv_use_doublewrite_buf = false; } high_level_read_only = srv_read_only_mode