From dc2a858bed2ba12080f915a2550e5d46286e52a1 Mon Sep 17 00:00:00 2001 From: Rasmus Johansson Date: Fri, 17 Apr 2020 08:28:31 +0000 Subject: [PATCH 01/25] MDEV-22270 JUnit patch: test name contains classname --- mysql-test/lib/mtr_report.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index a3282704dd2..6c65982bafa 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -466,6 +466,7 @@ sub mtr_report_stats ($$$$) { } $test_time = sprintf("%.3f", $test->{timer} / 1000); + $test->{'name'} =~ s/$current_suite\.//; $xml_report .= qq(\t\t{'comment'}; From 95fa7bc89ddd248023bbe54aa3d9ba4d9903a4c2 Mon Sep 17 00:00:00 2001 From: Rasmus Johansson Date: Mon, 4 May 2020 10:10:07 +0000 Subject: [PATCH 02/25] MDEV-22273 jUnit patch: xml test result differs from MTR output in case if retry --- mysql-test/lib/mtr_report.pm | 11 +++++++---- mysql-test/mysql-test-run.pl | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 6c65982bafa..0b99eafa4cf 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -472,12 +472,15 @@ sub mtr_report_stats ($$$$) { my $comment = $test->{'comment'}; $comment =~ s/[\"]//g; - if ($test->{'result'} eq "MTR_RES_FAILED") { - $xml_report .= qq(>\n\t\t\t\n{'logfile'}]]>\n\t\t\t\n\t\t\n); + # if a test case has to be retried it should have the result MTR_RES_FAILED in jUnit XML + if ($test->{'result'} eq "MTR_RES_FAILED" || $test->{'retries'}) { + my $logcontents = $test->{'logfile-failed'} || $test->{'logfile'}; + + $xml_report .= qq(>\n\t\t\t\n\n\t\t\t\n\t\t\n); } elsif ($test->{'result'} eq "MTR_RES_SKIPPED" && $test->{'disable'}) { - $xml_report .= qq(>\n\t\t\t\n\t\t\n); + $xml_report .= qq(>\n\t\t\t\n\t\t\n); } elsif ($test->{'result'} eq "MTR_RES_SKIPPED") { - $xml_report .= qq(>\n\t\t\t\n\t\t\n); + $xml_report .= qq(>\n\t\t\t\n\t\t\n); } else { $xml_report .= " />\n"; } diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 43e35bdab6d..2850aafa67a 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -769,6 +769,7 @@ sub run_test_server ($$$) { if ( $result->is_failed() ) { my $worker_logdir= $result->{savedir}; my $log_file_name=dirname($worker_logdir)."/".$result->{shortname}.".log"; + $result->{'logfile-failed'} = mtr_lastlinesfromfile($log_file_name, 20); rename $log_file_name,$log_file_name.".failed"; } delete($result->{result}); From b9f177f66ae89d38dc635d2eb35e5db3522cb0c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 5 May 2020 08:54:33 +0300 Subject: [PATCH 03/25] MDEV-11254 cleanup: Remove buf_page_t::write_size commit 6495806e59cc27313375fa8d431b7b8e777f73ff removed all reads of buf_page_t::write_size. Let us remove the field altogether. --- storage/innobase/buf/buf0buf.cc | 10 ++++------ storage/innobase/include/buf0buf.h | 7 +------ 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 954b16eb2d2..91d8cf0b18e 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -547,13 +547,13 @@ decompress: decompress_with_slot: ut_d(fil_page_type_validate(dst_frame)); - bpage->write_size = fil_page_decompress(slot->crypt_buf, - dst_frame); + ulint write_size = fil_page_decompress(slot->crypt_buf, + dst_frame); slot->release(); - ut_ad(!bpage->write_size || fil_page_type_validate(dst_frame)); + ut_ad(!write_size || fil_page_type_validate(dst_frame)); ut_ad(space->n_pending_ios > 0); - return bpage->write_size != 0; + return write_size != 0; } if (space->crypt_data @@ -1502,7 +1502,6 @@ buf_block_init( block->page.io_fix = BUF_IO_NONE; block->page.flush_observer = NULL; block->page.real_size = 0; - block->page.write_size = 0; block->modify_clock = 0; block->page.slot = NULL; @@ -5244,7 +5243,6 @@ buf_page_init_low( bpage->access_time = 0; bpage->newest_modification = 0; bpage->oldest_modification = 0; - bpage->write_size = 0; bpage->real_size = 0; bpage->slot = NULL; diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index d120dc36091..0536e2f8ac6 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2020 MariaDB Corporation. +Copyright (c) 2013, 2020, 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 @@ -1508,11 +1508,6 @@ public: zip.data == NULL means an active buf_pool->watch */ - ulint write_size; /* Write size is set when this - page is first time written and then - if written again we check is TRIM - operation needed. */ - ulint real_size; /*!< Real size of the page Normal pages == UNIV_PAGE_SIZE page compressed pages, payload From 06b245f76822d6c857877339a02a99aaded4940f Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Tue, 5 May 2020 15:35:58 +0530 Subject: [PATCH 04/25] MDEV-13266: Race condition in ANALYZE TABLE / statistics collection Fixing a race condition while collecting the engine independent statistics. Thread1> 1) start running "ANALYZE TABLE t PERISTENT FOR COLUMNS (..) INDEXES ($list)" 2) Walk through $list and save it in TABLE::keys_in_use_for_query 3) Close/re-open tables Thread2> 1) Make some use of table t. This involves taking table t from the table cache, and putting it back (with TABLE::keys_in_use_for_query reset to 0) Thread1> continue collecting EITS stats. Since TABLE::keys_in_use_for_query is set to 0 we will not collect statistics for indexes in $list. --- sql/sql_admin.cc | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index ab95fdc340c..0613495f202 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -769,31 +769,6 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, (table->table->s->table_category == TABLE_CATEGORY_USER && (get_use_stat_tables_mode(thd) > NEVER || lex->with_persistent_for_clause)); - - - if (!lex->index_list) - { - tab->keys_in_use_for_query.init(tab->s->keys); - } - else - { - int pos; - LEX_STRING *index_name; - List_iterator_fast it(*lex->index_list); - - tab->keys_in_use_for_query.clear_all(); - while ((index_name= it++)) - { - if (tab->s->keynames.type_names == 0 || - (pos= find_type(&tab->s->keynames, index_name->str, - index_name->length, 1)) <= 0) - { - compl_result_code= result_code= HA_ADMIN_INVALID; - break; - } - tab->keys_in_use_for_query.set_bit(--pos); - } - } } if (result_code == HA_ADMIN_OK) @@ -878,6 +853,27 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, } tab->file->column_bitmaps_signal(); } + if (!lex->index_list) + tab->keys_in_use_for_query.init(tab->s->keys); + else + { + int pos; + LEX_STRING *index_name; + List_iterator_fast it(*lex->index_list); + + tab->keys_in_use_for_query.clear_all(); + while ((index_name= it++)) + { + if (tab->s->keynames.type_names == 0 || + (pos= find_type(&tab->s->keynames, index_name->str, + index_name->length, 1)) <= 0) + { + compl_result_code= result_code= HA_ADMIN_INVALID; + break; + } + tab->keys_in_use_for_query.set_bit(--pos); + } + } if (!(compl_result_code= alloc_statistics_for_table(thd, table->table)) && !(compl_result_code= From 1af74d523a70622e8abb528d4fd991d72b90c887 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 5 May 2020 12:49:29 +0200 Subject: [PATCH 05/25] postfix after e3f5789ac0b2 - var/log/stdout.log contains escape sequences. --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 2850aafa67a..ef2f001b532 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -389,7 +389,7 @@ if (-t STDOUT) { if (IS_WINDOWS and HAVE_WIN32_CONSOLE) { $set_titlebar = sub {Win32::Console::Title $_[0];}; } elsif (defined $ENV{TERM} and $ENV{TERM} =~ /xterm/) { - $set_titlebar = sub { print "\e];$_[0]\a"; }; + $set_titlebar = sub { syswrite STDOUT, "\e];$_[0]\a"; }; } } From 2907ff2c2d84228ffdd3c7e73afd7b5bd0bc34d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 29 Apr 2020 17:19:54 +0300 Subject: [PATCH 06/25] MDEV-19741 : Galera test failure on galera.galera_sst_mariabackup_table_options Test seems to work. --- mysql-test/suite/galera/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 59faf2c2fe7..e1337ddbd0c 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -25,7 +25,6 @@ galera_parallel_simple : MDEV-20318 galera.galera_parallel_simple fails galera_shutdown_nonprim : MDEV-21493 galera.galera_shutdown_nonprim galera_ssl_upgrade : MDEV-19950 Galera test failure on galera_ssl_upgrade galera_sst_mariabackup_encrypt_with_key : MDEV-21484 galera_sst_mariabackup_encrypt_with_key -galera_sst_mariabackup_table_options: MDEV-19741 Galera test failure on galera.galera_sst_mariabackup_table_options galera_var_innodb_disallow_writes : MDEV-20928 galera.galera_var_innodb_disallow_writes galera_var_node_address : MDEV-20485 Galera test failure galera_wan : MDEV-17259 Test failure on galera.galera_wan From e6301d8f67558544c3415f41f722e41ca6bfd782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 6 May 2020 17:23:49 +0300 Subject: [PATCH 07/25] MDEV-21515 : Galera test sporadic failure on galera.galera_wsrep_new_cluster: Result content mismatch Test starts two servers and we do not know order they really start, thus wsrep_local_index can be 1 or 2. --- .../galera/r/galera_wsrep_new_cluster.result | 69 ++++++++++--------- .../galera/t/galera_wsrep_new_cluster.test | 38 ++++------ 2 files changed, 49 insertions(+), 58 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_wsrep_new_cluster.result b/mysql-test/suite/galera/r/galera_wsrep_new_cluster.result index ca388496794..3ba34e8ea79 100644 --- a/mysql-test/suite/galera/r/galera_wsrep_new_cluster.result +++ b/mysql-test/suite/galera/r/galera_wsrep_new_cluster.result @@ -1,37 +1,38 @@ -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -VARIABLE_VALUE = 'Primary' -1 -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; -VARIABLE_VALUE = 'ON' -1 -SELECT VARIABLE_VALUE = 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_index'; -VARIABLE_VALUE = 0 -1 -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; -VARIABLE_VALUE = 'ON' -1 -SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; -VARIABLE_VALUE = 4 -1 -SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; -VARIABLE_VALUE = 'Synced' +connection node_1; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +VARIABLE_VALUE +Primary +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; +VARIABLE_VALUE +ON +SELECT (VARIABLE_VALUE = 0 OR VARIABLE_VALUE = 1 ) FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_index'; +(VARIABLE_VALUE = 0 OR VARIABLE_VALUE = 1 ) 1 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +VARIABLE_VALUE +ON +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; +VARIABLE_VALUE +4 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +VARIABLE_VALUE +Synced connection node_2; -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -VARIABLE_VALUE = 'Primary' -1 -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; -VARIABLE_VALUE = 'ON' -1 -SELECT VARIABLE_VALUE = 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_index'; -VARIABLE_VALUE = 0 -1 -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; -VARIABLE_VALUE = 'ON' -1 -SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; -VARIABLE_VALUE = 4 -1 -SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; -VARIABLE_VALUE = 'Synced' +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +VARIABLE_VALUE +Primary +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; +VARIABLE_VALUE +ON +SELECT (VARIABLE_VALUE = 0 OR VARIABLE_VALUE = 1 ) FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_index'; +(VARIABLE_VALUE = 0 OR VARIABLE_VALUE = 1 ) 1 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +VARIABLE_VALUE +ON +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; +VARIABLE_VALUE +4 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +VARIABLE_VALUE +Synced diff --git a/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test b/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test index 59350222a4c..422759ece59 100644 --- a/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test +++ b/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test @@ -7,44 +7,34 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +--connection node_1 + --let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; --source include/wait_condition.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 'on' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; ---source include/wait_condition.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_index'; ---source include/wait_condition.inc --let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; --source include/wait_condition.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; ---source include/wait_condition.inc --let $wait_condition = SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; --source include/wait_condition.inc -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; -SELECT VARIABLE_VALUE = 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_index'; -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; -SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; -SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; +SELECT (VARIABLE_VALUE = 0 OR VARIABLE_VALUE = 1 ) FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_index'; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; --connection node_2 --let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; --source include/wait_condition.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 'on' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; ---source include/wait_condition.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_index'; ---source include/wait_condition.inc --let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; --source include/wait_condition.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; ---source include/wait_condition.inc --let $wait_condition = SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; --source include/wait_condition.inc -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; -SELECT VARIABLE_VALUE = 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_index'; -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; -SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; -SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; +SELECT (VARIABLE_VALUE = 0 OR VARIABLE_VALUE = 1 ) FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_index'; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; From f7ba675555e84f51a017c348686079a9f4ba954b Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Wed, 6 May 2020 18:14:26 +0200 Subject: [PATCH 08/25] MDEV-22344: Fix typos in comments --- mysql-test/r/type_set.result | 2 +- mysql-test/t/type_set.test | 2 +- mysys/list.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/type_set.result b/mysql-test/r/type_set.result index 586c6345e00..289073a2ed0 100644 --- a/mysql-test/r/type_set.result +++ b/mysql-test/r/type_set.result @@ -108,7 +108,7 @@ End of 5.0 tests # Start of 10.0 tests # # -# MDEV-6950 Bad results with joins compating DATE and INT/ENUM/VARCHAR columns +# MDEV-6950 Bad results with joins comparing DATE and INT/ENUM/VARCHAR columns # CREATE TABLE t1 (c1 DATE PRIMARY KEY); INSERT INTO t1 VALUES ('2001-01-01'); diff --git a/mysql-test/t/type_set.test b/mysql-test/t/type_set.test index 16e4f42301d..4bc5d8c4858 100644 --- a/mysql-test/t/type_set.test +++ b/mysql-test/t/type_set.test @@ -101,7 +101,7 @@ DROP TABLE t1; --echo # --echo # ---echo # MDEV-6950 Bad results with joins compating DATE and INT/ENUM/VARCHAR columns +--echo # MDEV-6950 Bad results with joins comparing DATE and INT/ENUM/VARCHAR columns --echo # CREATE TABLE t1 (c1 DATE PRIMARY KEY); diff --git a/mysys/list.c b/mysys/list.c index 8f4c934f64e..380de83c031 100644 --- a/mysys/list.c +++ b/mysys/list.c @@ -14,7 +14,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ /* - Code for handling dubble-linked lists in C + Code for handling doubly linked lists in C */ #include "mysys_priv.h" @@ -22,7 +22,7 @@ - /* Add a element to start of list */ + /* Add an element to start of list */ LIST *list_add(LIST *root, LIST *element) { From d01d94d77bbb663caca2f34f4b25d5db028f4c4d Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Wed, 6 May 2020 23:44:34 +0300 Subject: [PATCH 09/25] MDEV-17568: LATERAL DERIVED is not clearly visible in EXPLAIN FORMAT=JSON Make LATERAL DERIVED tables visible in EXPLAIN FORMAT=JSON output. --- mysql-test/main/derived_cond_pushdown.result | 8 ++++++++ sql/sql_explain.cc | 5 +++++ sql/sql_explain.h | 2 ++ sql/sql_select.cc | 2 ++ 4 files changed, 17 insertions(+) diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index bd632e39dfc..542397755dc 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -15115,6 +15115,7 @@ EXPLAIN "rows": 2, "filtered": 100, "materialized": { + "lateral": 1, "query_block": { "select_id": 2, "outer_ref_condition": "t1.a is not null", @@ -15324,6 +15325,7 @@ EXPLAIN "filtered": 100, "attached_condition": "trigcond(trigcond(t1.a is not null))", "materialized": { + "lateral": 1, "query_block": { "select_id": 2, "outer_ref_condition": "t1.a is not null", @@ -15418,6 +15420,7 @@ EXPLAIN "rows": 2, "filtered": 100, "materialized": { + "lateral": 1, "query_block": { "select_id": 2, "outer_ref_condition": "t3.a is not null and t3.c is not null", @@ -15570,6 +15573,7 @@ EXPLAIN "rows": 2, "filtered": 100, "materialized": { + "lateral": 1, "query_block": { "select_id": 2, "outer_ref_condition": "t3.a is not null and t3.c is not null", @@ -15742,6 +15746,7 @@ EXPLAIN "rows": 2, "filtered": 100, "materialized": { + "lateral": 1, "query_block": { "select_id": 2, "outer_ref_condition": "t3.c is not null", @@ -15989,6 +15994,7 @@ EXPLAIN "rows": 2, "filtered": 100, "materialized": { + "lateral": 1, "query_block": { "select_id": 2, "outer_ref_condition": "t3.c is not null", @@ -16473,6 +16479,7 @@ EXPLAIN "filtered": 100, "first_match": "t4", "materialized": { + "lateral": 1, "query_block": { "select_id": 3, "const_condition": "1", @@ -16619,6 +16626,7 @@ EXPLAIN "rows": 2, "filtered": 100, "materialized": { + "lateral": 1, "query_block": { "select_id": 2, "table": { diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 70b177a556d..95ff94273b4 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -1756,6 +1756,11 @@ void Explain_table_access::print_explain_json(Explain_query *query, /* This is a derived table. Print its contents here */ writer->add_member("materialized").start_object(); Explain_node *node= query->get_node(derived_select_number); + if (node->get_type() == Explain_node::EXPLAIN_SELECT && + ((Explain_select*)node)->is_lateral) + { + writer->add_member("lateral").add_ll(1); + } node->print_explain_json(query, writer, is_analyze); writer->end_object(); } diff --git a/sql/sql_explain.h b/sql/sql_explain.h index 7a814dfa3af..97fe07572cf 100644 --- a/sql/sql_explain.h +++ b/sql/sql_explain.h @@ -211,6 +211,7 @@ public: select_lex(NULL), #endif linkage(UNSPECIFIED_TYPE), + is_lateral(false), message(NULL), having(NULL), having_value(Item::COND_UNDEF), using_temporary(false), using_filesort(false), @@ -226,6 +227,7 @@ public: #endif const char *select_type; enum sub_select_type linkage; + bool is_lateral; /* If message != NULL, this is a degenerate join plan, and all subsequent diff --git a/sql/sql_select.cc b/sql/sql_select.cc index de66f8bc59e..dd12ef0aa17 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -26014,6 +26014,8 @@ int JOIN::save_explain_data_intern(Explain_query *output, xpl_sel->select_id= join->select_lex->select_number; xpl_sel->select_type= join->select_lex->type; xpl_sel->linkage= select_lex->linkage; + xpl_sel->is_lateral= ((select_lex->linkage == DERIVED_TABLE_TYPE) && + (select_lex->uncacheable & UNCACHEABLE_DEPENDENT)); if (select_lex->master_unit()->derived) xpl_sel->connection_type= Explain_node::EXPLAIN_NODE_DERIVED; From 8c4b5261210accea8aa18b2870f8accd87b25f94 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 7 May 2020 00:40:48 +0200 Subject: [PATCH 10/25] Windows, mtr : Fix "Subroutine HAVE_WIN32_CONSOLE redefined at (eval 25) line 1." --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index ef2f001b532..538b76677f4 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -381,7 +381,7 @@ my $set_titlebar; }; eval 'sub HAVE_WIN32_CONSOLE { $have_win32_console }'; } else { - sub HAVE_WIN32_CONSOLE { 0 }; + eval 'sub HAVE_WIN32_CONSOLE { 0 }'; } } From 26aab96ecfc9eca647ab9d5b4be3ba5823df4cde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 7 May 2020 20:44:33 +0300 Subject: [PATCH 11/25] MDEV-22497 [ERROR] InnoDB: Unable to purge a record The InnoDB insert buffer was upgraded in MySQL 5.5 into a change buffer that also covers delete-mark and delete (purge) operations. There is an important constraint for delete operations: a B-tree leaf page must not become empty unless the entire tree becomes empty, consisting of an empty root page. Because change buffer merges only occur on a single leaf page at a time, delete operations must not be buffered if it is possible that the last record of the page could be deleted. (In that case, we would refuse to use the change buffer, and if we really delete the last record, we would shrink the index tree.) The function ibuf_get_volume_buffered_hash() is part of our insurance that the page would not become empty. It is supposed to map each buffered INSERT or DELETE_MARK record payload into a hash value. We will only count each such record as a distinct key if there is no hash collision. DELETE operations will always decrement the predicted number fo records in the page. Due to a bug in the function, we would actually compute the hash value not only on the record payload, but also on some following bytes, in case the record contains NULL values. In MySQL Bug #61104, we had some examples of this dating back to 2012. But back then, we failed to reproduce the bug, and in commit d84c95579ba1eca2f9bf5b0be9f14040e4441227 we simply demoted the hard assertion to a message printout and a debug assertion failure. ibuf_get_volume_buffered_hash(): Correctly compute the hash value of the payload bytes only. Note: we will consider ('foo','bar'),(NULL,'foobar'),('foob','ar') to be equal, but this is not a problem, because in case of a hash collision, we could also consider ('boo','far') to be equal, and underestimate the number of records in the page, leading to refusing to buffer a DELETE. --- storage/innobase/ibuf/ibuf0ibuf.cc | 61 +++++++++++------------------- storage/xtradb/ibuf/ibuf0ibuf.cc | 61 +++++++++++------------------- 2 files changed, 44 insertions(+), 78 deletions(-) diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 74d73379fbb..086fb3427c8 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2019, MariaDB Corporation. +Copyright (c) 2016, 2020, 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 @@ -62,6 +62,7 @@ UNIV_INTERN my_bool srv_ibuf_disable_background_merge; #include "que0que.h" #include "srv0start.h" /* srv_shutdown_state */ #include "ha_prototypes.h" +#include "ut0crc32.h" #include "rem0cmp.h" /* STRUCTURE OF AN INSERT BUFFER RECORD @@ -2885,42 +2886,28 @@ ibuf_contract_after_insert( } while (size > 0 && sum_sizes < entry_size); } -/*********************************************************************//** -Determine if an insert buffer record has been encountered already. -@return TRUE if a new record, FALSE if possible duplicate */ -static -ibool -ibuf_get_volume_buffered_hash( -/*==========================*/ - const rec_t* rec, /*!< in: ibuf record in post-4.1 format */ - const byte* types, /*!< in: fields */ - const byte* data, /*!< in: start of user record data */ - ulint comp, /*!< in: 0=ROW_FORMAT=REDUNDANT, - nonzero=ROW_FORMAT=COMPACT */ - ulint* hash, /*!< in/out: hash array */ - ulint size) /*!< in: number of elements in hash array */ +/** Determine if a change buffer record has been encountered already. +@param rec change buffer record in the MySQL 5.5 format +@param hash hash table of encountered records +@param size number of elements in hash +@retval true if a distinct record +@retval false if this may be duplicating an earlier record */ +static bool ibuf_get_volume_buffered_hash(const rec_t *rec, ulint *hash, + ulint size) { - ulint len; - ulint fold; - ulint bitmask; + ut_ad(rec_get_n_fields_old(rec) > IBUF_REC_FIELD_USER); + const ulint start= rec_get_field_start_offs(rec, IBUF_REC_FIELD_USER); + const ulint len= rec_get_data_size_old(rec) - start; + const uint32_t fold= ut_crc32(rec + start, len); + hash+= (fold / (CHAR_BIT * sizeof *hash)) % size; + ulint bitmask= static_cast(1) << (fold % (CHAR_BIT * sizeof(*hash))); - len = ibuf_rec_get_size( - rec, types, - rec_get_n_fields_old(rec) - IBUF_REC_FIELD_USER, comp); - fold = ut_fold_binary(data, len); + if (*hash & bitmask) + return false; - hash += (fold / (CHAR_BIT * sizeof *hash)) % size; - bitmask = static_cast(1) << (fold % (CHAR_BIT * sizeof(*hash))); - - if (*hash & bitmask) { - - return(FALSE); - } - - /* We have not seen this record yet. Insert it. */ - *hash |= bitmask; - - return(TRUE); + /* We have not seen this record yet. Remember it. */ + *hash|= bitmask; + return true; } #ifdef UNIV_DEBUG @@ -3012,11 +2999,7 @@ ibuf_get_volume_buffered_count_func( case IBUF_OP_DELETE_MARK: /* There must be a record to delete-mark. See if this record has been already buffered. */ - if (n_recs && ibuf_get_volume_buffered_hash( - rec, types + IBUF_REC_INFO_SIZE, - types + len, - types[IBUF_REC_OFFSET_FLAGS] & IBUF_REC_COMPACT, - hash, size)) { + if (n_recs && ibuf_get_volume_buffered_hash(rec, hash, size)) { (*n_recs)++; } diff --git a/storage/xtradb/ibuf/ibuf0ibuf.cc b/storage/xtradb/ibuf/ibuf0ibuf.cc index 264d1677afa..cd65ea15729 100644 --- a/storage/xtradb/ibuf/ibuf0ibuf.cc +++ b/storage/xtradb/ibuf/ibuf0ibuf.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2019, MariaDB Corporation. +Copyright (c) 2016, 2020, 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 @@ -63,6 +63,7 @@ UNIV_INTERN my_bool srv_ibuf_disable_background_merge; #include "que0que.h" #include "srv0start.h" /* srv_shutdown_state */ #include "ha_prototypes.h" +#include "ut0crc32.h" #include "rem0cmp.h" /* STRUCTURE OF AN INSERT BUFFER RECORD @@ -2925,42 +2926,28 @@ ibuf_contract_after_insert( } while (size > 0 && sum_sizes < entry_size); } -/*********************************************************************//** -Determine if an insert buffer record has been encountered already. -@return TRUE if a new record, FALSE if possible duplicate */ -static -ibool -ibuf_get_volume_buffered_hash( -/*==========================*/ - const rec_t* rec, /*!< in: ibuf record in post-4.1 format */ - const byte* types, /*!< in: fields */ - const byte* data, /*!< in: start of user record data */ - ulint comp, /*!< in: 0=ROW_FORMAT=REDUNDANT, - nonzero=ROW_FORMAT=COMPACT */ - ulint* hash, /*!< in/out: hash array */ - ulint size) /*!< in: number of elements in hash array */ +/** Determine if a change buffer record has been encountered already. +@param rec change buffer record in the MySQL 5.5 format +@param hash hash table of encountered records +@param size number of elements in hash +@retval true if a distinct record +@retval false if this may be duplicating an earlier record */ +static bool ibuf_get_volume_buffered_hash(const rec_t *rec, ulint *hash, + ulint size) { - ulint len; - ulint fold; - ulint bitmask; + ut_ad(rec_get_n_fields_old(rec) > IBUF_REC_FIELD_USER); + const ulint start= rec_get_field_start_offs(rec, IBUF_REC_FIELD_USER); + const ulint len= rec_get_data_size_old(rec) - start; + const uint32_t fold= ut_crc32(rec + start, len); + hash+= (fold / (CHAR_BIT * sizeof *hash)) % size; + ulint bitmask= static_cast(1) << (fold % (CHAR_BIT * sizeof(*hash))); - len = ibuf_rec_get_size( - rec, types, - rec_get_n_fields_old(rec) - IBUF_REC_FIELD_USER, comp); - fold = ut_fold_binary(data, len); + if (*hash & bitmask) + return false; - hash += (fold / (CHAR_BIT * sizeof *hash)) % size; - bitmask = static_cast(1) << (fold % (CHAR_BIT * sizeof(*hash))); - - if (*hash & bitmask) { - - return(FALSE); - } - - /* We have not seen this record yet. Insert it. */ - *hash |= bitmask; - - return(TRUE); + /* We have not seen this record yet. Remember it. */ + *hash|= bitmask; + return true; } #ifdef UNIV_DEBUG @@ -3052,11 +3039,7 @@ ibuf_get_volume_buffered_count_func( case IBUF_OP_DELETE_MARK: /* There must be a record to delete-mark. See if this record has been already buffered. */ - if (n_recs && ibuf_get_volume_buffered_hash( - rec, types + IBUF_REC_INFO_SIZE, - types + len, - types[IBUF_REC_OFFSET_FLAGS] & IBUF_REC_COMPACT, - hash, size)) { + if (n_recs && ibuf_get_volume_buffered_hash(rec, hash, size)) { (*n_recs)++; } From 0dee57c6f56160ce84b04fcf71a85bf27de2581a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 7 May 2020 21:01:22 +0300 Subject: [PATCH 12/25] MDEV-19344 innodb.innodb-change-buffer-recovery fails The test was incompatible with ./mtr --repeat=2 until commit 2d6719d7ee92843d5b0b9a27c7deaff5cacd4745 fixed that. It turns out that the failing assertion that we disabled in commit 3db94d2403c1f2791bddd43656d7b0d6320b453d is bogus and can fail when the change buffer is emptied during the last batch of crash recovery. The reason for this is the condition around the page_create_empty() call in page_cur_delete_rec(). The condition was removed in MariaDB Server 10.5 as part of MDEV-12353, in commit 7ae21b18a6b73bbc3bf1ff448faf60c29ac1d386 and commit f8a9f906679e1d1ab026c245f7d24c652050d8b3. The bug that the assertion aimed to catch is MDEV-22497, which was fixed in commit 26aab96ecfc9eca647ab9d5b4be3ba5823df4cde. --- storage/innobase/include/page0page.ic | 3 --- 1 file changed, 3 deletions(-) diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic index 4efb92f7182..5f69925a41a 100644 --- a/storage/innobase/include/page0page.ic +++ b/storage/innobase/include/page0page.ic @@ -173,9 +173,6 @@ page_header_set_field( { ut_ad(page); ut_ad(field <= PAGE_N_RECS); -#if 0 /* FIXME: MDEV-19344 hits this */ - ut_ad(field != PAGE_N_RECS || val); -#endif ut_ad(field == PAGE_N_HEAP || val < srv_page_size); ut_ad(field != PAGE_N_HEAP || (val & 0x7fff) < srv_page_size); From 40d0b6416729cec49d7cf1ae4dfa5ec59c455812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Fri, 8 May 2020 09:13:47 +0300 Subject: [PATCH 13/25] MDEV-21421 : Galera test sporadic failure on galera.galera_as_slave_gtid_myisam: Result length mismatch Add wait_condition so that drop table has time to replicate to Galera cluster. --- .../suite/galera/r/galera_as_slave_gtid_myisam.result | 3 +++ .../suite/galera/t/galera_as_slave_gtid_myisam.test | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/mysql-test/suite/galera/r/galera_as_slave_gtid_myisam.result b/mysql-test/suite/galera/r/galera_as_slave_gtid_myisam.result index d8a9f0d6f57..bea76e19dbb 100644 --- a/mysql-test/suite/galera/r/galera_as_slave_gtid_myisam.result +++ b/mysql-test/suite/galera/r/galera_as_slave_gtid_myisam.result @@ -23,6 +23,9 @@ gtid_binlog_state_equal #cleanup connection node_1; DROP TABLE t1; +connection node_2; +connection node_3; +connection node_1; reset master; connection node_2; STOP SLAVE; diff --git a/mysql-test/suite/galera/t/galera_as_slave_gtid_myisam.test b/mysql-test/suite/galera/t/galera_as_slave_gtid_myisam.test index 33668da11be..3710e6d65be 100644 --- a/mysql-test/suite/galera/t/galera_as_slave_gtid_myisam.test +++ b/mysql-test/suite/galera/t/galera_as_slave_gtid_myisam.test @@ -55,6 +55,16 @@ SELECT COUNT(*) = 0 FROM t1; --echo #cleanup --connection node_1 DROP TABLE t1; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +--source include/wait_condition.inc + +--connection node_3 +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +--source include/wait_condition.inc + +--connection node_1 reset master; --connection node_2 From 748fb55093aae023ca4237288e8b5b41e3816522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Fri, 8 May 2020 11:35:15 +0300 Subject: [PATCH 14/25] MDEV-21483 : Galera MTR tests failed: galera.MW-328A galera.MW-328B Enable tests with additional galera output to find out actual reason for test failures. --- mysql-test/suite/galera/disabled.def | 2 -- mysql-test/suite/galera/t/MW-328A.cnf | 7 +++++++ mysql-test/suite/galera/t/MW-328A.test | 2 +- mysql-test/suite/galera/t/MW-328B.cnf | 7 +++++++ mysql-test/suite/galera/t/MW-328B.test | 2 +- 5 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 mysql-test/suite/galera/t/MW-328A.cnf create mode 100644 mysql-test/suite/galera/t/MW-328B.cnf diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index e1337ddbd0c..0cbde628e45 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -11,8 +11,6 @@ ############################################################################## MW-286 : MDEV-18464 Killing thread can cause mutex deadlock if done concurrently with Galera/replication victim kill -MW-328A : MDEV-21483 galera.MW-328A galera.MW-328B -MW-328B : MDEV-21483 galera.MW-328A galera.MW-328B MW-329 : MDEV-19962 Galera test failure on MW-329 galera.galera_defaults : MDEV-21494 Galera test sporadic failure on galera.galera_defaults galera_as_slave_replication_bundle : MDEV-15785 OPTION_GTID_BEGIN is set in Gtid_log_event::do_apply_event() diff --git a/mysql-test/suite/galera/t/MW-328A.cnf b/mysql-test/suite/galera/t/MW-328A.cnf new file mode 100644 index 00000000000..a10ea88bdf2 --- /dev/null +++ b/mysql-test/suite/galera/t/MW-328A.cnf @@ -0,0 +1,7 @@ +!include ../galera_2nodes.cnf + +[mysqld.1] +wsrep-debug=ON + +[mysqld.2] +wsrep-debug=ON diff --git a/mysql-test/suite/galera/t/MW-328A.test b/mysql-test/suite/galera/t/MW-328A.test index dd692a292b8..a547823ced0 100644 --- a/mysql-test/suite/galera/t/MW-328A.test +++ b/mysql-test/suite/galera/t/MW-328A.test @@ -13,7 +13,7 @@ # --source include/galera_cluster.inc ---source include/big_test.inc +--source include/force_restart.inc --source suite/galera/t/MW-328-header.inc --connection node_2 diff --git a/mysql-test/suite/galera/t/MW-328B.cnf b/mysql-test/suite/galera/t/MW-328B.cnf new file mode 100644 index 00000000000..a10ea88bdf2 --- /dev/null +++ b/mysql-test/suite/galera/t/MW-328B.cnf @@ -0,0 +1,7 @@ +!include ../galera_2nodes.cnf + +[mysqld.1] +wsrep-debug=ON + +[mysqld.2] +wsrep-debug=ON diff --git a/mysql-test/suite/galera/t/MW-328B.test b/mysql-test/suite/galera/t/MW-328B.test index 04503ce31e3..41581d9c239 100644 --- a/mysql-test/suite/galera/t/MW-328B.test +++ b/mysql-test/suite/galera/t/MW-328B.test @@ -8,7 +8,7 @@ # --source include/galera_cluster.inc ---source include/big_test.inc +--source include/force_restart.inc --source suite/galera/t/MW-328-header.inc --connection node_2 From 1887b5ae87ac0d1519f95a1e2f59efe09aded98f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 8 May 2020 13:27:57 +0300 Subject: [PATCH 15/25] MDEV-22501 Various issues when using --innodb-data-file-size-debug=-1 Let us limit the maximum value of the debug parameter innodb_data_file_size to 256 MiB. It is only being used in the test innodb.log_data_file_size, and the size of the system tablespace should never exceed some 70 MiB in ./mtr. Thus, 256 MiB should be a reasonable limit. The fact that negative values that are passed to unsigned parameters wrap around to the maximum value appears to be a regression due to commit 18ef02b04dfae21148c7397d088c7ffdfcd23c4e and has been filed as bug MDEV-22219. --- mysql-test/suite/sys_vars/r/sysvars_innodb.result | 2 +- storage/innobase/handler/ha_innodb.cc | 2 +- storage/xtradb/handler/ha_innodb.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result index 67f891501e5..38bafc03d6f 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result @@ -588,7 +588,7 @@ VARIABLE_SCOPE GLOBAL VARIABLE_TYPE INT UNSIGNED VARIABLE_COMMENT InnoDB system tablespace size to be set in recovery. NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 4294967295 +NUMERIC_MAX_VALUE 268435456 NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY YES diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c54dae220ae..a06a9ed103f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -19831,7 +19831,7 @@ static MYSQL_SYSVAR_UINT(data_file_size_debug, srv_sys_space_size_debug, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "InnoDB system tablespace size to be set in recovery.", - NULL, NULL, 0, 0, UINT_MAX32, 0); + NULL, NULL, 0, 0, 256U << 20, 0); static MYSQL_SYSVAR_ULONG(fil_make_page_dirty_debug, srv_fil_make_page_dirty_debug, PLUGIN_VAR_OPCMDARG, diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index c57870915dc..06f0388349e 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -21071,7 +21071,7 @@ static MYSQL_SYSVAR_UINT(data_file_size_debug, srv_sys_space_size_debug, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "InnoDB system tablespace size to be set in recovery.", - NULL, NULL, 0, 0, UINT_MAX32, 0); + NULL, NULL, 0, 0, 256U << 20, 0); static MYSQL_SYSVAR_ULONG(fil_make_page_dirty_debug, srv_fil_make_page_dirty_debug, PLUGIN_VAR_OPCMDARG, From 0b218df07255b65b228878886f76530aa0eb0251 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 8 May 2020 14:11:41 +0200 Subject: [PATCH 16/25] MDEV-22483 mysql_upgrade does not use current user as default for connecting to server correct the help text --- client/mysql_upgrade.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 8633dc04b95..227b66e8c86 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -153,7 +153,7 @@ static struct my_option my_long_options[]= &opt_systables_only, &opt_systables_only, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #define USER_OPT (array_elements(my_long_options) - 6) - {"user", 'u', "User for login if not current user.", &opt_user, + {"user", 'u', "User for login.", &opt_user, &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"verbose", 'v', "Display more output about the process; Using it twice will print connection argument; Using it 3 times will print out all CHECK, RENAME and ALTER TABLE during the check phase.", &opt_not_used, &opt_not_used, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, From faf6f8c6a482fbdfce1628eca65806eb38c8d76d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Fri, 8 May 2020 16:39:37 +0300 Subject: [PATCH 17/25] Add global suppression for connectivity problems. --- mysql-test/suite/galera/suite.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/galera/suite.pm b/mysql-test/suite/galera/suite.pm index f3c04979705..96580150c7d 100644 --- a/mysql-test/suite/galera/suite.pm +++ b/mysql-test/suite/galera/suite.pm @@ -65,6 +65,7 @@ push @::global_suppressions, qr|WSREP: JOIN message from member .* in non-primary configuration. Ignored.|, qr(WSREP: Failed to remove page file .*), qr(WSREP: wsrep_sst_method is set to 'mysqldump' yet mysqld bind_address is set to .*), + qr(WSREP: .*Transport endpoint is not connected.*), ); bless { }; From 4ae778bbec4514bdfe08baddd7630446276fa9c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Van=C4=9Bk?= Date: Mon, 4 May 2020 17:39:50 +0200 Subject: [PATCH 18/25] innodb: add space between thread name and "to exit" text --- storage/innobase/log/log0log.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index c3eaa05b680..9ad551f805d 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -1893,7 +1893,7 @@ wait_suspend_loop: "Waiting for %s to exit", thread_name); if (srv_print_verbose_log && count > COUNT_INTERVAL) { ib::info() << "Waiting for " << thread_name - << "to exit"; + << " to exit"; count = 0; } goto loop; From ba3d58ad4cf4e152bc3854c1526ea72bbcb31ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 11 May 2020 14:23:37 +0300 Subject: [PATCH 19/25] MDEV-22523 index->rtr_ssn.mutex is wasting memory As part of the SPATIAL INDEX implementation in InnoDB, dict_index_t was expanded by a rtr_ssn_t field. There are only 3 operations for this field, all protected by rtr_ssn_t::mutex: * btr_cur_search_to_nth_level() stores the least significant 32 bits of the 64-bit value that is stored in the index root page. (This would better be done when the table is opened for the very first time.) * rtr_get_new_ssn_id() increments the value by 1. * rtr_get_current_ssn_id() reads the current value. All these operations can be implemented equally safely by using atomic memory access operations. --- storage/innobase/btr/btr0cur.cc | 7 +++---- storage/innobase/dict/dict0mem.cc | 2 -- storage/innobase/handler/ha_innodb.cc | 1 - storage/innobase/include/dict0mem.h | 5 +++-- storage/innobase/include/gis0rtree.ic | 20 +++++--------------- storage/innobase/include/gis0type.h | 8 +------- storage/innobase/include/sync0sync.h | 2 +- storage/innobase/include/sync0types.h | 3 +-- storage/innobase/sync/sync0debug.cc | 7 ++----- storage/innobase/sync/sync0sync.cc | 2 +- 10 files changed, 17 insertions(+), 40 deletions(-) diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index c282d864543..a187402328f 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -1475,10 +1475,9 @@ retry_page_get: node_seq_t root_seq_no; root_seq_no = page_get_ssn_id(page); - - mutex_enter(&(index->rtr_ssn.mutex)); - index->rtr_ssn.seq_no = root_seq_no + 1; - mutex_exit(&(index->rtr_ssn.mutex)); + my_atomic_store32_explicit( + &index->rtr_ssn, root_seq_no + 1, + MY_MEMORY_ORDER_RELAXED); } /* Save the MBR */ diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index 02ab1d77eb3..21a3c743f52 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -741,7 +741,6 @@ dict_mem_index_create( dict_index_zip_pad_mutex_create_lazy(index); if (type & DICT_SPATIAL) { - mutex_create(LATCH_ID_RTR_SSN_MUTEX, &index->rtr_ssn.mutex); index->rtr_track = static_cast( mem_heap_alloc( heap, @@ -1067,7 +1066,6 @@ dict_mem_index_free( rtr_info->index = NULL; } - mutex_destroy(&index->rtr_ssn.mutex); mutex_destroy(&index->rtr_track->rtr_active_mutex); UT_DELETE(index->rtr_track->rtr_active); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 25304b82d64..32f7c6460e2 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -626,7 +626,6 @@ static PSI_mutex_info all_innodb_mutexes[] = { PSI_KEY(rtr_active_mutex), PSI_KEY(rtr_match_mutex), PSI_KEY(rtr_path_mutex), - PSI_KEY(rtr_ssn_mutex), PSI_KEY(trx_sys_mutex), PSI_KEY(zip_pad_mutex) }; diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index ed4bf073061..b259d2fb2ad 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -2,7 +2,7 @@ Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2019, MariaDB Corporation. +Copyright (c) 2013, 2020, 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 @@ -964,7 +964,8 @@ struct dict_index_t{ /* in which slot the next sample should be saved. */ /* @} */ - rtr_ssn_t rtr_ssn;/*!< Node sequence number for RTree */ + /** R-tree split sequence number */ + volatile int32 rtr_ssn; rtr_info_track_t* rtr_track;/*!< tracking all R-Tree search cursors */ trx_id_t trx_id; /*!< id of the transaction that created this diff --git a/storage/innobase/include/gis0rtree.ic b/storage/innobase/include/gis0rtree.ic index 0d346051f00..696aa1e2f5f 100644 --- a/storage/innobase/include/gis0rtree.ic +++ b/storage/innobase/include/gis0rtree.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2020, 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 @@ -132,13 +132,9 @@ rtr_get_new_ssn_id( /*===============*/ dict_index_t* index) /*!< in/out: the index struct */ { - node_seq_t ssn; - - mutex_enter(&(index->rtr_ssn.mutex)); - ssn = ++index->rtr_ssn.seq_no; - mutex_exit(&(index->rtr_ssn.mutex)); - - return(ssn); + node_seq_t ssn= my_atomic_add32_explicit(&index->rtr_ssn, 1, + MY_MEMORY_ORDER_RELAXED); + return ssn + 1; } /*****************************************************************//** Get the current Split Sequence Number. @@ -149,13 +145,7 @@ rtr_get_current_ssn_id( /*===================*/ dict_index_t* index) /*!< in: index struct */ { - node_seq_t ssn; - - mutex_enter(&(index->rtr_ssn.mutex)); - ssn = index->rtr_ssn.seq_no; - mutex_exit(&(index->rtr_ssn.mutex)); - - return(ssn); + return my_atomic_load32_explicit(&index->rtr_ssn, MY_MEMORY_ORDER_RELAXED); } /*********************************************************************//** diff --git a/storage/innobase/include/gis0type.h b/storage/innobase/include/gis0type.h index ee350ea56ce..c5ea817c6bf 100644 --- a/storage/innobase/include/gis0type.h +++ b/storage/innobase/include/gis0type.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2018, MariaDB Corporation. +Copyright (c) 2018, 2020, 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 @@ -143,12 +143,6 @@ typedef struct rtr_info_track { rtr_active */ } rtr_info_track_t; -/* Node Sequence Number and mutex protects it. */ -typedef struct rtree_ssn { - ib_mutex_t mutex; /*!< mutex protect the seq num */ - node_seq_t seq_no; /*!< the SSN (node sequence number) */ -} rtr_ssn_t; - /* This is to record the record movement between pages. Used for corresponding lock movement */ typedef struct rtr_rec_move { diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h index 0d8bd0a4509..e250307fa28 100644 --- a/storage/innobase/include/sync0sync.h +++ b/storage/innobase/include/sync0sync.h @@ -3,6 +3,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2012, Facebook Inc. +Copyright (c) 2020, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -81,7 +82,6 @@ extern mysql_pfs_key_t recv_writer_mutex_key; extern mysql_pfs_key_t rtr_active_mutex_key; extern mysql_pfs_key_t rtr_match_mutex_key; extern mysql_pfs_key_t rtr_path_mutex_key; -extern mysql_pfs_key_t rtr_ssn_mutex_key; extern mysql_pfs_key_t redo_rseg_mutex_key; extern mysql_pfs_key_t noredo_rseg_mutex_key; extern mysql_pfs_key_t page_zip_stat_per_index_mutex_key; diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h index 9b1443523c7..c21f3bbf853 100644 --- a/storage/innobase/include/sync0types.h +++ b/storage/innobase/include/sync0types.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, 2020, 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 @@ -327,7 +327,6 @@ enum latch_id_t { LATCH_ID_REDO_RSEG, LATCH_ID_NOREDO_RSEG, LATCH_ID_RW_LOCK_DEBUG, - LATCH_ID_RTR_SSN_MUTEX, LATCH_ID_RTR_ACTIVE_MUTEX, LATCH_ID_RTR_MATCH_MUTEX, LATCH_ID_RTR_PATH_MUTEX, diff --git a/storage/innobase/sync/sync0debug.cc b/storage/innobase/sync/sync0debug.cc index c4a2fd90b37..78c3058573f 100644 --- a/storage/innobase/sync/sync0debug.cc +++ b/storage/innobase/sync/sync0debug.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2020, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -383,8 +383,7 @@ private: { return(latch->get_id() == LATCH_ID_RTR_ACTIVE_MUTEX || latch->get_id() == LATCH_ID_RTR_PATH_MUTEX - || latch->get_id() == LATCH_ID_RTR_MATCH_MUTEX - || latch->get_id() == LATCH_ID_RTR_SSN_MUTEX); + || latch->get_id() == LATCH_ID_RTR_MATCH_MUTEX); } private: @@ -1375,8 +1374,6 @@ sync_latch_meta_init() rw_lock_debug_mutex_key); #endif /* UNIV_DEBUG */ - LATCH_ADD_MUTEX(RTR_SSN_MUTEX, SYNC_ANY_LATCH, rtr_ssn_mutex_key); - LATCH_ADD_MUTEX(RTR_ACTIVE_MUTEX, SYNC_ANY_LATCH, rtr_active_mutex_key); diff --git a/storage/innobase/sync/sync0sync.cc b/storage/innobase/sync/sync0sync.cc index 0a81f9c00e7..22bd9f823ec 100644 --- a/storage/innobase/sync/sync0sync.cc +++ b/storage/innobase/sync/sync0sync.cc @@ -2,6 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. +Copyright (c) 2020, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -73,7 +74,6 @@ mysql_pfs_key_t rw_lock_debug_mutex_key; mysql_pfs_key_t rtr_active_mutex_key; mysql_pfs_key_t rtr_match_mutex_key; mysql_pfs_key_t rtr_path_mutex_key; -mysql_pfs_key_t rtr_ssn_mutex_key; mysql_pfs_key_t rw_lock_list_mutex_key; mysql_pfs_key_t rw_lock_mutex_key; mysql_pfs_key_t srv_innodb_monitor_mutex_key; From a0778860af564edeca97ed8a7a6e3e8cbad333b4 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Mon, 11 May 2020 12:52:53 -0400 Subject: [PATCH 20/25] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 735bcc43b0b..42407f29a37 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=1 -MYSQL_VERSION_PATCH=45 +MYSQL_VERSION_PATCH=46 From 37759b262f51ddcf19e229db4a471af79c22cc34 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Mon, 11 May 2020 12:55:06 -0400 Subject: [PATCH 21/25] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index edbb44f59e8..ed8554d24d9 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=2 -MYSQL_VERSION_PATCH=32 +MYSQL_VERSION_PATCH=33 From 9f5ab66b72e35d8ed0447ba4c179636b1a59517a Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Mon, 11 May 2020 12:57:01 -0400 Subject: [PATCH 22/25] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 01540871584..19a3d95ed2d 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=3 -MYSQL_VERSION_PATCH=23 +MYSQL_VERSION_PATCH=24 SERVER_MATURITY=stable From a2560b00770d36d3509c5ebdddad8c34dab0dddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 12 May 2020 10:13:00 +0300 Subject: [PATCH 23/25] =?UTF-8?q?MDEV-22529=20thd=5Fquery=5Fsafe()=20isn?= =?UTF-8?q?=E2=80=99t,=20causing=20InnoDB=20to=20hang?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function thd_query_safe() is used in the implementation of the following INFORMATION_SCHEMA views: information_schema.innodb_trx information_schema.innodb_locks information_schema.innodb_lock_waits information_schema.rocksdb_trx The implementation of the InnoDB views is in trx_i_s_common_fill_table(). This function invokes trx_i_s_possibly_fetch_data_into_cache(), which will acquire lock_sys->mutex and trx_sys->mutex in order to protect the set of active transactions and explicit locks. While holding those mutexes, it will traverse the collection of InnoDB transactions. For each transaction, thd_query_safe() will be invoked. When called via trx_i_s_common_fill_table(), thd_query_safe() is acquiring THD::LOCK_thd_data while holding the InnoDB locks. This will cause a deadlock with THD::awake() (such as executing KILL QUERY), because THD::awake() could invoke lock_trx_handle_wait(), which attempts to acquire lock_sys->mutex while already holding THD::lock_thd_data. thd_query_safe(): Invoke mysql_mutex_trylock() instead of mysql_mutex_lock(). Return the empty string if the mutex cannot be acquired without waiting. --- sql/sql_class.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 38770a24dec..655824d93fe 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -4530,6 +4530,7 @@ extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd) @param buflen Length of the buffer @return Length of the query + @retval 0 if LOCK_thd_data cannot be acquired without waiting @note This function is thread safe as the query string is accessed under mutex protection and the string is copied @@ -4538,10 +4539,19 @@ extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd) extern "C" size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen) { - mysql_mutex_lock(&thd->LOCK_thd_data); - size_t len= MY_MIN(buflen - 1, thd->query_length()); - memcpy(buf, thd->query(), len); - mysql_mutex_unlock(&thd->LOCK_thd_data); + size_t len= 0; + /* InnoDB invokes this function while holding internal mutexes. + THD::awake() will hold LOCK_thd_data while invoking an InnoDB + function that would acquire the internal mutex. Because this + function is a non-essential part of information_schema view output, + we will break the deadlock by avoiding a mutex wait here + and returning the empty string if a wait would be needed. */ + if (!mysql_mutex_trylock(&thd->LOCK_thd_data)) + { + len= MY_MIN(buflen - 1, thd->query_length()); + memcpy(buf, thd->query(), len); + mysql_mutex_unlock(&thd->LOCK_thd_data); + } buf[len]= '\0'; return len; } From 0e6a5786d4fc0e96c34ccee2c59a707e3debb3b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 12 May 2020 10:13:16 +0300 Subject: [PATCH 24/25] Cleanup: Remove InnoDB wrappers of thd_charset(), thd_query_safe() innobase_get_charset(), innobase_get_stmt_safe(): Remove. It is more efficient and readable to invoke thd_charset() and thd_query_safe() directly, without a non-inlined wrapper function. --- storage/innobase/dict/dict0dict.cc | 4 ++-- storage/innobase/handler/ha_innodb.cc | 27 ------------------------ storage/innobase/handler/ha_innodb.h | 2 -- storage/innobase/include/ha_prototypes.h | 23 ++------------------ storage/innobase/trx/trx0i_s.cc | 9 +++----- 5 files changed, 7 insertions(+), 58 deletions(-) diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 455d51af438..8f94ccb4c63 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -4959,7 +4959,7 @@ dict_create_foreign_constraints( heap = mem_heap_create(10000); err = dict_create_foreign_constraints_low( - trx, heap, innobase_get_charset(trx->mysql_thd), + trx, heap, thd_charset(trx->mysql_thd), str, name, reject_fks); mem_heap_free(heap); @@ -4994,7 +4994,7 @@ dict_foreign_parse_drop_constraints( ut_a(trx->mysql_thd); - cs = innobase_get_charset(trx->mysql_thd); + cs = thd_charset(trx->mysql_thd); *n = 0; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 32f7c6460e2..8cf867458e2 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2299,17 +2299,6 @@ innobase_casedn_str( my_casedn_str(system_charset_info, a); } -/**********************************************************************//** -Determines the connection character set. -@return connection character set */ -CHARSET_INFO* -innobase_get_charset( -/*=================*/ - THD* mysql_thd) /*!< in: MySQL thread handle */ -{ - return(thd_charset(mysql_thd)); -} - /** Determines the current SQL statement. Thread unsafe, can only be called from the thread owning the THD. @param[in] thd MySQL thread handle @@ -2329,22 +2318,6 @@ innobase_get_stmt_unsafe( return NULL; } -/** Determines the current SQL statement. -Thread safe, can be called from any thread as the string is copied -into the provided buffer. -@param[in] thd MySQL thread handle -@param[out] buf Buffer containing SQL statement -@param[in] buflen Length of provided buffer -@return Length of the SQL statement */ -size_t -innobase_get_stmt_safe( - THD* thd, - char* buf, - size_t buflen) -{ - return thd_query_safe(thd, buf, buflen); -} - /**********************************************************************//** Get the current setting of the tdc_size global parameter. We do a dirty read because for one there is no synchronization object and diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index cdbbce51085..6d5c108c4a3 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -508,8 +508,6 @@ size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen); extern "C" { -struct charset_info_st *thd_charset(MYSQL_THD thd); - /** Check if a user thread is a replication slave thread @param thd user thread @retval 0 the user thread is not a replication slave thread diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 693dcd15163..05dc3f57df7 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2019, MariaDB Corporation. +Copyright (c) 2017, 2020, 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 @@ -244,13 +244,7 @@ int wsrep_innobase_mysql_sort(int mysql_type, uint charset_number, unsigned int buf_length); #endif /* WITH_WSREP */ -/**********************************************************************//** -Determines the connection character set. -@return connection character set */ -CHARSET_INFO* -innobase_get_charset( -/*=================*/ - THD* thd); /*!< in: MySQL thread handle */ +extern "C" struct charset_info_st *thd_charset(THD *thd); /** Determines the current SQL statement. Thread unsafe, can only be called from the thread owning the THD. @@ -262,19 +256,6 @@ innobase_get_stmt_unsafe( THD* thd, size_t* length); -/** Determines the current SQL statement. -Thread safe, can be called from any thread as the string is copied -into the provided buffer. -@param[in] thd MySQL thread handle -@param[out] buf Buffer containing SQL statement -@param[in] buflen Length of provided buffer -@return Length of the SQL statement */ -size_t -innobase_get_stmt_safe( - THD* thd, - char* buf, - size_t buflen); - /******************************************************************//** This function is used to find the storage length in bytes of the first n characters for prefix indexes using a multibyte character set. The function diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc index 7838ef4826d..2b9d6c96acd 100644 --- a/storage/innobase/trx/trx0i_s.cc +++ b/storage/innobase/trx/trx0i_s.cc @@ -450,7 +450,6 @@ fill_trx_row( which to copy volatile strings */ { - size_t stmt_len; const char* s; ut_ad(lock_mutex_own()); @@ -485,16 +484,14 @@ fill_trx_row( row->trx_mysql_thread_id = thd_get_thread_id(trx->mysql_thd); char query[TRX_I_S_TRX_QUERY_MAX_LEN + 1]; - stmt_len = innobase_get_stmt_safe(trx->mysql_thd, query, sizeof(query)); - - if (stmt_len > 0) { - + if (size_t stmt_len = thd_query_safe(trx->mysql_thd, query, + sizeof query)) { row->trx_query = static_cast( ha_storage_put_memlim( cache->storage, query, stmt_len + 1, MAX_ALLOWED_FOR_STORAGE(cache))); - row->trx_query_cs = innobase_get_charset(trx->mysql_thd); + row->trx_query_cs = thd_charset(trx->mysql_thd); if (row->trx_query == NULL) { From 218d20ffe3d4e833eb20a75d880fec1c1507b221 Mon Sep 17 00:00:00 2001 From: Vlad Lesin Date: Tue, 12 May 2020 13:57:09 +0300 Subject: [PATCH 25/25] MDEV-22398: mariabackup.innodb_xa_rollback fails on repeat Flush LSN to system tablespace on innodb shutdown if XA is rolled back by mariabackup. --- storage/innobase/srv/srv0start.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 41a1d42f649..e8a6a10d39d 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -2777,11 +2777,15 @@ innodb_shutdown() ut_ad(!srv_undo_sources); switch (srv_operation) { + case SRV_OPERATION_RESTORE_ROLLBACK_XA: + if (dberr_t err = fil_write_flushed_lsn(log_sys->lsn)) + ib::error() << "Writing flushed lsn " << log_sys->lsn + << " failed; error=" << err; + /* fall through */ case SRV_OPERATION_BACKUP: case SRV_OPERATION_RESTORE: case SRV_OPERATION_RESTORE_DELTA: case SRV_OPERATION_RESTORE_EXPORT: - case SRV_OPERATION_RESTORE_ROLLBACK_XA: fil_close_all_files(); break; case SRV_OPERATION_NORMAL: