From 579c1a8c202dc1a725ae9a0d897734604f2f2444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 13 May 2019 11:31:01 +0300 Subject: [PATCH 01/43] MDEV-17061: Test failure on galera.galera_gcs_fc_limit Remove unnecessary sleeps and fix wait_condition to use wsrep_flow_control_paused i.e. we wait until flow control pauses a transaction on master. --- mysql-test/suite/galera/disabled.def | 1 - .../suite/galera/r/galera_gcs_fc_limit.result | 27 +++++++++-------- .../suite/galera/t/galera_gcs_fc_limit.test | 30 +++++++++---------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 2c0ef3f8e20..5389730710b 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -27,7 +27,6 @@ galera_binlog_rows_query_log_events: MariaDB does not support binlog_rows_query_ galera_binlog_stmt_autoinc : MDEV-13549 auto_increment mismatch galera_flush : MariaDB does not have global.thread_statistics galera_gcache_recover_manytrx : MDEV-18834 Galera test failure -galera_gcs_fc_limit : MDEV-17061 Timeout in wait_condition.inc for PROCESSLIST galera_ist_mariabackup : MDEV-18829 test leaves port open galera_ist_progress: MDEV-15236 fails when trying to read transfer status galera_kill_applier : race condition at the start of the test diff --git a/mysql-test/suite/galera/r/galera_gcs_fc_limit.result b/mysql-test/suite/galera/r/galera_gcs_fc_limit.result index 9463b5f8eef..f3f417058f7 100644 --- a/mysql-test/suite/galera/r/galera_gcs_fc_limit.result +++ b/mysql-test/suite/galera/r/galera_gcs_fc_limit.result @@ -1,17 +1,20 @@ -CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1); -SELECT COUNT(*) = 1 FROM t1; -COUNT(*) = 1 +CREATE TABLE t1 (f1 INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,B INTEGER) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1); +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) FROM t1; +COUNT(*) 1 SET GLOBAL wsrep_provider_options = 'gcs.fc_limit=1'; LOCK TABLE t1 WRITE; -INSERT INTO t1 VALUES (2); -INSERT INTO t1 VALUES (3); -INSERT INTO t1 VALUES (4); -INSERT INTO t1 VALUES (5); +FLUSH STATUS; +INSERT INTO t1 VALUES (2,2); +INSERT INTO t1 VALUES (3,3); +INSERT INTO t1 VALUES (4,4); +INSERT INTO t1(B) SELECT B FROM t1; +# In node_1 either insert or commit should be stuck UNLOCK TABLES; -INSERT INTO t1 VALUES (6); -SELECT COUNT(*) = 6 FROM t1; -COUNT(*) = 6 -1 +INSERT INTO t1 VALUES (NULL,6); +SELECT COUNT(*) FROM t1; +COUNT(*) +9 DROP TABLE t1; 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 61576a39316..e0626bd8946 100644 --- a/mysql-test/suite/galera/t/galera_gcs_fc_limit.test +++ b/mysql-test/suite/galera/t/galera_gcs_fc_limit.test @@ -5,12 +5,12 @@ --source include/galera_cluster.inc --source include/have_innodb.inc -CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1); +CREATE TABLE t1 (f1 INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,B INTEGER) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1); --connection node_2 -SELECT COUNT(*) = 1 FROM t1; ---sleep 1 +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) FROM t1; --let $wsrep_provider_options_orig = `SELECT @@wsrep_provider_options` SET GLOBAL wsrep_provider_options = 'gcs.fc_limit=1'; @@ -19,24 +19,22 @@ SET GLOBAL wsrep_provider_options = 'gcs.fc_limit=1'; LOCK TABLE t1 WRITE; --connection node_1 ---sleep 1 -INSERT INTO t1 VALUES (2); ---sleep 2 -INSERT INTO t1 VALUES (3); ---sleep 2 -INSERT INTO t1 VALUES (4); ---sleep 2 +FLUSH STATUS; +INSERT INTO t1 VALUES (2,2); +INSERT INTO t1 VALUES (3,3); +INSERT INTO t1 VALUES (4,4); # This query will hang because flow control will kick in --send -INSERT INTO t1 VALUES (5); ---sleep 2 +INSERT INTO t1(B) SELECT B FROM t1; --let $galera_connection_name = node_1a --let $galera_server_number = 1 --source include/galera_connect.inc --connection node_1a ---let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'query end' AND INFO = 'INSERT INTO t1 VALUES (5)'; + +--echo # In node_1 either insert or commit should be stuck +--let $wait_condition = SELECT VARIABLE_VALUE > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_flow_control_paused'; --source include/wait_condition.inc --connection node_2 @@ -46,11 +44,11 @@ UNLOCK TABLES; --connection node_1 --reap -INSERT INTO t1 VALUES (6); +INSERT INTO t1 VALUES (NULL,6); --connection node_2 # Replication catches up and continues normally -SELECT COUNT(*) = 6 FROM t1; +SELECT COUNT(*) FROM t1; --disable_query_log --eval SET GLOBAL wsrep_provider_options = '$wsrep_provider_options_orig'; From 61469b3a3b01d9491f17f58c4bd34a33150efcb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 13 May 2019 13:23:52 +0300 Subject: [PATCH 02/43] MDEV-13549: Timeout in wait_condition.inc for PROCESSLIST Use wsrep sync wait instead of unnecessary waits and correct slave setting. --- mysql-test/suite/galera/disabled.def | 1 - mysql-test/suite/galera/r/MW-336.result | 18 ++++++++-------- mysql-test/suite/galera/t/MW-336.test | 28 ++++++++----------------- 3 files changed, 18 insertions(+), 29 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 5389730710b..a9458f599d4 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -15,7 +15,6 @@ MW-328A : MDEV-17847 Galera test failure on MW-328[A|B|C] MW-328B : MDEV-17847 Galera test failure on MW-328[A|B|C] MW-328C : MDEV-17847 Galera test failure on MW-328[A|B|C] MW-329 : wsrep_local_replays not stable -MW-336 : MDEV-13549 Timeout in wait_condition.inc for PROCESSLIST MW-416 : MDEV-13549 Galera test failures MW-44 : MDEV-15809 Test failure on galera.MW-44 galera_account_management : MariaDB 10.0 does not support ALTER USER diff --git a/mysql-test/suite/galera/r/MW-336.result b/mysql-test/suite/galera/r/MW-336.result index 81e8eae0eb3..9a5bc88a48f 100644 --- a/mysql-test/suite/galera/r/MW-336.result +++ b/mysql-test/suite/galera/r/MW-336.result @@ -3,29 +3,29 @@ INSERT INTO t1 values(0); SET GLOBAL wsrep_slave_threads = 10; SET GLOBAL wsrep_slave_threads = 1; # Wait 10 slave threads to start 1 -# Generate 12 replication events +SET SESSION wsrep_sync_wait=15; +# Generate 100 replication events +SET SESSION wsrep_sync_wait=15; SELECT COUNT(*) FROM t1; COUNT(*) -13 +101 # Wait 9 slave threads to exit 1 SET GLOBAL wsrep_slave_threads = 10; # Wait 10 slave threads to start 2 SET GLOBAL wsrep_slave_threads = 20; # Wait 20 slave threads to start 3 SET GLOBAL wsrep_slave_threads = 1; -# Generate 40 replication events +# Generate 100 replication events SELECT COUNT(*) FROM t1; COUNT(*) -53 +201 # Wait 10 slave threads to exit 3 SET GLOBAL wsrep_slave_threads = 10; -SET GLOBAL wsrep_slave_threads = 0; -Warnings: -Warning 1292 Truncated incorrect wsrep_slave_threads value: '0' +SET GLOBAL wsrep_slave_threads = 1; # Wait 10 slave threads to start 3 -# Generate 12 replication events +# Generate 100 replication events SELECT COUNT(*) FROM t1; COUNT(*) -65 +301 # Wait 10 slave threads to exit 4 DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/MW-336.test b/mysql-test/suite/galera/t/MW-336.test index 749ffe671be..15e0a38a0b7 100644 --- a/mysql-test/suite/galera/t/MW-336.test +++ b/mysql-test/suite/galera/t/MW-336.test @@ -19,13 +19,14 @@ SET GLOBAL wsrep_slave_threads = 1; --source include/wait_condition.inc --connection node_2 +SET SESSION wsrep_sync_wait=15; # Wait until inserts are replicated --let $wait_condition = SELECT COUNT(*) = 1 FROM t1; --source include/wait_condition.inc ---echo # Generate 12 replication events +--echo # Generate 100 replication events --disable_query_log --disable_result_log ---let $count = 12 +--let $count = 100 while ($count) { INSERT INTO t1 VALUES (1); @@ -35,9 +36,7 @@ while ($count) --enable_query_log --connection node_1 -# Wait until inserts are replicated ---let $wait_condition = SELECT COUNT(*) = 13 FROM t1; ---source include/wait_condition.inc +SET SESSION wsrep_sync_wait=15; SELECT COUNT(*) FROM t1; @@ -61,10 +60,10 @@ SET GLOBAL wsrep_slave_threads = 20; SET GLOBAL wsrep_slave_threads = 1; --connection node_2 ---echo # Generate 40 replication events +--echo # Generate 100 replication events --disable_query_log --disable_result_log ---let $count = 40 +--let $count = 100 while ($count) { INSERT INTO t1 VALUES (1); @@ -74,11 +73,6 @@ while ($count) --enable_result_log --connection node_1 - -# Wait until inserts are replicated ---let $wait_condition = SELECT COUNT(*) = 53 FROM t1; ---source include/wait_condition.inc - SELECT COUNT(*) FROM t1; --echo # Wait 10 slave threads to exit 3 @@ -87,7 +81,7 @@ SELECT COUNT(*) FROM t1; --source include/wait_condition.inc SET GLOBAL wsrep_slave_threads = 10; -SET GLOBAL wsrep_slave_threads = 0; +SET GLOBAL wsrep_slave_threads = 1; --echo # Wait 10 slave threads to start 3 --let $wait_timeout=600 @@ -95,10 +89,10 @@ SET GLOBAL wsrep_slave_threads = 0; --source include/wait_condition.inc --connection node_2 ---echo # Generate 12 replication events +--echo # Generate 100 replication events --disable_query_log --disable_result_log ---let $count = 12 +--let $count = 100 while ($count) { INSERT INTO t1 VALUES (1); @@ -108,10 +102,6 @@ while ($count) --enable_query_log --connection node_1 -# Wait until inserts are replicated ---let $wait_condition = SELECT COUNT(*) = 65 FROM t1; ---source include/wait_condition.inc - SELECT COUNT(*) FROM t1; --echo # Wait 10 slave threads to exit 4 From c84f390df20c9fa385351d3f21a6f0f48dde1803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 14 May 2019 10:50:49 +0300 Subject: [PATCH 03/43] MDEV-16021: galera mtr test galera_evs_suspect_timeout crashed Crash was timeout crash. Add correct waits for connections, wsrep sync waits and auto increment offset save and restore. --- .../r/galera_evs_suspect_timeout.result | 21 ++++---- .../t/galera_evs_suspect_timeout.test | 48 ++++++++++++------- 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result b/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result index 7e0d282ec7f..833d045f274 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result +++ b/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result @@ -1,20 +1,25 @@ SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_timeout=PT1S'; SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_timeout=PT1S'; Suspending node ... -SET SESSION wsrep_sync_wait = 0; +SET SESSION wsrep_sync_wait=0; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 2 1 -CREATE TABLE t1 (f1 INTEGER); +CREATE TABLE t1 (f1 INTEGER) engine=InnoDB; INSERT INTO t1 VALUES (1); -SET SESSION wsrep_sync_wait = 0; +SET SESSION wsrep_sync_wait=0; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 2 1 -SET SESSION wsrep_sync_wait = DEFAULT; -SELECT COUNT(*) = 1 FROM t1; -COUNT(*) = 1 +SET SESSION wsrep_sync_wait = 15; +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +Resuming node ... +CALL mtr.add_suppression("WSREP: gcs_caused.*"); +CALL mtr.add_suppression("WSREP: gcs/src/gcs_core.cpp:core_handle_uuid_msg.*"); +SET SESSION wsrep_sync_wait = 15; +SELECT COUNT(*) FROM t1; +COUNT(*) 1 DROP TABLE t1; -Resuming node ... -CALL mtr.add_suppression("WSREP: gcs_caused() returned -1 \\(Operation not permitted\\)"); diff --git a/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test b/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test index 03236a3cb93..298613b3596 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test +++ b/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test @@ -7,24 +7,28 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +--let $galera_connection_name = node_3 +--let $galera_server_number = 3 +--source include/galera_connect.inc +--let $wsrep_cluster_address_node3 = `SELECT @@wsrep_cluster_address` + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + --connection node_1 --let $wsrep_provider_options_node1 = `SELECT @@wsrep_provider_options` SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_timeout=PT1S'; --connection node_2 ---source include/wait_until_connected_again.inc --let $wsrep_provider_options_node2 = `SELECT @@wsrep_provider_options` SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_timeout=PT1S'; ---let $galera_connection_name = node_3 ---let $galera_server_number = 3 ---source include/galera_connect.inc ---connection node_3 ---source include/wait_until_connected_again.inc ---let $wsrep_cluster_address_node3 = `SELECT @@wsrep_cluster_address` - # Suspend node #3 +--connection node_3 --source include/galera_suspend.inc --sleep 5 @@ -32,27 +36,27 @@ SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_ti --connection node_1 --source include/wait_until_connected_again.inc -SET SESSION wsrep_sync_wait = 0; +SET SESSION wsrep_sync_wait=0; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --disable_query_log --eval SET GLOBAL wsrep_provider_options = '$wsrep_provider_options_node1'; --enable_query_log - --source include/wait_until_connected_again.inc -CREATE TABLE t1 (f1 INTEGER); + +CREATE TABLE t1 (f1 INTEGER) engine=InnoDB; INSERT INTO t1 VALUES (1); --connection node_2 -SET SESSION wsrep_sync_wait = 0; +--source include/wait_until_connected_again.inc +SET SESSION wsrep_sync_wait=0; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --disable_query_log --eval SET GLOBAL wsrep_provider_options = '$wsrep_provider_options_node2'; --enable_query_log - --source include/wait_until_connected_again.inc -SET SESSION wsrep_sync_wait = DEFAULT; -SELECT COUNT(*) = 1 FROM t1; -DROP TABLE t1; + +SET SESSION wsrep_sync_wait = 15; +SELECT COUNT(*) FROM t1; # Reconnect node #3 so that MTR's end-of-test checks can run @@ -60,9 +64,19 @@ DROP TABLE t1; --source include/galera_resume.inc --source include/wait_until_connected_again.inc -CALL mtr.add_suppression("WSREP: gcs_caused() returned -1 \\(Operation not permitted\\)"); +CALL mtr.add_suppression("WSREP: gcs_caused.*"); +CALL mtr.add_suppression("WSREP: gcs/src/gcs_core.cpp:core_handle_uuid_msg.*"); --disable_query_log --eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_node3'; --enable_query_log --source include/wait_until_connected_again.inc + +SET SESSION wsrep_sync_wait = 15; +SELECT COUNT(*) FROM t1; + +--connection node_1 +DROP TABLE t1; +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc + From bc511443b132a244b18c51200473555e614b0fd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 13 May 2019 11:31:01 +0300 Subject: [PATCH 04/43] MDEV-17061: Test failure on galera.galera_gcs_fc_limit Remove unnecessary sleeps and fix wait_condition to use wsrep_flow_control_paused i.e. we wait until flow control pauses a transaction on master. --- mysql-test/suite/galera/disabled.def | 1 - .../suite/galera/r/galera_gcs_fc_limit.result | 27 +++++++++-------- .../suite/galera/t/galera_gcs_fc_limit.test | 30 +++++++++---------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 1296d494b76..f7ea3b65e73 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -27,7 +27,6 @@ galera_binlog_rows_query_log_events: MariaDB does not support binlog_rows_query_ galera_binlog_stmt_autoinc : MDEV-13549 auto_increment mismatch galera_flush : MariaDB does not have global.thread_statistics galera_gcache_recover_manytrx : MDEV-18834 Galera test failure -galera_gcs_fc_limit : MDEV-17061 Timeout in wait_condition.inc for PROCESSLIST galera_ist_mariabackup : MDEV-18829 test leaves port open galera_ist_progress: MDEV-15236 fails when trying to read transfer status galera_kill_applier : race condition at the start of the test diff --git a/mysql-test/suite/galera/r/galera_gcs_fc_limit.result b/mysql-test/suite/galera/r/galera_gcs_fc_limit.result index 464a8b7ea97..bf1a82f9f90 100644 --- a/mysql-test/suite/galera/r/galera_gcs_fc_limit.result +++ b/mysql-test/suite/galera/r/galera_gcs_fc_limit.result @@ -1,23 +1,26 @@ -CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1); +CREATE TABLE t1 (f1 INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,B INTEGER) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1); connection node_2; -SELECT COUNT(*) = 1 FROM t1; -COUNT(*) = 1 +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) FROM t1; +COUNT(*) 1 SET GLOBAL wsrep_provider_options = 'gcs.fc_limit=1'; LOCK TABLE t1 WRITE; connection node_1; -INSERT INTO t1 VALUES (2); -INSERT INTO t1 VALUES (3); -INSERT INTO t1 VALUES (4); -INSERT INTO t1 VALUES (5); +FLUSH STATUS; +INSERT INTO t1 VALUES (2,2); +INSERT INTO t1 VALUES (3,3); +INSERT INTO t1 VALUES (4,4); +INSERT INTO t1(B) SELECT B FROM t1; connection node_1a; +# In node_1 either insert or commit should be stuck connection node_2; UNLOCK TABLES; connection node_1; -INSERT INTO t1 VALUES (6); +INSERT INTO t1 VALUES (NULL,6); connection node_2; -SELECT COUNT(*) = 6 FROM t1; -COUNT(*) = 6 -1 +SELECT COUNT(*) FROM t1; +COUNT(*) +9 DROP TABLE t1; 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 61576a39316..e0626bd8946 100644 --- a/mysql-test/suite/galera/t/galera_gcs_fc_limit.test +++ b/mysql-test/suite/galera/t/galera_gcs_fc_limit.test @@ -5,12 +5,12 @@ --source include/galera_cluster.inc --source include/have_innodb.inc -CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1); +CREATE TABLE t1 (f1 INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,B INTEGER) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1); --connection node_2 -SELECT COUNT(*) = 1 FROM t1; ---sleep 1 +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) FROM t1; --let $wsrep_provider_options_orig = `SELECT @@wsrep_provider_options` SET GLOBAL wsrep_provider_options = 'gcs.fc_limit=1'; @@ -19,24 +19,22 @@ SET GLOBAL wsrep_provider_options = 'gcs.fc_limit=1'; LOCK TABLE t1 WRITE; --connection node_1 ---sleep 1 -INSERT INTO t1 VALUES (2); ---sleep 2 -INSERT INTO t1 VALUES (3); ---sleep 2 -INSERT INTO t1 VALUES (4); ---sleep 2 +FLUSH STATUS; +INSERT INTO t1 VALUES (2,2); +INSERT INTO t1 VALUES (3,3); +INSERT INTO t1 VALUES (4,4); # This query will hang because flow control will kick in --send -INSERT INTO t1 VALUES (5); ---sleep 2 +INSERT INTO t1(B) SELECT B FROM t1; --let $galera_connection_name = node_1a --let $galera_server_number = 1 --source include/galera_connect.inc --connection node_1a ---let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'query end' AND INFO = 'INSERT INTO t1 VALUES (5)'; + +--echo # In node_1 either insert or commit should be stuck +--let $wait_condition = SELECT VARIABLE_VALUE > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_flow_control_paused'; --source include/wait_condition.inc --connection node_2 @@ -46,11 +44,11 @@ UNLOCK TABLES; --connection node_1 --reap -INSERT INTO t1 VALUES (6); +INSERT INTO t1 VALUES (NULL,6); --connection node_2 # Replication catches up and continues normally -SELECT COUNT(*) = 6 FROM t1; +SELECT COUNT(*) FROM t1; --disable_query_log --eval SET GLOBAL wsrep_provider_options = '$wsrep_provider_options_orig'; From cd87e4e134d6a5502a0cf036316ee9922199a8b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 13 May 2019 13:23:52 +0300 Subject: [PATCH 05/43] MDEV-13549: Timeout in wait_condition.inc for PROCESSLIST Use wsrep sync wait instead of unnecessary waits and correct slave setting. --- mysql-test/suite/galera/disabled.def | 1 - mysql-test/suite/galera/r/MW-336.result | 18 ++++++++-------- mysql-test/suite/galera/t/MW-336.test | 28 ++++++++----------------- 3 files changed, 18 insertions(+), 29 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index f7ea3b65e73..f8510aa7429 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -15,7 +15,6 @@ MW-328A : MDEV-17847 Galera test failure on MW-328[A|B|C] MW-328B : MDEV-17847 Galera test failure on MW-328[A|B|C] MW-328C : MDEV-17847 Galera test failure on MW-328[A|B|C] MW-329 : wsrep_local_replays not stable -MW-336 : MDEV-13549 Timeout in wait_condition.inc for PROCESSLIST MW-416 : MDEV-13549 Galera test failures MW-44 : MDEV-15809 Test failure on galera.MW-44 galera_account_management : MariaDB 10.0 does not support ALTER USER diff --git a/mysql-test/suite/galera/r/MW-336.result b/mysql-test/suite/galera/r/MW-336.result index 4d7d6440066..191811680e0 100644 --- a/mysql-test/suite/galera/r/MW-336.result +++ b/mysql-test/suite/galera/r/MW-336.result @@ -5,11 +5,13 @@ SET GLOBAL wsrep_slave_threads = 10; SET GLOBAL wsrep_slave_threads = 1; # Wait 10 slave threads to start 1 connection node_2; -# Generate 12 replication events +SET SESSION wsrep_sync_wait=15; +# Generate 100 replication events connection node_1; +SET SESSION wsrep_sync_wait=15; SELECT COUNT(*) FROM t1; COUNT(*) -13 +101 # Wait 9 slave threads to exit 1 SET GLOBAL wsrep_slave_threads = 10; # Wait 10 slave threads to start 2 @@ -17,23 +19,21 @@ SET GLOBAL wsrep_slave_threads = 20; # Wait 20 slave threads to start 3 SET GLOBAL wsrep_slave_threads = 1; connection node_2; -# Generate 40 replication events +# Generate 100 replication events connection node_1; SELECT COUNT(*) FROM t1; COUNT(*) -53 +201 # Wait 10 slave threads to exit 3 SET GLOBAL wsrep_slave_threads = 10; -SET GLOBAL wsrep_slave_threads = 0; -Warnings: -Warning 1292 Truncated incorrect wsrep_slave_threads value: '0' +SET GLOBAL wsrep_slave_threads = 1; # Wait 10 slave threads to start 3 connection node_2; -# Generate 12 replication events +# Generate 100 replication events connection node_1; SELECT COUNT(*) FROM t1; COUNT(*) -65 +301 # Wait 10 slave threads to exit 4 connection node_1; DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/MW-336.test b/mysql-test/suite/galera/t/MW-336.test index 40d093a1a86..195418cff55 100644 --- a/mysql-test/suite/galera/t/MW-336.test +++ b/mysql-test/suite/galera/t/MW-336.test @@ -19,13 +19,14 @@ SET GLOBAL wsrep_slave_threads = 1; --source include/wait_condition.inc --connection node_2 +SET SESSION wsrep_sync_wait=15; # Wait until inserts are replicated --let $wait_condition = SELECT COUNT(*) = 1 FROM t1; --source include/wait_condition.inc ---echo # Generate 12 replication events +--echo # Generate 100 replication events --disable_query_log --disable_result_log ---let $count = 12 +--let $count = 100 while ($count) { INSERT INTO t1 VALUES (1); @@ -35,9 +36,7 @@ while ($count) --enable_query_log --connection node_1 -# Wait until inserts are replicated ---let $wait_condition = SELECT COUNT(*) = 13 FROM t1; ---source include/wait_condition.inc +SET SESSION wsrep_sync_wait=15; SELECT COUNT(*) FROM t1; @@ -61,10 +60,10 @@ SET GLOBAL wsrep_slave_threads = 20; SET GLOBAL wsrep_slave_threads = 1; --connection node_2 ---echo # Generate 40 replication events +--echo # Generate 100 replication events --disable_query_log --disable_result_log ---let $count = 40 +--let $count = 100 while ($count) { INSERT INTO t1 VALUES (1); @@ -74,11 +73,6 @@ while ($count) --enable_result_log --connection node_1 - -# Wait until inserts are replicated ---let $wait_condition = SELECT COUNT(*) = 53 FROM t1; ---source include/wait_condition.inc - SELECT COUNT(*) FROM t1; --echo # Wait 10 slave threads to exit 3 @@ -87,7 +81,7 @@ SELECT COUNT(*) FROM t1; --source include/wait_condition.inc SET GLOBAL wsrep_slave_threads = 10; -SET GLOBAL wsrep_slave_threads = 0; +SET GLOBAL wsrep_slave_threads = 1; --echo # Wait 10 slave threads to start 3 --let $wait_timeout=600 @@ -95,10 +89,10 @@ SET GLOBAL wsrep_slave_threads = 0; --source include/wait_condition.inc --connection node_2 ---echo # Generate 12 replication events +--echo # Generate 100 replication events --disable_query_log --disable_result_log ---let $count = 12 +--let $count = 100 while ($count) { INSERT INTO t1 VALUES (1); @@ -108,10 +102,6 @@ while ($count) --enable_query_log --connection node_1 -# Wait until inserts are replicated ---let $wait_condition = SELECT COUNT(*) = 65 FROM t1; ---source include/wait_condition.inc - SELECT COUNT(*) FROM t1; --echo # Wait 10 slave threads to exit 4 From 395ce1dcb33b5866f810299095978f2fb9263c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 14 May 2019 10:50:49 +0300 Subject: [PATCH 06/43] MDEV-16021: galera mtr test galera_evs_suspect_timeout crashed Crash was timeout crash. Add correct waits for connections, wsrep sync waits and auto increment offset save and restore. --- .../r/galera_evs_suspect_timeout.result | 25 ++++++---- .../t/galera_evs_suspect_timeout.test | 48 ++++++++++++------- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result b/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result index 6a7eea94077..34ef5b00033 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result +++ b/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result @@ -1,26 +1,35 @@ connection node_1; +connection node_2; +connection node_3; +connection node_1; SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_timeout=PT1S'; connection node_2; SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_timeout=PT1S'; connection node_3; Suspending node ... connection node_1; -SET SESSION wsrep_sync_wait = 0; +SET SESSION wsrep_sync_wait=0; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 2 1 -CREATE TABLE t1 (f1 INTEGER); +CREATE TABLE t1 (f1 INTEGER) engine=InnoDB; INSERT INTO t1 VALUES (1); connection node_2; -SET SESSION wsrep_sync_wait = 0; +SET SESSION wsrep_sync_wait=0; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 2 1 -SET SESSION wsrep_sync_wait = DEFAULT; -SELECT COUNT(*) = 1 FROM t1; -COUNT(*) = 1 +SET SESSION wsrep_sync_wait = 15; +SELECT COUNT(*) FROM t1; +COUNT(*) 1 -DROP TABLE t1; Resuming node ... connection node_3; -CALL mtr.add_suppression("WSREP: gcs_caused() returned -1 \\(Operation not permitted\\)"); +CALL mtr.add_suppression("WSREP: gcs_caused.*"); +CALL mtr.add_suppression("WSREP: gcs/src/gcs_core.cpp:core_handle_uuid_msg.*"); +SET SESSION wsrep_sync_wait = 15; +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +connection node_1; +DROP TABLE t1; diff --git a/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test b/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test index 4dab936c343..136fc8fd8a0 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test +++ b/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test @@ -7,24 +7,28 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +--let $galera_connection_name = node_3 +--let $galera_server_number = 3 +--source include/galera_connect.inc +--let $wsrep_cluster_address_node3 = `SELECT @@wsrep_cluster_address` + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + --connection node_1 --let $wsrep_provider_options_node1 = `SELECT @@wsrep_provider_options` SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_timeout=PT1S'; --connection node_2 ---source include/wait_until_connected_again.inc --let $wsrep_provider_options_node2 = `SELECT @@wsrep_provider_options` SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_timeout=PT1S'; ---let $galera_connection_name = node_3 ---let $galera_server_number = 3 ---source include/galera_connect.inc ---connection node_3 ---source include/wait_until_connected_again.inc ---let $wsrep_cluster_address_node3 = `SELECT @@wsrep_cluster_address` - # Suspend node #3 +--connection node_3 --source include/galera_suspend.inc --sleep 5 @@ -32,27 +36,27 @@ SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_ti --connection node_1 --source include/wait_until_connected_again.inc -SET SESSION wsrep_sync_wait = 0; +SET SESSION wsrep_sync_wait=0; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --disable_query_log --eval SET GLOBAL wsrep_provider_options = '$wsrep_provider_options_node1'; --enable_query_log - --source include/wait_until_connected_again.inc -CREATE TABLE t1 (f1 INTEGER); + +CREATE TABLE t1 (f1 INTEGER) engine=InnoDB; INSERT INTO t1 VALUES (1); --connection node_2 -SET SESSION wsrep_sync_wait = 0; +--source include/wait_until_connected_again.inc +SET SESSION wsrep_sync_wait=0; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --disable_query_log --eval SET GLOBAL wsrep_provider_options = '$wsrep_provider_options_node2'; --enable_query_log - --source include/wait_until_connected_again.inc -SET SESSION wsrep_sync_wait = DEFAULT; -SELECT COUNT(*) = 1 FROM t1; -DROP TABLE t1; + +SET SESSION wsrep_sync_wait = 15; +SELECT COUNT(*) FROM t1; # Reconnect node #3 so that MTR's end-of-test checks can run @@ -60,9 +64,19 @@ DROP TABLE t1; --connection node_3 --source include/wait_until_connected_again.inc -CALL mtr.add_suppression("WSREP: gcs_caused() returned -1 \\(Operation not permitted\\)"); +CALL mtr.add_suppression("WSREP: gcs_caused.*"); +CALL mtr.add_suppression("WSREP: gcs/src/gcs_core.cpp:core_handle_uuid_msg.*"); --disable_query_log --eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_node3'; --enable_query_log --source include/wait_until_connected_again.inc + +SET SESSION wsrep_sync_wait = 15; +SELECT COUNT(*) FROM t1; + +--connection node_1 +DROP TABLE t1; +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc + From 91efcc6392cef920aa3697dc9789830ae9cdd379 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Fri, 17 May 2019 19:17:19 +0300 Subject: [PATCH 07/43] Better comment from Monty for code in make_join_select --- sql/sql_select.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index cb8c0429674..c1bec0f1c20 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10027,8 +10027,16 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) /* We plan to scan all rows. Check again if we should use an index. - We could have used an column from a previous table in - the index if we are using limit and this is the first table + + There are two cases: + 1) There could be an index usage the refers to a previous + table that we didn't consider before, but could be consider + now as a "last resort". For example + SELECT * from t1,t2 where t1.a between t2.a and t2.b; + 2) If the current table is the first non const table + and there is a limit it still possibly beneficial + to use the index even if the index range is big as + we can stop when we've found limit rows. (1) - Don't switch the used index if we are using semi-join LooseScan on this table. Using different index will not From 2c9844a438c5f0bddcb037a1e05978118f48abb6 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sun, 19 May 2019 11:44:34 -0700 Subject: [PATCH 08/43] MDEV-18896 Crash in convert_join_subqueries_to_semijoins : Correction This patch complements the original patch for MDEV-18896 that prevents conversions to semi-joins in tableless selects used in INSERT statements in post-5.5 versions of the server. The test case was corrected as well to ensure that potential conversion to jtbm semi-joins is also checked (the problem was that one of the preceeding testcases in subselect_sj.test did not restore the state of the optimizer switch leaving the 'materialization' in the state 'off' and so blocking this check). Noticed an inconsistency in the state of select_lex::table_list used in INSERT statements and left a comment about this. --- mysql-test/r/subselect_sj.result | 1 + mysql-test/r/subselect_sj_jcl6.result | 1 + mysql-test/t/subselect_sj.test | 2 ++ sql/opt_subselect.cc | 2 +- sql/sql_parse.cc | 7 +++++++ 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index 73c620b2973..d0b8b626ba2 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -3181,6 +3181,7 @@ drop table t1,t2,t3; # # MDEV-18896: IN subquery in WHERE of a table-less query used for INSERT # +set @@optimizer_switch= @subselect_sj_tmp; create table t1 (a1 varchar(25)); create table t2 (a2 varchar(25)) ; insert into t1 select 'xxx' from dual where 'xxx' in (select a2 from t2); diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index 03cf368f32c..e9a8b7301f7 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -3195,6 +3195,7 @@ drop table t1,t2,t3; # # MDEV-18896: IN subquery in WHERE of a table-less query used for INSERT # +set @@optimizer_switch= @subselect_sj_tmp; create table t1 (a1 varchar(25)); create table t2 (a2 varchar(25)) ; insert into t1 select 'xxx' from dual where 'xxx' in (select a2 from t2); diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index aabb21b4245..6b59049bc4f 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -2873,6 +2873,8 @@ drop table t1,t2,t3; --echo # MDEV-18896: IN subquery in WHERE of a table-less query used for INSERT --echo # +set @@optimizer_switch= @subselect_sj_tmp; + create table t1 (a1 varchar(25)); create table t2 (a2 varchar(25)) ; insert into t1 select 'xxx' from dual where 'xxx' in (select a2 from t2); diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index fee68d33c33..a0e19af3d4e 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -525,7 +525,7 @@ bool is_materialization_applicable(THD *thd, Item_in_subselect *in_subs, parent_unit->first_select()->leaf_tables.elements && // 2 (thd->lex->sql_command == SQLCOM_SELECT || // * thd->lex->sql_command == SQLCOM_CREATE_TABLE) && // * - child_select->outer_select()->leaf_tables.elements && // 2A + child_select->outer_select()->table_list.first && // 2A subquery_types_allow_materialization(in_subs) && (in_subs->is_top_level_item() || //3 optimizer_flag(thd, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4ed2bcaed38..1d5733a646b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3034,6 +3034,13 @@ end_with_restore_list: */ /* Skip first table, which is the table we are inserting in */ TABLE_LIST *second_table= first_table->next_local; + /* + This is a hack: this leaves select_lex->table_list in an inconsistent + state as 'elements' does not contain number of elements in the list. + Moreover, if second_table == NULL then 'next' becomes invalid. + TODO: fix it by removing the front element (restoring of it should + be done properly as well) + */ select_lex->table_list.first= second_table; select_lex->context.table_list= select_lex->context.first_name_resolution_table= second_table; From d4e9a50e887c40da6a57cc5438d9857eae7c45f2 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Sun, 19 May 2019 23:50:23 +0400 Subject: [PATCH 09/43] MDEV-17456 Malicious SUPER user can possibly change audit log configuration without leaving traces. Fix for the SET GLOBAL server_audit_loggin=on; added. --- mysql-test/suite/plugins/r/server_audit.result | 2 ++ plugin/server_audit/server_audit.c | 15 +++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result index b8d2986feea..4088b36d440 100644 --- a/mysql-test/suite/plugins/r/server_audit.result +++ b/mysql-test/suite/plugins/r/server_audit.result @@ -271,6 +271,7 @@ TIME,HOSTNAME,root,localhost,ID,0,CONNECT,mysql,,0 TIME,HOSTNAME,root,localhost,ID,0,DISCONNECT,mysql,,0 TIME,HOSTNAME,no_such_user,localhost,ID,0,FAILED_CONNECT,,,ID TIME,HOSTNAME,no_such_user,localhost,ID,0,DISCONNECT,,,0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_incl_users=\'odin, dva, tri\'',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_incl_users=\'odin, root, dva, tri\'',0 TIME,HOSTNAME,root,localhost,ID,ID,CREATE,test,t2, TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'create table t2 (id int)',0 @@ -381,6 +382,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *** TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'insert into t1 values (1), (2)',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global server_audit_logging= off',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global server_audit_logging= on',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global server_audit_events=\'\'',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global serv',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'select (1), (2)',0 diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index 8472f9749c3..e143f56b415 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -15,7 +15,7 @@ #define PLUGIN_VERSION 0x104 -#define PLUGIN_STR_VERSION "1.4.5" +#define PLUGIN_STR_VERSION "1.4.6" #define _my_thread_var loc_thread_var @@ -2022,10 +2022,14 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) update_connection_info(cn, event_class, ev, &after_action); if (!logging) + { + if (cn) + cn->log_always= 0; goto exit_func; + } if (event_class == MYSQL_AUDIT_GENERAL_CLASS && FILTER(EVENT_QUERY) && - cn && do_log_user(cn->user)) + cn && (cn->log_always || do_log_user(cn->user))) { const struct mysql_event_general *event = (const struct mysql_event_general *) ev; @@ -2038,6 +2042,7 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) { log_statement(cn, event, "QUERY"); cn->query_length= 0; /* So the log_current_query() won't log this again. */ + cn->log_always= 0; } } else if (event_class == MYSQL_AUDIT_TABLE_CLASS && FILTER(EVENT_TABLE) && cn) @@ -2108,8 +2113,6 @@ exit_func: break; } } - if (cn) - cn->log_always= 0; flogger_mutex_unlock(&lock_operations); } @@ -2553,8 +2556,7 @@ static void log_current_query(MYSQL_THD thd) if (!thd) return; cn= get_loc_info(thd); - if (!ci_needs_setup(cn) && cn->query_length && - FILTER(EVENT_QUERY) && do_log_user(cn->user)) + if (!ci_needs_setup(cn) && cn->query_length) { cn->log_always= 1; log_statement_ex(cn, cn->query_time, thd_get_thread_id(thd), @@ -2814,6 +2816,7 @@ static void update_logging(MYSQL_THD thd, { CLIENT_ERROR(1, "Logging was disabled.", MYF(ME_JUST_WARNING)); } + mark_always_logged(thd); } else { From 5a2110e7cf98a14da8fe12797521b425a69a9373 Mon Sep 17 00:00:00 2001 From: Sujatha Date: Thu, 16 May 2019 16:36:20 +0530 Subject: [PATCH 10/43] MDEV-19076: rpl_parallel_temptable result mismatch '-33 optimistic' Problem: ======== The test now fails with the following trace: CURRENT_TEST: rpl.rpl_parallel_temptable --- /mariadb/10.4/mysql-test/suite/rpl/r/rpl_parallel_temptable.result +++ /mariadb/10.4/mysql-test/suite/rpl/r/rpl_parallel_temptable.reject @@ -194,7 +194,6 @@ 30 conservative 31 conservative 32 optimistic -33 optimistic Analysis: ========= The part of test which fails with result content mismatch is given below. CREATE TEMPORARY TABLE t4 (a INT PRIMARY KEY) ENGINE=InnoDB; INSERT INTO t4 VALUES (32); INSERT INTO t4 VALUES (33); INSERT INTO t1 SELECT a, "optimistic" FROM t4; slave_parallel_mode=optimistic The expectation of the above test script is, INSERT FROM SELECT should read both 32, 33 and populate table 't1'. But this expectation fails occasionally. All three INSERT statements are handed over to three different slave parallel workers. Temporary tables are not safe for parallel replication. They were designed to be visible to one thread only, so have no table locking. Thus there is no protection against two conflicting transactions committing in parallel and things like that. So anything that uses temporary tables will be serialized with anything before it, when using parallel replication by using a "wait_for_prior_commit" function call. This will ensure that the each transaction is executed sequentially. But there exists a code path in which the above wait doesn't happen. Because of this at times INSERT from SELECT doesn't wait for the INSERT (33) to complete and it completes its executes and enters commit stage. Hence only row 32 is found in those cases resulting in test failure. The wait needs to be added within "open_temporary_table" call. The code looks like this within "open_temporary_table". Each thread tries to open temporary table in 3 different ways: case 1: Find a temporary table which is already in use by using find_temporary_table(tl) && wait_for_prior_commit() case 2: If above failed then try to look for temporary table which is marked for free for reuse. This internally calls "wait_for_prior_commit()" if table is found. find_and_use_tmp_table(tl, &table) case 3: If none of the above open a new table handle from table share. if (!table && (share= find_tmp_table_share(tl))) { table= open_temporary_table(share, tl->get_table_name(), true); } At present the "wait_for_prior_commit" happens only in case 1 & 2. Fix: ==== On slave add a call for "wait_for_prior_commit" for case 3. The above wait on slave will solve the issue. A more detailed fix would be to mark temporary tables as not safe for parallel execution on the master side. In order to do that, on the master side, mark the Gtid_log_event specific flag FL_TRANSACTIONAL to be false all the time. So that they are not scheduled parallely. --- sql/log_event.cc | 3 ++- sql/sql_lex.h | 32 ++++++++++++++++++++++++++++++++ sql/temporary_tables.cc | 13 +++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index c37ee8d1e5c..01f31aceff7 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -7546,6 +7546,7 @@ Gtid_log_event::Gtid_log_event(THD *thd_arg, uint64 seq_no_arg, flags2((standalone ? FL_STANDALONE : 0) | (commit_id_arg ? FL_GROUP_COMMIT_ID : 0)) { cache_type= Log_event::EVENT_NO_CACHE; + bool is_tmp_table= thd_arg->lex->stmt_accessed_temp_table(); if (thd_arg->transaction.stmt.trans_did_wait() || thd_arg->transaction.all.trans_did_wait()) flags2|= FL_WAITED; @@ -7554,7 +7555,7 @@ Gtid_log_event::Gtid_log_event(THD *thd_arg, uint64 seq_no_arg, thd_arg->transaction.all.trans_did_ddl() || thd_arg->transaction.all.has_created_dropped_temp_table()) flags2|= FL_DDL; - else if (is_transactional) + else if (is_transactional && !is_tmp_table) flags2|= FL_TRANSACTIONAL; if (!(thd_arg->variables.option_bits & OPTION_RPL_SKIP_PARALLEL)) flags2|= FL_ALLOW_PARALLEL; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ea074ee6426..9a49e4024fe 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1761,6 +1761,38 @@ public: DBUG_RETURN((stmt_accessed_table_flag & (1U << accessed_table)) != 0); } + /** + Checks either a trans/non trans temporary table is being accessed while + executing a statement. + + @return + @retval TRUE if a temporary table is being accessed + @retval FALSE otherwise + */ + inline bool stmt_accessed_temp_table() + { + DBUG_ENTER("THD::stmt_accessed_temp_table"); + DBUG_RETURN(stmt_accessed_non_trans_temp_table() || + stmt_accessed_trans_temp_table()); + } + + /** + Checks if a temporary transactional table is being accessed while executing + a statement. + + @return + @retval TRUE if a temporary transactional table is being accessed + @retval FALSE otherwise + */ + inline bool stmt_accessed_trans_temp_table() + { + DBUG_ENTER("THD::stmt_accessed_trans_temp_table"); + + DBUG_RETURN((stmt_accessed_table_flag & + ((1U << STMT_READS_TEMP_TRANS_TABLE) | + (1U << STMT_WRITES_TEMP_TRANS_TABLE))) != 0); + } + /** Checks if a temporary non-transactional table is about to be accessed while executing a statement. diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc index 29097092680..15a81f4b375 100644 --- a/sql/temporary_tables.cc +++ b/sql/temporary_tables.cc @@ -369,6 +369,19 @@ bool THD::open_temporary_table(TABLE_LIST *tl) if (!table && (share= find_tmp_table_share(tl))) { table= open_temporary_table(share, tl->get_table_name(), true); + /* + Temporary tables are not safe for parallel replication. They were + designed to be visible to one thread only, so have no table locking. + Thus there is no protection against two conflicting transactions + committing in parallel and things like that. + + So for now, anything that uses temporary tables will be serialised + with anything before it, when using parallel replication. + */ + if (table && rgi_slave && + rgi_slave->is_parallel_exec && + wait_for_prior_commit()) + DBUG_RETURN(true); } if (!table) From 74904a667e184c2e190e0b6e20dfa7613f4b2723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 20 May 2019 17:00:21 +0300 Subject: [PATCH 11/43] Remove UT_NOT_USED btr_pcur_move_to_last_on_page(): Merge with the only caller. --- storage/innobase/fil/fil0crypt.cc | 7 +------ storage/innobase/include/btr0pcur.h | 10 +--------- storage/innobase/include/btr0pcur.ic | 20 +------------------- storage/innobase/include/ut0dbg.h | 6 +----- storage/innobase/row/row0sel.cc | 5 +++-- 5 files changed, 7 insertions(+), 41 deletions(-) diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index acf0b5eb1a3..902af66ebe7 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -2101,13 +2101,8 @@ A thread which monitors global key state and rotates tablespaces accordingly @return a dummy parameter */ extern "C" UNIV_INTERN os_thread_ret_t -DECLARE_THREAD(fil_crypt_thread)( -/*=============================*/ - void* arg __attribute__((unused))) /*!< in: a dummy parameter required - * by os_thread_create */ +DECLARE_THREAD(fil_crypt_thread)(void*) { - UT_NOT_USED(arg); - mutex_enter(&fil_crypt_threads_mutex); uint thread_no = srv_n_fil_crypt_threads_started; srv_n_fil_crypt_threads_started++; diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h index 9eccd9e9636..b79260e5ab6 100644 --- a/storage/innobase/include/btr0pcur.h +++ b/storage/innobase/include/btr0pcur.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -328,14 +328,6 @@ btr_pcur_move_to_prev( function may release the page latch */ mtr_t* mtr); /*!< in: mtr */ /*********************************************************//** -Moves the persistent cursor to the last record on the same page. */ -UNIV_INLINE -void -btr_pcur_move_to_last_on_page( -/*==========================*/ - btr_pcur_t* cursor, /*!< in: persistent cursor */ - mtr_t* mtr); /*!< in: mtr */ -/*********************************************************//** Moves the persistent cursor to the next user record in the tree. If no user records are left, the cursor ends up 'after last in tree'. @return TRUE if the cursor moved forward, ending on a user record */ diff --git a/storage/innobase/include/btr0pcur.ic b/storage/innobase/include/btr0pcur.ic index 948eee242b8..51ebcfbb2ee 100644 --- a/storage/innobase/include/btr0pcur.ic +++ b/storage/innobase/include/btr0pcur.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2017, MariaDB Corporation. +Copyright (c) 2015, 2019, 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 @@ -280,24 +280,6 @@ btr_pcur_move_to_prev_on_page( cursor->old_stored = false; } -/*********************************************************//** -Moves the persistent cursor to the last record on the same page. */ -UNIV_INLINE -void -btr_pcur_move_to_last_on_page( -/*==========================*/ - btr_pcur_t* cursor, /*!< in: persistent cursor */ - mtr_t* mtr) /*!< in: mtr */ -{ - UT_NOT_USED(mtr); - ut_ad(cursor->latch_mode != BTR_NO_LATCHES); - - page_cur_set_after_last(btr_pcur_get_block(cursor), - btr_pcur_get_page_cur(cursor)); - - cursor->old_stored = false; -} - /*********************************************************//** Moves the persistent cursor to the next user record in the tree. If no user records are left, the cursor ends up 'after last in tree'. diff --git a/storage/innobase/include/ut0dbg.h b/storage/innobase/include/ut0dbg.h index c145b932771..5d3fa1cf987 100644 --- a/storage/innobase/include/ut0dbg.h +++ b/storage/innobase/include/ut0dbg.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -68,10 +68,6 @@ ut_dbg_assertion_failed( #define ut_d(EXPR) #endif -/** Silence warnings about an unused variable by doing a null assignment. -@param A the unused variable */ -#define UT_NOT_USED(A) A = A - #if defined(HAVE_SYS_TIME_H) && defined(HAVE_SYS_RESOURCE_H) #define HAVE_UT_CHRONO_T diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 24e2b52faa6..afdac984cfd 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -4871,8 +4871,9 @@ wrong_offs: << " of table " << index->table->name << ". We try to skip the rest of the page."; - btr_pcur_move_to_last_on_page(pcur, &mtr); - + page_cur_set_after_last(btr_pcur_get_block(pcur), + btr_pcur_get_page_cur(pcur)); + pcur->old_stored = false; goto next_rec; } } From 71ee69c81c9362ee7a4be1031f2d05b07cda5ec0 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Mon, 20 May 2019 17:45:32 +0400 Subject: [PATCH 12/43] MDEV-17456 Malicious SUPER user can possibly change audit log configuration without leaving traces. thread_pool_server_audit.result fixed. --- mysql-test/suite/plugins/r/thread_pool_server_audit.result | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/plugins/r/thread_pool_server_audit.result b/mysql-test/suite/plugins/r/thread_pool_server_audit.result index cf09ccb3a51..250450e6451 100644 --- a/mysql-test/suite/plugins/r/thread_pool_server_audit.result +++ b/mysql-test/suite/plugins/r/thread_pool_server_audit.result @@ -244,6 +244,7 @@ TIME,HOSTNAME,root,localhost,ID,0,CONNECT,mysql,,0 TIME,HOSTNAME,root,localhost,ID,0,DISCONNECT,mysql,,0 TIME,HOSTNAME,no_such_user,localhost,ID,0,FAILED_CONNECT,,,ID TIME,HOSTNAME,no_such_user,localhost,ID,0,DISCONNECT,,,0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_incl_users=\'odin, dva, tri\'',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_incl_users=\'odin, root, dva, tri\'',0 TIME,HOSTNAME,root,localhost,ID,ID,CREATE,test,t2, TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'create table t2 (id int)',0 From 7b59ec6f345986db0cbc6f8b1d504a6e7e21cb5f Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Wed, 28 Nov 2018 13:25:43 +0300 Subject: [PATCH 13/43] MDEV-17799 Add ASAN-poisoned redzones for MEM_ROOT and mem_heap_t This patch is for MEM_ROOT only. In debug mode add 8 byte of poisoned memory before every allocated chunk. On the right of every chunk there will be either 1-7 trailing poisoned bytes, or next chunk's redzone, or poisoned non allocated memory or redzone of a malloc()ed buffer. --- include/my_valgrind.h | 7 +++++++ mysys/my_alloc.c | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/my_valgrind.h b/include/my_valgrind.h index 6df8f5a772e..14db2af2cb3 100644 --- a/include/my_valgrind.h +++ b/include/my_valgrind.h @@ -13,6 +13,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ +#ifndef _my_valgrind_h +#define _my_valgrind_h + /* clang -> gcc */ #ifndef __has_feature # define __has_feature(x) 0 @@ -49,9 +52,13 @@ https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */ #endif /* HAVE_VALGRIND */ #ifndef DBUG_OFF +static const size_t REDZONE_SIZE= 8; #define TRASH_FILL(A,B,C) do { const size_t trash_tmp= (B); MEM_UNDEFINED(A, trash_tmp); memset(A, C, trash_tmp); } while (0) #else +static const size_t REDZONE_SIZE= 0; #define TRASH_FILL(A,B,C) do { MEM_UNDEFINED((A), (B)); } while (0) #endif #define TRASH_ALLOC(A,B) do { TRASH_FILL(A,B,0xA5); MEM_UNDEFINED(A,B); } while(0) #define TRASH_FREE(A,B) do { TRASH_FILL(A,B,0x8F); MEM_NOACCESS(A,B); } while(0) + +#endif /* _my_valgrind_h */ diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index 15b96e8a20a..9e5b6809dea 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -197,7 +197,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) DBUG_SET("-d,simulate_out_of_memory"); DBUG_RETURN((void*) 0); /* purecov: inspected */ }); - length= ALIGN_SIZE(length); + length= ALIGN_SIZE(length) + REDZONE_SIZE; if ((*(prev= &mem_root->free)) != NULL) { if ((*prev)->left < length && @@ -242,6 +242,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) mem_root->used= next; mem_root->first_block_usage= 0; } + point+= REDZONE_SIZE; TRASH_ALLOC(point, original_length); DBUG_PRINT("exit",("ptr: 0x%lx", (ulong) point)); DBUG_RETURN((void*) point); From 5034b31b01b790ce1c28159402d754f7f951edc5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 20 May 2019 18:23:10 +0200 Subject: [PATCH 14/43] MDEV-17799 Add ASAN-poisoned redzones for MEM_ROOT post-merge changes Closes #954 --- include/my_valgrind.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/include/my_valgrind.h b/include/my_valgrind.h index 14db2af2cb3..ad22f0cad40 100644 --- a/include/my_valgrind.h +++ b/include/my_valgrind.h @@ -13,8 +13,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ -#ifndef _my_valgrind_h -#define _my_valgrind_h +#ifndef MY_VALGRIND_INCLUDED +#define MY_VALGRIND_INCLUDED /* clang -> gcc */ #ifndef __has_feature @@ -36,6 +36,7 @@ # define MEM_NOACCESS(a,len) VALGRIND_MAKE_MEM_NOACCESS(a,len) # define MEM_CHECK_ADDRESSABLE(a,len) VALGRIND_CHECK_MEM_IS_ADDRESSABLE(a,len) # define MEM_CHECK_DEFINED(a,len) VALGRIND_CHECK_MEM_IS_DEFINED(a,len) +# define REDZONE_SIZE 8 #elif defined(__SANITIZE_ADDRESS__) # include /* How to do manual poisoning: @@ -44,21 +45,21 @@ https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */ # define MEM_NOACCESS(a,len) ASAN_POISON_MEMORY_REGION(a,len) # define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0) # define MEM_CHECK_DEFINED(a,len) ((void) 0) +# define REDZONE_SIZE 8 #else # define MEM_UNDEFINED(a,len) ((void) (a), (void) (len)) # define MEM_NOACCESS(a,len) ((void) 0) # define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0) # define MEM_CHECK_DEFINED(a,len) ((void) 0) +# define REDZONE_SIZE 0 #endif /* HAVE_VALGRIND */ #ifndef DBUG_OFF -static const size_t REDZONE_SIZE= 8; #define TRASH_FILL(A,B,C) do { const size_t trash_tmp= (B); MEM_UNDEFINED(A, trash_tmp); memset(A, C, trash_tmp); } while (0) #else -static const size_t REDZONE_SIZE= 0; #define TRASH_FILL(A,B,C) do { MEM_UNDEFINED((A), (B)); } while (0) #endif #define TRASH_ALLOC(A,B) do { TRASH_FILL(A,B,0xA5); MEM_UNDEFINED(A,B); } while(0) #define TRASH_FREE(A,B) do { TRASH_FILL(A,B,0x8F); MEM_NOACCESS(A,B); } while(0) -#endif /* _my_valgrind_h */ +#endif /* MY_VALGRIND_INCLUDED */ From 3a871c39a97c8029ec0f8a424a2ea5c2ac557d24 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 5 Sep 2017 16:24:29 +0300 Subject: [PATCH 15/43] Fixed monitor.test to handle statistics >= 10 --- mysql-test/suite/innodb/r/monitor.result | 30 ++++++++++++------------ mysql-test/suite/innodb/t/monitor.test | 18 +++++--------- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/mysql-test/suite/innodb/r/monitor.result b/mysql-test/suite/innodb/r/monitor.result index 33a09a553b9..2700479e7f7 100644 --- a/mysql-test/suite/innodb/r/monitor.result +++ b/mysql-test/suite/innodb/r/monitor.result @@ -622,46 +622,46 @@ set global innodb_monitor_reset_all = default; # MONITORS # CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; -SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; -NAME COUNT +NAME COUNT > 0 buffer_page_written_index_leaf 0 SET GLOBAL innodb_monitor_enable='module_buffer_page'; INSERT INTO t1 VALUES (1), (2), (3), (4); FLUSH TABLES t1 FOR EXPORT; UNLOCK TABLES; -SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; -NAME COUNT -buffer_page_written_index_leaf NNNN +NAME COUNT > 0 +buffer_page_written_index_leaf 1 SET GLOBAL innodb_monitor_disable='module_buffer_page'; SET GLOBAL innodb_monitor_reset_all='module_buffer_page'; -SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; -NAME COUNT +NAME COUNT > 0 buffer_page_written_index_leaf 0 SET GLOBAL innodb_monitor_enable='%'; INSERT INTO t1 VALUES (5), (6), (7), (8); FLUSH TABLES t1 FOR EXPORT; UNLOCK TABLES; -SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; -NAME COUNT -buffer_page_written_index_leaf NNNN +NAME COUNT > 0 +buffer_page_written_index_leaf 1 SET GLOBAL innodb_monitor_disable='%'; SET GLOBAL innodb_monitor_reset_all='%'; -SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; -NAME COUNT +NAME COUNT > 0 buffer_page_written_index_leaf 0 SET GLOBAL innodb_monitor_enable='ALL'; INSERT INTO t1 VALUES (9), (10), (11), (12); FLUSH TABLES t1 FOR EXPORT; UNLOCK TABLES; -SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; -NAME COUNT -buffer_page_written_index_leaf NNNN +NAME COUNT > 0 +buffer_page_written_index_leaf 1 SET GLOBAL innodb_monitor_enable=default; SET GLOBAL innodb_monitor_disable=default; SET GLOBAL innodb_monitor_reset_all=default; diff --git a/mysql-test/suite/innodb/t/monitor.test b/mysql-test/suite/innodb/t/monitor.test index 98aa4505e34..dfae93694bf 100644 --- a/mysql-test/suite/innodb/t/monitor.test +++ b/mysql-test/suite/innodb/t/monitor.test @@ -391,41 +391,35 @@ CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; let $innodb_monitor_enable = `SELECT @@innodb_monitor_enable`; ---replace_regex /[1-9]/NNNN/ -SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; SET GLOBAL innodb_monitor_enable='module_buffer_page'; INSERT INTO t1 VALUES (1), (2), (3), (4); FLUSH TABLES t1 FOR EXPORT; UNLOCK TABLES; ---replace_regex /[1-9]/NNNN/ -SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; SET GLOBAL innodb_monitor_disable='module_buffer_page'; SET GLOBAL innodb_monitor_reset_all='module_buffer_page'; ---replace_regex /[1-9]/NNNN/ -SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; SET GLOBAL innodb_monitor_enable='%'; INSERT INTO t1 VALUES (5), (6), (7), (8); FLUSH TABLES t1 FOR EXPORT; UNLOCK TABLES; ---replace_regex /[1-9]/NNNN/ -SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; SET GLOBAL innodb_monitor_disable='%'; SET GLOBAL innodb_monitor_reset_all='%'; ---replace_regex /[1-9]/NNNN/ -SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; SET GLOBAL innodb_monitor_enable='ALL'; INSERT INTO t1 VALUES (9), (10), (11), (12); FLUSH TABLES t1 FOR EXPORT; UNLOCK TABLES; ---replace_regex /[1-9]/NNNN/ -SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; --disable_warnings From aaa920dad359abd4b1b94330a0a942387a8814ad Mon Sep 17 00:00:00 2001 From: Ian Gilfillan Date: Tue, 21 May 2019 14:54:03 +0200 Subject: [PATCH 16/43] MDEV-19537: Document mysqlimport option ignore-foreign-keys --- man/mysqlimport.1 | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/man/mysqlimport.1 b/man/mysqlimport.1 index 0032edf8a8f..61d270d7057 100644 --- a/man/mysqlimport.1 +++ b/man/mysqlimport.1 @@ -1,6 +1,6 @@ '\" t .\" -.TH "\FBMYSQLIMPORT\FR" "1" "14/12/2015" "MariaDB 10\&.1" "MariaDB Database System" +.TH "\FBMYSQLIMPORT\FR" "1" "21 May 2019" "MariaDB 10\&.1" "MariaDB Database System" .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -346,6 +346,22 @@ option\&. .sp -1 .IP \(bu 2.3 .\} +.\" mysqlimport: ignore-foreign-keys option +.\" ignore-foreign-keys option: mysqlimport +\fB\-\-ignore\-foreign\-keys\fR, +\fB\-k\fR +.sp +Disable foreign key checks while importing the data\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} .\" mysqlimport: ignore-lines option .\" ignore-lines option: mysqlimport \fB\-\-ignore\-lines=\fR\fB\fIN\fR\fR From 6dbc2ab8b36ca9b9255a9a4e3bae28e76522e5c8 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Mon, 20 May 2019 17:44:55 +0530 Subject: [PATCH 17/43] MDEV-17752: Plan changes from hash_index_merge to index_merge with new optimizer defaults The code in best_access_path function, when it does not find a key suitable for ref access and join_cache_level is set to a value so that hash_join is possible we build a hash key. Later in the function we compare the cost of ref access with table scan (or index scan or quick selects). No need to do this when we have got the hash key. --- mysql-test/r/join_cache.result | 31 +++++++++++++++++++++++++ mysql-test/r/join_nested_jcl6.result | 2 +- mysql-test/t/join_cache.test | 34 ++++++++++++++++++++++++++++ sql/sql_select.cc | 4 +++- 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index 01339f7c191..cf23979b49a 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -2885,6 +2885,37 @@ Klaipeda Lithuania xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Panevezys Lithuania xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx set join_cache_level=default; set join_buffer_size=default; +# +# MDEV-17752: Plan changes from hash_index_merge to index_merge with new optimizer defaults +# +set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity; +set @save_use_stat_tables=@@use_stat_tables; +set optimizer_use_condition_selectivity=4; +set use_stat_tables='preferably'; +use world; +set join_cache_level=4; +CREATE INDEX City_Name ON City(Name); +ANALYZE TABLE City, Country; +EXPLAIN +SELECT Country.Name, Country.Population, City.Name, City.Population +FROM Country LEFT JOIN City +ON City.Country=Country.Code AND City.Population > 5000000 +WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE Country range Name Name 302 NULL 15 Using index condition; Using where; Rowid-ordered scan +1 SIMPLE City hash_range Population,Country #hash#Country:Population 3:4 world.Country.Code 25 Using where; Rowid-ordered scan; Using join buffer (flat, BNLH join) +EXPLAIN +SELECT Country.Name, Country.Population, City.Name, City.Population +FROM Country LEFT JOIN City +ON City.Country=Country.Code AND +(City.Population > 5000000 OR City.Name LIKE 'Za%') +WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE Country range Name Name 302 NULL 15 Using index condition; Using where; Rowid-ordered scan +1 SIMPLE City hash_index_merge Population,Country,City_Name #hash#Country:Population,City_Name 3:4,35 world.Country.Code 96 Using sort_union(Population,City_Name); Using where; Using join buffer (flat, BNLH join) +set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +set @@use_stat_tables=@save_use_stat_tables; +set join_cache_level=default; DROP DATABASE world; use test; CREATE TABLE t1( diff --git a/mysql-test/r/join_nested_jcl6.result b/mysql-test/r/join_nested_jcl6.result index bac8e1cb7db..51073bf0f1d 100644 --- a/mysql-test/r/join_nested_jcl6.result +++ b/mysql-test/r/join_nested_jcl6.result @@ -1342,7 +1342,7 @@ EXPLAIN SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON c21=c31) ON c11=c21; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 1 SIMPLE t2 hash_ALL NULL #hash#$hj 5 test.t1.c11 0 Using where; Using join buffer (flat, BNLH join) -1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t3 hash_ALL NULL #hash#$hj 5 test.t1.c11 0 Using where; Using join buffer (incremental, BNLH join) DROP TABLE t1,t2,t3; CREATE TABLE t1 (goods int(12) NOT NULL, price varchar(128) NOT NULL); INSERT INTO t1 VALUES (23, 2340), (26, 9900); diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 24dd637052c..48f129c676d 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -967,6 +967,40 @@ SELECT City.Name, Country.Name, Country.PopulationBar FROM City,Country set join_cache_level=default; set join_buffer_size=default; + +--echo # +--echo # MDEV-17752: Plan changes from hash_index_merge to index_merge with new optimizer defaults +--echo # + +set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity; +set @save_use_stat_tables=@@use_stat_tables; +set optimizer_use_condition_selectivity=4; +set use_stat_tables='preferably'; + +use world; +set join_cache_level=4; +CREATE INDEX City_Name ON City(Name); + +--disable_result_log +ANALYZE TABLE City, Country; +--enable_result_log + +EXPLAIN +SELECT Country.Name, Country.Population, City.Name, City.Population + FROM Country LEFT JOIN City + ON City.Country=Country.Code AND City.Population > 5000000 + WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; + +EXPLAIN +SELECT Country.Name, Country.Population, City.Name, City.Population + FROM Country LEFT JOIN City + ON City.Country=Country.Code AND + (City.Population > 5000000 OR City.Name LIKE 'Za%') + WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; +set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +set @@use_stat_tables=@save_use_stat_tables; +set join_cache_level=default; + DROP DATABASE world; use test; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c1bec0f1c20..7426540c8d7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6396,7 +6396,8 @@ best_access_path(JOIN *join, 'range' access using index IDX, and the best way to perform 'ref' access is to use the same index IDX, with the same or more key parts. (note: it is not clear how this rule is/should be extended to - index_merge quick selects) + index_merge quick selects). Also if we have a hash join we prefer that + over a table scan (3) See above note about InnoDB. (4) NOT ("FORCE INDEX(...)" is used for table and there is 'ref' access path, but there is no quick select) @@ -6412,6 +6413,7 @@ best_access_path(JOIN *join, be used for cases with small datasets, which is annoying. */ if ((records >= s->found_records || best > s->read_time) && // (1) + !(best_key && best_key->key == MAX_KEY) && // (2) !(s->quick && best_key && s->quick->index == best_key->key && // (2) best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2) !((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3) From 4584c186312a6e9b16271c5d863c76f939d4df53 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 22 May 2019 00:52:15 +0200 Subject: [PATCH 18/43] make CPACK_RPM_DEBUGINFO_PACKAGE configurable from the command-line --- cmake/cpack_rpm.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake index 4e9410306a8..10afa56aec1 100644 --- a/cmake/cpack_rpm.cmake +++ b/cmake/cpack_rpm.cmake @@ -32,7 +32,7 @@ IF(CMAKE_VERSION VERSION_LESS "3.6.0") SET(CPACK_PACKAGE_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${VERSION}-${RPM}-${CMAKE_SYSTEM_PROCESSOR}") ELSE() SET(CPACK_RPM_FILE_NAME "RPM-DEFAULT") - SET(CPACK_RPM_DEBUGINFO_PACKAGE ON) + SET(CPACK_RPM_DEBUGINFO_PACKAGE ON CACHE INTERNAL "") ENDIF() SET(CPACK_RPM_PACKAGE_RELEASE "1%{?dist}") From aad4e5637daf52c2b27a355e0c2f9038d940209d Mon Sep 17 00:00:00 2001 From: Robert Bindar Date: Wed, 22 May 2019 12:20:02 +0300 Subject: [PATCH 19/43] Stale files cause intermittent failure when ordering is unfortunate Running trigger_null-8605 drop_bad_db_type tests in this order was failing due to unremoved temporary files created in trigger_null-8605 --- mysql-test/t/trigger_null-8605.test | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysql-test/t/trigger_null-8605.test b/mysql-test/t/trigger_null-8605.test index 34a57654b48..7645b61f5ad 100644 --- a/mysql-test/t/trigger_null-8605.test +++ b/mysql-test/t/trigger_null-8605.test @@ -149,6 +149,7 @@ EOF load data infile 'mdev8605.txt' into table t1 fields terminated by ','; select * from t1; drop table t1; +--remove_file $datadir/test/mdev8605.txt # timestamps (on NULL = NOW()) create table t1 (a timestamp, b int auto_increment primary key); @@ -218,6 +219,7 @@ load data infile 'sep8605.txt' into table t1 fields terminated by ',' (@a,a2,a3,b,c) set a1=100-@a; select 100-a1,a2,a3,b,c from t1; delete from t1; +--remove_file $datadir/test/sep8605.txt --write_file $datadir/test/fix8605.txt 00012010-11-12 01:02:030010000000000000000 @@ -231,6 +233,7 @@ set statement timestamp=777777777 for load data infile 'fix8605.txt' into table t1 fields terminated by ''; select * from t1; delete from t1; +--remove_file $datadir/test/fix8605.txt --write_file $datadir/test/xml8605.txt @@ -300,6 +303,7 @@ set statement timestamp=777777777 for load xml infile 'xml8605.txt' into table t1 rows identified by ''; select * from t1; drop table t1; +--remove_file $datadir/test/xml8605.txt # explicit DEFAULT create table t1 (a int not null default 5, b int, c int); From e57bb1f76cd0f8eac587a5fede01ba19bd54677a Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 14 May 2019 23:58:56 -0700 Subject: [PATCH 20/43] MDEV-19258 RIGHT JOIN hangs in MariaDB This patch corrects the patch for the bug 10006. The latter incorrectly calculates the attribute TABLE_LIST::dep_tables for inner tables of outer joins that are to be converted into inner joins. As a result after the patch some valid join orders were not evaluated and the optimizer could choose an execution plan that was far from being optimal. --- mysql-test/r/join_outer.result | 139 +++++++++++++++++++++++++++- mysql-test/r/join_outer_jcl6.result | 139 +++++++++++++++++++++++++++- mysql-test/t/join_outer.test | 127 ++++++++++++++++++++++++- sql/sql_select.cc | 16 +++- 4 files changed, 416 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 6bd12dbe1a6..3120a6df81e 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -2447,7 +2447,7 @@ t1.b1+'0' t2.b2 + '0' 0 0 1 1 DROP TABLE t1, t2; -set @join_cache_level= @save_join_cache_level; +set @@join_cache_level= @save_join_cache_level; # # MDEV-14779: using left join causes incorrect results with materialization and derived tables # @@ -2513,4 +2513,141 @@ ORDER BY tb1.i1; v2 DROP TABLE t1,t2; # end of 5.5 tests +# +# MDEV-19258: chained right joins all converted to inner joins +# +CREATE TABLE t1 ( +id int NOT NULL AUTO_INCREMENT, +timestamp bigint NOT NULL, +modifiedBy varchar(255) DEFAULT NULL, +PRIMARY KEY (id) +); +CREATE TABLE t2 ( +id int NOT NULL, +REV int NOT NULL, +REVTYPE tinyint DEFAULT NULL, +profile_id int DEFAULT NULL, +PRIMARY KEY (id,REV) +); +CREATE TABLE t3 ( +id int NOT NULL, +REV int NOT NULL, +person_id int DEFAULT NULL, +PRIMARY KEY (id,REV) +); +CREATE TABLE t4 ( +id int NOT NULL, +REV int NOT NULL, +PRIMARY KEY (id,REV) +); +INSERT INTO t1 VALUES +(1,1294391193890,'Cxqy$*9.kKeE'),(2,1294643906883,'rE4wqGV0gif@'), +(3,1294643927456,'L?3yt(%dY$Br'),(4,1294644343525,'WH&ObiZ$#2S4'), +(5,1294644616416,'YXnCbt?olUZ0'),(6,1294644954537,'8Npe4!(#lU@k'), +(7,1294645046659,'knc0GhXB1#ib'),(8,1294645183829,'w*oPpVfuS8^m'), +(9,1294645386701,'hwXR@3qVzrbU'),(10,1294645525982,'BeLW*Y9ndP0l'), +(11,1294645627723,'nTegib^)qZ$I'),(12,1294650860266,'u62C^Kzx3wH8'), +(13,1294657613745,'4&BkFjGa!qLg'),(14,1294660627161,')anpt312SCoh'), +(15,1294661023336,'LtJ2PX?*kTmx'),(16,1294662838066,'POGRr@?#ofpl'), +(17,1294663020989,'o.)1EOT2jnF7'),(18,1294663308065,'&TZ0F0LHE6.h'), +(19,1294664900039,'j)kSC%^In$9d'),(20,1294668904556,'97glN50)cAo.'), +(21,1294728056853,'lrKZxmw?I.Ek'),(22,1294728157174,'@P*SRg!pT.q?'), +(23,1294728327099,'W9gPrptF.)8n'),(24,1294728418481,'$q*c^sM&URd#'), +(25,1294728729620,'9*f4&bTPRtHo'),(26,1294728906014,')4VtTEnS7$oI'), +(27,1294732190003,'8dkNSPq2u3AQ'),(28,1294733205065,'SV2N6IoEf438'), +(29,1294741984927,'rBKj.0S^Ey%*'),(30,1294751748352,'j$2DvlBqk)Fw'), +(31,1294753902212,'C$N6OrEw8elz'),(32,1294758120598,'DCSVZw!rnxXq'), +(33,1294761769556,'OTS@QU8a6s5c'),(34,1294816845305,'IUE2stG0D3L5'), +(35,1294816966909,'Xd16yka.9nHe'),(36,1294817116302,'lOQHZpm%!8qb'), +(37,1294817374775,'^&pE3IhNf7ey'),(38,1294817538907,'oEn4#7C0Vhfp'), +(39,1294818482950,'bx54J*O0Va&?'),(40,1294819047024,'J%@a&1.qgdb?'), +(41,1294821826077,'C9kojr$L3Phz'),(42,1294825454458,'gG#BOnM80ZPi'), +(43,1294904129918,'F^!TrjM#zdvc'),(44,1294904254166,'Va&Tb)k0RvlM'), +(45,1294904414964,'dJjq0M6HvhR#'),(46,1294904505784,'nJmxg)ELqY(b'), +(47,1294904602835,'dhF#or$Vge!7'),(48,1294904684728,'?bIh5E3l!0em'), +(49,1294904877898,'Y*WflOdcxnk.'),(50,1294905002390,'*?H!lUgez5A.'), +(51,1294905096043,'wlEIY3n9uz!p'),(52,1294905404621,'T?qv3H6&hlQD'), +(53,1294905603922,'S@Bhys^Ti7bt'),(54,1294905788416,'KR?a5NVukz#l'), +(55,1294905993190,'A*&q4kWhED!o'),(56,1294906205254,'fT0%7z0DF6h*'), +(57,1294906319680,'LhzdW4?ivjR0'),(58,1294906424296,'h0KDlns%U*6T'), +(59,1294906623844,'b$CfB1noI6Ax'),(60,1294911258896,'#T1*LP!3$Oys'); +INSERT INTO t2 VALUES +(1,1,0,10209),(1,42480,1,10209),(1,61612,1,10209),(1,257545,1,10209), +(1,385332,1,10209),(1,1687999,1,10209),(3,1,0,10210),(3,617411,2,10210), +(4,11,0,14),(4,95149,1,10211),(4,607890,2,10211),(5,1,0,10212), +(6,1,0,10213),(6,93344,1,10213),(6,295578,1,10213),(6,295579,1,10213), +(6,295644,1,10213),(7,1,0,10214),(7,12,1,7),(7,688796,1,10214), +(7,1140433,1,10214),(7,1715227,1,10214),(8,1,0,10215),(8,74253,1,10215), +(8,93345,1,10215),(8,12,2,2),(9,1,0,10216),(9,93342,1,10216), +(9,122354,1,10216),(9,301499,2,10216),(10,11,0,5),(10,93343,1,10217), +(10,122355,1,10217),(10,123050,1,10217),(10,301500,2,10217),(11,1,0,10218), +(11,87852,1,10218),(11,605499,2,10218),(12,1,0,10219),(12,88024,1,10219), +(12,605892,2,10219),(13,1,0,10220); +INSERT INTO t3 VALUES +(1,1,300003),(1,117548,NULL),(2,1,300003),(2,117548,300006), +(3,1,300153),(3,117548,NULL),(4,1,300153),(4,117548,NULL), +(5,1,300153),(5,117548,NULL),(6,1,300182),(6,117548,NULL), +(7,1,300205),(7,117548,NULL),(8,1,300217),(8,117548,NULL), +(9,1,300290),(9,117548,NULL),(10,1,300290),(10,117548,NULL), +(11,1,300405),(11,117548,NULL),(12,1,300670),(12,117548,NULL), +(13,1,300670),(13,117548,NULL),(14,1,300006),(14,117548,NULL), +(15,1,300671),(15,117548,NULL),(16,1,300732),(16,117548,NULL); +INSERT INTO t4 VALUES +(300000,1),(300001,1),(300003,1),(300004,1), +(300005,1),(300005,688796),(300006,1),(300006,97697), +(300009,1),(300010,1),(300011,1),(300012,1),(300013,1), +(300014,1),(300015,1),(300016,1),(300017,1),(300018,1), +(300019,1),(300020,1),(300021,1),(300022,1),(300023,1), +(300024,1),(300025,1),(300026,1),(300027,1),(300028,1); +# This should have join order of t2,t3,t4,t1 +EXPLAIN EXTENDED SELECT * +FROM t1 INNER JOIN t2 ON t2.REV=t1.id +INNER JOIN t3 ON t3.id=t2.profile_id +INNER JOIN t4 ON t4.id=t3.person_id +WHERE t1.timestamp < 1294664900039 AND t1.timestamp > 1294644616416 AND +t2.REVTYPE=2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 42 100.00 Using where +1 SIMPLE t3 ref PRIMARY PRIMARY 4 test.t2.profile_id 1 100.00 Using where +1 SIMPLE t4 ref PRIMARY PRIMARY 4 test.t3.person_id 1 100.00 Using index +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.REV 1 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`timestamp` AS `timestamp`,`test`.`t1`.`modifiedBy` AS `modifiedBy`,`test`.`t2`.`id` AS `id`,`test`.`t2`.`REV` AS `REV`,`test`.`t2`.`REVTYPE` AS `REVTYPE`,`test`.`t2`.`profile_id` AS `profile_id`,`test`.`t3`.`id` AS `id`,`test`.`t3`.`REV` AS `REV`,`test`.`t3`.`person_id` AS `person_id`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`REV` AS `REV` from `test`.`t1` join `test`.`t2` join `test`.`t3` join `test`.`t4` where ((`test`.`t2`.`REVTYPE` = 2) and (`test`.`t4`.`id` = `test`.`t3`.`person_id`) and (`test`.`t3`.`id` = `test`.`t2`.`profile_id`) and (`test`.`t1`.`id` = `test`.`t2`.`REV`) and (`test`.`t1`.`timestamp` < 1294664900039) and (`test`.`t1`.`timestamp` > 1294644616416)) +SELECT * +FROM t1 INNER JOIN t2 ON t2.REV=t1.id +INNER JOIN t3 ON t3.id=t2.profile_id +INNER JOIN t4 ON t4.id=t3.person_id +WHERE t1.timestamp < 1294664900039 AND t1.timestamp > 1294644616416 AND +t2.REVTYPE=2; +id timestamp modifiedBy id REV REVTYPE profile_id id REV person_id id REV +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 1 300003 300003 1 +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 117548 300006 300006 1 +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 117548 300006 300006 97697 +# This should have join order of t2,t3,t4,t1 with the same plan as above +# because all RIGHT JOIN operations are converted into INNER JOIN +EXPLAIN EXTENDED SELECT * +FROM t1 RIGHT JOIN t2 ON t2.REV=t1.id +RIGHT JOIN t3 ON t3.id=t2.profile_id +RIGHT JOIN t4 ON t4.id=t3.person_id +WHERE t1.timestamp < 1294664900039 AND t1.timestamp > 1294644616416 +AND t2.REVTYPE=2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 42 100.00 Using where +1 SIMPLE t3 ref PRIMARY PRIMARY 4 test.t2.profile_id 1 100.00 Using where +1 SIMPLE t4 ref PRIMARY PRIMARY 4 test.t3.person_id 1 100.00 Using index +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.REV 1 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`timestamp` AS `timestamp`,`test`.`t1`.`modifiedBy` AS `modifiedBy`,`test`.`t2`.`id` AS `id`,`test`.`t2`.`REV` AS `REV`,`test`.`t2`.`REVTYPE` AS `REVTYPE`,`test`.`t2`.`profile_id` AS `profile_id`,`test`.`t3`.`id` AS `id`,`test`.`t3`.`REV` AS `REV`,`test`.`t3`.`person_id` AS `person_id`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`REV` AS `REV` from `test`.`t4` join `test`.`t3` join `test`.`t2` join `test`.`t1` where ((`test`.`t2`.`REVTYPE` = 2) and (`test`.`t1`.`id` = `test`.`t2`.`REV`) and (`test`.`t3`.`id` = `test`.`t2`.`profile_id`) and (`test`.`t4`.`id` = `test`.`t3`.`person_id`) and (`test`.`t1`.`timestamp` < 1294664900039) and (`test`.`t1`.`timestamp` > 1294644616416)) +SELECT * +FROM t1 RIGHT JOIN t2 ON t2.REV=t1.id +RIGHT JOIN t3 ON t3.id=t2.profile_id +RIGHT JOIN t4 ON t4.id=t3.person_id +WHERE t1.timestamp < 1294664900039 AND t1.timestamp > 1294644616416 +AND t2.REVTYPE=2; +id timestamp modifiedBy id REV REVTYPE profile_id id REV person_id id REV +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 1 300003 300003 1 +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 117548 300006 300006 1 +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 117548 300006 300006 97697 +DROP TABLE t1,t2,t3,t4; +# end of 10.1 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 faad87468c5..44250a96c05 100644 --- a/mysql-test/r/join_outer_jcl6.result +++ b/mysql-test/r/join_outer_jcl6.result @@ -2458,7 +2458,7 @@ t1.b1+'0' t2.b2 + '0' 0 0 1 1 DROP TABLE t1, t2; -set @join_cache_level= @save_join_cache_level; +set @@join_cache_level= @save_join_cache_level; # # MDEV-14779: using left join causes incorrect results with materialization and derived tables # @@ -2524,6 +2524,143 @@ ORDER BY tb1.i1; v2 DROP TABLE t1,t2; # end of 5.5 tests +# +# MDEV-19258: chained right joins all converted to inner joins +# +CREATE TABLE t1 ( +id int NOT NULL AUTO_INCREMENT, +timestamp bigint NOT NULL, +modifiedBy varchar(255) DEFAULT NULL, +PRIMARY KEY (id) +); +CREATE TABLE t2 ( +id int NOT NULL, +REV int NOT NULL, +REVTYPE tinyint DEFAULT NULL, +profile_id int DEFAULT NULL, +PRIMARY KEY (id,REV) +); +CREATE TABLE t3 ( +id int NOT NULL, +REV int NOT NULL, +person_id int DEFAULT NULL, +PRIMARY KEY (id,REV) +); +CREATE TABLE t4 ( +id int NOT NULL, +REV int NOT NULL, +PRIMARY KEY (id,REV) +); +INSERT INTO t1 VALUES +(1,1294391193890,'Cxqy$*9.kKeE'),(2,1294643906883,'rE4wqGV0gif@'), +(3,1294643927456,'L?3yt(%dY$Br'),(4,1294644343525,'WH&ObiZ$#2S4'), +(5,1294644616416,'YXnCbt?olUZ0'),(6,1294644954537,'8Npe4!(#lU@k'), +(7,1294645046659,'knc0GhXB1#ib'),(8,1294645183829,'w*oPpVfuS8^m'), +(9,1294645386701,'hwXR@3qVzrbU'),(10,1294645525982,'BeLW*Y9ndP0l'), +(11,1294645627723,'nTegib^)qZ$I'),(12,1294650860266,'u62C^Kzx3wH8'), +(13,1294657613745,'4&BkFjGa!qLg'),(14,1294660627161,')anpt312SCoh'), +(15,1294661023336,'LtJ2PX?*kTmx'),(16,1294662838066,'POGRr@?#ofpl'), +(17,1294663020989,'o.)1EOT2jnF7'),(18,1294663308065,'&TZ0F0LHE6.h'), +(19,1294664900039,'j)kSC%^In$9d'),(20,1294668904556,'97glN50)cAo.'), +(21,1294728056853,'lrKZxmw?I.Ek'),(22,1294728157174,'@P*SRg!pT.q?'), +(23,1294728327099,'W9gPrptF.)8n'),(24,1294728418481,'$q*c^sM&URd#'), +(25,1294728729620,'9*f4&bTPRtHo'),(26,1294728906014,')4VtTEnS7$oI'), +(27,1294732190003,'8dkNSPq2u3AQ'),(28,1294733205065,'SV2N6IoEf438'), +(29,1294741984927,'rBKj.0S^Ey%*'),(30,1294751748352,'j$2DvlBqk)Fw'), +(31,1294753902212,'C$N6OrEw8elz'),(32,1294758120598,'DCSVZw!rnxXq'), +(33,1294761769556,'OTS@QU8a6s5c'),(34,1294816845305,'IUE2stG0D3L5'), +(35,1294816966909,'Xd16yka.9nHe'),(36,1294817116302,'lOQHZpm%!8qb'), +(37,1294817374775,'^&pE3IhNf7ey'),(38,1294817538907,'oEn4#7C0Vhfp'), +(39,1294818482950,'bx54J*O0Va&?'),(40,1294819047024,'J%@a&1.qgdb?'), +(41,1294821826077,'C9kojr$L3Phz'),(42,1294825454458,'gG#BOnM80ZPi'), +(43,1294904129918,'F^!TrjM#zdvc'),(44,1294904254166,'Va&Tb)k0RvlM'), +(45,1294904414964,'dJjq0M6HvhR#'),(46,1294904505784,'nJmxg)ELqY(b'), +(47,1294904602835,'dhF#or$Vge!7'),(48,1294904684728,'?bIh5E3l!0em'), +(49,1294904877898,'Y*WflOdcxnk.'),(50,1294905002390,'*?H!lUgez5A.'), +(51,1294905096043,'wlEIY3n9uz!p'),(52,1294905404621,'T?qv3H6&hlQD'), +(53,1294905603922,'S@Bhys^Ti7bt'),(54,1294905788416,'KR?a5NVukz#l'), +(55,1294905993190,'A*&q4kWhED!o'),(56,1294906205254,'fT0%7z0DF6h*'), +(57,1294906319680,'LhzdW4?ivjR0'),(58,1294906424296,'h0KDlns%U*6T'), +(59,1294906623844,'b$CfB1noI6Ax'),(60,1294911258896,'#T1*LP!3$Oys'); +INSERT INTO t2 VALUES +(1,1,0,10209),(1,42480,1,10209),(1,61612,1,10209),(1,257545,1,10209), +(1,385332,1,10209),(1,1687999,1,10209),(3,1,0,10210),(3,617411,2,10210), +(4,11,0,14),(4,95149,1,10211),(4,607890,2,10211),(5,1,0,10212), +(6,1,0,10213),(6,93344,1,10213),(6,295578,1,10213),(6,295579,1,10213), +(6,295644,1,10213),(7,1,0,10214),(7,12,1,7),(7,688796,1,10214), +(7,1140433,1,10214),(7,1715227,1,10214),(8,1,0,10215),(8,74253,1,10215), +(8,93345,1,10215),(8,12,2,2),(9,1,0,10216),(9,93342,1,10216), +(9,122354,1,10216),(9,301499,2,10216),(10,11,0,5),(10,93343,1,10217), +(10,122355,1,10217),(10,123050,1,10217),(10,301500,2,10217),(11,1,0,10218), +(11,87852,1,10218),(11,605499,2,10218),(12,1,0,10219),(12,88024,1,10219), +(12,605892,2,10219),(13,1,0,10220); +INSERT INTO t3 VALUES +(1,1,300003),(1,117548,NULL),(2,1,300003),(2,117548,300006), +(3,1,300153),(3,117548,NULL),(4,1,300153),(4,117548,NULL), +(5,1,300153),(5,117548,NULL),(6,1,300182),(6,117548,NULL), +(7,1,300205),(7,117548,NULL),(8,1,300217),(8,117548,NULL), +(9,1,300290),(9,117548,NULL),(10,1,300290),(10,117548,NULL), +(11,1,300405),(11,117548,NULL),(12,1,300670),(12,117548,NULL), +(13,1,300670),(13,117548,NULL),(14,1,300006),(14,117548,NULL), +(15,1,300671),(15,117548,NULL),(16,1,300732),(16,117548,NULL); +INSERT INTO t4 VALUES +(300000,1),(300001,1),(300003,1),(300004,1), +(300005,1),(300005,688796),(300006,1),(300006,97697), +(300009,1),(300010,1),(300011,1),(300012,1),(300013,1), +(300014,1),(300015,1),(300016,1),(300017,1),(300018,1), +(300019,1),(300020,1),(300021,1),(300022,1),(300023,1), +(300024,1),(300025,1),(300026,1),(300027,1),(300028,1); +# This should have join order of t2,t3,t4,t1 +EXPLAIN EXTENDED SELECT * +FROM t1 INNER JOIN t2 ON t2.REV=t1.id +INNER JOIN t3 ON t3.id=t2.profile_id +INNER JOIN t4 ON t4.id=t3.person_id +WHERE t1.timestamp < 1294664900039 AND t1.timestamp > 1294644616416 AND +t2.REVTYPE=2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 42 100.00 Using where +1 SIMPLE t3 ref PRIMARY PRIMARY 4 test.t2.profile_id 1 100.00 Using where +1 SIMPLE t4 ref PRIMARY PRIMARY 4 test.t3.person_id 1 100.00 Using index +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.REV 1 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`timestamp` AS `timestamp`,`test`.`t1`.`modifiedBy` AS `modifiedBy`,`test`.`t2`.`id` AS `id`,`test`.`t2`.`REV` AS `REV`,`test`.`t2`.`REVTYPE` AS `REVTYPE`,`test`.`t2`.`profile_id` AS `profile_id`,`test`.`t3`.`id` AS `id`,`test`.`t3`.`REV` AS `REV`,`test`.`t3`.`person_id` AS `person_id`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`REV` AS `REV` from `test`.`t1` join `test`.`t2` join `test`.`t3` join `test`.`t4` where ((`test`.`t2`.`REVTYPE` = 2) and (`test`.`t4`.`id` = `test`.`t3`.`person_id`) and (`test`.`t3`.`id` = `test`.`t2`.`profile_id`) and (`test`.`t1`.`id` = `test`.`t2`.`REV`) and (`test`.`t1`.`timestamp` < 1294664900039) and (`test`.`t1`.`timestamp` > 1294644616416)) +SELECT * +FROM t1 INNER JOIN t2 ON t2.REV=t1.id +INNER JOIN t3 ON t3.id=t2.profile_id +INNER JOIN t4 ON t4.id=t3.person_id +WHERE t1.timestamp < 1294664900039 AND t1.timestamp > 1294644616416 AND +t2.REVTYPE=2; +id timestamp modifiedBy id REV REVTYPE profile_id id REV person_id id REV +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 1 300003 300003 1 +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 117548 300006 300006 1 +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 117548 300006 300006 97697 +# This should have join order of t2,t3,t4,t1 with the same plan as above +# because all RIGHT JOIN operations are converted into INNER JOIN +EXPLAIN EXTENDED SELECT * +FROM t1 RIGHT JOIN t2 ON t2.REV=t1.id +RIGHT JOIN t3 ON t3.id=t2.profile_id +RIGHT JOIN t4 ON t4.id=t3.person_id +WHERE t1.timestamp < 1294664900039 AND t1.timestamp > 1294644616416 +AND t2.REVTYPE=2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 42 100.00 Using where +1 SIMPLE t3 ref PRIMARY PRIMARY 4 test.t2.profile_id 1 100.00 Using where +1 SIMPLE t4 ref PRIMARY PRIMARY 4 test.t3.person_id 1 100.00 Using index +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.REV 1 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`timestamp` AS `timestamp`,`test`.`t1`.`modifiedBy` AS `modifiedBy`,`test`.`t2`.`id` AS `id`,`test`.`t2`.`REV` AS `REV`,`test`.`t2`.`REVTYPE` AS `REVTYPE`,`test`.`t2`.`profile_id` AS `profile_id`,`test`.`t3`.`id` AS `id`,`test`.`t3`.`REV` AS `REV`,`test`.`t3`.`person_id` AS `person_id`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`REV` AS `REV` from `test`.`t4` join `test`.`t3` join `test`.`t2` join `test`.`t1` where ((`test`.`t2`.`REVTYPE` = 2) and (`test`.`t1`.`id` = `test`.`t2`.`REV`) and (`test`.`t3`.`id` = `test`.`t2`.`profile_id`) and (`test`.`t4`.`id` = `test`.`t3`.`person_id`) and (`test`.`t1`.`timestamp` < 1294664900039) and (`test`.`t1`.`timestamp` > 1294644616416)) +SELECT * +FROM t1 RIGHT JOIN t2 ON t2.REV=t1.id +RIGHT JOIN t3 ON t3.id=t2.profile_id +RIGHT JOIN t4 ON t4.id=t3.person_id +WHERE t1.timestamp < 1294664900039 AND t1.timestamp > 1294644616416 +AND t2.REVTYPE=2; +id timestamp modifiedBy id REV REVTYPE profile_id id REV person_id id REV +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 1 300003 300003 1 +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 117548 300006 300006 1 +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 117548 300006 300006 97697 +DROP TABLE t1,t2,t3,t4; +# end of 10.1 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 6d20c089bd9..19cc5b8049a 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -1976,7 +1976,7 @@ set @save_join_cache_level= @@join_cache_level; SET @@join_cache_level = 3; SELECT t1.b1+'0' , t2.b2 + '0' FROM t1 LEFT JOIN t2 ON b1 = b2; DROP TABLE t1, t2; -set @join_cache_level= @save_join_cache_level; +set @@join_cache_level= @save_join_cache_level; --echo # --echo # MDEV-14779: using left join causes incorrect results with materialization and derived tables @@ -2042,4 +2042,129 @@ DROP TABLE t1,t2; --echo # end of 5.5 tests +--echo # +--echo # MDEV-19258: chained right joins all converted to inner joins +--echo # + + CREATE TABLE t1 ( + id int NOT NULL AUTO_INCREMENT, + timestamp bigint NOT NULL, + modifiedBy varchar(255) DEFAULT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE t2 ( + id int NOT NULL, + REV int NOT NULL, + REVTYPE tinyint DEFAULT NULL, + profile_id int DEFAULT NULL, + PRIMARY KEY (id,REV) +); + +CREATE TABLE t3 ( + id int NOT NULL, + REV int NOT NULL, + person_id int DEFAULT NULL, + PRIMARY KEY (id,REV) +); + +CREATE TABLE t4 ( + id int NOT NULL, + REV int NOT NULL, + PRIMARY KEY (id,REV) +); + +INSERT INTO t1 VALUES +(1,1294391193890,'Cxqy$*9.kKeE'),(2,1294643906883,'rE4wqGV0gif@'), +(3,1294643927456,'L?3yt(%dY$Br'),(4,1294644343525,'WH&ObiZ$#2S4'), +(5,1294644616416,'YXnCbt?olUZ0'),(6,1294644954537,'8Npe4!(#lU@k'), +(7,1294645046659,'knc0GhXB1#ib'),(8,1294645183829,'w*oPpVfuS8^m'), +(9,1294645386701,'hwXR@3qVzrbU'),(10,1294645525982,'BeLW*Y9ndP0l'), +(11,1294645627723,'nTegib^)qZ$I'),(12,1294650860266,'u62C^Kzx3wH8'), +(13,1294657613745,'4&BkFjGa!qLg'),(14,1294660627161,')anpt312SCoh'), +(15,1294661023336,'LtJ2PX?*kTmx'),(16,1294662838066,'POGRr@?#ofpl'), +(17,1294663020989,'o.)1EOT2jnF7'),(18,1294663308065,'&TZ0F0LHE6.h'), +(19,1294664900039,'j)kSC%^In$9d'),(20,1294668904556,'97glN50)cAo.'), +(21,1294728056853,'lrKZxmw?I.Ek'),(22,1294728157174,'@P*SRg!pT.q?'), +(23,1294728327099,'W9gPrptF.)8n'),(24,1294728418481,'$q*c^sM&URd#'), +(25,1294728729620,'9*f4&bTPRtHo'),(26,1294728906014,')4VtTEnS7$oI'), +(27,1294732190003,'8dkNSPq2u3AQ'),(28,1294733205065,'SV2N6IoEf438'), +(29,1294741984927,'rBKj.0S^Ey%*'),(30,1294751748352,'j$2DvlBqk)Fw'), +(31,1294753902212,'C$N6OrEw8elz'),(32,1294758120598,'DCSVZw!rnxXq'), +(33,1294761769556,'OTS@QU8a6s5c'),(34,1294816845305,'IUE2stG0D3L5'), +(35,1294816966909,'Xd16yka.9nHe'),(36,1294817116302,'lOQHZpm%!8qb'), +(37,1294817374775,'^&pE3IhNf7ey'),(38,1294817538907,'oEn4#7C0Vhfp'), +(39,1294818482950,'bx54J*O0Va&?'),(40,1294819047024,'J%@a&1.qgdb?'), +(41,1294821826077,'C9kojr$L3Phz'),(42,1294825454458,'gG#BOnM80ZPi'), +(43,1294904129918,'F^!TrjM#zdvc'),(44,1294904254166,'Va&Tb)k0RvlM'), +(45,1294904414964,'dJjq0M6HvhR#'),(46,1294904505784,'nJmxg)ELqY(b'), +(47,1294904602835,'dhF#or$Vge!7'),(48,1294904684728,'?bIh5E3l!0em'), +(49,1294904877898,'Y*WflOdcxnk.'),(50,1294905002390,'*?H!lUgez5A.'), +(51,1294905096043,'wlEIY3n9uz!p'),(52,1294905404621,'T?qv3H6&hlQD'), +(53,1294905603922,'S@Bhys^Ti7bt'),(54,1294905788416,'KR?a5NVukz#l'), +(55,1294905993190,'A*&q4kWhED!o'),(56,1294906205254,'fT0%7z0DF6h*'), +(57,1294906319680,'LhzdW4?ivjR0'),(58,1294906424296,'h0KDlns%U*6T'), +(59,1294906623844,'b$CfB1noI6Ax'),(60,1294911258896,'#T1*LP!3$Oys'); + + +INSERT INTO t2 VALUES +(1,1,0,10209),(1,42480,1,10209),(1,61612,1,10209),(1,257545,1,10209), +(1,385332,1,10209),(1,1687999,1,10209),(3,1,0,10210),(3,617411,2,10210), +(4,11,0,14),(4,95149,1,10211),(4,607890,2,10211),(5,1,0,10212), +(6,1,0,10213),(6,93344,1,10213),(6,295578,1,10213),(6,295579,1,10213), +(6,295644,1,10213),(7,1,0,10214),(7,12,1,7),(7,688796,1,10214), +(7,1140433,1,10214),(7,1715227,1,10214),(8,1,0,10215),(8,74253,1,10215), +(8,93345,1,10215),(8,12,2,2),(9,1,0,10216),(9,93342,1,10216), +(9,122354,1,10216),(9,301499,2,10216),(10,11,0,5),(10,93343,1,10217), +(10,122355,1,10217),(10,123050,1,10217),(10,301500,2,10217),(11,1,0,10218), +(11,87852,1,10218),(11,605499,2,10218),(12,1,0,10219),(12,88024,1,10219), +(12,605892,2,10219),(13,1,0,10220); + +INSERT INTO t3 VALUES +(1,1,300003),(1,117548,NULL),(2,1,300003),(2,117548,300006), +(3,1,300153),(3,117548,NULL),(4,1,300153),(4,117548,NULL), +(5,1,300153),(5,117548,NULL),(6,1,300182),(6,117548,NULL), +(7,1,300205),(7,117548,NULL),(8,1,300217),(8,117548,NULL), +(9,1,300290),(9,117548,NULL),(10,1,300290),(10,117548,NULL), +(11,1,300405),(11,117548,NULL),(12,1,300670),(12,117548,NULL), +(13,1,300670),(13,117548,NULL),(14,1,300006),(14,117548,NULL), +(15,1,300671),(15,117548,NULL),(16,1,300732),(16,117548,NULL); + +INSERT INTO t4 VALUES +(300000,1),(300001,1),(300003,1),(300004,1), +(300005,1),(300005,688796),(300006,1),(300006,97697), +(300009,1),(300010,1),(300011,1),(300012,1),(300013,1), +(300014,1),(300015,1),(300016,1),(300017,1),(300018,1), +(300019,1),(300020,1),(300021,1),(300022,1),(300023,1), +(300024,1),(300025,1),(300026,1),(300027,1),(300028,1); + +let $q1= +SELECT * +FROM t1 INNER JOIN t2 ON t2.REV=t1.id + INNER JOIN t3 ON t3.id=t2.profile_id + INNER JOIN t4 ON t4.id=t3.person_id +WHERE t1.timestamp < 1294664900039 AND t1.timestamp > 1294644616416 AND + t2.REVTYPE=2; + +--echo # This should have join order of t2,t3,t4,t1 +eval EXPLAIN EXTENDED $q1; +eval $q1; + +let $q2= +SELECT * +FROM t1 RIGHT JOIN t2 ON t2.REV=t1.id + RIGHT JOIN t3 ON t3.id=t2.profile_id + RIGHT JOIN t4 ON t4.id=t3.person_id +WHERE t1.timestamp < 1294664900039 AND t1.timestamp > 1294644616416 + AND t2.REVTYPE=2; + +--echo # This should have join order of t2,t3,t4,t1 with the same plan as above +--echo # because all RIGHT JOIN operations are converted into INNER JOIN +eval EXPLAIN EXTENDED $q2; +eval $q2; + +DROP TABLE t1,t2,t3,t4; + +--echo # end of 10.1 tests + SET optimizer_switch=@save_optimizer_switch; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7426540c8d7..02f1623a878 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14635,8 +14635,20 @@ 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->sj_subq_pred ? - table->embedding->dep_tables : 0; + { + table->dep_tables= 0; + TABLE_LIST *embedding= table->embedding; + while (embedding) + { + if (embedding->nested_join->join_list.head()->outer_join) + { + if (!embedding->sj_subq_pred) + table->dep_tables= embedding->dep_tables; + break; + } + embedding= embedding->embedding; + } + } if (table->on_expr) { /* Add ON expression to the WHERE or upper-level ON condition. */ From c8740407297f8bf0339b9e907adccdd43133b7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 24 May 2019 10:22:34 +0300 Subject: [PATCH 21/43] Declare INFORMATION_SCHEMA.INNODB_SYS_VIRTUAL stable The INFORMATION_SCHEMA plugin INNODB_SYS_VIRTUAL, which was introduced in MariaDB 10.2.2 along with the dictionary table SYS_VIRTUAL, is similar to other, much older and already stable plugins that provide access to InnoDB dictionary tables. --- storage/innobase/handler/i_s.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 8eb6b1d3427..fae634630fd 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -7227,7 +7227,7 @@ struct st_maria_plugin i_s_innodb_sys_virtual = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), }; /** SYS_FIELDS ***************************************************/ /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_FIELDS */ From bff9b8026bd69f44d62d0eb33364d4a1ca1788f4 Mon Sep 17 00:00:00 2001 From: Vlad Lesin Date: Thu, 16 May 2019 11:04:39 +0300 Subject: [PATCH 22/43] MDEV-14192: mariabackup.incremental_backup failed in buildbot with Failing assertion: byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0 In some cases it's possible that InnoDB redo log file header is re-written so, that checkpoint lsn and checkpoint lsn offset are updated, but checkpoint number stays the same. The fix is to re-read redo log header if at least one of those three parametes is changed at backup start. Repeat the logic of log_group_checkpoint() on choosing InnoDB checkpoint info field on backup start. This does not influence backup correctness, but simplifies bugs analysis. --- extra/mariabackup/xtrabackup.cc | 62 ++++++++++++++++----------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index e7d60c22145..3d5e8a690a4 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -4187,9 +4187,11 @@ reread_log_header: log_group_header_read(&log_sys->log, max_cp_field); - if (checkpoint_no_start != mach_read_from_8(buf + LOG_CHECKPOINT_NO)) { + if (checkpoint_no_start != mach_read_from_8(buf + LOG_CHECKPOINT_NO) + || checkpoint_lsn_start != mach_read_from_8(buf + LOG_CHECKPOINT_LSN) + || log_sys->log.lsn_offset + != mach_read_from_8(buf + LOG_CHECKPOINT_OFFSET)) goto reread_log_header; - } log_mutex_exit(); @@ -4209,43 +4211,39 @@ reread_log_header: } /* label it */ - byte MY_ALIGNED(OS_FILE_LOG_BLOCK_SIZE) log_hdr[OS_FILE_LOG_BLOCK_SIZE]; - memset(log_hdr, 0, sizeof log_hdr); - mach_write_to_4(LOG_HEADER_FORMAT + log_hdr, log_sys->log.format); - mach_write_to_4(LOG_HEADER_SUBFORMAT + log_hdr, - log_sys->log.subformat); - mach_write_to_8(LOG_HEADER_START_LSN + log_hdr, checkpoint_lsn_start); - strcpy(reinterpret_cast(LOG_HEADER_CREATOR + log_hdr), - "Backup " MYSQL_SERVER_VERSION); - log_block_set_checksum(log_hdr, - log_block_calc_checksum_crc32(log_hdr)); + byte MY_ALIGNED(OS_FILE_LOG_BLOCK_SIZE) log_hdr_buf[LOG_FILE_HDR_SIZE]; + memset(log_hdr_buf, 0, sizeof log_hdr_buf); - /* Write the log header. */ - if (ds_write(dst_log_file, log_hdr, sizeof log_hdr)) { - log_write_fail: - msg("error: write to logfile failed"); - goto fail; - } - /* Adjust the checkpoint page. */ - memcpy(log_hdr, buf, OS_FILE_LOG_BLOCK_SIZE); - mach_write_to_8(log_hdr + LOG_CHECKPOINT_OFFSET, - (checkpoint_lsn_start & (OS_FILE_LOG_BLOCK_SIZE - 1)) - | LOG_FILE_HDR_SIZE); + byte *log_hdr_field = log_hdr_buf; + mach_write_to_4(LOG_HEADER_FORMAT + log_hdr_field, log_sys->log.format); + mach_write_to_4(LOG_HEADER_SUBFORMAT + log_hdr_field, log_sys->log.subformat); + mach_write_to_8(LOG_HEADER_START_LSN + log_hdr_field, checkpoint_lsn_start); + strcpy(reinterpret_cast(LOG_HEADER_CREATOR + log_hdr_field), + "Backup " MYSQL_SERVER_VERSION); + log_block_set_checksum(log_hdr_field, + log_block_calc_checksum_crc32(log_hdr_field)); + + /* copied from log_group_checkpoint() */ + log_hdr_field += + (log_sys->next_checkpoint_no & 1) ? LOG_CHECKPOINT_2 : LOG_CHECKPOINT_1; /* The least significant bits of LOG_CHECKPOINT_OFFSET must be stored correctly in the copy of the ib_logfile. The most significant bits, which identify the start offset of the log block in the file, we did choose freely, as LOG_FILE_HDR_SIZE. */ ut_ad(!((log_sys->log.lsn ^ checkpoint_lsn_start) & (OS_FILE_LOG_BLOCK_SIZE - 1))); - log_block_set_checksum(log_hdr, - log_block_calc_checksum_crc32(log_hdr)); - /* Write checkpoint page 1 and two empty log pages before the - payload. */ - if (ds_write(dst_log_file, log_hdr, OS_FILE_LOG_BLOCK_SIZE) - || !memset(log_hdr, 0, sizeof log_hdr) - || ds_write(dst_log_file, log_hdr, sizeof log_hdr) - || ds_write(dst_log_file, log_hdr, sizeof log_hdr)) { - goto log_write_fail; + /* Adjust the checkpoint page. */ + memcpy(log_hdr_field, log_sys->checkpoint_buf, OS_FILE_LOG_BLOCK_SIZE); + mach_write_to_8(log_hdr_field + LOG_CHECKPOINT_OFFSET, + (checkpoint_lsn_start & (OS_FILE_LOG_BLOCK_SIZE - 1)) + | LOG_FILE_HDR_SIZE); + log_block_set_checksum(log_hdr_field, + log_block_calc_checksum_crc32(log_hdr_field)); + + /* Write log header*/ + if (ds_write(dst_log_file, log_hdr_buf, sizeof(log_hdr_buf))) { + msg("error: write to logfile failed"); + goto fail; } log_copying_running = true; From aaf53ea0b68efde4a90cabbbcaf9ca41c1fbf62f Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Thu, 23 May 2019 21:12:14 +0300 Subject: [PATCH 23/43] MDEV-17948 Assertion `thd_killed(thd) || !m_active_tranxs .. Simulation of a big-sized event in rpl.rpl_semi_sync_skip_repl did not clean up after itself so screw the last binlog event offset which could jump backwards. The test is refined to rotate a binlog file with simulation and use the next one for logics of the test incl master-slave synchonization. --- .../rpl/r/rpl_semi_sync_skip_repl.result | 13 +++++---- .../suite/rpl/t/rpl_semi_sync_skip_repl.test | 29 +++++++++++-------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_skip_repl.result b/mysql-test/suite/rpl/r/rpl_semi_sync_skip_repl.result index 4762ac8dd07..272263bc288 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_skip_repl.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_skip_repl.result @@ -5,19 +5,22 @@ SET @@GLOBAL.rpl_semi_sync_master_enabled = 1; SET @@GLOBAL.rpl_semi_sync_master_timeout=100; include/stop_slave.inc SET @@GLOBAL.replicate_events_marked_for_skip=FILTER_ON_MASTER; -SET @@GLOBAL. rpl_semi_sync_slave_enabled = 1; +SET @@GLOBAL.rpl_semi_sync_slave_enabled = 1; include/start_slave.inc CREATE TABLE t1 (a INT) ENGINE=innodb; -SET @@GLOBAL.debug_dbug= "d,dbug_master_binlog_over_2GB"; +SET @@GLOBAL.debug_dbug="d,dbug_master_binlog_over_2GB"; SET @@SESSION.skip_replication=1; INSERT INTO t1 SET a=1; SET @@SESSION.skip_replication=0; INSERT INTO t1 SET a=0; SET @@GLOBAL.debug_dbug=""; -SET @@GLOBAL. rpl_semi_sync_master_timeout = 10000; -SET @@GLOBAL. rpl_semi_sync_master_enabled = 0; +FLUSH LOGS; +SET @@GLOBAL.debug_dbug=@@GLOBAL.debug_dbug; +SET @@GLOBAL.rpl_semi_sync_master_timeout = 10000; +SET @@GLOBAL.rpl_semi_sync_master_enabled = 0; DROP TABLE t1; include/stop_slave.inc -SET @@GLOBAL. rpl_semi_sync_slave_enabled = 0; +SET @@GLOBAL.rpl_semi_sync_slave_enabled = 0; SET @@GLOBAL.replicate_events_marked_for_skip = REPLICATE; +include/start_slave.inc include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_skip_repl.test b/mysql-test/suite/rpl/t/rpl_semi_sync_skip_repl.test index 2f6da18067c..8c00bae06cd 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_skip_repl.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_skip_repl.test @@ -16,29 +16,34 @@ source include/master-slave.inc; # Suppress warnings that might be generated during the test call mtr.add_suppression("Timeout waiting for reply of binlog"); ---let $sav_enabled_master=`SELECT @@GLOBAL.rpl_semi_sync_master_enabled ` ---let $sav_timeout_master=`SELECT @@GLOBAL.rpl_semi_sync_master_timeout ` +--let $sav_enabled_master=`SELECT @@GLOBAL.rpl_semi_sync_master_enabled` +--let $sav_timeout_master=`SELECT @@GLOBAL.rpl_semi_sync_master_timeout` SET @@GLOBAL.rpl_semi_sync_master_enabled = 1; SET @@GLOBAL.rpl_semi_sync_master_timeout=100; --connection slave +--let $sav_skip_marked_slave=`SELECT @@GLOBAL.replicate_events_marked_for_skip` +--let $sav_enabled_slave=`SELECT @@GLOBAL.rpl_semi_sync_slave_enabled` source include/stop_slave.inc; ---let $sav_skip_marked_slave=`SELECT @@GLOBAL.replicate_events_marked_for_skip ` SET @@GLOBAL.replicate_events_marked_for_skip=FILTER_ON_MASTER; ---let $sav_enabled_slave=`SELECT @@GLOBAL.rpl_semi_sync_slave_enabled ` -SET @@GLOBAL. rpl_semi_sync_slave_enabled = 1; - +SET @@GLOBAL.rpl_semi_sync_slave_enabled = 1; source include/start_slave.inc; --connection master CREATE TABLE t1 (a INT) ENGINE=innodb; # Make the following events as if they offset over 2GB from the beginning of binlog -SET @@GLOBAL.debug_dbug= "d,dbug_master_binlog_over_2GB"; +--let $sav_debug_dbug=@@GLOBAL.debug_dbug +SET @@GLOBAL.debug_dbug="d,dbug_master_binlog_over_2GB"; SET @@SESSION.skip_replication=1; INSERT INTO t1 SET a=1; SET @@SESSION.skip_replication=0; INSERT INTO t1 SET a=0; +SET @@GLOBAL.debug_dbug=""; + +# The current binlog is inconsistent so let's rotate it away +# to clean up simulation results. +FLUSH LOGS; --sync_slave_with_master @@ -46,17 +51,17 @@ INSERT INTO t1 SET a=0; # Clean up # --connection master -SET @@GLOBAL.debug_dbug=""; ---eval SET @@GLOBAL. rpl_semi_sync_master_timeout = $sav_timeout_master ---eval SET @@GLOBAL. rpl_semi_sync_master_enabled = $sav_enabled_master +--eval SET @@GLOBAL.debug_dbug=$sav_debug_dbug +--eval SET @@GLOBAL.rpl_semi_sync_master_timeout = $sav_timeout_master +--eval SET @@GLOBAL.rpl_semi_sync_master_enabled = $sav_enabled_master --connection master DROP TABLE t1; --sync_slave_with_master source include/stop_slave.inc; ---eval SET @@GLOBAL. rpl_semi_sync_slave_enabled = $sav_enabled_slave +--eval SET @@GLOBAL.rpl_semi_sync_slave_enabled = $sav_enabled_slave --eval SET @@GLOBAL.replicate_events_marked_for_skip = $sav_skip_marked_slave ---let $rpl_only_running_threads= 1 +source include/start_slave.inc; --source include/rpl_end.inc From 617d34ae8039d3c943a8564d1a7733fcc395a595 Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 27 May 2019 16:30:17 +0300 Subject: [PATCH 24/43] Fixed wrong reset of join_cache_level in join_outer*test --- mysql-test/main/join_outer.result | 3 +- mysql-test/main/join_outer.test | 3 +- mysql-test/main/join_outer_jcl6.result | 49 +++++++++++++------------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/mysql-test/main/join_outer.result b/mysql-test/main/join_outer.result index 6b671a0759f..ecc5d603c73 100644 --- a/mysql-test/main/join_outer.result +++ b/mysql-test/main/join_outer.result @@ -2000,6 +2000,7 @@ INSERT INTO t2 VALUES CREATE TABLE t3 ( a int, b int NOT NULL , PRIMARY KEY (b)) ; INSERT INTO t3 VALUES (0,6),(0,7),(0,8),(2,9),(0,10),(2,21),(0,22),(2,23),(2,24),(2,25); +set @save_join_cache_level= @@join_cache_level; SET SESSION join_cache_level=4; EXPLAIN EXTENDED SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b; @@ -2018,7 +2019,7 @@ EXECUTE stmt; b b a b 10 10 0 10 DEALLOCATE PREPARE stmt; -SET SESSION join_cache_level=default; +SET SESSION join_cache_level=@save_join_cache_level; DROP TABLE t1,t2,t3; # # LP bug #943543: LEFT JOIN converted to JOIN with diff --git a/mysql-test/main/join_outer.test b/mysql-test/main/join_outer.test index 82127397bee..d80e283215d 100644 --- a/mysql-test/main/join_outer.test +++ b/mysql-test/main/join_outer.test @@ -1575,6 +1575,7 @@ CREATE TABLE t3 ( a int, b int NOT NULL , PRIMARY KEY (b)) ; INSERT INTO t3 VALUES (0,6),(0,7),(0,8),(2,9),(0,10),(2,21),(0,22),(2,23),(2,24),(2,25); +set @save_join_cache_level= @@join_cache_level; SET SESSION join_cache_level=4; EXPLAIN EXTENDED @@ -1588,7 +1589,7 @@ EXECUTE stmt; DEALLOCATE PREPARE stmt; -SET SESSION join_cache_level=default; +SET SESSION join_cache_level=@save_join_cache_level; DROP TABLE t1,t2,t3; diff --git a/mysql-test/main/join_outer_jcl6.result b/mysql-test/main/join_outer_jcl6.result index f46f3e2df21..c6e08c2ec70 100644 --- a/mysql-test/main/join_outer_jcl6.result +++ b/mysql-test/main/join_outer_jcl6.result @@ -2011,6 +2011,7 @@ INSERT INTO t2 VALUES CREATE TABLE t3 ( a int, b int NOT NULL , PRIMARY KEY (b)) ; INSERT INTO t3 VALUES (0,6),(0,7),(0,8),(2,9),(0,10),(2,21),(0,22),(2,23),(2,24),(2,25); +set @save_join_cache_level= @@join_cache_level; SET SESSION join_cache_level=4; EXPLAIN EXTENDED SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b; @@ -2029,7 +2030,7 @@ EXECUTE stmt; b b a b 10 10 0 10 DEALLOCATE PREPARE stmt; -SET SESSION join_cache_level=default; +SET SESSION join_cache_level=@save_join_cache_level; DROP TABLE t1,t2,t3; # # LP bug #943543: LEFT JOIN converted to JOIN with @@ -2086,7 +2087,7 @@ WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 ORDER BY t1.b; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ref idx idx 4 const 2 100.00 Using where -1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00 +1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan Warnings: Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where `test`.`t2`.`c` = `test`.`t1`.`a` and `test`.`t1`.`b` = 5 order by `test`.`t1`.`b` SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a @@ -2094,16 +2095,16 @@ WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 ORDER BY t1.b; b c d 5 8 88 -5 8 81 5 8 88 5 8 81 +5 8 81 EXPLAIN EXTENDED SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 ORDER BY t1.b; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ref PRIMARY,idx idx 4 const 2 100.00 Using where -1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00 +1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan Warnings: Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where `test`.`t2`.`c` = `test`.`t1`.`a` and `test`.`t1`.`b` = 5 order by `test`.`t1`.`b` SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a @@ -2111,9 +2112,9 @@ WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 ORDER BY t1.b; b c d 5 8 88 -5 8 81 5 8 88 5 8 81 +5 8 81 DROP TABLE t1,t2; # # Bug mdev-4336: LEFT JOIN with disjunctive @@ -2229,10 +2230,10 @@ SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON i2 = i3 ON i1 = i3 WHERE d3 IS NULL; 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) -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t2 hash_ALL NULL #hash#$hj 5 test.t1.i1 2 100.00 Using where; Using join buffer (flat, BNLH join) +1 SIMPLE t3 hash_ALL NULL #hash#$hj 5 test.t1.i1 2 100.00 Using where; Using join buffer (incremental, BNLH join) Warnings: -Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t2`.`i2` AS `i2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`d3` AS `d3` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(`test`.`t2`.`i2` = `test`.`t1`.`i1` and `test`.`t3`.`i3` = `test`.`t1`.`i1`) where `test`.`t3`.`d3` = 0 or `test`.`t3`.`d3` is null +Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t2`.`i2` AS `i2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`d3` AS `d3` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(`test`.`t2`.`i2` = `test`.`t1`.`i1` and `test`.`t3`.`i3` = `test`.`t1`.`i1` and `test`.`t1`.`i1` is not null and `test`.`t1`.`i1` is not null) where `test`.`t3`.`d3` = 0 or `test`.`t3`.`d3` is null DROP TABLE t1,t2,t3; # # Bug mdev-6705: wrong on expression after constant row substitution @@ -2250,9 +2251,9 @@ WHERE b IN (1,2,3) OR b = d; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t3 hash_ALL NULL #hash#$hj 5 const 2 100.00 Using where; Using join buffer (flat, BNLH join) Warnings: -Note 1003 select 10 AS `a`,8 AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t2` left join `test`.`t3` on(`test`.`t3`.`d` = 10) where `test`.`t2`.`c` = 8 and `test`.`t3`.`d` = 8 +Note 1003 select 10 AS `a`,8 AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t2` left join `test`.`t3` on(`test`.`t3`.`d` = 10 and 10 is not null) where `test`.`t2`.`c` = 8 and `test`.`t3`.`d` = 8 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 @@ -2279,11 +2280,11 @@ id select_type table type possible_keys key key_len ref rows Extra explain select * from t1 left join t2 on t2.b is null; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 9 -1 SIMPLE t2 ref b b 5 const 780 Using where +1 SIMPLE t2 ref b b 5 const 780 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan explain select * from t1 left join t2 on t2.c is null; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 9 -1 SIMPLE t2 ref c c 5 const 393 Using where +1 SIMPLE t2 ref c c 5 const 393 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan drop table t1,t2; # # MDEV-10006: optimizer doesn't convert outer join to inner on views with WHERE clause @@ -2325,8 +2326,8 @@ LEFT JOIN t3 on t2.i2 = t3.i3 WHERE v3 = 4; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 ref PRIMARY,v3 v3 5 const 1 100.00 -1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t3.i3 1 100.00 -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t3.i3 1 100.00 +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t3.i3 1 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t3.i3 1 100.00 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan Warnings: Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t1`.`v1` AS `v1`,`test`.`t2`.`i2` AS `i2`,`test`.`t2`.`v2` AS `v2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`v3` AS `v3` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t3`.`v3` = 4 and `test`.`t1`.`i1` = `test`.`t3`.`i3` and `test`.`t2`.`i2` = `test`.`t3`.`i3` # This should have the same join order like the query above: @@ -2343,8 +2344,8 @@ AND 1 = 1 WHERE v3 = 4; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 ref PRIMARY,v3 v3 5 const 1 100.00 -1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t3.i3 1 100.00 -1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t3.i3 1 100.00 +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t3.i3 1 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t3.i3 1 100.00 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan Warnings: Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t1`.`v1` AS `v1`,`test`.`t2`.`i2` AS `i2`,`test`.`t2`.`v2` AS `v2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`v3` AS `v3` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t3`.`v3` = 4 and `test`.`t1`.`i1` = `test`.`t3`.`i3` and `test`.`t2`.`i2` = `test`.`t3`.`i3` drop table t1,t2,t3; @@ -2367,9 +2368,9 @@ 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) +1 SIMPLE t2 hash_ALL NULL #hash#$hj 5 test.t1.x 2 100.00 Using where; Using join buffer (flat, BNLH 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 +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` and `test`.`t1`.`x` is not null) 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 @@ -2383,9 +2384,9 @@ 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) +1 SIMPLE t2 hash_ALL NULL #hash#$hj 5 test.t1.x 2 100.00 Using where; Using join buffer (flat, BNLH 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 +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` and `test`.`t1`.`x` is not null) where `f`(`test`.`t2`.`x`,0) = 0 drop function f; drop table t; CREATE TABLE t1 ( @@ -2423,9 +2424,9 @@ 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) +1 SIMPLE t2 hash_ALL NULL #hash#$hj 17 test.t1.col1 2 100.00 Using where; Using join buffer (flat, BNLH 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 +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` and `test`.`t1`.`col1` is not null) 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; @@ -2437,9 +2438,9 @@ 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) +1 SIMPLE t2 hash_ALL NULL #hash#$hj 17 test.t1.col1 2 100.00 Using where; Using join buffer (flat, BNLH 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 +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` and `test`.`t1`.`col1` is not null) where `f1`(`test`.`t2`.`col3`,0) = 0 DROP FUNCTION f1; DROP TABLE t1,t2; # From 35522455e0c0d680a68609b2bb82e4321afce32f Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 22 Nov 2018 14:51:31 +1100 Subject: [PATCH 25/43] RocksDB: use crc32c optimised version for POWER --- storage/rocksdb/build_rocksdb.cmake | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake index 93f5fa2d1f3..eb7a7fed6c1 100644 --- a/storage/rocksdb/build_rocksdb.cmake +++ b/storage/rocksdb/build_rocksdb.cmake @@ -112,6 +112,24 @@ if(NOT WIN32) add_definitions(-DROCKSDB_PLATFORM_POSIX -DROCKSDB_LIB_IO_POSIX) endif() +include(CheckCCompilerFlag) +# ppc64 or ppc64le +if(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64") + CHECK_C_COMPILER_FLAG("-maltivec" HAS_ALTIVEC) + if(HAS_ALTIVEC) + message(STATUS " HAS_ALTIVEC yes") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maltivec") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec") + endif(HAS_ALTIVEC) + if(NOT CMAKE_C_FLAGS MATCHES "m(cpu|tune)") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcpu=power8") + endif() + if(NOT CMAKE_CXX_FLAGS MATCHES "m(cpu|tune)") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=power8") + endif() + ADD_DEFINITIONS(-DHAVE_POWER8 -DHAS_ALTIVEC) +endif(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64") + option(WITH_FALLOCATE "build with fallocate" ON) if(WITH_FALLOCATE AND UNIX) @@ -377,6 +395,13 @@ else() port/port_posix.cc env/env_posix.cc env/io_posix.cc) + # ppc64 or ppc64le + if(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64") + enable_language(ASM) + list(APPEND ROCKSDB_SOURCES + util/crc32c_ppc.c + util/crc32c_ppc_asm.S) + endif(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64") endif() SET(SOURCES) FOREACH(s ${ROCKSDB_SOURCES}) From b8b74e141d0aef3f93241ce027af2fb944085fbe Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Mon, 27 May 2019 21:28:33 +0530 Subject: [PATCH 26/43] MDEV-19027 create_table_def fails when virtual column is present between stored columns - create_table_def() misconstructs the dict_table_t by ignoring the stored columns of the table if virtual column is present between stored columns. --- storage/innobase/handler/ha_innodb.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index dbb74e4d99f..f2f43f18502 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -11016,7 +11016,6 @@ create_table_info_t::create_table_def() ulint binary_type; ulint long_true_varchar; ulint charset_no; - ulint j = 0; ulint doc_id_col = 0; ibool has_doc_id_col = FALSE; mem_heap_t* heap; @@ -11106,7 +11105,7 @@ error_ret: heap = mem_heap_create(1000); - for (ulint i = 0; i < n_cols; i++) { + for (ulint i = 0, j = 0; j < n_cols; i++) { Field* field = m_form->field[i]; col_type = get_innobase_type_from_mysql_type( @@ -11214,10 +11213,16 @@ err_col: dict_mem_table_add_s_col( table, 0); } + + if (is_virtual && omit_virtual) { + continue; + } + + j++; } if (num_v) { - for (ulint i = 0; i < n_cols; i++) { + for (ulint i = 0, j = 0; i < n_cols; i++) { dict_v_col_t* v_col; const Field* field = m_form->field[i]; From 0955462d0aafab01def9c1a5ec131eb641cb9e68 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 27 May 2019 19:08:00 -0700 Subject: [PATCH 27/43] MDEV-18479 Assertion `join->best_read < double(1.79769313486231570815e+308L)' or server crashes in JOIN::fix_all_splittings_in_plan after EXPLAIN This patch resolves the problem of overflowing when performing calculations to estimate the cost of an evaluated query execution plan. The overflowing in a non-debug build could cause different kind of problems uncluding crashes of the server. --- mysql-test/r/derived_view.result | 401 +++++++++++++++++++++++++++++++ mysql-test/t/derived_view.test | 260 ++++++++++++++++++++ sql/opt_subselect.cc | 69 +++--- sql/sql_const.h | 8 + sql/sql_select.cc | 113 +++++---- 5 files changed, 772 insertions(+), 79 deletions(-) diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index 12811ebc6b3..ab363934e8f 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -2640,3 +2640,404 @@ Note 1003 select straight_join `test`.`t1`.`c1` AS `c1` from `test`.`t1` where < DROP TABLE t1, t2; set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; +# +# Bug mdev-12812: EXPLAIN for query with many expensive derived +# +CREATE TABLE t1 +(id int auto_increment primary key, +uid int NOT NULL, +gp_id int NOT NULL, +r int NOT NULL +); +INSERT INTO t1(uid,gp_id,r) VALUES +(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1), +(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1), +(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1), +(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1), +(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1), +(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1), +(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1), +(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1), +(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1), +(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1), +(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1), +(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1), +(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1), +(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1), +(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1), +(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1), +(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1), +(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1), +(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1), +(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1), +(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1), +(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1), +(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1), +(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1), +(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1), +(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1), +(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1), +(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1), +(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1), +(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1), +(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1), +(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1), +(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1), +(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1), +(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1), +(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1), +(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1), +(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1), +(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1), +(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1), +(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1), +(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1), +(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1), +(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1), +(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1), +(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1), +(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1), +(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1), +(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1), +(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1), +(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1), +(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1), +(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1), +(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1), +(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1), +(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1), +(1,11,1); +CREATE TABLE t2 (id int) ; +INSERT INTO t2 VALUES (1); +explain SELECT 1 FROM t2 JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +) gp_1 ON gp_1.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +) gp_2 ON gp_2.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p1 ON p1.r=1 AND p1.uid=t2.id +JOIN t1 p3 ON p3.r=3 AND p3.uid=t2.id +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +) gp_3 ON gp_3.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p1 ON p1.r=1 AND p1.uid=t2.id +JOIN t1 p3 ON p3.r=3 AND p3.uid=t2.id +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +) gp_4 ON gp_4.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p1 ON p1.r=1 AND p1.uid=t2.id +JOIN t1 p3 ON p3.r=3 AND p3.uid=t2.id +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +) gp_5 ON gp_5.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p1 ON p1.r=1 AND p1.uid=t2.id +JOIN t1 p3 ON p3.r=3 AND p3.uid=t2.id +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +) gp_6 ON gp_6.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p1 ON p1.r=1 AND p1.uid=t2.id +JOIN t1 p3 ON p3.r=3 AND p3.uid=t2.id +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +WHERE p1.gp_id=7) gp_7 ON gp_7.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +) gp_8 ON gp_8.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +) gp_9 ON gp_9.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +) gp_14 ON gp_14.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +) gp_15 ON gp_15.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +) gp_16 ON gp_16.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +)gp_17 ON gp_17.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +)gp_18 ON gp_18.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id +JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id +)gp_19 ON gp_19.id=t2.id +JOIN +(SELECT t2.id +FROM t2 +JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id +JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id +JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id +JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id +JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id +) gp_20 ON gp_20.id=t2.id ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 system NULL NULL NULL NULL 1 +1 SIMPLE t2 system NULL NULL NULL NULL 1 +1 SIMPLE t2 system NULL NULL NULL NULL 1 +1 SIMPLE t2 system NULL NULL NULL NULL 1 +1 SIMPLE t2 system NULL NULL NULL NULL 1 +1 SIMPLE t2 system NULL NULL NULL NULL 1 +1 SIMPLE p4 ALL NULL NULL NULL NULL 550 Using where +1 SIMPLE p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join) +1 SIMPLE p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p4 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p1 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p3 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p4 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p1 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p3 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p4 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p1 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p3 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p4 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 50328437500000 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 27680640625000000 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 7798774269472204288 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL 7798774269472204288 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join) +17 DERIVED t2 system NULL NULL NULL NULL 1 +17 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where +17 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join) +17 DERIVED p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +17 DERIVED p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +17 DERIVED p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +16 DERIVED t2 system NULL NULL NULL NULL 1 +16 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where +16 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join) +16 DERIVED p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +16 DERIVED p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +16 DERIVED p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +16 DERIVED p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +16 DERIVED p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +15 DERIVED t2 system NULL NULL NULL NULL 1 +15 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where +15 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join) +15 DERIVED p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +15 DERIVED p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +15 DERIVED p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +15 DERIVED p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +15 DERIVED p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +14 DERIVED t2 system NULL NULL NULL NULL 1 +14 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where +14 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join) +14 DERIVED p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +14 DERIVED p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +14 DERIVED p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +14 DERIVED p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +13 DERIVED t2 system NULL NULL NULL NULL 1 +13 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where +13 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join) +13 DERIVED p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +13 DERIVED p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +13 DERIVED p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +13 DERIVED p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +13 DERIVED p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +12 DERIVED t2 system NULL NULL NULL NULL 1 +12 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where +12 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join) +12 DERIVED p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +12 DERIVED p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +12 DERIVED p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +12 DERIVED p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +12 DERIVED p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +11 DERIVED t2 system NULL NULL NULL NULL 1 +11 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where +11 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join) +11 DERIVED p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +11 DERIVED p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +11 DERIVED p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +11 DERIVED p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +11 DERIVED p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +10 DERIVED t2 system NULL NULL NULL NULL 1 +10 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where +10 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join) +10 DERIVED p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +10 DERIVED p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +10 DERIVED p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +10 DERIVED p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +10 DERIVED p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +9 DERIVED t2 system NULL NULL NULL NULL 1 +9 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where +9 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join) +9 DERIVED p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +9 DERIVED p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +9 DERIVED p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +9 DERIVED p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +9 DERIVED p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +8 DERIVED t2 system NULL NULL NULL NULL 1 +8 DERIVED p1 ALL NULL NULL NULL NULL 550 Using where +8 DERIVED p3 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join) +8 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +8 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +8 DERIVED p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +8 DERIVED p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +8 DERIVED p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +8 DERIVED p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +8 DERIVED p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +7 DERIVED t2 system NULL NULL NULL NULL 1 +7 DERIVED p1 ALL NULL NULL NULL NULL 550 Using where +7 DERIVED p3 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join) +7 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +7 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +7 DERIVED p6 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +7 DERIVED p7 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +7 DERIVED p8 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +7 DERIVED p9 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +7 DERIVED p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join) +DROP TABLE t1, t2; diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test index 07fbe4980a5..f6613e2593a 100644 --- a/mysql-test/t/derived_view.test +++ b/mysql-test/t/derived_view.test @@ -1934,3 +1934,263 @@ DROP TABLE t1, t2; # The following command must be the last one the file set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; + +--echo # +--echo # Bug mdev-12812: EXPLAIN for query with many expensive derived +--echo # + +CREATE TABLE t1 +(id int auto_increment primary key, + uid int NOT NULL, + gp_id int NOT NULL, + r int NOT NULL +); + +INSERT INTO t1(uid,gp_id,r) VALUES +(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1), +(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1), +(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1), +(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1), +(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1),(1,1,1), +(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1), +(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1), +(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1), +(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1), +(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1),(1,2,1), +(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1), +(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1), +(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1), +(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1), +(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1),(1,3,1), +(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1), +(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1), +(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1), +(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1), +(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1),(1,4,1), +(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1), +(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1), +(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1), +(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1), +(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1),(1,5,1), +(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1), +(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1), +(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1), +(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1), +(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1),(1,6,1), +(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1), +(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1), +(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1), +(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1), +(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1),(1,7,1), +(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1), +(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1), +(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1), +(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1), +(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1),(1,8,1), +(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1), +(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1), +(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1), +(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1), +(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1),(1,9,1), +(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1), +(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1), +(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1), +(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1), +(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1), +(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,10,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1), +(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1), +(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1), +(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1), +(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1), +(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1),(1,11,1), +(1,11,1); + +CREATE TABLE t2 (id int) ; +INSERT INTO t2 VALUES (1); + +explain SELECT 1 FROM t2 JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + ) gp_1 ON gp_1.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + ) gp_2 ON gp_2.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p1 ON p1.r=1 AND p1.uid=t2.id + JOIN t1 p3 ON p3.r=3 AND p3.uid=t2.id + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + ) gp_3 ON gp_3.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p1 ON p1.r=1 AND p1.uid=t2.id + JOIN t1 p3 ON p3.r=3 AND p3.uid=t2.id + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + ) gp_4 ON gp_4.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p1 ON p1.r=1 AND p1.uid=t2.id + JOIN t1 p3 ON p3.r=3 AND p3.uid=t2.id + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + ) gp_5 ON gp_5.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p1 ON p1.r=1 AND p1.uid=t2.id + JOIN t1 p3 ON p3.r=3 AND p3.uid=t2.id + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + ) gp_6 ON gp_6.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p1 ON p1.r=1 AND p1.uid=t2.id + JOIN t1 p3 ON p3.r=3 AND p3.uid=t2.id + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + WHERE p1.gp_id=7) gp_7 ON gp_7.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + ) gp_8 ON gp_8.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + ) gp_9 ON gp_9.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + ) gp_14 ON gp_14.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + ) gp_15 ON gp_15.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + ) gp_16 ON gp_16.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + )gp_17 ON gp_17.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + )gp_18 ON gp_18.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + JOIN t1 p9 ON p9.r=9 AND p9.uid=t2.id + JOIN t1 p10 ON p10.r=10 AND p10.uid=t2.id + )gp_19 ON gp_19.id=t2.id +JOIN +(SELECT t2.id + FROM t2 + JOIN t1 p4 ON p4.r=4 AND p4.uid=t2.id + JOIN t1 p5 ON p5.r=5 AND p5.uid=t2.id + JOIN t1 p6 ON p6.r=6 AND p6.uid=t2.id + JOIN t1 p7 ON p7.r=7 AND p7.uid=t2.id + JOIN t1 p8 ON p8.r=8 AND p8.uid=t2.id + ) gp_20 ON gp_20.id=t2.id ; + +DROP TABLE t1, t2; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index a0e19af3d4e..cb821325e57 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -27,6 +27,7 @@ #endif #include "sql_base.h" +#include "sql_const.h" #include "sql_select.h" #include "filesort.h" #include "opt_subselect.h" @@ -1380,8 +1381,8 @@ void get_delayed_table_estimates(TABLE *table, *startup_cost= item->jtbm_read_time; /* Calculate cost of scanning the temptable */ - double data_size= item->jtbm_record_count * - hash_sj_engine->tmp_table->s->reclength; + double data_size= COST_MULT(item->jtbm_record_count, + hash_sj_engine->tmp_table->s->reclength); /* Do like in handler::read_time */ *scan_time= data_size/IO_SIZE + 2; } @@ -2451,7 +2452,8 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map) int tableno; double rows= 1.0; while ((tableno = tm_it.next_bit()) != Table_map_iterator::BITMAP_END) - rows *= join->map2table[tableno]->table->quick_condition_rows; + rows= COST_MULT(rows, + join->map2table[tableno]->table->quick_condition_rows); sjm->rows= min(sjm->rows, rows); } memcpy(sjm->positions, join->best_positions + join->const_tables, @@ -2564,7 +2566,7 @@ static uint get_tmp_table_rec_length(Item **p_items, uint elements) static double get_tmp_table_lookup_cost(THD *thd, double row_count, uint row_size) { - if (row_count * row_size > thd->variables.max_heap_table_size) + if (row_count > thd->variables.max_heap_table_size / (double) row_size) return (double) DISK_TEMPTABLE_LOOKUP_COST; else return (double) HEAP_TEMPTABLE_LOOKUP_COST; @@ -2970,8 +2972,11 @@ bool Sj_materialization_picker::check_qep(JOIN *join, } double mat_read_time= prefix_cost.total_cost(); - mat_read_time += mat_info->materialization_cost.total_cost() + - prefix_rec_count * mat_info->lookup_cost.total_cost(); + mat_read_time= + COST_ADD(mat_read_time, + COST_ADD(mat_info->materialization_cost.total_cost(), + COST_MULT(prefix_rec_count, + mat_info->lookup_cost.total_cost()))); /* NOTE: When we pick to use SJM[-Scan] we don't memcpy its POSITION @@ -3011,9 +3016,12 @@ bool Sj_materialization_picker::check_qep(JOIN *join, } /* Add materialization cost */ - prefix_cost += mat_info->materialization_cost.total_cost() + - prefix_rec_count * mat_info->scan_cost.total_cost(); - prefix_rec_count *= mat_info->rows; + prefix_cost= + COST_ADD(prefix_cost, + COST_ADD(mat_info->materialization_cost.total_cost(), + COST_MULT(prefix_rec_count, + mat_info->scan_cost.total_cost()))); + prefix_rec_count= COST_MULT(prefix_rec_count, mat_info->rows); uint i; table_map rem_tables= remaining_tables; @@ -3027,8 +3035,8 @@ bool Sj_materialization_picker::check_qep(JOIN *join, { best_access_path(join, join->positions[i].table, rem_tables, i, disable_jbuf, prefix_rec_count, &curpos, &dummy); - prefix_rec_count *= curpos.records_read; - prefix_cost += curpos.read_time; + prefix_rec_count= COST_MULT(prefix_rec_count, curpos.records_read); + prefix_cost= COST_ADD(prefix_cost, curpos.read_time); } *strategy= SJ_OPT_MATERIALIZE_SCAN; @@ -3335,16 +3343,18 @@ bool Duplicate_weedout_picker::check_qep(JOIN *join, for (uint j= first_dupsweedout_table; j <= idx; j++) { POSITION *p= join->positions + j; - current_fanout *= p->records_read; - dups_cost += p->read_time + current_fanout / TIME_FOR_COMPARE; + current_fanout= COST_MULT(current_fanout, p->records_read); + dups_cost= COST_ADD(dups_cost, + COST_ADD(p->read_time, + current_fanout / TIME_FOR_COMPARE)); if (p->table->emb_sj_nest) { - sj_inner_fanout *= p->records_read; + sj_inner_fanout= COST_MULT(sj_inner_fanout, p->records_read); dups_removed_fanout |= p->table->table->map; } else { - sj_outer_fanout *= p->records_read; + sj_outer_fanout= COST_MULT(sj_outer_fanout, p->records_read); temptable_rec_size += p->table->table->file->ref_length; } } @@ -3363,12 +3373,13 @@ bool Duplicate_weedout_picker::check_qep(JOIN *join, sj_outer_fanout, temptable_rec_size); - double write_cost= join->positions[first_tab].prefix_record_count* - sj_outer_fanout * one_write_cost; - double full_lookup_cost= join->positions[first_tab].prefix_record_count* - sj_outer_fanout* sj_inner_fanout * - one_lookup_cost; - dups_cost += write_cost + full_lookup_cost; + double write_cost= COST_MULT(join->positions[first_tab].prefix_record_count, + sj_outer_fanout * one_write_cost); + double full_lookup_cost= + COST_MULT(join->positions[first_tab].prefix_record_count, + COST_MULT(sj_outer_fanout, + sj_inner_fanout * one_lookup_cost)); + dups_cost= COST_ADD(dups_cost, COST_ADD(write_cost, full_lookup_cost)); *read_time= dups_cost; *record_count= prefix_rec_count * sj_outer_fanout; @@ -3515,8 +3526,8 @@ static void recalculate_prefix_record_count(JOIN *join, uint start, uint end) if (j == join->const_tables) prefix_count= 1.0; else - prefix_count= join->best_positions[j-1].prefix_record_count * - join->best_positions[j-1].records_read; + prefix_count= COST_MULT(join->best_positions[j-1].prefix_record_count, + join->best_positions[j-1].records_read); join->best_positions[j].prefix_record_count= prefix_count; } @@ -5807,14 +5818,16 @@ bool JOIN::choose_subquery_plan(table_map join_tables) The cost of executing the subquery and storing its result in an indexed temporary table. */ - double materialization_cost= inner_read_time_1 + - write_cost * inner_record_count_1; + double materialization_cost= COST_ADD(inner_read_time_1, + COST_MULT(write_cost, + inner_record_count_1)); - materialize_strategy_cost= materialization_cost + - outer_lookup_keys * lookup_cost; + materialize_strategy_cost= COST_ADD(materialization_cost, + COST_MULT(outer_lookup_keys, + lookup_cost)); /* C.2 Compute the cost of the IN=>EXISTS strategy. */ - in_exists_strategy_cost= outer_lookup_keys * inner_read_time_2; + in_exists_strategy_cost= COST_MULT(outer_lookup_keys, inner_read_time_2); /* C.3 Compare the costs and choose the cheaper strategy. */ if (materialize_strategy_cost >= in_exists_strategy_cost) diff --git a/sql/sql_const.h b/sql/sql_const.h index 96b64481936..c3b03dd7848 100644 --- a/sql/sql_const.h +++ b/sql/sql_const.h @@ -214,6 +214,14 @@ #define HEAP_TEMPTABLE_LOOKUP_COST 0.05 #define DISK_TEMPTABLE_LOOKUP_COST 1.0 + +#define COST_MAX (DBL_MAX * (1.0 - DBL_EPSILON)) + +#define COST_ADD(c,d) (COST_MAX - (d) > (c) ? (c) + (d) : COST_MAX) + +#define COST_MULT(c,f) (COST_MAX / (f) > (c) ? (c) * (f) : COST_MAX) + + #define MY_CHARSET_BIN_MB_MAXLEN 1 /** Don't pack string keys shorter than this (if PACK_KEYS=1 isn't used). */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4886e35c82e..961a7dac265 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5676,7 +5676,7 @@ best_access_path(JOIN *join, else tmp= table->file->read_time(key, 1, (ha_rows) min(tmp,s->worst_seeks)); - tmp*= record_count; + tmp= COST_MULT(tmp, record_count); } } else @@ -5841,18 +5841,18 @@ best_access_path(JOIN *join, else tmp= table->file->read_time(key, 1, (ha_rows) min(tmp,s->worst_seeks)); - tmp*= record_count; + tmp= COST_MULT(tmp, record_count); } else - tmp= best_time; // Do nothing + tmp= best_time; // Do nothing } - tmp += s->startup_cost; + tmp= COST_ADD(tmp, s->startup_cost); loose_scan_opt.check_ref_access_part2(key, start_key, records, tmp); } /* not ft_key */ if (tmp + 0.0001 < best_time - records/(double) TIME_FOR_COMPARE) { - best_time= tmp + records/(double) TIME_FOR_COMPARE; + best_time= COST_ADD(tmp, records/(double) TIME_FOR_COMPARE); best= tmp; best_records= records; best_key= start_key; @@ -5885,14 +5885,18 @@ best_access_path(JOIN *join, ha_rows rnd_records= matching_candidates_in_table(s, found_constraint); tmp= s->quick ? s->quick->read_time : s->scan_time(); - tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE; + double cmp_time= (s->records - rnd_records)/(double) TIME_FOR_COMPARE; + tmp= COST_ADD(tmp, cmp_time); /* We read the table as many times as join buffer becomes full. */ - tmp*= (1.0 + floor((double) cache_record_length(join,idx) * - record_count / - (double) thd->variables.join_buff_size)); - best_time= tmp + - (record_count*join_sel) / TIME_FOR_COMPARE * rnd_records; + + double refills= (1.0 + floor((double) cache_record_length(join,idx) * + record_count / + (double) thd->variables.join_buff_size)); + tmp= COST_MULT(tmp, refills); + best_time= COST_ADD(tmp, + COST_MULT((record_count*join_sel) / TIME_FOR_COMPARE, + rnd_records)); best= tmp; records= rows2double(rnd_records); best_key= hj_start_key; @@ -5960,9 +5964,9 @@ best_access_path(JOIN *join, access (see first else-branch below), but we don't take it into account here for range/index_merge access. Find out why this is so. */ - tmp= record_count * - (s->quick->read_time + - (s->found_records - rnd_records)/(double) TIME_FOR_COMPARE); + double cmp_time= (s->found_records - rnd_records)/(double) TIME_FOR_COMPARE; + tmp= COST_MULT(record_count, + COST_ADD(s->quick->read_time, cmp_time)); loose_scan_opt.check_range_access(join, idx, s->quick); } @@ -5977,16 +5981,15 @@ best_access_path(JOIN *join, - read the whole table record - skip rows which does not satisfy join condition */ - tmp= record_count * - (tmp + - (s->records - rnd_records)/(double) TIME_FOR_COMPARE); + double cmp_time= (s->records - rnd_records)/(double) TIME_FOR_COMPARE; + tmp= COST_MULT(record_count, COST_ADD(tmp,cmp_time)); } else { - /* We read the table as many times as join buffer becomes full. */ - tmp*= (1.0 + floor((double) cache_record_length(join,idx) * - record_count / - (double) thd->variables.join_buff_size)); + double refills= (1.0 + floor((double) cache_record_length(join,idx) * + (record_count / + (double) thd->variables.join_buff_size))); + tmp= COST_MULT(tmp, refills); /* We don't make full cartesian product between rows in the scanned table and existing records because we skip all rows from the @@ -5994,7 +5997,8 @@ best_access_path(JOIN *join, we read the table (see flush_cached_records for details). Here we take into account cost to read and skip these records. */ - tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE; + double cmp_time= (s->records - rnd_records)/(double) TIME_FOR_COMPARE; + tmp= COST_ADD(tmp, cmp_time); } } @@ -6005,9 +6009,9 @@ best_access_path(JOIN *join, tmp give us total cost of using TABLE SCAN */ if (best == DBL_MAX || - (tmp + record_count/(double) TIME_FOR_COMPARE*rnd_records < + COST_ADD(tmp, record_count/(double) TIME_FOR_COMPARE*rnd_records) < (best_key->is_for_hash_join() ? best_time : - best + record_count/(double) TIME_FOR_COMPARE*records))) + COST_ADD(best, record_count/(double) TIME_FOR_COMPARE*records))) { /* If the table has a range (s->quick is set) make_join_select() @@ -6526,9 +6530,10 @@ optimize_straight_join(JOIN *join, table_map join_tables) join->positions + idx, &loose_scan_pos); /* compute the cost of the new plan extended with 's' */ - record_count*= join->positions[idx].records_read; - read_time+= join->positions[idx].read_time + - record_count / (double) TIME_FOR_COMPARE; + record_count= COST_MULT(record_count, join->positions[idx].records_read); + read_time= COST_ADD(read_time, + COST_ADD(join->positions[idx].read_time, + record_count / (double) TIME_FOR_COMPARE)); advance_sj_state(join, join_tables, idx, &record_count, &read_time, &loose_scan_pos); @@ -6710,9 +6715,10 @@ greedy_search(JOIN *join, swap_variables(JOIN_TAB*, join->best_ref[idx], join->best_ref[best_idx]); /* compute the cost of the new plan extended with 'best_table' */ - record_count*= join->positions[idx].records_read; - read_time+= join->positions[idx].read_time + - record_count / (double) TIME_FOR_COMPARE; + record_count= COST_MULT(record_count, join->positions[idx].records_read); + read_time= COST_ADD(read_time, + COST_ADD(join->positions[idx].read_time, + record_count / (double) TIME_FOR_COMPARE)); remaining_tables&= ~(best_table->table->map); --size_remain; @@ -6819,11 +6825,13 @@ void JOIN::get_partial_cost_and_fanout(int end_tab_idx, } if (tab->records_read && (cur_table_map & filter_map)) { - record_count *= tab->records_read; - read_time += tab->read_time + record_count / (double) TIME_FOR_COMPARE; + record_count= COST_MULT(record_count, tab->records_read); + read_time= COST_ADD(read_time, + COST_ADD(tab->read_time, + record_count / (double) TIME_FOR_COMPARE)); if (tab->emb_sj_nest) - sj_inner_fanout *= tab->records_read; - } + sj_inner_fanout= COST_MULT(sj_inner_fanout, tab->records_read); + } if (i == last_sj_table) { @@ -6861,8 +6869,8 @@ void JOIN::get_prefix_cost_and_fanout(uint n_tables, { if (best_positions[i].records_read) { - record_count *= best_positions[i].records_read; - read_time += best_positions[i].read_time; + record_count= COST_MULT(record_count, best_positions[i].records_read); + read_time= COST_ADD(read_time, best_positions[i].read_time); } } *read_time_arg= read_time;// + record_count / TIME_FOR_COMPARE; @@ -7068,10 +7076,11 @@ best_extension_by_limited_search(JOIN *join, record_count, join->positions + idx, &loose_scan_pos); /* Compute the cost of extending the plan with 's' */ - - current_record_count= record_count * position->records_read; - current_read_time=read_time + position->read_time + - current_record_count / (double) TIME_FOR_COMPARE; + current_record_count= COST_MULT(record_count, position->records_read); + current_read_time=COST_ADD(read_time, + COST_ADD(position->read_time, + current_record_count / + (double) TIME_FOR_COMPARE)); advance_sj_state(join, remaining_tables, idx, ¤t_record_count, ¤t_read_time, &loose_scan_pos); @@ -7145,7 +7154,7 @@ best_extension_by_limited_search(JOIN *join, join->sort_by_table != join->positions[join->const_tables].table->table) /* We have to make a temp table */ - current_read_time+= current_record_count; + current_read_time= COST_ADD(current_read_time, current_record_count); if (current_read_time < join->best_read) { memcpy((uchar*) join->best_positions, (uchar*) join->positions, @@ -7189,11 +7198,11 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, DBUG_PRINT("best",("read_time: %g record_count: %g",read_time, record_count)); - read_time+=record_count/(double) TIME_FOR_COMPARE; + read_time= COST_ADD(read_time, record_count/(double) TIME_FOR_COMPARE); if (join->sort_by_table && join->sort_by_table != join->positions[join->const_tables].table->table) - read_time+=record_count; // We have to make a temp table + read_time= COST_ADD(read_time, record_count); // We have to make a temp table if (read_time < join->best_read) { memcpy((uchar*) join->best_positions,(uchar*) join->positions, @@ -7202,7 +7211,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, } DBUG_RETURN(FALSE); } - if (read_time+record_count/(double) TIME_FOR_COMPARE >= join->best_read) + if (COST_ADD(read_time, record_count/(double) TIME_FOR_COMPARE) + >= join->best_read) DBUG_RETURN(FALSE); /* Found better before */ JOIN_TAB *s; @@ -7224,8 +7234,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, Go to the next level only if there hasn't been a better key on this level! This will cut down the search for a lot simple cases! */ - double current_record_count=record_count*records; - double current_read_time=read_time+best; + double current_record_count= COST_MULT(record_count, records); + double current_read_time= COST_ADD(read_time, best); advance_sj_state(join, rest_tables, idx, ¤t_record_count, ¤t_read_time, &loose_scan_pos); @@ -7552,8 +7562,8 @@ prev_record_reads(POSITION *positions, uint idx, table_map found_ref) #max_nested_outer_joins=64-1) will not make it any more precise. */ if (pos->records_read) - found*= pos->records_read; - } + found= COST_MULT(found, pos->records_read); + } } return found; } @@ -13835,11 +13845,12 @@ void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab, pos= loose_scan_pos; reopt_remaining_tables &= ~rs->table->map; - rec_count *= pos.records_read; - cost += pos.read_time; + rec_count= COST_MULT(rec_count, pos.records_read); + cost= COST_ADD(cost, pos.read_time); + if (!rs->emb_sj_nest) - *outer_rec_count *= pos.records_read; + *outer_rec_count= COST_MULT(*outer_rec_count, pos.records_read); } join->cur_sj_inner_tables= save_cur_sj_inner_tables; From 661289f4627b81b85d362cf62587dcfd4fb381c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 21 May 2019 09:20:49 +0300 Subject: [PATCH 28/43] Mention the sample IPv4 address 10.0.0.1 --- debian/po/ca.po | 4 ++-- debian/po/cs.po | 4 ++-- debian/po/da.po | 4 ++-- debian/po/es.po | 4 ++-- debian/po/pt_BR.po | 4 ++-- debian/po/tr.po | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/debian/po/ca.po b/debian/po/ca.po index 7c7d2210834..f2a6a3dc0bf 100644 --- a/debian/po/ca.po +++ b/debian/po/ca.po @@ -207,13 +207,13 @@ msgstr "" #~ msgid "" #~ "MySQL will only install if you have a non-numeric hostname that is " #~ "resolvable via the /etc/hosts file. E.g. if the \"hostname\" command " -#~ "returns \"myhostname\" then there must be a line like \"10.1.0.1 " +#~ "returns \"myhostname\" then there must be a line like \"10.0.0.1 " #~ "myhostname\"." #~ msgstr "" #~ "El MySQL només s'instal·la en cas de tenir un nom d'ordinador central que " #~ "no sigui numèric i que es pugui resoldre a través del fitxer /etc/hosts. " #~ "Ex. si l'ordre \"hostname\" retorna \"myhostname\", llavors hi ha d'haver " -#~ "una línia com la següent \"10.1.0.1 myhostname\"." +#~ "una línia com la següent \"10.0.0.1 myhostname\"." #, fuzzy #~ msgid "" diff --git a/debian/po/cs.po b/debian/po/cs.po index f3ae24b1e8c..259bc9a96f8 100644 --- a/debian/po/cs.po +++ b/debian/po/cs.po @@ -298,13 +298,13 @@ msgstr "" #~ msgid "" #~ "MySQL will only install if you have a non-numeric hostname that is " #~ "resolvable via the /etc/hosts file. E.g. if the \"hostname\" command " -#~ "returns \"myhostname\" then there must be a line like \"10.1.0.1 " +#~ "returns \"myhostname\" then there must be a line like \"10.0.0.1 " #~ "myhostname\"." #~ msgstr "" #~ "MySQL se nainstaluje pouze v případÄ›, že používáte nenumerické jméno " #~ "poÄítaÄe, které se dá pÅ™eložit pÅ™es soubor /etc/hosts. NapÅ™. když příkaz " #~ "\"hostname\" vrátí \"diamond\", tak v /etc/hosts musí existovat obdobný " -#~ "řádek jako \"10.1.0.1 diamond\"." +#~ "řádek jako \"10.0.0.1 diamond\"." #~ msgid "" #~ "A new mysql user \"debian-sys-maint\" will be created. This mysql account " diff --git a/debian/po/da.po b/debian/po/da.po index d68b8575d72..8abb89ebbd4 100644 --- a/debian/po/da.po +++ b/debian/po/da.po @@ -324,12 +324,12 @@ msgstr "" #~ msgid "" #~ "MySQL will only install if you have a non-numeric hostname that is " #~ "resolvable via the /etc/hosts file. E.g. if the \"hostname\" command " -#~ "returns \"myhostname\" then there must be a line like \"10.1.0.1 " +#~ "returns \"myhostname\" then there must be a line like \"10.0.0.1 " #~ "myhostname\"." #~ msgstr "" #~ "MySQL vil kun blive installeret, hvis du har et ikke-numerisk værtsnavn, " #~ "som kan slås op i filen /ets/hosts. Hvis f.eks. kommandoen \"hostname\" " -#~ "svarer med \"mitvaertsnavn\", skal du have en linje a'la \"10.1.0.1 " +#~ "svarer med \"mitvaertsnavn\", skal du have en linje a'la \"10.0.0.1 " #~ "mitvaertsnavn\" i /etc/hosts." #~ msgid "" diff --git a/debian/po/es.po b/debian/po/es.po index e76c173a9f5..e0b72b87737 100644 --- a/debian/po/es.po +++ b/debian/po/es.po @@ -341,13 +341,13 @@ msgstr "" #~ msgid "" #~ "MySQL will only install if you have a non-numeric hostname that is " #~ "resolvable via the /etc/hosts file. E.g. if the \"hostname\" command " -#~ "returns \"myhostname\" then there must be a line like \"10.1.0.1 " +#~ "returns \"myhostname\" then there must be a line like \"10.0.0.1 " #~ "myhostname\"." #~ msgstr "" #~ "Sólo se instalará MySQL si tiene un nombre de equipo que no sea una " #~ "dirección IP y pueda resolverse a través del archivo /etc/hosts. Por " #~ "ejemplo, si la orden «hostname» devuelve «MiNombreEquipo» entonces deberá " -#~ "existir una línea «10.1.0.1 MiNombreEquipo» en dicho archivo." +#~ "existir una línea «10.0.0.1 MiNombreEquipo» en dicho archivo." #~ msgid "" #~ "A new mysql user \"debian-sys-maint\" will be created. This mysql account " diff --git a/debian/po/pt_BR.po b/debian/po/pt_BR.po index a0b4cdbfbfb..35f1b4fcea4 100644 --- a/debian/po/pt_BR.po +++ b/debian/po/pt_BR.po @@ -308,13 +308,13 @@ msgstr "" #~ msgid "" #~ "MySQL will only install if you have a non-numeric hostname that is " #~ "resolvable via the /etc/hosts file. E.g. if the \"hostname\" command " -#~ "returns \"myhostname\" then there must be a line like \"10.1.0.1 " +#~ "returns \"myhostname\" then there must be a line like \"10.0.0.1 " #~ "myhostname\"." #~ msgstr "" #~ "O MySQL será instalado somente caso você possua um nome de host NÃO " #~ "NUMÉRICO que possa ser resolvido através do arquivo /etc/hosts, ou seja, " #~ "caso o comando \"hostname\" retorne \"myhostname\", uma linha como " -#~ "\"10.1.0.1 myhostname\" deverá existir no arquivo /etc/hosts." +#~ "\"10.0.0.1 myhostname\" deverá existir no arquivo /etc/hosts." #~ msgid "" #~ "A new mysql user \"debian-sys-maint\" will be created. This mysql account " diff --git a/debian/po/tr.po b/debian/po/tr.po index 814341a6bc2..dafbd6121d8 100644 --- a/debian/po/tr.po +++ b/debian/po/tr.po @@ -206,12 +206,12 @@ msgstr "" #~ msgid "" #~ "MySQL will only install if you have a non-numeric hostname that is " #~ "resolvable via the /etc/hosts file. E.g. if the \"hostname\" command " -#~ "returns \"myhostname\" then there must be a line like \"10.1.0.1 " +#~ "returns \"myhostname\" then there must be a line like \"10.0.0.1 " #~ "myhostname\"." #~ msgstr "" #~ "MySQL sadece /etc/hosts dosyası yoluyla çözülebilir NUMERİK OLMAYAN bir " #~ "makine adına sahipseniz kurulacaktır. ÖrneÄŸin, eÄŸer \"hostname\" komutu " -#~ "\"makinem\" ismini döndürüyorsa, bu dosya içinde \"10.1.0.1 makinem\" " +#~ "\"makinem\" ismini döndürüyorsa, bu dosya içinde \"10.0.0.1 makinem\" " #~ "gibi bir satır olmalıdır." #, fuzzy From 242a28c320ae8b16144c5e91cbcf8806ce1e5d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 28 May 2019 08:07:45 +0300 Subject: [PATCH 29/43] MDEV-6812: Remove the wrapper my_log2f() --- storage/innobase/row/row0merge.cc | 17 +++-------------- storage/xtradb/row/row0merge.cc | 17 +++-------------- 2 files changed, 6 insertions(+), 28 deletions(-) diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 5042a9ed170..463be8d229d 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -27,6 +27,7 @@ Completed by Sunny Bains and Marko Makela #include #include #include +#include #include "row0merge.h" #include "row0ext.h" @@ -42,15 +43,8 @@ Completed by Sunny Bains and Marko Makela #include "row0import.h" #include "handler0alter.h" #include "ha_prototypes.h" -#include "math.h" /* log() */ #include "fil0crypt.h" -float my_log2f(float n) -{ - /* log(n) / log(2) is log2. */ - return (float)(log((double)n) / log((double)2)); -} - /* Ignore posix_fadvise() on those platforms where it does not exist */ #if defined __WIN__ # define posix_fadvise(fd, offset, len, advice) /* nothing */ @@ -2503,18 +2497,13 @@ row_merge_sort( /* Record the number of merge runs we need to perform */ num_runs = file->offset; - /* Find the number N which 2^N is greater or equal than num_runs */ - /* N is merge sort running count */ - total_merge_sort_count = ceil(my_log2f(num_runs)); - if(total_merge_sort_count <= 0) { - total_merge_sort_count=1; - } - /* If num_runs are less than 1, nothing to merge */ if (num_runs <= 1) { DBUG_RETURN(error); } + total_merge_sort_count = ceil(log2f(num_runs)); + /* "run_offset" records each run's first offset number */ run_offset = (ulint*) mem_alloc(file->offset * sizeof(ulint)); diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc index cc7c648fe4c..f71a623da20 100644 --- a/storage/xtradb/row/row0merge.cc +++ b/storage/xtradb/row/row0merge.cc @@ -27,6 +27,7 @@ Completed by Sunny Bains and Marko Makela #include #include #include +#include #include "row0merge.h" #include "row0ext.h" @@ -42,15 +43,8 @@ Completed by Sunny Bains and Marko Makela #include "row0import.h" #include "handler0alter.h" #include "ha_prototypes.h" -#include "math.h" /* log2() */ #include "fil0crypt.h" -float my_log2f(float n) -{ - /* log(n) / log(2) is log2. */ - return (float)(log((double)n) / log((double)2)); -} - /* Ignore posix_fadvise() on those platforms where it does not exist */ #if defined __WIN__ # define posix_fadvise(fd, offset, len, advice) /* nothing */ @@ -2516,18 +2510,13 @@ row_merge_sort( /* Record the number of merge runs we need to perform */ num_runs = file->offset; - /* Find the number N which 2^N is greater or equal than num_runs */ - /* N is merge sort running count */ - total_merge_sort_count = ceil(my_log2f(num_runs)); - if(total_merge_sort_count <= 0) { - total_merge_sort_count=1; - } - /* If num_runs are less than 1, nothing to merge */ if (num_runs <= 1) { DBUG_RETURN(error); } + total_merge_sort_count = ceil(log2f(num_runs)); + /* "run_offset" records each run's first offset number */ run_offset = (ulint*) mem_alloc(file->offset * sizeof(ulint)); From 626f2a1c170e615c7866c1041746159dc3f709af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 28 May 2019 10:50:17 +0300 Subject: [PATCH 30/43] MDEV-19614 SET GLOBAL innodb_ deadlock due to LOCK_global_system_variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The update callback functions for several settable global InnoDB variables are acquiring InnoDB latches while holding LOCK_global_system_variables. On the other hand, some InnoDB code is invoking THDVAR() while holding InnoDB latches. An example of this is thd_lock_wait_timeout() that is called by lock_rec_enqueue_waiting(). In some cases, the intern_sys_var_ptr() that is invoked by THDVAR() may acquire LOCK_global_system_variables, via sync_dynamic_session_variables(). In lock_rec_enqueue_waiting(), we really must be holding some InnoDB latch while invoking THDVAR(). This implies that LOCK_global_system_variables must conceptually reside below any InnoDB latch in the latching order. That in turns implies that the various update callback functions must release LOCK_global_system_variables before acquiring any InnoDB mutexes or rw-locks, and reacquire LOCK_global_system_variables later. The validate functions are being invoked while not holding LOCK_global_system_variables and thus they do not need any changes. The following statements are affected by this: SET GLOBAL innodb_adaptive_hash_index = …; SET GLOBAL innodb_cmp_per_index_enabled = 1; SET GLOBAL innodb_old_blocks_pct = …; SET GLOBAL innodb_fil_make_page_dirty_debug = …; -- debug builds only SET GLOBAL innodb_buffer_pool_evict = uncompressed; -- debug builds only SET GLOBAL innodb_purge_run_now = 1; -- debug builds only SET GLOBAL innodb_purge_stop_now = 1; -- debug builds only SET GLOBAL innodb_log_checkpoint_now = 1; -- debug builds only SET GLOBAL innodb_buf_flush_list_now = 1; -- debug builds only SET GLOBAL innodb_buffer_pool_dump_now = 1; SET GLOBAL innodb_buffer_pool_load_now = 1; SET GLOBAL innodb_buffer_pool_load_abort = 1; SET GLOBAL innodb_status_output = …; SET GLOBAL innodb_status_output_locks = …; SET GLOBAL innodb_encryption_threads = …; SET GLOBAL innodb_encryption_rotate_key_age = …; SET GLOBAL innodb_encryption_rotation_iops = …; SET GLOBAL innodb_encrypt_tables = …; SET GLOBAL innodb_disallow_writes = …; buf_LRU_old_ratio_update(): Correct the return type. --- storage/innobase/buf/buf0lru.cc | 14 +-- storage/innobase/handler/ha_innodb.cc | 126 +++++++++++++------------- storage/innobase/include/buf0lru.h | 8 +- storage/xtradb/buf/buf0lru.cc | 14 +-- storage/xtradb/handler/ha_innodb.cc | 126 +++++++++++++------------- storage/xtradb/include/buf0lru.h | 8 +- 6 files changed, 152 insertions(+), 144 deletions(-) diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index 7edc9520e02..29fe81dc920 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -2243,8 +2243,8 @@ buf_LRU_old_ratio_update_instance( buf_pool_t* buf_pool,/*!< in: buffer pool instance */ uint old_pct,/*!< in: Reserve this percentage of the buffer pool for "old" blocks. */ - ibool adjust) /*!< in: TRUE=adjust the LRU list; - FALSE=just assign buf_pool->LRU_old_ratio + bool adjust) /*!< in: true=adjust the LRU list; + false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB */ { uint ratio; @@ -2282,17 +2282,17 @@ buf_LRU_old_ratio_update_instance( Updates buf_pool->LRU_old_ratio. @return updated old_pct */ UNIV_INTERN -ulint +uint buf_LRU_old_ratio_update( /*=====================*/ uint old_pct,/*!< in: Reserve this percentage of the buffer pool for "old" blocks. */ - ibool adjust) /*!< in: TRUE=adjust the LRU list; - FALSE=just assign buf_pool->LRU_old_ratio + bool adjust) /*!< in: true=adjust the LRU list; + false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB */ { ulint i; - ulint new_ratio = 0; + uint new_ratio = 0; for (i = 0; i < srv_buf_pool_instances; i++) { buf_pool_t* buf_pool; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index cb6ec20e0d6..e04d431174a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -17166,11 +17166,13 @@ innodb_adaptive_hash_index_update( const void* save) /*!< in: immediate result from check function */ { + mysql_mutex_unlock(&LOCK_global_system_variables); if (*(my_bool*) save) { btr_search_enable(); } else { btr_search_disable(); } + mysql_mutex_lock(&LOCK_global_system_variables); } /****************************************************************//** @@ -17191,7 +17193,9 @@ innodb_cmp_per_index_update( /* Reset the stats whenever we enable the table INFORMATION_SCHEMA.innodb_cmp_per_index. */ if (!srv_cmp_per_index_enabled && *(my_bool*) save) { + mysql_mutex_unlock(&LOCK_global_system_variables); page_zip_reset_stat_per_index(); + mysql_mutex_lock(&LOCK_global_system_variables); } srv_cmp_per_index_enabled = !!(*(my_bool*) save); @@ -17212,9 +17216,11 @@ innodb_old_blocks_pct_update( const void* save) /*!< in: immediate result from check function */ { - innobase_old_blocks_pct = static_cast( - buf_LRU_old_ratio_update( - *static_cast(save), TRUE)); + mysql_mutex_unlock(&LOCK_global_system_variables); + uint ratio = buf_LRU_old_ratio_update(*static_cast(save), + true); + mysql_mutex_lock(&LOCK_global_system_variables); + innobase_old_blocks_pct = ratio; } /****************************************************************//** @@ -17232,9 +17238,10 @@ innodb_change_buffer_max_size_update( const void* save) /*!< in: immediate result from check function */ { - innobase_change_buffer_max_size = - (*static_cast(save)); + innobase_change_buffer_max_size = *static_cast(save); + mysql_mutex_unlock(&LOCK_global_system_variables); ibuf_max_size_update(innobase_change_buffer_max_size); + mysql_mutex_lock(&LOCK_global_system_variables); } #ifdef UNIV_DEBUG @@ -17278,6 +17285,7 @@ innodb_make_page_dirty( { mtr_t mtr; ulong space_id = *static_cast(save); + mysql_mutex_unlock(&LOCK_global_system_variables); mtr_start(&mtr); @@ -17295,6 +17303,7 @@ innodb_make_page_dirty( MLOG_2BYTES, &mtr); } mtr_commit(&mtr); + mysql_mutex_lock(&LOCK_global_system_variables); } #endif // UNIV_DEBUG @@ -17933,8 +17942,11 @@ innodb_buffer_pool_evict_update( { if (const char* op = *static_cast(save)) { if (!strcmp(op, "uncompressed")) { + mysql_mutex_unlock(&LOCK_global_system_variables); for (uint tries = 0; tries < 10000; tries++) { if (innodb_buffer_pool_evict_uncompressed()) { + mysql_mutex_lock( + &LOCK_global_system_variables); return; } @@ -18237,7 +18249,9 @@ purge_run_now_set( check function */ { if (*(my_bool*) save && trx_purge_state() != PURGE_STATE_DISABLED) { + mysql_mutex_unlock(&LOCK_global_system_variables); trx_purge_run(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -18260,7 +18274,9 @@ purge_stop_now_set( check function */ { if (*(my_bool*) save && trx_purge_state() != PURGE_STATE_DISABLED) { + mysql_mutex_unlock(&LOCK_global_system_variables); trx_purge_stop(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -18282,6 +18298,8 @@ checkpoint_now_set( check function */ { if (*(my_bool*) save) { + mysql_mutex_unlock(&LOCK_global_system_variables); + while (log_sys->last_checkpoint_lsn < log_sys->lsn) { log_make_checkpoint_at(LSN_MAX, TRUE); fil_flush_file_spaces(FIL_LOG); @@ -18295,6 +18313,8 @@ checkpoint_now_set( "system tablespace at checkpoint err=%s", ut_strerr(err)); } + + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -18316,8 +18336,10 @@ buf_flush_list_now_set( check function */ { if (*(my_bool*) save) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_flush_list(ULINT_MAX, LSN_MAX, NULL); buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); + mysql_mutex_lock(&LOCK_global_system_variables); } } #endif /* UNIV_DEBUG */ @@ -18419,7 +18441,9 @@ buffer_pool_dump_now( check function */ { if (*(my_bool*) save && !srv_read_only_mode) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_dump_start(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -18442,7 +18466,9 @@ buffer_pool_load_now( check function */ { if (*(my_bool*) save && !srv_read_only_mode) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_load_start(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -18465,96 +18491,71 @@ buffer_pool_load_abort( check function */ { if (*(my_bool*) save && !srv_read_only_mode) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_load_abort(); + mysql_mutex_lock(&LOCK_global_system_variables); } } /** Update innodb_status_output or innodb_status_output_locks, which control InnoDB "status monitor" output to the error log. -@param[in] thd thread handle -@param[in] var system variable -@param[out] var_ptr current value +@param[out] var current value @param[in] save to-be-assigned value */ static void -innodb_status_output_update( -/*========================*/ - THD* thd __attribute__((unused)), - struct st_mysql_sys_var* var __attribute__((unused)), - void* var_ptr __attribute__((unused)), - const void* save __attribute__((unused))) +innodb_status_output_update(THD*,st_mysql_sys_var*,void*var,const void*save) { - *static_cast(var_ptr) = *static_cast(save); + *static_cast(var) = *static_cast(save); + mysql_mutex_unlock(&LOCK_global_system_variables); /* Wakeup server monitor thread. */ os_event_set(srv_monitor_event); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encryption_threads */ +/** Update the system variable innodb_encryption_threads. +@param[in] save to-be-assigned value */ static void -innodb_encryption_threads_update( -/*=============================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encryption_threads_update(THD*,st_mysql_sys_var*,void*,const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_thread_cnt(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encryption_rotate_key_age */ +/** Update the system variable innodb_encryption_rotate_key_age. +@param[in] save to-be-assigned value */ static void -innodb_encryption_rotate_key_age_update( -/*====================================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encryption_rotate_key_age_update(THD*,st_mysql_sys_var*,void*, + const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_rotate_key_age(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encryption_rotation_iops */ +/** Update the system variable innodb_encryption_rotation_iops. +@param[in] save to-be-assigned value */ static void -innodb_encryption_rotation_iops_update( -/*===================================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encryption_rotation_iops_update(THD*,st_mysql_sys_var*,void*, + const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_rotation_iops(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encrypt_tables*/ +/** Update the system variable innodb_encrypt_tables. +@param[in] save to-be-assigned value */ static void -innodb_encrypt_tables_update( -/*=========================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encrypt_tables_update(THD*,st_mysql_sys_var*,void*,const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_encrypt_tables(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } static SHOW_VAR innodb_status_variables_export[]= { @@ -19736,12 +19737,15 @@ innobase_disallow_writes_update( variable */ const void* save) /* in: temporary storage */ { - *(my_bool*)var_ptr = *(my_bool*)save; + const my_bool val = *static_cast(save); + *static_cast(var_ptr) = val; ut_a(srv_allow_writes_event); - if (*(my_bool*)var_ptr) + mysql_mutex_unlock(&LOCK_global_system_variables); + if (val) os_event_reset(srv_allow_writes_event); else os_event_set(srv_allow_writes_event); + mysql_mutex_lock(&LOCK_global_system_variables); } static MYSQL_SYSVAR_BOOL(disallow_writes, innobase_disallow_writes, diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h index 948c6f25503..09100b35e68 100644 --- a/storage/innobase/include/buf0lru.h +++ b/storage/innobase/include/buf0lru.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -202,13 +202,13 @@ buf_LRU_make_block_old( Updates buf_pool->LRU_old_ratio. @return updated old_pct */ UNIV_INTERN -ulint +uint buf_LRU_old_ratio_update( /*=====================*/ uint old_pct,/*!< in: Reserve this percentage of the buffer pool for "old" blocks. */ - ibool adjust);/*!< in: TRUE=adjust the LRU list; - FALSE=just assign buf_pool->LRU_old_ratio + bool adjust);/*!< in: true=adjust the LRU list; + false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB */ /********************************************************************//** Update the historical stats that we are collecting for LRU eviction diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc index 5f3a8627055..13bf5e79f2d 100644 --- a/storage/xtradb/buf/buf0lru.cc +++ b/storage/xtradb/buf/buf0lru.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -2408,8 +2408,8 @@ buf_LRU_old_ratio_update_instance( buf_pool_t* buf_pool,/*!< in: buffer pool instance */ uint old_pct,/*!< in: Reserve this percentage of the buffer pool for "old" blocks. */ - ibool adjust) /*!< in: TRUE=adjust the LRU list; - FALSE=just assign buf_pool->LRU_old_ratio + bool adjust) /*!< in: true=adjust the LRU list; + false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB */ { uint ratio; @@ -2447,17 +2447,17 @@ buf_LRU_old_ratio_update_instance( Updates buf_pool->LRU_old_ratio. @return updated old_pct */ UNIV_INTERN -ulint +uint buf_LRU_old_ratio_update( /*=====================*/ uint old_pct,/*!< in: Reserve this percentage of the buffer pool for "old" blocks. */ - ibool adjust) /*!< in: TRUE=adjust the LRU list; - FALSE=just assign buf_pool->LRU_old_ratio + bool adjust) /*!< in: true=adjust the LRU list; + false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB */ { ulint i; - ulint new_ratio = 0; + uint new_ratio = 0; for (i = 0; i < srv_buf_pool_instances; i++) { buf_pool_t* buf_pool; diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index aa17eb6a5ea..0cdd5ac2452 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -17887,11 +17887,13 @@ innodb_adaptive_hash_index_update( const void* save) /*!< in: immediate result from check function */ { + mysql_mutex_unlock(&LOCK_global_system_variables); if (*(my_bool*) save) { btr_search_enable(); } else { btr_search_disable(); } + mysql_mutex_lock(&LOCK_global_system_variables); } /****************************************************************//** @@ -17912,7 +17914,9 @@ innodb_cmp_per_index_update( /* Reset the stats whenever we enable the table INFORMATION_SCHEMA.innodb_cmp_per_index. */ if (!srv_cmp_per_index_enabled && *(my_bool*) save) { + mysql_mutex_unlock(&LOCK_global_system_variables); page_zip_reset_stat_per_index(); + mysql_mutex_lock(&LOCK_global_system_variables); } srv_cmp_per_index_enabled = !!(*(my_bool*) save); @@ -17933,9 +17937,11 @@ innodb_old_blocks_pct_update( const void* save) /*!< in: immediate result from check function */ { - innobase_old_blocks_pct = static_cast( - buf_LRU_old_ratio_update( - *static_cast(save), TRUE)); + mysql_mutex_unlock(&LOCK_global_system_variables); + uint ratio = buf_LRU_old_ratio_update(*static_cast(save), + true); + mysql_mutex_lock(&LOCK_global_system_variables); + innobase_old_blocks_pct = ratio; } /****************************************************************//** @@ -17953,9 +17959,10 @@ innodb_change_buffer_max_size_update( const void* save) /*!< in: immediate result from check function */ { - innobase_change_buffer_max_size = - (*static_cast(save)); + innobase_change_buffer_max_size = *static_cast(save); + mysql_mutex_unlock(&LOCK_global_system_variables); ibuf_max_size_update(innobase_change_buffer_max_size); + mysql_mutex_lock(&LOCK_global_system_variables); } #ifdef UNIV_DEBUG @@ -17999,6 +18006,7 @@ innodb_make_page_dirty( { mtr_t mtr; ulong space_id = *static_cast(save); + mysql_mutex_unlock(&LOCK_global_system_variables); mtr_start(&mtr); @@ -18016,6 +18024,7 @@ innodb_make_page_dirty( MLOG_2BYTES, &mtr); } mtr_commit(&mtr); + mysql_mutex_lock(&LOCK_global_system_variables); } #endif // UNIV_DEBUG @@ -18661,8 +18670,11 @@ innodb_buffer_pool_evict_update( { if (const char* op = *static_cast(save)) { if (!strcmp(op, "uncompressed")) { + mysql_mutex_unlock(&LOCK_global_system_variables); for (uint tries = 0; tries < 10000; tries++) { if (innodb_buffer_pool_evict_uncompressed()) { + mysql_mutex_lock( + &LOCK_global_system_variables); return; } @@ -19199,7 +19211,9 @@ purge_run_now_set( check function */ { if (*(my_bool*) save && trx_purge_state() != PURGE_STATE_DISABLED) { + mysql_mutex_unlock(&LOCK_global_system_variables); trx_purge_run(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -19222,7 +19236,9 @@ purge_stop_now_set( check function */ { if (*(my_bool*) save && trx_purge_state() != PURGE_STATE_DISABLED) { + mysql_mutex_unlock(&LOCK_global_system_variables); trx_purge_stop(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -19244,6 +19260,8 @@ checkpoint_now_set( check function */ { if (*(my_bool*) save) { + mysql_mutex_unlock(&LOCK_global_system_variables); + while (log_sys->last_checkpoint_lsn < log_sys->lsn) { log_make_checkpoint_at(LSN_MAX, TRUE); fil_flush_file_spaces(FIL_LOG); @@ -19257,6 +19275,8 @@ checkpoint_now_set( "system tablespace at checkpoint err=%s", ut_strerr(err)); } + + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -19278,8 +19298,10 @@ buf_flush_list_now_set( check function */ { if (*(my_bool*) save) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_flush_list(ULINT_MAX, LSN_MAX, NULL); buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -19406,7 +19428,9 @@ buffer_pool_dump_now( check function */ { if (*(my_bool*) save && !srv_read_only_mode) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_dump_start(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -19429,7 +19453,9 @@ buffer_pool_load_now( check function */ { if (*(my_bool*) save && !srv_read_only_mode) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_load_start(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -19452,96 +19478,71 @@ buffer_pool_load_abort( check function */ { if (*(my_bool*) save && !srv_read_only_mode) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_load_abort(); + mysql_mutex_lock(&LOCK_global_system_variables); } } /** Update innodb_status_output or innodb_status_output_locks, which control InnoDB "status monitor" output to the error log. -@param[in] thd thread handle -@param[in] var system variable -@param[out] var_ptr current value +@param[out] var current value @param[in] save to-be-assigned value */ static void -innodb_status_output_update( -/*========================*/ - THD* thd __attribute__((unused)), - struct st_mysql_sys_var* var __attribute__((unused)), - void* var_ptr __attribute__((unused)), - const void* save __attribute__((unused))) +innodb_status_output_update(THD*,st_mysql_sys_var*,void*var,const void*save) { - *static_cast(var_ptr) = *static_cast(save); + *static_cast(var) = *static_cast(save); + mysql_mutex_unlock(&LOCK_global_system_variables); /* Wakeup server monitor thread. */ os_event_set(srv_monitor_event); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encryption_threads */ +/** Update the system variable innodb_encryption_threads. +@param[in] save to-be-assigned value */ static void -innodb_encryption_threads_update( -/*=============================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encryption_threads_update(THD*,st_mysql_sys_var*,void*,const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_thread_cnt(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encryption_rotate_key_age */ +/** Update the system variable innodb_encryption_rotate_key_age. +@param[in] save to-be-assigned value */ static void -innodb_encryption_rotate_key_age_update( -/*====================================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encryption_rotate_key_age_update(THD*,st_mysql_sys_var*,void*, + const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_rotate_key_age(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encryption_rotation_iops */ +/** Update the system variable innodb_encryption_rotation_iops. +@param[in] save to-be-assigned value */ static void -innodb_encryption_rotation_iops_update( -/*===================================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encryption_rotation_iops_update(THD*,st_mysql_sys_var*,void*, + const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_rotation_iops(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encrypt_tables*/ +/** Update the system variable innodb_encrypt_tables. +@param[in] save to-be-assigned value */ static void -innodb_encrypt_tables_update( -/*=========================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encrypt_tables_update(THD*,st_mysql_sys_var*,void*,const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_encrypt_tables(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } static SHOW_VAR innodb_status_variables_export[]= { @@ -20979,12 +20980,15 @@ innobase_disallow_writes_update( variable */ const void* save) /* in: temporary storage */ { - *(my_bool*)var_ptr = *(my_bool*)save; + const my_bool val = *static_cast(save); + *static_cast(var_ptr) = val; ut_a(srv_allow_writes_event); - if (*(my_bool*)var_ptr) + mysql_mutex_unlock(&LOCK_global_system_variables); + if (val) os_event_reset(srv_allow_writes_event); else os_event_set(srv_allow_writes_event); + mysql_mutex_lock(&LOCK_global_system_variables); } static MYSQL_SYSVAR_BOOL(disallow_writes, innobase_disallow_writes, diff --git a/storage/xtradb/include/buf0lru.h b/storage/xtradb/include/buf0lru.h index e0f2277b6a2..69ada4abb70 100644 --- a/storage/xtradb/include/buf0lru.h +++ b/storage/xtradb/include/buf0lru.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -208,13 +208,13 @@ buf_LRU_make_block_old( Updates buf_pool->LRU_old_ratio. @return updated old_pct */ UNIV_INTERN -ulint +uint buf_LRU_old_ratio_update( /*=====================*/ uint old_pct,/*!< in: Reserve this percentage of the buffer pool for "old" blocks. */ - ibool adjust);/*!< in: TRUE=adjust the LRU list; - FALSE=just assign buf_pool->LRU_old_ratio + bool adjust);/*!< in: true=adjust the LRU list; + false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB */ /********************************************************************//** Update the historical stats that we are collecting for LRU eviction From 79b46ab2a6eae493b89ab0fcfc03fcf6b585244c Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Thu, 23 May 2019 14:25:54 +0530 Subject: [PATCH 31/43] MDEV-19541 InnoDB crashes when trying to recover a corrupted page - Don't apply redo log for the corrupted page when innodb_force_recovery > 0. - Allow the table to be dropped when index root page is corrupted when innodb_force_recovery > 0. --- .../r/corrupted_during_recovery.result | 7 +-- .../t/corrupted_during_recovery.test | 7 ++- .../innodb/r/corrupted_during_recovery.result | 7 +-- .../innodb/t/corrupted_during_recovery.test | 6 +- storage/innobase/buf/buf0buf.cc | 57 ++++++++++++++----- storage/innobase/include/log0recv.h | 5 ++ storage/innobase/log/log0recv.cc | 26 +++++++++ 7 files changed, 88 insertions(+), 27 deletions(-) diff --git a/mysql-test/suite/encryption/r/corrupted_during_recovery.result b/mysql-test/suite/encryption/r/corrupted_during_recovery.result index 41c0d7d75a8..356dce64f8d 100644 --- a/mysql-test/suite/encryption/r/corrupted_during_recovery.result +++ b/mysql-test/suite/encryption/r/corrupted_during_recovery.result @@ -9,14 +9,11 @@ INSERT INTO t2 VALUES(2); SELECT * FROM t1; ERROR 42000: Unknown storage engine 'InnoDB' SELECT * FROM t1; -a -1 -2 +ERROR 42S02: Table 'test.t1' doesn't exist in engine SELECT * FROM t2; a 2 -CHECK TABLE t1,t2; +CHECK TABLE t2; Table Op Msg_type Msg_text -test.t1 check status OK test.t2 check status OK DROP TABLE t1, t2; diff --git a/mysql-test/suite/encryption/t/corrupted_during_recovery.test b/mysql-test/suite/encryption/t/corrupted_during_recovery.test index 5784d5775c6..1ca3419820b 100644 --- a/mysql-test/suite/encryption/t/corrupted_during_recovery.test +++ b/mysql-test/suite/encryption/t/corrupted_during_recovery.test @@ -50,11 +50,16 @@ EOF --source include/start_mysqld.inc --error ER_UNKNOWN_STORAGE_ENGINE SELECT * FROM t1; +--disable_query_log +call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t[1].ibd looks corrupted; key_version=1786080875"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted. Please drop the table and recreate."); +--enable_query_log let $restart_parameters=--innodb_force_recovery=1; --source include/restart_mysqld.inc +--error ER_NO_SUCH_TABLE_IN_ENGINE SELECT * FROM t1; SELECT * FROM t2; -CHECK TABLE t1,t2; +CHECK TABLE t2; DROP TABLE t1, t2; diff --git a/mysql-test/suite/innodb/r/corrupted_during_recovery.result b/mysql-test/suite/innodb/r/corrupted_during_recovery.result index 788f17e3284..ee4db08fc85 100644 --- a/mysql-test/suite/innodb/r/corrupted_during_recovery.result +++ b/mysql-test/suite/innodb/r/corrupted_during_recovery.result @@ -9,14 +9,11 @@ INSERT INTO t2 VALUES(1); SELECT * FROM t1; ERROR 42000: Unknown storage engine 'InnoDB' SELECT * FROM t1; -a -0 -2 +ERROR 42S02: Table 'test.t1' doesn't exist in engine SELECT * FROM t2; a 1 -CHECK TABLE t1,t2; +CHECK TABLE t2; Table Op Msg_type Msg_text -test.t1 check status OK test.t2 check status OK DROP TABLE t1, t2; diff --git a/mysql-test/suite/innodb/t/corrupted_during_recovery.test b/mysql-test/suite/innodb/t/corrupted_during_recovery.test index fbfb1bbe5d5..dad08645085 100644 --- a/mysql-test/suite/innodb/t/corrupted_during_recovery.test +++ b/mysql-test/suite/innodb/t/corrupted_during_recovery.test @@ -6,6 +6,8 @@ call mtr.add_suppression("Plugin 'InnoDB' init function returned error"); call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed"); call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed file read of tablespace test/t1 page"); call mtr.add_suppression("InnoDB: Failed to read file '.*test.t1\\.ibd' at offset 3: Page read from tablespace is corrupted."); +call mtr.add_suppression("InnoDB: Background Page read failed to read or decrypt \\[page id: space=\\d+, page number=3\\]"); +call mtr.add_suppression("InnoDB: Table `test`.`t1` is corrupted. Please drop the table and recreate."); --enable_query_log let INNODB_PAGE_SIZE=`select @@innodb_page_size`; @@ -53,8 +55,10 @@ EOF SELECT * FROM t1; let $restart_parameters=--innodb_force_recovery=1; --source include/restart_mysqld.inc + +--error ER_NO_SUCH_TABLE_IN_ENGINE SELECT * FROM t1; SELECT * FROM t2; -CHECK TABLE t1,t2; +CHECK TABLE t2; DROP TABLE t1, t2; diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 41d9efe25cc..756caac1f54 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -4378,6 +4378,11 @@ loop: return (NULL); } + if (local_err == DB_PAGE_CORRUPTED + && srv_force_recovery) { + return NULL; + } + /* Try to set table as corrupted instead of asserting. */ if (page_id.space() != TRX_SYS_SPACE && @@ -5743,18 +5748,33 @@ buf_page_monitor( MONITOR_INC_NOCHECK(counter); } -/********************************************************************//** -Mark a table with the specified space pointed by bpage->id.space() corrupted. -Also remove the bpage from LRU list. -@param[in,out] bpage Block */ +/** Mark a table corrupted. +@param[in] bpage Corrupted page. */ static void buf_mark_space_corrupt(buf_page_t* bpage) +{ + /* If block is not encrypted find the table with specified + space id, and mark it corrupted. Encrypted tables + are marked unusable later e.g. in ::open(). */ + if (!bpage->encrypted) { + dict_set_corrupted_by_space(bpage->id.space()); + } else { + dict_set_encrypted_by_space(bpage->id.space()); + } +} + +/** Mark a table corrupted. +@param[in] bpage Corrupted page +@param[in] space Corrupted page belongs to tablespace +Also remove the bpage from LRU list. */ +static +void +buf_corrupt_page_release(buf_page_t* bpage, const fil_space_t* space) { buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); const ibool uncompressed = (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE); - uint32_t space = bpage->id.space(); /* First unfix and release lock on the bpage */ buf_pool_mutex_enter(buf_pool); @@ -5773,13 +5793,8 @@ buf_mark_space_corrupt(buf_page_t* bpage) mutex_exit(buf_page_get_mutex(bpage)); - /* If block is not encrypted find the table with specified - space id, and mark it corrupted. Encrypted tables - are marked unusable later e.g. in ::open(). */ - if (!bpage->encrypted) { - dict_set_corrupted_by_space(space); - } else { - dict_set_encrypted_by_space(space); + if (!srv_force_recovery) { + buf_mark_space_corrupt(bpage); } /* After this point bpage can't be referenced. */ @@ -5981,7 +5996,7 @@ database_corrupted: "buf_page_import_corrupt_failure", if (!is_predefined_tablespace( bpage->id.space())) { - buf_mark_space_corrupt(bpage); + buf_corrupt_page_release(bpage, space); ib::info() << "Simulated IMPORT " "corruption"; fil_space_release_for_io(space); @@ -6015,7 +6030,7 @@ database_corrupted: << FORCE_RECOVERY_MSG; } - if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) { + if (!srv_force_recovery) { /* If page space id is larger than TRX_SYS_SPACE (0), we will attempt to mark the corresponding @@ -6025,7 +6040,7 @@ database_corrupted: " a corrupt database page."; } - buf_mark_space_corrupt(bpage); + buf_corrupt_page_release(bpage, space); fil_space_release_for_io(space); return(err); } @@ -6034,6 +6049,18 @@ database_corrupted: DBUG_EXECUTE_IF("buf_page_import_corrupt_failure", page_not_corrupt: bpage = bpage; ); + if (err == DB_PAGE_CORRUPTED + || err == DB_DECRYPTION_FAILED) { + buf_corrupt_page_release(bpage, space); + + if (recv_recovery_is_on()) { + recv_recover_corrupt_page(bpage); + } + + fil_space_release_for_io(space); + return err; + } + if (recv_recovery_is_on()) { recv_recover_page(bpage); } diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h index 0b04e1642cf..9bb54960058 100644 --- a/storage/innobase/include/log0recv.h +++ b/storage/innobase/include/log0recv.h @@ -49,6 +49,11 @@ dberr_t recv_find_max_checkpoint(ulint* max_field) MY_ATTRIBUTE((nonnull, warn_unused_result)); +/** Reduces recv_sys->n_addrs for the corrupted page. +This function should called when srv_force_recovery > 0. +@param[in] bpage buffer pool page */ +void recv_recover_corrupt_page(buf_page_t* bpage); + /** Apply any buffered redo log to a page that was just read from a data file. @param[in,out] bpage buffer pool page */ ATTRIBUTE_COLD void recv_recover_page(buf_page_t* bpage); diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 9484901c90f..c0521f1dba4 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2212,6 +2212,32 @@ skip_log: } } +/** Reduces recv_sys->n_addrs for the corrupted page. +This function should called when srv_force_recovery > 0. +@param[in] bpage buffer pool page */ +void recv_recover_corrupt_page(buf_page_t* bpage) +{ + ut_ad(srv_force_recovery); + mutex_enter(&recv_sys->mutex); + + if (!recv_sys->apply_log_recs) { + mutex_exit(&recv_sys->mutex); + return; + } + + recv_addr_t* recv_addr = recv_get_fil_addr_struct( + bpage->id.space(), bpage->id.page_no()); + + ut_ad(recv_addr->state != RECV_WILL_NOT_READ); + + if (recv_addr->state != RECV_BEING_PROCESSED + && recv_addr->state != RECV_PROCESSED) { + recv_sys->n_addrs--; + } + + mutex_exit(&recv_sys->mutex); +} + /** Apply any buffered redo log to a page that was just read from a data file. @param[in,out] bpage buffer pool page */ void recv_recover_page(buf_page_t* bpage) From c8d9ec2cbb546bb426a91d9d40d4b00989cfe82e Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Tue, 29 May 2018 23:25:50 +0300 Subject: [PATCH 32/43] Cleanup unused READ_RECORD::forms --- sql/records.cc | 1 - sql/records.h | 2 -- sql/sql_window.h | 1 - 3 files changed, 4 deletions(-) diff --git a/sql/records.cc b/sql/records.cc index 3decb8f1d24..fe2b2055c0e 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -194,7 +194,6 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, bzero((char*) info,sizeof(*info)); info->thd=thd; info->table=table; - info->forms= &info->table; /* Only one table */ info->addon_field= addon_field; if ((table->s->tmp_table == INTERNAL_TMP_TABLE || diff --git a/sql/records.h b/sql/records.h index 4f8e14da9ac..a4564df6146 100644 --- a/sql/records.h +++ b/sql/records.h @@ -52,8 +52,6 @@ struct READ_RECORD typedef int (*Setup_func)(struct st_join_table*); TABLE *table; /* Head-form */ - //handler *file; - TABLE **forms; /* head and ref forms */ Unlock_row_func unlock_row; Read_func read_record_func; THD *thd; diff --git a/sql/sql_window.h b/sql/sql_window.h index 21f2c8af108..373b367b211 100644 --- a/sql/sql_window.h +++ b/sql/sql_window.h @@ -18,7 +18,6 @@ #define SQL_WINDOW_INCLUDED #include "filesort.h" -#include "records.h" class Item_window_func; From 3950a98a34b182acddd49d5090cdb4d109e72cf6 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Tue, 29 May 2018 23:25:50 +0300 Subject: [PATCH 33/43] Cleanup unused READ_RECORD::index --- sql/records.h | 1 - sql/sql_select.cc | 2 -- 2 files changed, 3 deletions(-) diff --git a/sql/records.h b/sql/records.h index a4564df6146..38552e81ab3 100644 --- a/sql/records.h +++ b/sql/records.h @@ -58,7 +58,6 @@ struct READ_RECORD SQL_SELECT *select; uint cache_records; uint ref_length,struct_length,reclength,rec_cache_size,error_offset; - uint index; uchar *ref_pos; /* pointer to form->refpos */ uchar *record; uchar *rec_buf; /* to read field values after filesort */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6b1706e5451..b731b1851fd 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -20392,7 +20392,6 @@ join_read_first(JOIN_TAB *tab) tab->table->status=0; tab->read_record.read_record_func= join_read_next; tab->read_record.table=table; - tab->read_record.index=tab->index; tab->read_record.record=table->record[0]; if (!table->file->inited) error= table->file->ha_index_init(tab->index, tab->sorted); @@ -20433,7 +20432,6 @@ join_read_last(JOIN_TAB *tab) tab->table->status=0; tab->read_record.read_record_func= join_read_prev; tab->read_record.table=table; - tab->read_record.index=tab->index; tab->read_record.record=table->record[0]; if (!table->file->inited) error= table->file->ha_index_init(tab->index, 1); From 5d46eeefad33f084be3a52dfaf3169c0b5e3f608 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Tue, 29 May 2018 23:25:50 +0300 Subject: [PATCH 34/43] Simplified away READ_RECORD::cache_records --- sql/records.cc | 22 +++++++++++----------- sql/records.h | 1 - 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/sql/records.cc b/sql/records.cc index fe2b2055c0e..662931f3da7 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -584,7 +584,7 @@ static int rr_unpack_from_buffer(READ_RECORD *info) static int init_rr_cache(THD *thd, READ_RECORD *info) { - uint rec_cache_size; + uint rec_cache_size, cache_records; DBUG_ENTER("init_rr_cache"); info->struct_length= 3+MAX_REFLENGTH; @@ -593,22 +593,22 @@ static int init_rr_cache(THD *thd, READ_RECORD *info) info->reclength= ALIGN_SIZE(info->struct_length); info->error_offset= info->table->s->reclength; - info->cache_records= (thd->variables.read_rnd_buff_size / - (info->reclength+info->struct_length)); - rec_cache_size= info->cache_records*info->reclength; - info->rec_cache_size= info->cache_records*info->ref_length; + cache_records= thd->variables.read_rnd_buff_size / + (info->reclength + info->struct_length); + rec_cache_size= cache_records * info->reclength; + info->rec_cache_size= cache_records * info->ref_length; // We have to allocate one more byte to use uint3korr (see comments for it) - if (info->cache_records <= 2 || - !(info->cache=(uchar*) my_malloc_lock(rec_cache_size+info->cache_records* - info->struct_length+1, - MYF(MY_THREAD_SPECIFIC)))) + if (cache_records <= 2 || + !(info->cache= (uchar*) my_malloc_lock(rec_cache_size + cache_records * + info->struct_length + 1, + MYF(MY_THREAD_SPECIFIC)))) DBUG_RETURN(1); #ifdef HAVE_valgrind // Avoid warnings in qsort - bzero(info->cache,rec_cache_size+info->cache_records* info->struct_length+1); + bzero(info->cache, rec_cache_size + cache_records * info->struct_length + 1); #endif - DBUG_PRINT("info",("Allocated buffert for %d records",info->cache_records)); + DBUG_PRINT("info", ("Allocated buffer for %d records", cache_records)); info->read_positions=info->cache+rec_cache_size; info->cache_pos=info->cache_end=info->cache; DBUG_RETURN(0); diff --git a/sql/records.h b/sql/records.h index 38552e81ab3..534264c8223 100644 --- a/sql/records.h +++ b/sql/records.h @@ -56,7 +56,6 @@ struct READ_RECORD Read_func read_record_func; THD *thd; SQL_SELECT *select; - uint cache_records; uint ref_length,struct_length,reclength,rec_cache_size,error_offset; uchar *ref_pos; /* pointer to form->refpos */ uchar *record; From fcb68ffe3dfb1c841852bd62a9aac9708888f4e9 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Tue, 29 May 2018 23:25:50 +0300 Subject: [PATCH 35/43] Simplified away READ_RECORD::struct_length --- sql/records.cc | 16 ++++++++-------- sql/records.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sql/records.cc b/sql/records.cc index 662931f3da7..c2db29c4912 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -582,31 +582,32 @@ static int rr_unpack_from_buffer(READ_RECORD *info) } /* cacheing of records from a database */ +static const uint STRUCT_LENGTH= 3 + MAX_REFLENGTH; + static int init_rr_cache(THD *thd, READ_RECORD *info) { uint rec_cache_size, cache_records; DBUG_ENTER("init_rr_cache"); - info->struct_length= 3+MAX_REFLENGTH; info->reclength= ALIGN_SIZE(info->table->s->reclength+1); - if (info->reclength < info->struct_length) - info->reclength= ALIGN_SIZE(info->struct_length); + if (info->reclength < STRUCT_LENGTH) + info->reclength= ALIGN_SIZE(STRUCT_LENGTH); info->error_offset= info->table->s->reclength; cache_records= thd->variables.read_rnd_buff_size / - (info->reclength + info->struct_length); + (info->reclength + STRUCT_LENGTH); rec_cache_size= cache_records * info->reclength; info->rec_cache_size= cache_records * info->ref_length; // We have to allocate one more byte to use uint3korr (see comments for it) if (cache_records <= 2 || !(info->cache= (uchar*) my_malloc_lock(rec_cache_size + cache_records * - info->struct_length + 1, + STRUCT_LENGTH + 1, MYF(MY_THREAD_SPECIFIC)))) DBUG_RETURN(1); #ifdef HAVE_valgrind // Avoid warnings in qsort - bzero(info->cache, rec_cache_size + cache_records * info->struct_length + 1); + bzero(info->cache, rec_cache_size + cache_records * STRUCT_LENGTH + 1); #endif DBUG_PRINT("info", ("Allocated buffer for %d records", cache_records)); info->read_positions=info->cache+rec_cache_size; @@ -663,8 +664,7 @@ static int rr_from_cache(READ_RECORD *info) int3store(ref_position,(long) i); ref_position+=3; } - my_qsort(info->read_positions, length, info->struct_length, - (qsort_cmp) rr_cmp); + my_qsort(info->read_positions, length, STRUCT_LENGTH, (qsort_cmp) rr_cmp); position=info->read_positions; for (i=0 ; i < length ; i++) diff --git a/sql/records.h b/sql/records.h index 534264c8223..e97f6b273cc 100644 --- a/sql/records.h +++ b/sql/records.h @@ -56,7 +56,7 @@ struct READ_RECORD Read_func read_record_func; THD *thd; SQL_SELECT *select; - uint ref_length,struct_length,reclength,rec_cache_size,error_offset; + uint ref_length, reclength, rec_cache_size, error_offset; uchar *ref_pos; /* pointer to form->refpos */ uchar *record; uchar *rec_buf; /* to read field values after filesort */ From 8358c6f03edb941be488f009c2bd0eb9df47e8c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 28 May 2019 15:24:32 +0300 Subject: [PATCH 36/43] MDEV-19614: Fix innodb_plugin on Windows LOCK_global_system_variables: Declare with MYSQL_PLUGIN_IMPORT --- sql/mysqld.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/mysqld.h b/sql/mysqld.h index 1f34856c6c8..e939524dbff 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -1,5 +1,5 @@ /* Copyright (c) 2006, 2016, Oracle and/or its affiliates. - Copyright (c) 2010, 2016, MariaDB + Copyright (c) 2010, 2019, MariaDB 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 @@ -560,11 +560,11 @@ extern mysql_mutex_t LOCK_item_func_sleep, LOCK_status, LOCK_show_status, LOCK_error_log, LOCK_delayed_insert, LOCK_short_uuid_generator, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, - LOCK_slave_list, LOCK_active_mi, LOCK_manager, - LOCK_global_system_variables, LOCK_user_conn, + LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_user_conn, LOCK_prepared_stmt_count, LOCK_error_messages, LOCK_connection_count, LOCK_slave_background; -extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_thread_count; +extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_thread_count, + LOCK_global_system_variables; #ifdef HAVE_OPENSSL extern char* des_key_file; extern mysql_mutex_t LOCK_des_key_file; From 88157247fc5920ef77cfa96aebd33460d86b3905 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 17 May 2019 20:32:51 +0530 Subject: [PATCH 37/43] MDEV-19509 InnoDB skips the tablespace in rotation list - If one of the encryption threads already started the initialization of the tablespace then don't remove the other uninitialized tablespace from the rotation list. - If there is a change in innodb_encrypt_tables then don't remove the processed tablespace from rotation list. --- storage/innobase/fil/fil0crypt.cc | 32 ++++++++--------- storage/innobase/fil/fil0fil.cc | 58 +++++++++++++++--------------- storage/innobase/include/fil0fil.h | 27 ++++++++++++-- 3 files changed, 67 insertions(+), 50 deletions(-) diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 902af66ebe7..635ed619df0 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -943,14 +943,10 @@ fil_crypt_read_crypt_data(fil_space_t* space) mtr.commit(); } -/*********************************************************************** -Start encrypting a space +/** Start encrypting a space @param[in,out] space Tablespace -@return true if a recheck is needed */ -static -bool -fil_crypt_start_encrypting_space( - fil_space_t* space) +@return true if a recheck of tablespace is needed by encryption thread. */ +static bool fil_crypt_start_encrypting_space(fil_space_t* space) { bool recheck = false; @@ -1408,14 +1404,12 @@ fil_crypt_return_iops( fil_crypt_update_total_stat(state); } -/*********************************************************************** -Search for a space needing rotation -@param[in,out] key_state Key state -@param[in,out] state Rotation state -@param[in,out] recheck recheck ? */ -static -bool -fil_crypt_find_space_to_rotate( +/** Search for a space needing rotation +@param[in,out] key_state Key state +@param[in,out] state Rotation state +@param[in,out] recheck recheck of the tablespace is needed or + still encryption thread does write page 0 */ +static bool fil_crypt_find_space_to_rotate( key_state_t* key_state, rotate_thread_t* state, bool* recheck) @@ -1448,7 +1442,9 @@ fil_crypt_find_space_to_rotate( if (srv_fil_crypt_rotate_key_age) { state->space = fil_space_next(state->space); } else { - state->space = fil_space_keyrotate_next(state->space); + state->space = fil_system->keyrotate_next( + state->space, *recheck, + key_state->key_version); } while (!state->should_shutdown() && state->space) { @@ -1470,7 +1466,9 @@ fil_crypt_find_space_to_rotate( if (srv_fil_crypt_rotate_key_age) { state->space = fil_space_next(state->space); } else { - state->space = fil_space_keyrotate_next(state->space); + state->space = fil_system->keyrotate_next( + state->space, *recheck, + key_state->key_version); } } diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 595f9c3e729..08c3a699a04 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -5983,28 +5983,32 @@ fil_space_remove_from_keyrotation(fil_space_t* space) Once started, the caller must keep calling this until it returns NULL. fil_space_acquire() and fil_space_release() are invoked here which blocks a concurrent operation from dropping the tablespace. -@param[in] prev_space Pointer to the previous fil_space_t. +@param[in] prev_space Previous tablespace or NULL to start + from beginning of fil_system->rotation list +@param[in] recheck recheck of the tablespace is needed or + still encryption thread does write page0 for it +@param[in] key_version key version of the key state thread If NULL, use the first fil_space_t on fil_system->space_list. @return pointer to the next fil_space_t. -@retval NULL if this was the last*/ +@retval NULL if this was the last */ fil_space_t* -fil_space_keyrotate_next( - fil_space_t* prev_space) +fil_system_t::keyrotate_next( + fil_space_t* prev_space, + bool recheck, + uint key_version) { - fil_space_t* space = prev_space; - fil_space_t* old = NULL; - mutex_enter(&fil_system->mutex); - if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0) { - if (space) { - ut_ad(space->n_pending_ops > 0); - space->n_pending_ops--; - fil_space_remove_from_keyrotation(space); - } - mutex_exit(&fil_system->mutex); - return(NULL); - } + /* If one of the encryption threads already started the encryption + of the table then don't remove the unencrypted spaces from + rotation list + + If there is a change in innodb_encrypt_tables variables value then + don't remove the last processed tablespace from the rotation list. */ + const bool remove = ((!recheck || prev_space->crypt_data) + && (!key_version == !srv_encrypt_tables)); + + fil_space_t* space = prev_space; if (prev_space == NULL) { space = UT_LIST_GET_FIRST(fil_system->rotation_list); @@ -6017,22 +6021,17 @@ fil_space_keyrotate_next( /* Move on to the next fil_space_t */ space->n_pending_ops--; - old = space; space = UT_LIST_GET_NEXT(rotation_list, space); - fil_space_remove_from_keyrotation(old); - } + while (space != NULL + && (UT_LIST_GET_LEN(space->chain) == 0 + || space->is_stopping())) { + space = UT_LIST_GET_NEXT(rotation_list, space); + } - /* Skip spaces that are being created by fil_ibd_create(), - or dropped. Note that rotation_list contains only - space->purpose == FIL_TYPE_TABLESPACE. */ - while (space != NULL - && (UT_LIST_GET_LEN(space->chain) == 0 - || space->is_stopping())) { - - old = space; - space = UT_LIST_GET_NEXT(rotation_list, space); - fil_space_remove_from_keyrotation(old); + if (remove) { + fil_space_remove_from_keyrotation(prev_space); + } } if (space != NULL) { @@ -6040,7 +6039,6 @@ fil_space_keyrotate_next( } mutex_exit(&fil_system->mutex); - return(space); } diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index a892736f5c4..386f574a59f 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -538,6 +538,25 @@ struct fil_system_t { @return tablespace @retval NULL if the tablespace does not exist or cannot be read */ fil_space_t* read_page0(ulint id); + + /** Return the next fil_space_t from key rotation list. + Once started, the caller must keep calling this until it returns NULL. + fil_space_acquire() and fil_space_release() are invoked here which + blocks a concurrent operation from dropping the tablespace. + @param[in] prev_space Previous tablespace or NULL to start + from beginning of fil_system->rotation + list + @param[in] recheck recheck of the tablespace is needed or + still encryption thread does write page0 + for it + @param[in] key_version key version of the key state thread + If NULL, use the first fil_space_t on fil_system->space_list. + @return pointer to the next fil_space_t. + @retval NULL if this was the last */ + fil_space_t* keyrotate_next( + fil_space_t* prev_space, + bool remove, + uint key_version); }; /** The tablespace memory cache. This variable is NULL before the module is @@ -793,13 +812,15 @@ fil_space_next( Once started, the caller must keep calling this until it returns NULL. fil_space_acquire() and fil_space_release() are invoked here which blocks a concurrent operation from dropping the tablespace. -@param[in,out] prev_space Pointer to the previous fil_space_t. +@param[in] prev_space Previous tablespace or NULL to start + from beginning of fil_system->rotation list +@param[in] remove Whether to remove the previous tablespace from + the rotation list If NULL, use the first fil_space_t on fil_system->space_list. @return pointer to the next fil_space_t. @retval NULL if this was the last*/ fil_space_t* -fil_space_keyrotate_next( - fil_space_t* prev_space) +fil_space_keyrotate_next(fil_space_t* prev_space, bool remove) MY_ATTRIBUTE((warn_unused_result)); /** Wrapper with reference-counting for a fil_space_t. */ From 96d9f03328a737439dc81c5b85584db55449ca6b Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 28 May 2019 18:31:20 +0530 Subject: [PATCH 38/43] MDEV-19602 Replace mysql_version check with frm_version for virtual columns inside InnoDB - Replace mysql_version check with omit_virtual_cols() in ha_innobase::check_if_supported_inplace_alter(). --- storage/innobase/handler/handler0alter.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index c0c002e3042..ffb7d498453 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -593,7 +593,7 @@ ha_innobase::check_if_supported_inplace_alter( /* Before 10.2.2 information about virtual columns was not stored in system tables. We need to do a full alter to rebuild proper 10.2.2+ metadata with the information about virtual columns */ - if (table->s->mysql_version < 100202 && table->s->virtual_fields) { + if (omits_virtual_cols(*table_share)) { DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } From 1ca75ae1c881bf0afae00f4acac0d668446a15d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 28 May 2019 16:43:02 +0300 Subject: [PATCH 39/43] MDEV-19587 innodb_force_recovery=5 crash on DROP SCHEMA At higher levels of innodb_force_recovery, the InnoDB transaction subsystem will not be set up at all. At slightly lower levels, recovered transactions will not be rolled back, and DDL operations could hang due to locks being held at all. Let us consistently refuse all writes if the predicate high_level_read_only holds. We failed to refuse DROP TABLE and DROP DATABASE. (Refusing DROP TABLE is a partial backport from MDEV-19570 in the 10.5 branch.) --- .../innodb/r/innodb_force_recovery.result | 23 +++++++++++-------- .../suite/innodb/t/innodb_force_recovery.test | 15 +++++++----- storage/innobase/handler/ha_innodb.cc | 5 ++-- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb_force_recovery.result b/mysql-test/suite/innodb/r/innodb_force_recovery.result index 0220f68a626..8e700f9489d 100644 --- a/mysql-test/suite/innodb/r/innodb_force_recovery.result +++ b/mysql-test/suite/innodb/r/innodb_force_recovery.result @@ -28,8 +28,10 @@ ERROR HY000: Error on rename of './test/t1' to './test/t3' (errno: 165 "Table is truncate table t1; ERROR HY000: Table 't1' is read only drop table t1; +ERROR HY000: Table 't1' is read only show tables; Tables_in_test +t1 t2 # Restart the server with innodb_force_recovery as 5. select * from t2; @@ -45,18 +47,21 @@ drop index idx on t2; ERROR HY000: Can't create table `test`.`t2` (errno: 165 "Table is read only") update t2 set f1=3 where f2=2; ERROR HY000: Running in read-only mode -create table t1(f1 int not null)engine=innodb; -ERROR HY000: Can't create table `test`.`t1` (errno: 165 "Table is read only") -drop table t1; -ERROR 42S02: Unknown table 'test.t1' +create table t3(f1 int not null)engine=innodb; +ERROR HY000: Can't create table `test`.`t3` (errno: 165 "Table is read only") +drop table t3; +ERROR 42S02: Unknown table 'test.t3' rename table t2 to t3; ERROR HY000: Error on rename of './test/t2' to './test/t3' (errno: 165 "Table is read only") truncate table t2; ERROR HY000: Table 't2' is read only drop table t2; ERROR HY000: Table 't2' is read only +create schema db; +drop schema db; show tables; Tables_in_test +t1 t2 # Restart the server with innodb_force_recovery as 6. select * from t2; @@ -72,10 +77,10 @@ drop index idx on t2; ERROR HY000: Table 't2' is read only update t2 set f1=3 where f2=2; ERROR HY000: Table 't2' is read only -create table t1(f1 int not null)engine=innodb; -ERROR HY000: Can't create table `test`.`t1` (errno: 165 "Table is read only") +create table t3(f1 int not null)engine=innodb; +ERROR HY000: Can't create table `test`.`t3` (errno: 165 "Table is read only") drop table t1; -ERROR 42S02: Unknown table 'test.t1' +ERROR HY000: Table 't1' is read only rename table t2 to t3; ERROR HY000: Error on rename of './test/t2' to './test/t3' (errno: 165 "Table is read only") truncate table t2; @@ -84,6 +89,7 @@ drop table t2; ERROR HY000: Table 't2' is read only show tables; Tables_in_test +t1 t2 # Restart the server with innodb_force_recovery=2 select * from t2; @@ -92,10 +98,9 @@ f1 f2 begin; update t2 set f2=3; connect con1,localhost,root,,; -create table t3(a int)engine=innodb; # Force a redo log flush of the above uncommitted UPDATE SET GLOBAL innodb_flush_log_at_trx_commit=1; -drop table t3; +drop table t1; disconnect con1; connection default; # Kill the server diff --git a/mysql-test/suite/innodb/t/innodb_force_recovery.test b/mysql-test/suite/innodb/t/innodb_force_recovery.test index 822180dfbfa..b5b48281161 100644 --- a/mysql-test/suite/innodb/t/innodb_force_recovery.test +++ b/mysql-test/suite/innodb/t/innodb_force_recovery.test @@ -51,6 +51,7 @@ rename table t1 to t3; --error ER_OPEN_AS_READONLY truncate table t1; +--error ER_OPEN_AS_READONLY drop table t1; show tables; @@ -76,10 +77,10 @@ drop index idx on t2; update t2 set f1=3 where f2=2; --error ER_CANT_CREATE_TABLE -create table t1(f1 int not null)engine=innodb; +create table t3(f1 int not null)engine=innodb; --error ER_BAD_TABLE_ERROR -drop table t1; +drop table t3; --error ER_ERROR_ON_RENAME rename table t2 to t3; @@ -89,6 +90,9 @@ truncate table t2; --error ER_OPEN_AS_READONLY drop table t2; + +create schema db; +drop schema db; show tables; --echo # Restart the server with innodb_force_recovery as 6. @@ -113,9 +117,9 @@ drop index idx on t2; update t2 set f1=3 where f2=2; --error ER_CANT_CREATE_TABLE -create table t1(f1 int not null)engine=innodb; +create table t3(f1 int not null)engine=innodb; ---error ER_BAD_TABLE_ERROR +--error ER_OPEN_AS_READONLY drop table t1; --error ER_ERROR_ON_RENAME @@ -137,10 +141,9 @@ begin; update t2 set f2=3; connect (con1,localhost,root,,); -create table t3(a int)engine=innodb; --echo # Force a redo log flush of the above uncommitted UPDATE SET GLOBAL innodb_flush_log_at_trx_commit=1; -drop table t3; +drop table t1; disconnect con1; connection default; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index ef3f9617069..a511a3d175e 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -13118,8 +13118,7 @@ inline int ha_innobase::delete_table(const char* name, enum_sql_command sqlcom) extension, in contrast to ::create */ normalize_table_name(norm_name, name); - if (srv_read_only_mode - || srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) { + if (high_level_read_only) { DBUG_RETURN(HA_ERR_TABLE_READONLY); } @@ -13308,7 +13307,7 @@ innobase_drop_database( DBUG_ASSERT(hton == innodb_hton_ptr); - if (srv_read_only_mode) { + if (high_level_read_only) { return; } From 642ddc313131622cc491026ea21953cf66a9e568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 29 May 2019 08:14:49 +0300 Subject: [PATCH 40/43] MDEV-19541: Add a forgotten test case Also, --skip-innodb-buffer-pool-load-at-startup to avoid a crash in buf_load() due to loading pages that we are corrupting intentionally. --- .../t/corrupted_during_recovery.test | 2 +- ...leaf_page_corrupted_during_recovery.result | 20 ++++++++ .../innodb/t/corrupted_during_recovery.opt | 3 +- .../t/leaf_page_corrupted_during_recovery.opt | 2 + .../leaf_page_corrupted_during_recovery.test | 50 +++++++++++++++++++ 5 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/innodb/r/leaf_page_corrupted_during_recovery.result create mode 100644 mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.opt create mode 100644 mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test diff --git a/mysql-test/suite/encryption/t/corrupted_during_recovery.test b/mysql-test/suite/encryption/t/corrupted_during_recovery.test index 1ca3419820b..94fcd5f382d 100644 --- a/mysql-test/suite/encryption/t/corrupted_during_recovery.test +++ b/mysql-test/suite/encryption/t/corrupted_during_recovery.test @@ -54,7 +54,7 @@ SELECT * FROM t1; call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t[1].ibd looks corrupted; key_version=1786080875"); call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted. Please drop the table and recreate."); --enable_query_log -let $restart_parameters=--innodb_force_recovery=1; +let $restart_parameters=--innodb_force_recovery=1 --skip-innodb-buffer-pool-load-at-startup; --source include/restart_mysqld.inc --error ER_NO_SUCH_TABLE_IN_ENGINE diff --git a/mysql-test/suite/innodb/r/leaf_page_corrupted_during_recovery.result b/mysql-test/suite/innodb/r/leaf_page_corrupted_during_recovery.result new file mode 100644 index 00000000000..e0e920ef64e --- /dev/null +++ b/mysql-test/suite/innodb/r/leaf_page_corrupted_during_recovery.result @@ -0,0 +1,20 @@ +CREATE TABLE t1 (pk INT PRIMARY KEY, c CHAR(255))ENGINE=InnoDB STATS_PERSISTENT=0; +SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG = 2; +INSERT INTO t1 VALUES(1, 'sql'), (2, 'server'), (3, 'mariadb'), +(4, 'mariadb'), (5, 'test1'), (6, 'test2'), (7, 'test3'), +(8, 'test4'), (9, 'test5'), (10, 'test6'), (11, 'test7'), +(12, 'test8'); +SELECT COUNT(*) FROM t1; +COUNT(*) +12 +UPDATE t1 SET c='best8' WHERE pk=12; +# Kill the server +# Corrupt the pages +SELECT * FROM t1 WHERE PK = 1; +ERROR 42000: Unknown storage engine 'InnoDB' +SELECT * FROM t1 WHERE PK = 1; +pk c +1 sql +SELECT * FROM t1 WHERE pk = 12; +ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/corrupted_during_recovery.opt b/mysql-test/suite/innodb/t/corrupted_during_recovery.opt index 6051f4cd1fa..ba4fa744d8f 100644 --- a/mysql-test/suite/innodb/t/corrupted_during_recovery.opt +++ b/mysql-test/suite/innodb/t/corrupted_during_recovery.opt @@ -1 +1,2 @@ ---innodb_doublewrite=0 +--skip-innodb-doublewrite +--skip-innodb-buffer-pool-load-at-startup diff --git a/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.opt b/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.opt new file mode 100644 index 00000000000..ba4fa744d8f --- /dev/null +++ b/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.opt @@ -0,0 +1,2 @@ +--skip-innodb-doublewrite +--skip-innodb-buffer-pool-load-at-startup diff --git a/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test b/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test new file mode 100644 index 00000000000..747077ef02f --- /dev/null +++ b/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test @@ -0,0 +1,50 @@ +--source include/have_innodb.inc +--source include/have_debug.inc + +--disable_query_log +call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed file read of tablespace test/t1 page "); +call mtr.add_suppression("InnoDB: Background Page read failed to read or decrypt \\[page id: space=\\d+, page number=19\\]"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: Failed to read file '.*test.t1\\.ibd' at offset 19: Page read from tablespace is corrupted\\."); +call mtr.add_suppression("\\[ERROR\\] InnoDB: Plugin initialization aborted at srv0start\\.cc.* with error Data structure corruption"); +call mtr.add_suppression("\\[ERROR\\] Plugin 'InnoDB' (init function|registration)"); +--enable_query_log +CREATE TABLE t1 (pk INT PRIMARY KEY, c CHAR(255))ENGINE=InnoDB STATS_PERSISTENT=0; + +SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG = 2; + +INSERT INTO t1 VALUES(1, 'sql'), (2, 'server'), (3, 'mariadb'), + (4, 'mariadb'), (5, 'test1'), (6, 'test2'), (7, 'test3'), + (8, 'test4'), (9, 'test5'), (10, 'test6'), (11, 'test7'), + (12, 'test8'); + +--source include/restart_mysqld.inc + +SELECT COUNT(*) FROM t1; +UPDATE t1 SET c='best8' WHERE pk=12; + +let INNODB_PAGE_SIZE=`select @@innodb_page_size`; +let MYSQLD_DATADIR=`select @@datadir`; + +--source include/kill_mysqld.inc +--echo # Corrupt the pages + +perl; +my $file = "$ENV{MYSQLD_DATADIR}/test/t1.ibd"; +open(FILE, "+<$file") || die "Unable to open $file"; +binmode FILE; +seek (FILE, $ENV{INNODB_PAGE_SIZE} * 19, SEEK_SET) or die "seek"; +print FILE "junk"; +close FILE or die "close"; +EOF + +--source include/start_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1 WHERE PK = 1; + +let $restart_parameters=--innodb-force-recovery=1; +--source include/restart_mysqld.inc +SELECT * FROM t1 WHERE PK = 1; +--error ER_GET_ERRMSG +SELECT * FROM t1 WHERE pk = 12; + +DROP TABLE t1; From eeee1832d792ac296e1cebeeed1f7a7ce4ce4551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 29 May 2019 08:28:15 +0300 Subject: [PATCH 41/43] Speed up buildbot by requiring --big-test for some slow tests --- mysql-test/suite/innodb/include/innodb-page-compression.inc | 2 ++ mysql-test/suite/innodb/t/doublewrite.test | 2 ++ mysql-test/suite/innodb/t/innodb-alter-table.test | 2 ++ mysql-test/suite/innodb/t/innodb-change-buffer-recovery.test | 2 ++ mysql-test/suite/innodb/t/innodb-index-debug.test | 2 ++ mysql-test/suite/innodb/t/innodb-page_compression_zip.test | 2 ++ mysql-test/suite/innodb/t/log_file_size.test | 2 ++ mysql-test/suite/innodb/t/mdev-15707.test | 2 ++ mysql-test/suite/innodb/t/table_definition_cache_debug.test | 2 ++ mysql-test/suite/innodb/t/update_time.test | 2 ++ mysql-test/suite/mariabackup/mdev-14447.test | 2 ++ mysql-test/t/lowercase_table4.test | 2 ++ mysql-test/t/mysql_client_test.test | 2 ++ mysql-test/t/mysql_client_test_nonblock.test | 2 ++ mysql-test/t/mysqldump.test | 3 +++ mysql-test/t/selectivity_innodb.test | 2 ++ 16 files changed, 33 insertions(+) diff --git a/mysql-test/suite/innodb/include/innodb-page-compression.inc b/mysql-test/suite/innodb/include/innodb-page-compression.inc index 3acbeaf0988..150d26e58cb 100644 --- a/mysql-test/suite/innodb/include/innodb-page-compression.inc +++ b/mysql-test/suite/innodb/include/innodb-page-compression.inc @@ -1,3 +1,5 @@ +# This test is slow on buildbot. +--source include/big_test.inc --disable_warnings set global innodb_file_format = `Barracuda`; set global innodb_file_per_table = on; diff --git a/mysql-test/suite/innodb/t/doublewrite.test b/mysql-test/suite/innodb/t/doublewrite.test index 3c87b108d6c..059a7f37ccf 100644 --- a/mysql-test/suite/innodb/t/doublewrite.test +++ b/mysql-test/suite/innodb/t/doublewrite.test @@ -7,6 +7,8 @@ --source include/innodb_page_size.inc --source include/have_debug.inc --source include/not_embedded.inc +# This test is slow on buildbot. +--source include/big_test.inc # Slow shutdown and restart to make sure ibuf merge is finished SET GLOBAL innodb_fast_shutdown = 0; diff --git a/mysql-test/suite/innodb/t/innodb-alter-table.test b/mysql-test/suite/innodb/t/innodb-alter-table.test index 0cf456ad146..ab0bd7b3353 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-table.test +++ b/mysql-test/suite/innodb/t/innodb-alter-table.test @@ -1,5 +1,7 @@ --source include/innodb_page_size.inc --source include/have_partition.inc +# This test is slow on buildbot. +--source include/big_test.inc # # MMDEV-8386: MariaDB creates very big tmp file and hangs on xtradb diff --git a/mysql-test/suite/innodb/t/innodb-change-buffer-recovery.test b/mysql-test/suite/innodb/t/innodb-change-buffer-recovery.test index 6b52e386525..d8cc21c550c 100644 --- a/mysql-test/suite/innodb/t/innodb-change-buffer-recovery.test +++ b/mysql-test/suite/innodb/t/innodb-change-buffer-recovery.test @@ -9,6 +9,8 @@ --source include/not_embedded.inc # DBUG_SUICIDE() hangs under valgrind --source include/not_valgrind.inc +# This test is slow on buildbot. +--source include/big_test.inc CREATE TABLE t1( a INT AUTO_INCREMENT PRIMARY KEY, diff --git a/mysql-test/suite/innodb/t/innodb-index-debug.test b/mysql-test/suite/innodb/t/innodb-index-debug.test index adbde0c982f..64ca47ded13 100644 --- a/mysql-test/suite/innodb/t/innodb-index-debug.test +++ b/mysql-test/suite/innodb/t/innodb-index-debug.test @@ -2,6 +2,8 @@ -- source include/have_innodb.inc -- source include/count_sessions.inc -- source include/have_debug_sync.inc +# This test is slow on buildbot. +--source include/big_test.inc let $MYSQLD_DATADIR= `select @@datadir`; diff --git a/mysql-test/suite/innodb/t/innodb-page_compression_zip.test b/mysql-test/suite/innodb/t/innodb-page_compression_zip.test index 0c843314eee..89ec6f01db6 100644 --- a/mysql-test/suite/innodb/t/innodb-page_compression_zip.test +++ b/mysql-test/suite/innodb/t/innodb-page_compression_zip.test @@ -1,5 +1,7 @@ --source include/have_innodb.inc --source include/not_embedded.inc +# This test is slow on buildbot. +--source include/big_test.inc let $innodb_compression_algorithm_orig=`SELECT @@innodb_compression_algorithm`; diff --git a/mysql-test/suite/innodb/t/log_file_size.test b/mysql-test/suite/innodb/t/log_file_size.test index 1e6c7cd4d00..6f15b830e8d 100644 --- a/mysql-test/suite/innodb/t/log_file_size.test +++ b/mysql-test/suite/innodb/t/log_file_size.test @@ -4,6 +4,8 @@ --source include/not_embedded.inc # DBUG_EXECUTE_IF is needed --source include/have_debug.inc +# This test is slow on buildbot. +--source include/big_test.inc if (`SELECT @@innodb_log_file_size = 1048576`) { --skip Test requires innodb_log_file_size>1M. diff --git a/mysql-test/suite/innodb/t/mdev-15707.test b/mysql-test/suite/innodb/t/mdev-15707.test index 46e1ee7ce57..a0446ef4f81 100644 --- a/mysql-test/suite/innodb/t/mdev-15707.test +++ b/mysql-test/suite/innodb/t/mdev-15707.test @@ -1,4 +1,6 @@ --source include/windows.inc +# This test is slow on buildbot. +--source include/big_test.inc # Deadlock in conjunction with the innodb change buffering. diff --git a/mysql-test/suite/innodb/t/table_definition_cache_debug.test b/mysql-test/suite/innodb/t/table_definition_cache_debug.test index 1f3598d68c9..70467b53435 100644 --- a/mysql-test/suite/innodb/t/table_definition_cache_debug.test +++ b/mysql-test/suite/innodb/t/table_definition_cache_debug.test @@ -1,6 +1,8 @@ --source include/have_innodb.inc --source include/have_debug.inc --source include/have_debug_sync.inc +# This test is slow on buildbot. +--source include/big_test.inc call mtr.add_suppression("InnoDB: innodb_open_files=13 is exceeded"); diff --git a/mysql-test/suite/innodb/t/update_time.test b/mysql-test/suite/innodb/t/update_time.test index 1a00e3b9f73..a95c5171e9b 100644 --- a/mysql-test/suite/innodb/t/update_time.test +++ b/mysql-test/suite/innodb/t/update_time.test @@ -8,6 +8,8 @@ -- source include/have_innodb_max_16k.inc # restart does not work with embedded -- source include/not_embedded.inc +# This test is slow on buildbot. +--source include/big_test.inc CREATE TABLE t (a INT) ENGINE=INNODB; diff --git a/mysql-test/suite/mariabackup/mdev-14447.test b/mysql-test/suite/mariabackup/mdev-14447.test index 96d12368547..799d81a8710 100644 --- a/mysql-test/suite/mariabackup/mdev-14447.test +++ b/mysql-test/suite/mariabackup/mdev-14447.test @@ -1,4 +1,6 @@ --source include/have_debug.inc +# This test is slow on buildbot. +--source include/big_test.inc call mtr.add_suppression("InnoDB: New log files created"); let $basedir=$MYSQLTEST_VARDIR/tmp/backup; diff --git a/mysql-test/t/lowercase_table4.test b/mysql-test/t/lowercase_table4.test index 981c8a14564..24d2aa16f49 100644 --- a/mysql-test/t/lowercase_table4.test +++ b/mysql-test/t/lowercase_table4.test @@ -1,5 +1,7 @@ --source include/have_case_insensitive_file_system.inc --source include/have_innodb.inc +# This test is slow on buildbot. +--source include/big_test.inc --echo # --echo # Bug#46941 crash with lower_case_table_names=2 and diff --git a/mysql-test/t/mysql_client_test.test b/mysql-test/t/mysql_client_test.test index bf5331ca4f9..d486a93a79d 100644 --- a/mysql-test/t/mysql_client_test.test +++ b/mysql-test/t/mysql_client_test.test @@ -2,6 +2,8 @@ -- source include/not_embedded.inc # need to have the dynamic loading turned on for the client plugin tests --source include/have_plugin_auth.inc +# This test is slow on buildbot. +--source include/big_test.inc SET @old_general_log= @@global.general_log; SET @old_slow_query_log= @@global.slow_query_log; diff --git a/mysql-test/t/mysql_client_test_nonblock.test b/mysql-test/t/mysql_client_test_nonblock.test index 51263854e58..76126e15cee 100644 --- a/mysql-test/t/mysql_client_test_nonblock.test +++ b/mysql-test/t/mysql_client_test_nonblock.test @@ -2,6 +2,8 @@ # The non-blocking API is not supported in the embedded server. -- source include/not_embedded.inc +# This test is slow on buildbot. +--source include/big_test.inc SET @old_general_log= @@global.general_log; SET @old_slow_query_log= @@global.slow_query_log; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 2af3bb18bcd..df939fd368f 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -17,6 +17,9 @@ let collation=utf8_unicode_ci; # There are tables in 'mysql' database of type innodb --source include/have_innodb.inc +# This test is slow on buildbot. +--source include/big_test.inc + disable_query_log; call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); enable_query_log; diff --git a/mysql-test/t/selectivity_innodb.test b/mysql-test/t/selectivity_innodb.test index e2dba034363..f407eb052fe 100644 --- a/mysql-test/t/selectivity_innodb.test +++ b/mysql-test/t/selectivity_innodb.test @@ -1,4 +1,6 @@ --source include/have_innodb.inc +# This test is slow on buildbot. +--source include/big_test.inc SET SESSION STORAGE_ENGINE='InnoDB'; From 6eefeb6fea05ff17d010d173ef244a1d92078d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 29 May 2019 11:20:56 +0300 Subject: [PATCH 42/43] MDEV-19541: Avoid infinite loop of reading a corrupted page row_search_mvcc(): Duplicate the logic of btr_pcur_move_to_next() so that an infinite loop can be avoided when advancing to the next page fails due to a corrupted page. --- .../encryption/r/innodb-force-corrupt.result | 6 ++- .../encryption/t/innodb-force-corrupt.test | 6 ++- ...leaf_page_corrupted_during_recovery.result | 2 +- .../leaf_page_corrupted_during_recovery.test | 16 ++++-- storage/innobase/row/row0sel.cc | 54 +++++++++++-------- 5 files changed, 53 insertions(+), 31 deletions(-) diff --git a/mysql-test/suite/encryption/r/innodb-force-corrupt.result b/mysql-test/suite/encryption/r/innodb-force-corrupt.result index b525eba38a3..dc88e4397f6 100644 --- a/mysql-test/suite/encryption/r/innodb-force-corrupt.result +++ b/mysql-test/suite/encryption/r/innodb-force-corrupt.result @@ -1,5 +1,7 @@ +call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` (has an unreadable root page|is corrupted)"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=\\d+, page number=[36]\\] in file .*test.t[123]\\.ibd looks corrupted; key_version=3221342974"); -call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` is corrupted"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption in an InnoDB type table"); +call mtr.add_suppression("\\[ERROR\\] mysqld: Index for table 't2' is corrupt; try to repair it"); SET GLOBAL innodb_file_per_table = ON; set global innodb_compression_algorithm = 1; # Create and populate tables to be corrupted @@ -17,7 +19,7 @@ COMMIT; SELECT * FROM t1; ERROR 42S02: Table 'test.t1' doesn't exist in engine SELECT * FROM t2; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +Got one of the listed errors SELECT * FROM t3; ERROR 42S02: Table 'test.t3' doesn't exist in engine # Restore the original tables diff --git a/mysql-test/suite/encryption/t/innodb-force-corrupt.test b/mysql-test/suite/encryption/t/innodb-force-corrupt.test index 4bed3e75997..7fdf294f466 100644 --- a/mysql-test/suite/encryption/t/innodb-force-corrupt.test +++ b/mysql-test/suite/encryption/t/innodb-force-corrupt.test @@ -7,8 +7,10 @@ # Don't test under embedded -- source include/not_embedded.inc +call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` (has an unreadable root page|is corrupted)"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=\\d+, page number=[36]\\] in file .*test.t[123]\\.ibd looks corrupted; key_version=3221342974"); -call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` is corrupted"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption in an InnoDB type table"); +call mtr.add_suppression("\\[ERROR\\] mysqld: Index for table 't2' is corrupt; try to repair it"); SET GLOBAL innodb_file_per_table = ON; set global innodb_compression_algorithm = 1; @@ -68,7 +70,7 @@ EOF --error ER_NO_SUCH_TABLE_IN_ENGINE SELECT * FROM t1; ---error ER_GET_ERRMSG +--error ER_GET_ERRMSG,ER_NOT_KEYFILE SELECT * FROM t2; --error ER_NO_SUCH_TABLE_IN_ENGINE SELECT * FROM t3; diff --git a/mysql-test/suite/innodb/r/leaf_page_corrupted_during_recovery.result b/mysql-test/suite/innodb/r/leaf_page_corrupted_during_recovery.result index e0e920ef64e..37ddb0a9348 100644 --- a/mysql-test/suite/innodb/r/leaf_page_corrupted_during_recovery.result +++ b/mysql-test/suite/innodb/r/leaf_page_corrupted_during_recovery.result @@ -16,5 +16,5 @@ SELECT * FROM t1 WHERE PK = 1; pk c 1 sql SELECT * FROM t1 WHERE pk = 12; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR HY000: Index for table 't1' is corrupt; try to repair it DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test b/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test index 747077ef02f..2f52be40372 100644 --- a/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test +++ b/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test @@ -7,6 +7,8 @@ call mtr.add_suppression("InnoDB: Background Page read failed to read or decrypt call mtr.add_suppression("\\[ERROR\\] InnoDB: Failed to read file '.*test.t1\\.ibd' at offset 19: Page read from tablespace is corrupted\\."); call mtr.add_suppression("\\[ERROR\\] InnoDB: Plugin initialization aborted at srv0start\\.cc.* with error Data structure corruption"); call mtr.add_suppression("\\[ERROR\\] Plugin 'InnoDB' (init function|registration)"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption"); +call mtr.add_suppression("\\[ERROR\\] mysqld: Index for table 't1' is corrupt; try to repair it"); --enable_query_log CREATE TABLE t1 (pk INT PRIMARY KEY, c CHAR(255))ENGINE=InnoDB STATS_PERSISTENT=0; @@ -19,13 +21,15 @@ INSERT INTO t1 VALUES(1, 'sql'), (2, 'server'), (3, 'mariadb'), --source include/restart_mysqld.inc -SELECT COUNT(*) FROM t1; -UPDATE t1 SET c='best8' WHERE pk=12; - let INNODB_PAGE_SIZE=`select @@innodb_page_size`; let MYSQLD_DATADIR=`select @@datadir`; ---source include/kill_mysqld.inc +SELECT COUNT(*) FROM t1; +--source ../include/no_checkpoint_start.inc +UPDATE t1 SET c='best8' WHERE pk=12; + +--let CLEANUP_IF_CHECKPOINT=DROP TABLE t1; +--source ../include/no_checkpoint_end.inc --echo # Corrupt the pages perl; @@ -44,7 +48,9 @@ SELECT * FROM t1 WHERE PK = 1; let $restart_parameters=--innodb-force-recovery=1; --source include/restart_mysqld.inc SELECT * FROM t1 WHERE PK = 1; ---error ER_GET_ERRMSG +--error ER_NOT_KEYFILE SELECT * FROM t1 WHERE pk = 12; DROP TABLE t1; +let $restart_parameters=; +--source include/restart_mysqld.inc diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index afdac984cfd..877d9c3ef78 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -5636,36 +5636,48 @@ next_rec: } if (moves_up) { - bool move; - - if (spatial_search) { - move = rtr_pcur_move_to_next( - search_tuple, mode, pcur, 0, &mtr); + if (UNIV_UNLIKELY(spatial_search)) { + if (rtr_pcur_move_to_next( + search_tuple, mode, pcur, 0, &mtr)) { + goto rec_loop; + } } else { - move = btr_pcur_move_to_next(pcur, &mtr); - } - - if (!move) { -not_moved: - if (!spatial_search) { - btr_pcur_store_position(pcur, &mtr); - } - - if (match_mode != 0) { - err = DB_RECORD_NOT_FOUND; + const buf_block_t* block = btr_pcur_get_block(pcur); + /* This is based on btr_pcur_move_to_next(), + but avoids infinite read loop of a corrupted page. */ + ut_ad(pcur->pos_state == BTR_PCUR_IS_POSITIONED); + ut_ad(pcur->latch_mode != BTR_NO_LATCHES); + pcur->old_stored = false; + if (btr_pcur_is_after_last_on_page(pcur)) { + if (btr_pcur_is_after_last_in_tree(pcur, + &mtr)) { + goto not_moved; + } + btr_pcur_move_to_next_page(pcur, &mtr); + if (UNIV_UNLIKELY(btr_pcur_get_block(pcur) + == block)) { + err = DB_CORRUPTION; + goto lock_wait_or_error; + } } else { - err = DB_END_OF_INDEX; + btr_pcur_move_to_next_on_page(pcur); } - goto normal_return; + goto rec_loop; } } else { - if (UNIV_UNLIKELY(!btr_pcur_move_to_prev(pcur, &mtr))) { - goto not_moved; + if (btr_pcur_move_to_prev(pcur, &mtr)) { + goto rec_loop; } } - goto rec_loop; +not_moved: + if (!spatial_search) { + btr_pcur_store_position(pcur, &mtr); + } + + err = match_mode ? DB_RECORD_NOT_FOUND : DB_END_OF_INDEX; + goto normal_return; lock_wait_or_error: /* Reset the old and new "did semi-consistent read" flags. */ From 1d0c27412c3e3c1a7d52bfc02c02c121941485be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 29 May 2019 13:03:32 +0300 Subject: [PATCH 43/43] MDEV-19541: Suppress an error also on Windows --- mysql-test/suite/encryption/r/innodb-force-corrupt.result | 2 +- mysql-test/suite/encryption/t/innodb-force-corrupt.test | 2 +- .../suite/innodb/t/leaf_page_corrupted_during_recovery.test | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/encryption/r/innodb-force-corrupt.result b/mysql-test/suite/encryption/r/innodb-force-corrupt.result index dc88e4397f6..26ac03e06c6 100644 --- a/mysql-test/suite/encryption/r/innodb-force-corrupt.result +++ b/mysql-test/suite/encryption/r/innodb-force-corrupt.result @@ -1,7 +1,7 @@ call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` (has an unreadable root page|is corrupted)"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=\\d+, page number=[36]\\] in file .*test.t[123]\\.ibd looks corrupted; key_version=3221342974"); call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption in an InnoDB type table"); -call mtr.add_suppression("\\[ERROR\\] mysqld: Index for table 't2' is corrupt; try to repair it"); +call mtr.add_suppression("\\[ERROR\\] mysqld.*: Index for table 't2' is corrupt; try to repair it"); SET GLOBAL innodb_file_per_table = ON; set global innodb_compression_algorithm = 1; # Create and populate tables to be corrupted diff --git a/mysql-test/suite/encryption/t/innodb-force-corrupt.test b/mysql-test/suite/encryption/t/innodb-force-corrupt.test index 7fdf294f466..399f70e2322 100644 --- a/mysql-test/suite/encryption/t/innodb-force-corrupt.test +++ b/mysql-test/suite/encryption/t/innodb-force-corrupt.test @@ -10,7 +10,7 @@ call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` (has an unreadable root page|is corrupted)"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=\\d+, page number=[36]\\] in file .*test.t[123]\\.ibd looks corrupted; key_version=3221342974"); call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption in an InnoDB type table"); -call mtr.add_suppression("\\[ERROR\\] mysqld: Index for table 't2' is corrupt; try to repair it"); +call mtr.add_suppression("\\[ERROR\\] mysqld.*: Index for table 't2' is corrupt; try to repair it"); SET GLOBAL innodb_file_per_table = ON; set global innodb_compression_algorithm = 1; diff --git a/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test b/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test index 2f52be40372..688ea4867c8 100644 --- a/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test +++ b/mysql-test/suite/innodb/t/leaf_page_corrupted_during_recovery.test @@ -8,7 +8,7 @@ call mtr.add_suppression("\\[ERROR\\] InnoDB: Failed to read file '.*test.t1\\.i call mtr.add_suppression("\\[ERROR\\] InnoDB: Plugin initialization aborted at srv0start\\.cc.* with error Data structure corruption"); call mtr.add_suppression("\\[ERROR\\] Plugin 'InnoDB' (init function|registration)"); call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption"); -call mtr.add_suppression("\\[ERROR\\] mysqld: Index for table 't1' is corrupt; try to repair it"); +call mtr.add_suppression("\\[ERROR\\] mysqld.*: Index for table 't1' is corrupt; try to repair it"); --enable_query_log CREATE TABLE t1 (pk INT PRIMARY KEY, c CHAR(255))ENGINE=InnoDB STATS_PERSISTENT=0;