From a74fa579b94bb35127ae8f55a50541ad8e558284 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Fri, 19 Mar 2021 03:24:55 +0100 Subject: [PATCH 01/25] MDEV-24903: mariabackup SST fails while adding --log-bin in startup command Mariabackup SST fails if "--log-bin" option is added with no value to command line parameters at server startup. This is because the SST scripts do not correctly interpret the "--- log-bin" option without a value. This patch adds correct handling of the "--log-bin" parameter without value to the general part of the parameter parsing (for SST scripts) and fixes the problem. Also added a test that checks the correct operation of the server after the fix. --- .../suite/galera/r/galera_log_bin_opt.result | 73 +++++++++++++++++++ mysql-test/suite/galera/t/galera_log_bin.inc | 42 +++++++++++ mysql-test/suite/galera/t/galera_log_bin.test | 43 +---------- .../galera/t/galera_log_bin_opt-master.opt | 1 + .../suite/galera/t/galera_log_bin_opt.cnf | 15 ++++ .../suite/galera/t/galera_log_bin_opt.test | 2 + scripts/wsrep_sst_common.sh | 3 + 7 files changed, 137 insertions(+), 42 deletions(-) create mode 100644 mysql-test/suite/galera/r/galera_log_bin_opt.result create mode 100644 mysql-test/suite/galera/t/galera_log_bin.inc create mode 100644 mysql-test/suite/galera/t/galera_log_bin_opt-master.opt create mode 100644 mysql-test/suite/galera/t/galera_log_bin_opt.cnf create mode 100644 mysql-test/suite/galera/t/galera_log_bin_opt.test diff --git a/mysql-test/suite/galera/r/galera_log_bin_opt.result b/mysql-test/suite/galera/r/galera_log_bin_opt.result new file mode 100644 index 0000000000000..eb009a620e057 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_log_bin_opt.result @@ -0,0 +1,73 @@ +connection node_1; +reset master; +connection node_2; +reset master; +CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +CREATE TABLE t2 (id INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1); +INSERT INTO t2 VALUES (1); +connection node_2; +SELECT COUNT(*) = 1 FROM t1; +COUNT(*) = 1 +1 +SELECT COUNT(*) = 2 FROM t2; +COUNT(*) = 2 +1 +connection node_1; +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +mysqld-bin.000001 # Gtid # # GTID #-#-# +mysqld-bin.000001 # Query # # use `test`; CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB +mysqld-bin.000001 # Gtid # # BEGIN GTID #-#-# +mysqld-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES (1) +mysqld-bin.000001 # Table_map # # table_id: # (test.t1) +mysqld-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +mysqld-bin.000001 # Xid # # COMMIT /* XID */ +mysqld-bin.000001 # Gtid # # GTID #-#-# +mysqld-bin.000001 # Query # # use `test`; CREATE TABLE t2 (id INT) ENGINE=InnoDB +mysqld-bin.000001 # Gtid # # BEGIN GTID #-#-# +mysqld-bin.000001 # Annotate_rows # # INSERT INTO t2 VALUES (1) +mysqld-bin.000001 # Table_map # # table_id: # (test.t2) +mysqld-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +mysqld-bin.000001 # Xid # # COMMIT /* XID */ +mysqld-bin.000001 # Gtid # # BEGIN GTID #-#-# +mysqld-bin.000001 # Annotate_rows # # INSERT INTO t2 VALUES (1) +mysqld-bin.000001 # Table_map # # table_id: # (test.t2) +mysqld-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +mysqld-bin.000001 # Xid # # COMMIT /* XID */ +mysqld-bin.000001 # Gtid # # GTID #-#-# +mysqld-bin.000001 # Query # # use `test`; ALTER TABLE t1 ADD COLUMN f2 INTEGER +connection node_2; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +mysqld-bin.000001 # Gtid # # GTID #-#-# +mysqld-bin.000001 # Query # # use `test`; CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB +mysqld-bin.000001 # Gtid # # BEGIN GTID #-#-# +mysqld-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES (1) +mysqld-bin.000001 # Table_map # # table_id: # (test.t1) +mysqld-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +mysqld-bin.000001 # Xid # # COMMIT /* XID */ +mysqld-bin.000001 # Gtid # # GTID #-#-# +mysqld-bin.000001 # Query # # use `test`; CREATE TABLE t2 (id INT) ENGINE=InnoDB +mysqld-bin.000001 # Gtid # # BEGIN GTID #-#-# +mysqld-bin.000001 # Annotate_rows # # INSERT INTO t2 VALUES (1) +mysqld-bin.000001 # Table_map # # table_id: # (test.t2) +mysqld-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +mysqld-bin.000001 # Xid # # COMMIT /* XID */ +mysqld-bin.000001 # Gtid # # BEGIN GTID #-#-# +mysqld-bin.000001 # Annotate_rows # # INSERT INTO t2 VALUES (1) +mysqld-bin.000001 # Table_map # # table_id: # (test.t2) +mysqld-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +mysqld-bin.000001 # Xid # # COMMIT /* XID */ +mysqld-bin.000001 # Gtid # # GTID #-#-# +mysqld-bin.000001 # Query # # use `test`; ALTER TABLE t1 ADD COLUMN f2 INTEGER +DROP TABLE t1; +DROP TABLE t2; +#cleanup +connection node_1; +RESET MASTER; diff --git a/mysql-test/suite/galera/t/galera_log_bin.inc b/mysql-test/suite/galera/t/galera_log_bin.inc new file mode 100644 index 0000000000000..f1d2a12b9de97 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_log_bin.inc @@ -0,0 +1,42 @@ +--source include/galera_cluster.inc +--source include/force_restart.inc + +--connection node_1 +reset master; +--connection node_2 +reset master; + +# +# Test Galera with --log-bin --log-slave-updates . +# This way the actual MySQL binary log is used, +# rather than Galera's own implementation +# + +CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); + +CREATE TABLE t2 (id INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1); +INSERT INTO t2 VALUES (1); + +--connection node_2 +SELECT COUNT(*) = 1 FROM t1; +SELECT COUNT(*) = 2 FROM t2; + +--connection node_1 +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +--let $MASTER_MYPORT=$NODE_MYPORT_1 +--source include/show_binlog_events.inc + +--connection node_2 +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +--let $MASTER_MYPORT=$NODE_MYPORT_2 +--source include/show_binlog_events.inc + +DROP TABLE t1; +DROP TABLE t2; + +--echo #cleanup +--connection node_1 +RESET MASTER; + diff --git a/mysql-test/suite/galera/t/galera_log_bin.test b/mysql-test/suite/galera/t/galera_log_bin.test index f1d2a12b9de97..923bd623a8a23 100644 --- a/mysql-test/suite/galera/t/galera_log_bin.test +++ b/mysql-test/suite/galera/t/galera_log_bin.test @@ -1,42 +1 @@ ---source include/galera_cluster.inc ---source include/force_restart.inc - ---connection node_1 -reset master; ---connection node_2 -reset master; - -# -# Test Galera with --log-bin --log-slave-updates . -# This way the actual MySQL binary log is used, -# rather than Galera's own implementation -# - -CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1); - -CREATE TABLE t2 (id INT) ENGINE=InnoDB; -INSERT INTO t2 VALUES (1); -INSERT INTO t2 VALUES (1); - ---connection node_2 -SELECT COUNT(*) = 1 FROM t1; -SELECT COUNT(*) = 2 FROM t2; - ---connection node_1 -ALTER TABLE t1 ADD COLUMN f2 INTEGER; ---let $MASTER_MYPORT=$NODE_MYPORT_1 ---source include/show_binlog_events.inc - ---connection node_2 -SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; ---let $MASTER_MYPORT=$NODE_MYPORT_2 ---source include/show_binlog_events.inc - -DROP TABLE t1; -DROP TABLE t2; - ---echo #cleanup ---connection node_1 -RESET MASTER; - +--source galera_log_bin.inc diff --git a/mysql-test/suite/galera/t/galera_log_bin_opt-master.opt b/mysql-test/suite/galera/t/galera_log_bin_opt-master.opt new file mode 100644 index 0000000000000..03fcb5d040dac --- /dev/null +++ b/mysql-test/suite/galera/t/galera_log_bin_opt-master.opt @@ -0,0 +1 @@ +--log-slave-updates --log-bin diff --git a/mysql-test/suite/galera/t/galera_log_bin_opt.cnf b/mysql-test/suite/galera/t/galera_log_bin_opt.cnf new file mode 100644 index 0000000000000..a09efd2e01109 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_log_bin_opt.cnf @@ -0,0 +1,15 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep_sst_method=mariabackup +wsrep_sst_auth="root:" + +[mysqld.1] +wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true' + +[sst] +transferfmt=@ENV.MTR_GALERA_TFMT +streamfmt=xbstream diff --git a/mysql-test/suite/galera/t/galera_log_bin_opt.test b/mysql-test/suite/galera/t/galera_log_bin_opt.test new file mode 100644 index 0000000000000..f3d0afbc8bce3 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_log_bin_opt.test @@ -0,0 +1,2 @@ +--source include/have_mariabackup.inc +--source galera_log_bin.inc diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index f5adf0b0fd868..443cb26ab64ea 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -212,6 +212,9 @@ case "$1" in "$option" != "--port" && \ "$option" != "--socket" ]]; then value=${1#*=} + if [ "$value" == "$1" ]; then + value="" + fi case "$option" in '--innodb-data-home-dir') if [ -z "$INNODB_DATA_HOME_DIR_ARG" ]; then From 96dd4b53c16c458365d5cb6956db6ed96d55b4b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 19 Mar 2021 16:10:33 +0200 Subject: [PATCH 02/25] MDEV-8708 fixup: Remove dead code --- storage/innobase/row/row0merge.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 6571a7fbfec7c..3de85f024a316 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -4833,10 +4833,6 @@ row_merge_build_indexes( buf, i + 1, n_indexes); } - DBUG_EXECUTE_IF( - "ib_merge_wait_after_sort", - os_thread_sleep(20000000);); /* 20 sec */ - if (error == DB_SUCCESS) { BtrBulk btr_bulk(sort_idx, trx, trx->get_flush_observer()); From 209e8ecf9a976a4c7d07dda5afc22adef7e33fc5 Mon Sep 17 00:00:00 2001 From: Alexey Yurchenko Date: Sat, 20 Mar 2021 10:46:43 +0200 Subject: [PATCH 03/25] MDEV-22240: don't use pc.splitbrain=true on node2 in galera.galera_gcache_recover --- mysql-test/suite/galera/t/galera_gcache_recover.cnf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/galera/t/galera_gcache_recover.cnf b/mysql-test/suite/galera/t/galera_gcache_recover.cnf index c7b59b6a27ea3..34c757de77ef9 100644 --- a/mysql-test/suite/galera/t/galera_gcache_recover.cnf +++ b/mysql-test/suite/galera/t/galera_gcache_recover.cnf @@ -4,4 +4,4 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.recover=yes;pc.ignore_sb=true' [mysqld.2] -wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.recover=yes;pc.ignore_sb=true' +wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.recover=yes' From aba7884138fa649f3e1377174afbb567cf3be7af Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sun, 21 Mar 2021 12:08:54 -0700 Subject: [PATCH 04/25] MDEV-25206 Crash with CREATE VIEW .. SELECT with non-existing field in ON condition The fix of the bug MDEV-25002 for 10.4 turned out to be incomplete. It caused crashes when executing CREATE VIEW, CREATE TABLE .. SELECT, INSERT .. SELECT statements if their SELECTs contained references to non-existing fields. This patch complements the fix for MDEV-25002 in order to avoid such crashes. Approved by Oleksandr Byelkin --- mysql-test/main/view.result | 16 ++++++++++++++++ mysql-test/main/view.test | 21 +++++++++++++++++++++ sql/item.cc | 5 +++-- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/view.result b/mysql-test/main/view.result index c55c93e118e1e..de4be4efda53c 100644 --- a/mysql-test/main/view.result +++ b/mysql-test/main/view.result @@ -6824,3 +6824,19 @@ Drop table t1; # # End of 10.3 tests # +# +# MDEV-25206: view specification contains unknown column reference +# +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b int); +INSERT INTO t2 VALUES (2),(3); +CREATE TABLE t3 (c int); +CREATE VIEW v1 AS SELECT * FROM t1 JOIN t2 ON t1.x > t2.b; +ERROR 42S22: Unknown column 't1.x' in 'on clause' +INSERT INTO t3 SELECT * FROM t1 JOIN t2 ON t1.x > t2.b; +ERROR 42S22: Unknown column 't1.x' in 'on clause' +CREATE TABLE t4 AS SELECT * FROM t1 JOIN t2 ON t1.x > t2.b; +ERROR 42S22: Unknown column 't1.x' in 'on clause' +DROP TABLE t1,t2,t3; +# End of 10.4 tests diff --git a/mysql-test/main/view.test b/mysql-test/main/view.test index 1429642b0ab05..ca5456930baba 100644 --- a/mysql-test/main/view.test +++ b/mysql-test/main/view.test @@ -6542,3 +6542,24 @@ Drop table t1; --echo # --echo # End of 10.3 tests --echo # + +--echo # +--echo # MDEV-25206: view specification contains unknown column reference +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b int); +INSERT INTO t2 VALUES (2),(3); +CREATE TABLE t3 (c int); + +--error ER_BAD_FIELD_ERROR +CREATE VIEW v1 AS SELECT * FROM t1 JOIN t2 ON t1.x > t2.b; +--error ER_BAD_FIELD_ERROR +INSERT INTO t3 SELECT * FROM t1 JOIN t2 ON t1.x > t2.b; +--error ER_BAD_FIELD_ERROR +CREATE TABLE t4 AS SELECT * FROM t1 JOIN t2 ON t1.x > t2.b; + +DROP TABLE t1,t2,t3; + +--echo # End of 10.4 tests diff --git a/sql/item.cc b/sql/item.cc index b8eb0d453d57c..ab1916c766f54 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5422,8 +5422,9 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) Name_resolution_context *outer_context= 0; SELECT_LEX *select= 0; /* Currently derived tables cannot be correlated */ - if (current_sel->master_unit()->first_select()->get_linkage() != - DERIVED_TABLE_TYPE) + if ((current_sel->master_unit()->first_select()->get_linkage() != + DERIVED_TABLE_TYPE) && + current_sel->master_unit()->outer_select()) outer_context= context->outer_context; /* From b58b289827af4a4905a8afeee9c381f3b593c293 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 19 Mar 2021 10:56:10 +1100 Subject: [PATCH 05/25] MDEV-25195: pam check getgrouplist function AIX doesn't have getgrouplist so ensure function is checked. The HAVE_POSIX_GETGROUPLIST check was insufficient. --- plugin/auth_pam/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugin/auth_pam/CMakeLists.txt b/plugin/auth_pam/CMakeLists.txt index dbb4701fbc405..1f58c7567b3ff 100644 --- a/plugin/auth_pam/CMakeLists.txt +++ b/plugin/auth_pam/CMakeLists.txt @@ -4,10 +4,11 @@ INCLUDE (CheckFunctionExists) CHECK_INCLUDE_FILES (security/pam_ext.h HAVE_PAM_EXT_H) CHECK_INCLUDE_FILES (security/pam_appl.h HAVE_PAM_APPL_H) CHECK_FUNCTION_EXISTS (strndup HAVE_STRNDUP) +CHECK_FUNCTION_EXISTS (getgrouplist HAVE_GETGROUPLIST) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) -# Check whether getgrouplist uses git_t for second and third arguments. +# Check whether getgrouplist uses gtid_t for second and third arguments. SET(CMAKE_REQUIRED_FLAGS -Werror) CHECK_C_SOURCE_COMPILES( " @@ -29,7 +30,7 @@ SET(CMAKE_REQUIRED_LIBRARIES pam) CHECK_FUNCTION_EXISTS(pam_syslog HAVE_PAM_SYSLOG) SET(CMAKE_REQUIRED_LIBRARIES) -IF(HAVE_PAM_APPL_H) +IF(HAVE_PAM_APPL_H AND HAVE_GETGROUPLIST) FIND_LIBRARY(PAM_LIBRARY pam) # for srpm build-depends detection MYSQL_ADD_PLUGIN(auth_pam auth_pam.c LINK_LIBRARIES pam MODULE_ONLY) @@ -42,7 +43,7 @@ IF(HAVE_PAM_APPL_H) INSTALL(FILES mapper/user_map.conf DESTINATION ${INSTALL_PAMDATADIR} COMPONENT Server) ENDIF() ENDIF() -ENDIF(HAVE_PAM_APPL_H) +ENDIF() CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config_auth_pam.h) From 0e9657017189883d3fbe3604e96fad9fc558dc23 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Mon, 22 Mar 2021 18:55:59 +0700 Subject: [PATCH 06/25] Added missed ' -- ' between the end of the lldb command options and the beginning of the arguments. --- mysql-test/lib/My/Debugger.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/lib/My/Debugger.pm b/mysql-test/lib/My/Debugger.pm index a2d5f2a54355a..7331238e1c895 100644 --- a/mysql-test/lib/My/Debugger.pm +++ b/mysql-test/lib/My/Debugger.pm @@ -61,7 +61,7 @@ my %debuggers = ( lldb => { term => 1, options => '-s {script} {exe}', - script => 'process launch --stop-at-entry {args}', + script => 'process launch --stop-at-entry -- {args}', }, valgrind => { options => '--tool=memcheck --show-reachable=yes --leak-check=yes --num-callers=16 --quiet --suppressions='.cwd().'/valgrind.supp {exe} {args} --loose-wait-for-pos-timeout=1500', From 61e00db6ad5d74ca167267a954712a9c3973c518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 22 Mar 2021 15:22:59 +0200 Subject: [PATCH 07/25] MDEV-24796 Assertion `page_has_next... failed in btr_pcur_store_position() In commit eaeb8ec4b87882711ecb8e1c7476a6e410d5d2a9 (MDEV-24653) an incorrect debug assertion was introduced. btr_pcur_store_position(): If the only record in the page is the instant ALTER TABLE metadata record, we cannot expect there to be a successor page. The situation could be improved by MDEV-24673 later. --- .../suite/innodb/r/instant_alter_debug.result | 14 ++++++++++++++ .../suite/innodb/t/instant_alter_debug.test | 16 ++++++++++++++++ storage/innobase/btr/btr0pcur.cc | 3 --- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/innodb/r/instant_alter_debug.result b/mysql-test/suite/innodb/r/instant_alter_debug.result index fb298a84efa6b..3b85be1ef1c11 100644 --- a/mysql-test/suite/innodb/r/instant_alter_debug.result +++ b/mysql-test/suite/innodb/r/instant_alter_debug.result @@ -303,5 +303,19 @@ SELECT * FROM t1; a b c DROP TABLE t1; SET GLOBAL innodb_limit_optimistic_insert_debug = @saved_limit; +# +# MDEV-24796 Assertion page_has_next... failed +# in btr_pcur_store_position() +# +CREATE TABLE t1 (c INT KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1),(2); +SET GLOBAL innodb_limit_optimistic_insert_debug=2; +ALTER TABLE t1 ADD COLUMN d INT; +DELETE FROM t1; +InnoDB 0 transactions not purged +SELECT * FROM t1 WHERE c<>1 ORDER BY c DESC; +c d +DROP TABLE t1; +SET GLOBAL innodb_limit_optimistic_insert_debug = @saved_limit; # End of 10.3 tests SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; diff --git a/mysql-test/suite/innodb/t/instant_alter_debug.test b/mysql-test/suite/innodb/t/instant_alter_debug.test index 3d3bb7d3e5706..0431177a130b2 100644 --- a/mysql-test/suite/innodb/t/instant_alter_debug.test +++ b/mysql-test/suite/innodb/t/instant_alter_debug.test @@ -348,6 +348,22 @@ SELECT * FROM t1; DROP TABLE t1; SET GLOBAL innodb_limit_optimistic_insert_debug = @saved_limit; +--echo # +--echo # MDEV-24796 Assertion page_has_next... failed +--echo # in btr_pcur_store_position() +--echo # + +CREATE TABLE t1 (c INT KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1),(2); +SET GLOBAL innodb_limit_optimistic_insert_debug=2; +ALTER TABLE t1 ADD COLUMN d INT; +DELETE FROM t1; +--source include/wait_all_purged.inc +SELECT * FROM t1 WHERE c<>1 ORDER BY c DESC; +DROP TABLE t1; + +SET GLOBAL innodb_limit_optimistic_insert_debug = @saved_limit; + --echo # End of 10.3 tests SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc index 8faa6c626ff6f..9c6189acbcee1 100644 --- a/storage/innobase/btr/btr0pcur.cc +++ b/storage/innobase/btr/btr0pcur.cc @@ -169,9 +169,6 @@ btr_pcur_store_position( ut_ad(!page_has_prev(block->frame)); rec = page_rec_get_next(rec); if (page_rec_is_supremum(rec)) { - ut_ad(page_has_next(block->frame) - || block->page.id.page_no() - != index->page); goto before_first; } } From 0f8caadc96d1b34ac6bfe980fba660166ed65f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 22 Mar 2021 17:46:49 +0200 Subject: [PATCH 08/25] MDEV-22653: Remove the useless parameter innodb_simulate_comp_failures The debug parameter innodb_simulate_comp_failures injected compression failures for ROW_FORMAT=COMPRESSED tables, breaking the pre-existing logic that I had implemented in the InnoDB Plugin for MySQL 5.1 to prevent compressed page overflows. A much better check is already achieved by defining UNIV_ZIP_COPY at the compilation time. (Only UNIV_ZIP_DEBUG is part of cmake -DWITH_INNODB_EXTRA_DEBUG=ON.) --- .../include/innodb_simulate_comp_failures.inc | 152 ------------------ .../r/innodb_simulate_comp_failures.result | 17 -- ...innodb_simulate_comp_failures_small.result | 17 -- .../innodb_simulate_comp_failures-master.opt | 2 - .../t/innodb_simulate_comp_failures.test | 9 -- ...db_simulate_comp_failures_small-master.opt | 2 - .../innodb_simulate_comp_failures_small.test | 8 - ...innodb_simulate_comp_failures_basic.result | 77 --------- .../suite/sys_vars/r/sysvars_innodb.result | 12 -- .../innodb_simulate_comp_failures_basic.test | 65 -------- storage/innobase/handler/ha_innodb.cc | 6 - storage/innobase/include/srv0srv.h | 3 - storage/innobase/page/page0zip.cc | 27 ---- storage/innobase/srv/srv0srv.cc | 3 - 14 files changed, 400 deletions(-) delete mode 100644 mysql-test/suite/innodb/include/innodb_simulate_comp_failures.inc delete mode 100644 mysql-test/suite/innodb/r/innodb_simulate_comp_failures.result delete mode 100644 mysql-test/suite/innodb/r/innodb_simulate_comp_failures_small.result delete mode 100644 mysql-test/suite/innodb/t/innodb_simulate_comp_failures-master.opt delete mode 100644 mysql-test/suite/innodb/t/innodb_simulate_comp_failures.test delete mode 100644 mysql-test/suite/innodb/t/innodb_simulate_comp_failures_small-master.opt delete mode 100644 mysql-test/suite/innodb/t/innodb_simulate_comp_failures_small.test delete mode 100644 mysql-test/suite/sys_vars/r/innodb_simulate_comp_failures_basic.result delete mode 100644 mysql-test/suite/sys_vars/t/innodb_simulate_comp_failures_basic.test diff --git a/mysql-test/suite/innodb/include/innodb_simulate_comp_failures.inc b/mysql-test/suite/innodb/include/innodb_simulate_comp_failures.inc deleted file mode 100644 index d9c0294faf52b..0000000000000 --- a/mysql-test/suite/innodb/include/innodb_simulate_comp_failures.inc +++ /dev/null @@ -1,152 +0,0 @@ ---echo # ---echo # Testing robustness against random compression failures ---echo # - ---source include/not_embedded.inc ---source include/have_innodb.inc - ---let $simulate_comp_failures_save = `SELECT @@innodb_simulate_comp_failures` - ---disable_query_log -call mtr.add_suppression("InnoDB: Simulating a compression failure for table `test`\\.`t1`"); ---enable_query_log - -# create the table with compressed pages of size 8K. -CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, msg VARCHAR(255), KEY msg_i(msg)) ENGINE=INNODB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; - -SHOW CREATE TABLE t1; - -# percentage of compressions that will be forced to fail -SET GLOBAL innodb_simulate_comp_failures = 25; - ---disable_query_log ---disable_result_log - -let $num_inserts_ind = $num_inserts; -let $commit_iterations=50; - -while ($num_inserts_ind) -{ - let $repeat = `select floor(rand() * 10)`; - eval INSERT INTO t1(id, msg) - VALUES ($num_inserts_ind, REPEAT('abcdefghijklmnopqrstuvwxyz', $repeat)); - dec $num_inserts_ind; -} - ---enable_query_log ---enable_result_log - -COMMIT; -SELECT COUNT(id) FROM t1; - ---disable_query_log ---disable_result_log - -# do random ops, making sure that some pages will get fragmented and reorganized. -let $num_ops_ind = $num_ops; -let $commit_count= $commit_iterations; - -BEGIN; - -while($num_ops_ind) -{ - let $idx = `select floor(rand()*$num_inserts)`; - let $insert_or_update = `select floor(rand()*3)`; - - let $repeat = `select floor(rand() * 9) + 1`; - - let $msg = query_get_value(`select repeat('abcdefghijklmnopqrstuvwxyz', $repeat) as x`, x, 1); - - let $single_or_multi = `select floor(rand()*10)`; - - if ($insert_or_update) - { - let $cnt = query_get_value(SELECT COUNT(*) cnt FROM t1 WHERE id=$idx, cnt, 1); - - if ($cnt) - { - let $update = `select floor(rand()*2)`; - - if ($update) - { - if ($single_or_multi) - { - eval UPDATE t1 SET msg=\"$msg\" WHERE id=$idx; - } - - if (!$single_or_multi) - { - eval UPDATE t1 SET msg=\"$msg\" WHERE id >= $idx - 100 AND id <= $idx + 100; - } - - } - - if (!$update) - { - if ($single_or_multi) - { - eval INSERT INTO t1(msg, id) VALUES (\"$msg\", $idx) ON DUPLICATE KEY UPDATE msg=VALUES(msg), id = VALUES(id); - } - - if (!$single_or_multi) - { - let $diff = 200; - - while ($diff) - { - eval INSERT INTO t1(msg, id) VALUES (\"$msg\", $idx + 100 - $diff) ON DUPLICATE KEY UPDATE msg=VALUES(msg), id=VALUES(id); - - dec $diff; - } - } - } - } - - if (!$cnt) - { - let $null_msg = `select floor(rand()*2)`; - - if ($null_msg) - { - eval INSERT INTO t1(id,msg) VALUES ($idx, NULL); - } - - if (!$null_msg) - { - eval INSERT INTO t1(id, msg) VALUES ($idx, \"$msg\"); - } - } - } - - if (!$insert_or_update) - { - if ($single_or_multi) - { - eval DELETE from t1 WHERE id=$idx; - } - - if (!$single_or_multi) - { - eval DELETE from t1 WHERE id >= $idx - 100 AND id <= $idx + 100; - } - } - - dec $commit_count; - if (!$commit_count) - { - let $commit_count= $commit_iterations; - COMMIT; - BEGIN; - } - - dec $num_ops_ind; -} - -COMMIT; - -# final cleanup -DROP TABLE t1; - -eval SET GLOBAL innodb_simulate_comp_failures = $simulate_comp_failures_save; - ---enable_query_log diff --git a/mysql-test/suite/innodb/r/innodb_simulate_comp_failures.result b/mysql-test/suite/innodb/r/innodb_simulate_comp_failures.result deleted file mode 100644 index f35e415960378..0000000000000 --- a/mysql-test/suite/innodb/r/innodb_simulate_comp_failures.result +++ /dev/null @@ -1,17 +0,0 @@ -# -# Testing robustness against random compression failures -# -CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, msg VARCHAR(255), KEY msg_i(msg)) ENGINE=INNODB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; -SHOW CREATE TABLE t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `msg` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `msg_i` (`msg`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8 -SET GLOBAL innodb_simulate_comp_failures = 25; -COMMIT; -SELECT COUNT(id) FROM t1; -COUNT(id) -1500 diff --git a/mysql-test/suite/innodb/r/innodb_simulate_comp_failures_small.result b/mysql-test/suite/innodb/r/innodb_simulate_comp_failures_small.result deleted file mode 100644 index 099c673bca788..0000000000000 --- a/mysql-test/suite/innodb/r/innodb_simulate_comp_failures_small.result +++ /dev/null @@ -1,17 +0,0 @@ -# -# Testing robustness against random compression failures -# -CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, msg VARCHAR(255), KEY msg_i(msg)) ENGINE=INNODB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; -SHOW CREATE TABLE t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `msg` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `msg_i` (`msg`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8 -SET GLOBAL innodb_simulate_comp_failures = 25; -COMMIT; -SELECT COUNT(id) FROM t1; -COUNT(id) -1000 diff --git a/mysql-test/suite/innodb/t/innodb_simulate_comp_failures-master.opt b/mysql-test/suite/innodb/t/innodb_simulate_comp_failures-master.opt deleted file mode 100644 index 39b205c9b6824..0000000000000 --- a/mysql-test/suite/innodb/t/innodb_simulate_comp_failures-master.opt +++ /dev/null @@ -1,2 +0,0 @@ ---innodb-file-per-table ---skip-innodb-doublewrite diff --git a/mysql-test/suite/innodb/t/innodb_simulate_comp_failures.test b/mysql-test/suite/innodb/t/innodb_simulate_comp_failures.test deleted file mode 100644 index 5a4978c9b370f..0000000000000 --- a/mysql-test/suite/innodb/t/innodb_simulate_comp_failures.test +++ /dev/null @@ -1,9 +0,0 @@ ---source include/big_test.inc -# test takes too long with valgrind ---source include/not_valgrind.inc ---source include/have_debug.inc ---let $num_inserts = 1500 ---let $num_ops = 3500 ---source suite/innodb/include/innodb_simulate_comp_failures.inc -# clean exit ---exit diff --git a/mysql-test/suite/innodb/t/innodb_simulate_comp_failures_small-master.opt b/mysql-test/suite/innodb/t/innodb_simulate_comp_failures_small-master.opt deleted file mode 100644 index fae3205924993..0000000000000 --- a/mysql-test/suite/innodb/t/innodb_simulate_comp_failures_small-master.opt +++ /dev/null @@ -1,2 +0,0 @@ ---innodb-file-per-table - diff --git a/mysql-test/suite/innodb/t/innodb_simulate_comp_failures_small.test b/mysql-test/suite/innodb/t/innodb_simulate_comp_failures_small.test deleted file mode 100644 index 79a16d3691753..0000000000000 --- a/mysql-test/suite/innodb/t/innodb_simulate_comp_failures_small.test +++ /dev/null @@ -1,8 +0,0 @@ ---source include/have_debug.inc ---source include/not_valgrind.inc - ---let $num_inserts = 1000 ---let $num_ops = 30 ---source suite/innodb/include/innodb_simulate_comp_failures.inc -# clean exit ---exit diff --git a/mysql-test/suite/sys_vars/r/innodb_simulate_comp_failures_basic.result b/mysql-test/suite/sys_vars/r/innodb_simulate_comp_failures_basic.result deleted file mode 100644 index 7a6c9ca2db6a4..0000000000000 --- a/mysql-test/suite/sys_vars/r/innodb_simulate_comp_failures_basic.result +++ /dev/null @@ -1,77 +0,0 @@ -SET @start_global_value = @@global.innodb_simulate_comp_failures; -SELECT @start_global_value; -@start_global_value -0 -Valid values are between 0 and 99 -select @@global.innodb_simulate_comp_failures between 0 and 99; -@@global.innodb_simulate_comp_failures between 0 and 99 -1 -select @@global.innodb_simulate_comp_failures; -@@global.innodb_simulate_comp_failures -0 -select @@session.innodb_simulate_comp_failures; -ERROR HY000: Variable 'innodb_simulate_comp_failures' is a GLOBAL variable -show global variables like 'innodb_simulate_comp_failures'; -Variable_name Value -innodb_simulate_comp_failures 0 -show session variables like 'innodb_simulate_comp_failures'; -Variable_name Value -innodb_simulate_comp_failures 0 -select * from information_schema.global_variables where variable_name='innodb_simulate_comp_failures'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_SIMULATE_COMP_FAILURES 0 -select * from information_schema.session_variables where variable_name='innodb_simulate_comp_failures'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_SIMULATE_COMP_FAILURES 0 -set global innodb_simulate_comp_failures=10; -select @@global.innodb_simulate_comp_failures; -@@global.innodb_simulate_comp_failures -10 -select * from information_schema.global_variables where variable_name='innodb_simulate_comp_failures'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_SIMULATE_COMP_FAILURES 10 -select * from information_schema.session_variables where variable_name='innodb_simulate_comp_failures'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_SIMULATE_COMP_FAILURES 10 -set session innodb_simulate_comp_failures=1; -ERROR HY000: Variable 'innodb_simulate_comp_failures' is a GLOBAL variable and should be set with SET GLOBAL -set global innodb_simulate_comp_failures=1.1; -ERROR 42000: Incorrect argument type to variable 'innodb_simulate_comp_failures' -set global innodb_simulate_comp_failures=1e1; -ERROR 42000: Incorrect argument type to variable 'innodb_simulate_comp_failures' -set global innodb_simulate_comp_failures="foo"; -ERROR 42000: Incorrect argument type to variable 'innodb_simulate_comp_failures' -set global innodb_simulate_comp_failures=-7; -Warnings: -Warning 1292 Truncated incorrect innodb_simulate_comp_failures value: '-7' -select @@global.innodb_simulate_comp_failures; -@@global.innodb_simulate_comp_failures -0 -select * from information_schema.global_variables where variable_name='innodb_simulate_comp_failures'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_SIMULATE_COMP_FAILURES 0 -set global innodb_simulate_comp_failures=106; -Warnings: -Warning 1292 Truncated incorrect innodb_simulate_comp_failures value: '106' -select @@global.innodb_simulate_comp_failures; -@@global.innodb_simulate_comp_failures -99 -select * from information_schema.global_variables where variable_name='innodb_simulate_comp_failures'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_SIMULATE_COMP_FAILURES 99 -set global innodb_simulate_comp_failures=0; -select @@global.innodb_simulate_comp_failures; -@@global.innodb_simulate_comp_failures -0 -set global innodb_simulate_comp_failures=99; -select @@global.innodb_simulate_comp_failures; -@@global.innodb_simulate_comp_failures -99 -set global innodb_simulate_comp_failures=DEFAULT; -select @@global.innodb_simulate_comp_failures; -@@global.innodb_simulate_comp_failures -0 -SET @@global.innodb_simulate_comp_failures = @start_global_value; -SELECT @@global.innodb_simulate_comp_failures; -@@global.innodb_simulate_comp_failures -0 diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result index e67a3d28fb618..5a845825c47d2 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result @@ -2202,18 +2202,6 @@ NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED -VARIABLE_NAME INNODB_SIMULATE_COMP_FAILURES -SESSION_VALUE NULL -DEFAULT_VALUE 0 -VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE INT UNSIGNED -VARIABLE_COMMENT Simulate compression failures. -NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 99 -NUMERIC_BLOCK_SIZE 0 -ENUM_VALUE_LIST NULL -READ_ONLY NO -COMMAND_LINE_ARGUMENT NONE VARIABLE_NAME INNODB_SORT_BUFFER_SIZE SESSION_VALUE NULL DEFAULT_VALUE 1048576 diff --git a/mysql-test/suite/sys_vars/t/innodb_simulate_comp_failures_basic.test b/mysql-test/suite/sys_vars/t/innodb_simulate_comp_failures_basic.test deleted file mode 100644 index 07e70bf7343ad..0000000000000 --- a/mysql-test/suite/sys_vars/t/innodb_simulate_comp_failures_basic.test +++ /dev/null @@ -1,65 +0,0 @@ ---source include/have_innodb.inc ---source include/have_debug.inc - -SET @start_global_value = @@global.innodb_simulate_comp_failures; -SELECT @start_global_value; - -# -# exists as global only -# - ---echo Valid values are between 0 and 99 -select @@global.innodb_simulate_comp_failures between 0 and 99; -select @@global.innodb_simulate_comp_failures; - ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -select @@session.innodb_simulate_comp_failures; - -show global variables like 'innodb_simulate_comp_failures'; -show session variables like 'innodb_simulate_comp_failures'; -select * from information_schema.global_variables where variable_name='innodb_simulate_comp_failures'; -select * from information_schema.session_variables where variable_name='innodb_simulate_comp_failures'; - -# -# show that it's writable -# - -set global innodb_simulate_comp_failures=10; -select @@global.innodb_simulate_comp_failures; -select * from information_schema.global_variables where variable_name='innodb_simulate_comp_failures'; -select * from information_schema.session_variables where variable_name='innodb_simulate_comp_failures'; - ---error ER_GLOBAL_VARIABLE -set session innodb_simulate_comp_failures=1; - -# -# incorrect types -# - ---error ER_WRONG_TYPE_FOR_VAR -set global innodb_simulate_comp_failures=1.1; ---error ER_WRONG_TYPE_FOR_VAR -set global innodb_simulate_comp_failures=1e1; ---error ER_WRONG_TYPE_FOR_VAR -set global innodb_simulate_comp_failures="foo"; - -set global innodb_simulate_comp_failures=-7; -select @@global.innodb_simulate_comp_failures; -select * from information_schema.global_variables where variable_name='innodb_simulate_comp_failures'; -set global innodb_simulate_comp_failures=106; -select @@global.innodb_simulate_comp_failures; -select * from information_schema.global_variables where variable_name='innodb_simulate_comp_failures'; - -# -# min/max/DEFAULT values -# - -set global innodb_simulate_comp_failures=0; -select @@global.innodb_simulate_comp_failures; -set global innodb_simulate_comp_failures=99; -select @@global.innodb_simulate_comp_failures; -set global innodb_simulate_comp_failures=DEFAULT; -select @@global.innodb_simulate_comp_failures; - -SET @@global.innodb_simulate_comp_failures = @start_global_value; -SELECT @@global.innodb_simulate_comp_failures; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 7478cdf498756..144f9951eb0c1 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -21044,11 +21044,6 @@ static MYSQL_SYSVAR_BOOL(master_thread_disabled_debug, PLUGIN_VAR_OPCMDARG, "Disable master thread", NULL, srv_master_thread_disabled_debug_update, FALSE); - -static MYSQL_SYSVAR_UINT(simulate_comp_failures, srv_simulate_comp_failures, - PLUGIN_VAR_NOCMDARG, - "Simulate compression failures.", - NULL, NULL, 0, 0, 99, 0); #endif /* UNIV_DEBUG */ static MYSQL_SYSVAR_BOOL(force_primary_key, @@ -21392,7 +21387,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(compression_pad_pct_max), MYSQL_SYSVAR(default_row_format), #ifdef UNIV_DEBUG - MYSQL_SYSVAR(simulate_comp_failures), MYSQL_SYSVAR(trx_rseg_n_slots_debug), MYSQL_SYSVAR(limit_optimistic_insert_debug), MYSQL_SYSVAR(trx_purge_view_update_only_debug), diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 684d8bbaf9020..d196a4d6db600 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -619,9 +619,6 @@ extern struct export_var_t export_vars; /** Global counters */ extern srv_stats_t srv_stats; -/** Simulate compression failures. */ -extern uint srv_simulate_comp_failures; - /** Fatal semaphore wait threshold = maximum number of seconds that semaphore times out in InnoDB */ #define DEFAULT_SRV_FATAL_SEMAPHORE_TIMEOUT 600 diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index 9664bda6feafe..1acbfd2e23018 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -1372,33 +1372,6 @@ page_zip_compress( MONITOR_INC(MONITOR_PAGE_COMPRESS); - /* Simulate a compression failure with a probability determined by - innodb_simulate_comp_failures, only if the page has 2 or more - records. */ - - if (srv_simulate_comp_failures - && !dict_index_is_ibuf(index) - && page_get_n_recs(page) >= 2 - && ((ulint)(rand() % 100) < srv_simulate_comp_failures) - && strcasecmp(index->table_name, "IBUF_DUMMY") != 0) { - -#ifdef UNIV_DEBUG - ib::error() - << "Simulating a compression failure" - << " for table " << index->table->name - << " index " - << index->name() - << " page " - << page_get_page_no(page) - << "(" - << (page_is_leaf(page) ? "leaf" : "non-leaf") - << ")"; - -#endif - - goto err_exit; - } - heap = mem_heap_create(page_zip_get_size(page_zip) + n_fields * (2 + sizeof(ulint)) + REC_OFFS_HEADER_SIZE diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 4974b50d6c6be..44e0946f067c7 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -509,9 +509,6 @@ current_time % 5 != 0. */ #endif /* MEM_PERIODIC_CHECK */ # define SRV_MASTER_DICT_LRU_INTERVAL (47) -/** Simulate compression failures. */ -UNIV_INTERN uint srv_simulate_comp_failures; - /** Buffer pool dump status frequence in percentages */ UNIV_INTERN ulong srv_buf_dump_status_frequency; From 56274bd5e4115d86059936ddd3bf656dab1b4354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 22 Mar 2021 18:11:44 +0200 Subject: [PATCH 09/25] MDEV-23076 Misleading "InnoDB: using atomic writes" As suggested by Vladislav Vaintroub, let us remove misleading and malformatted startup messages. Even if the global variable srv_use_atomic_writes were set, we would still invoke my_test_if_atomic_write() to check if writes are atomic with a particular page size. When using the default innodb_page_size=16k, page writes should be atomic on NTFS when using ROW_FORMAT=COMPRESSED and KEY_BLOCK_SIZE<=4. Disabling srv_use_atomic_writes when innodb_file_per_table=OFF does not make sense, because that is a dynamic parameter. We also correct the documentation string of innodb_use_atomic_writes and remove the duplicate variable innobase_use_atomic_writes. --- .../suite/sys_vars/r/sysvars_innodb.result | 2 +- storage/innobase/handler/ha_innodb.cc | 20 ++++--------------- storage/innobase/handler/ha_innodb.h | 4 ++-- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result index 5a845825c47d2..440efc6a9cdd1 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result @@ -2591,7 +2591,7 @@ SESSION_VALUE NULL DEFAULT_VALUE ON VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BOOLEAN -VARIABLE_COMMENT Enable atomic writes, instead of using the doublewrite buffer, for files on devices that supports atomic writes. To use this option one must use file_per_table=1, flush_method=O_DIRECT and use_fallocate=1. This option only works on Linux with either FusionIO cards using the directFS filesystem or with Shannon cards using any file system. +VARIABLE_COMMENT Enable atomic writes, instead of using the doublewrite buffer, for files on devices that supports atomic writes. This option only works on Linux with either FusionIO cards using the directFS filesystem or with Shannon cards using any file system. NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 144f9951eb0c1..af6fc4d5b4820 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -236,7 +236,6 @@ static char* innobase_server_stopword_table; values */ static my_bool innobase_file_format_check; -static my_bool innobase_use_atomic_writes; static my_bool innobase_use_fallocate; static my_bool innobase_use_doublewrite; static my_bool innobase_use_checksums; @@ -4314,29 +4313,20 @@ innobase_init( ib::warn() << deprecated_idle_flush_pct; } - srv_use_atomic_writes - = innobase_use_atomic_writes && my_may_have_atomic_write; - if (srv_use_atomic_writes && !srv_file_per_table) - { - fprintf(stderr, "InnoDB: Disabling atomic_writes as file_per_table is not used.\n"); - srv_use_atomic_writes= 0; - } - - if (srv_use_atomic_writes) { - fprintf(stderr, "InnoDB: using atomic writes.\n"); +#ifndef _WIN32 + if (srv_use_atomic_writes && my_may_have_atomic_write) { /* Force O_DIRECT on Unixes (on Windows writes are always unbuffered) */ -#ifndef _WIN32 if (!innobase_file_flush_method || !strstr(innobase_file_flush_method, "O_DIRECT")) { innobase_file_flush_method = srv_file_flush_method_str = (char*)"O_DIRECT"; fprintf(stderr, "InnoDB: using O_DIRECT due to atomic writes.\n"); } -#endif } +#endif #ifdef HAVE_PSI_INTERFACE /* Register keys with MySQL performance schema */ @@ -20016,12 +20006,10 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite, " Disable with --skip-innodb-doublewrite.", NULL, NULL, TRUE); -static MYSQL_SYSVAR_BOOL(use_atomic_writes, innobase_use_atomic_writes, +static MYSQL_SYSVAR_BOOL(use_atomic_writes, srv_use_atomic_writes, PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, "Enable atomic writes, instead of using the doublewrite buffer, for files " "on devices that supports atomic writes. " - "To use this option one must use " - "file_per_table=1, flush_method=O_DIRECT and use_fallocate=1. " "This option only works on Linux with either FusionIO cards using " "the directFS filesystem or with Shannon cards using any file system.", NULL, NULL, TRUE); diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index b1c34f643264d..274c6761d4f4f 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2020, MariaDB Corporation. +Copyright (c) 2013, 2021, 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 @@ -46,7 +46,7 @@ struct ha_table_option_struct uint atomic_writes; /*!< Use atomic writes for this table if this options is ON or in DEFAULT if - srv_use_atomic_writes=1. + innodb_use_atomic_writes. Atomic writes are not used if value OFF.*/ uint encryption; /*!< DEFAULT, ON, OFF */ From 8f7a6cde580298116b50b144984f996dc6af60ae Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 22 Mar 2021 22:04:54 -0700 Subject: [PATCH 10/25] MDEV-24767 Wrong result when forced BNLH is used for join supported by compound index This typo bug may lead to wrong result sets for equi-join queries where the join operation is supported by a compound index such that the order of its components differs from the order of the corresponding columns in the table the index belongs to. The bug manifests itself only when usage of the BNLH algorithm is forced. The fix for the bug was provided by Chu Huaxing. --- mysql-test/r/join_cache.result | 30 ++++++++++++++++++++++++++++++ mysql-test/t/join_cache.test | 24 ++++++++++++++++++++++++ sql/sql_join_cache.cc | 2 +- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index 87c40790cfa38..6b458e0733adf 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -6107,4 +6107,34 @@ WHERE e IS NULL; a b c d e DROP TABLE t1,t2,t3,t4; set join_cache_level=@save_join_cache_level; +# +# MDEV-24767: forced BNLH used for equi-join supported by compound index +# +create table t1 (a int, b int, c int ) engine=myisam ; +create table t2 (a int, b int, c int, primary key (c,a,b)) engine=myisam ; +insert into t1 values (3,4,2), (5,6,4); +insert into t2 values (3,4,2), (5,6,4); +select t1.a, t1.b, t1.c from t1,t2 +where t2.a = t1.a and t2.b = t1.b and t2.c=t1.c; +a b c +3 4 2 +5 6 4 +explain select t1.a, t1.b, t1.c from t1,t2 +where t2.a = t1.a and t2.b = t1.b and t2.c=t1.c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 12 test.t1.c,test.t1.a,test.t1.b 1 Using index +set join_cache_level=3; +select t1.a, t1.b, t1.c from t1,t2 +where t2.a = t1.a and t2.b = t1.b and t2.c=t1.c; +a b c +3 4 2 +5 6 4 +explain select t1.a, t1.b, t1.c from t1,t2 +where t2.a = t1.a and t2.b = t1.b and t2.c=t1.c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE t2 hash_index PRIMARY #hash#PRIMARY:PRIMARY 12:12 test.t1.c,test.t1.a,test.t1.b 2 Using index; Using join buffer (flat, BNLH join) +drop table t1,t2; +set join_cache_level=@save_join_cache_level; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 15cd1e9772f1a..55ae6afc436c3 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -4050,5 +4050,29 @@ DROP TABLE t1,t2,t3,t4; set join_cache_level=@save_join_cache_level; +--echo # +--echo # MDEV-24767: forced BNLH used for equi-join supported by compound index +--echo # + +create table t1 (a int, b int, c int ) engine=myisam ; +create table t2 (a int, b int, c int, primary key (c,a,b)) engine=myisam ; +insert into t1 values (3,4,2), (5,6,4); +insert into t2 values (3,4,2), (5,6,4); + +let $q= +select t1.a, t1.b, t1.c from t1,t2 + where t2.a = t1.a and t2.b = t1.b and t2.c=t1.c; + +eval $q; +eval explain $q; + +set join_cache_level=3; +eval $q; +eval explain $q; + +drop table t1,t2; + +set join_cache_level=@save_join_cache_level; + # The following command must be the last one in the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 594094afd744b..4f9facc6d0caa 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -1199,7 +1199,7 @@ bool JOIN_CACHE::check_emb_key_usage() Item *item= ref->items[i]->real_item(); Field *fld= ((Item_field *) item)->field; CACHE_FIELD *init_copy= field_descr+flag_fields+i; - for (j= i, copy= init_copy; i < local_key_arg_fields; i++, copy++) + for (j= i, copy= init_copy; j < local_key_arg_fields; j++, copy++) { if (fld->eq(copy->field)) { From 9e57bd278f5bfb66a50f4a0d5aaf394db6625c63 Mon Sep 17 00:00:00 2001 From: Alexey Bychko Date: Tue, 23 Mar 2021 12:37:55 +0700 Subject: [PATCH 11/25] fixed typo in postinst script --- support-files/rpm/server-postin.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/support-files/rpm/server-postin.sh b/support-files/rpm/server-postin.sh index 7151842368700..4d49f6f4e3586 100644 --- a/support-files/rpm/server-postin.sh +++ b/support-files/rpm/server-postin.sh @@ -40,7 +40,7 @@ if [ $1 = 1 ] ; then # Create a MySQL user and group. Do not report any problems if it already # exists. groupadd -r %{mysqld_group} 2> /dev/null || true - useradd -M -r --home $datadir --shell /sbin/nologin --comment "MySQL server" --gid %{mysqld_group} %{mysqld_user} 2> /dev/null || true + useradd -M -r --home $datadir --shell /sbin/nologin --comment "MySQL server" --gid %{mysqld_group} %{mysqld_user} 2> /dev/null || true # The user may already exist, make sure it has the proper group nevertheless (BUG#12823) usermod --gid %{mysqld_group} %{mysqld_user} 2> /dev/null || true @@ -78,7 +78,7 @@ if [ -x /usr/sbin/semodule ] ; then /usr/sbin/semodule -i /usr/share/mysql/policy/selinux/mariadb.pp fi -if [ -x sbin/restorecon ] ; then - sbin/restorecon -R var/lib/mysql +if [ -x /sbin/restorecon ] ; then + /sbin/restorecon -R /var/lib/mysql fi From 7d5ec9f1aeec1ea8d00a0aa5bfec521948cfb8be Mon Sep 17 00:00:00 2001 From: Alexey Bychko Date: Tue, 23 Mar 2021 12:37:55 +0700 Subject: [PATCH 12/25] fixed typo in postinst script --- support-files/rpm/server-postin.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/support-files/rpm/server-postin.sh b/support-files/rpm/server-postin.sh index 7151842368700..4d49f6f4e3586 100644 --- a/support-files/rpm/server-postin.sh +++ b/support-files/rpm/server-postin.sh @@ -40,7 +40,7 @@ if [ $1 = 1 ] ; then # Create a MySQL user and group. Do not report any problems if it already # exists. groupadd -r %{mysqld_group} 2> /dev/null || true - useradd -M -r --home $datadir --shell /sbin/nologin --comment "MySQL server" --gid %{mysqld_group} %{mysqld_user} 2> /dev/null || true + useradd -M -r --home $datadir --shell /sbin/nologin --comment "MySQL server" --gid %{mysqld_group} %{mysqld_user} 2> /dev/null || true # The user may already exist, make sure it has the proper group nevertheless (BUG#12823) usermod --gid %{mysqld_group} %{mysqld_user} 2> /dev/null || true @@ -78,7 +78,7 @@ if [ -x /usr/sbin/semodule ] ; then /usr/sbin/semodule -i /usr/share/mysql/policy/selinux/mariadb.pp fi -if [ -x sbin/restorecon ] ; then - sbin/restorecon -R var/lib/mysql +if [ -x /sbin/restorecon ] ; then + /sbin/restorecon -R /var/lib/mysql fi From 2eae1376fed1314eb1ccc8fb79157db9698f24d1 Mon Sep 17 00:00:00 2001 From: Alexey Bychko Date: Tue, 23 Mar 2021 12:37:55 +0700 Subject: [PATCH 13/25] fixed typo in postinst script --- support-files/rpm/server-postin.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/support-files/rpm/server-postin.sh b/support-files/rpm/server-postin.sh index db249c326a673..61c417e3e7d31 100644 --- a/support-files/rpm/server-postin.sh +++ b/support-files/rpm/server-postin.sh @@ -40,7 +40,7 @@ if [ $1 = 1 ] ; then # Create a MySQL user and group. Do not report any problems if it already # exists. groupadd -r %{mysqld_group} 2> /dev/null || true - useradd -M -r --home $datadir --shell /sbin/nologin --comment "MySQL server" --gid %{mysqld_group} %{mysqld_user} 2> /dev/null || true + useradd -M -r --home $datadir --shell /sbin/nologin --comment "MySQL server" --gid %{mysqld_group} %{mysqld_user} 2> /dev/null || true # The user may already exist, make sure it has the proper group nevertheless (BUG#12823) usermod --gid %{mysqld_group} %{mysqld_user} 2> /dev/null || true @@ -81,7 +81,7 @@ if [ -x /usr/sbin/semodule ] ; then /usr/sbin/semodule -i /usr/share/mysql/policy/selinux/mariadb.pp fi -if [ -x sbin/restorecon ] ; then - sbin/restorecon -R var/lib/mysql +if [ -x /sbin/restorecon ] ; then + /sbin/restorecon -R /var/lib/mysql fi From 3dae564703a63881901074cafbe5a55f1c4631ea Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Mon, 22 Mar 2021 11:36:33 +0100 Subject: [PATCH 14/25] Follow up fixes for making @@wsrep_provider read-only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove usage of wsrep_provider variable in galera_ist_restart_joiner * Rename galera_load_provider.inc and galera_unload_provider.inc to galera_stop_replication.inc and galera_start_replication.inc. Their original names were no longer reflecting what these include files do. followup for ce3a2a688db Reviewed-by: Jan Lindström --- .../suite/galera/include/galera_st_disconnect_slave.inc | 4 ++-- ...{galera_load_provider.inc => galera_start_replication.inc} | 0 ...galera_unload_provider.inc => galera_stop_replication.inc} | 0 mysql-test/suite/galera/r/galera_ist_restart_joiner.result | 3 ++- mysql-test/suite/galera/t/galera_ist_restart_joiner.test | 4 ++-- .../suite/galera/t/galera_sst_mariabackup_lost_found.test | 2 +- mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.test | 4 ++-- .../suite/galera_3nodes/t/galera_ist_gcache_rollover.test | 4 ++-- 8 files changed, 11 insertions(+), 10 deletions(-) rename mysql-test/suite/galera/include/{galera_load_provider.inc => galera_start_replication.inc} (100%) rename mysql-test/suite/galera/include/{galera_unload_provider.inc => galera_stop_replication.inc} (100%) diff --git a/mysql-test/suite/galera/include/galera_st_disconnect_slave.inc b/mysql-test/suite/galera/include/galera_st_disconnect_slave.inc index 4674fc7867ffe..830a170d50bc6 100644 --- a/mysql-test/suite/galera/include/galera_st_disconnect_slave.inc +++ b/mysql-test/suite/galera/include/galera_st_disconnect_slave.inc @@ -21,7 +21,7 @@ INSERT INTO t1 VALUES ('node2_committed_before'); INSERT INTO t1 VALUES ('node2_committed_before'); COMMIT; ---source suite/galera/include/galera_unload_provider.inc +--source suite/galera/include/galera_stop_replication.inc --connection node_1 --let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' @@ -53,7 +53,7 @@ INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); --connection node_2 ---source suite/galera/include/galera_load_provider.inc +--source suite/galera/include/galera_start_replication.inc --let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' --source include/wait_condition.inc diff --git a/mysql-test/suite/galera/include/galera_load_provider.inc b/mysql-test/suite/galera/include/galera_start_replication.inc similarity index 100% rename from mysql-test/suite/galera/include/galera_load_provider.inc rename to mysql-test/suite/galera/include/galera_start_replication.inc diff --git a/mysql-test/suite/galera/include/galera_unload_provider.inc b/mysql-test/suite/galera/include/galera_stop_replication.inc similarity index 100% rename from mysql-test/suite/galera/include/galera_unload_provider.inc rename to mysql-test/suite/galera/include/galera_stop_replication.inc diff --git a/mysql-test/suite/galera/r/galera_ist_restart_joiner.result b/mysql-test/suite/galera/r/galera_ist_restart_joiner.result index d38d664b6faea..e58d04b30b3b0 100644 --- a/mysql-test/suite/galera/r/galera_ist_restart_joiner.result +++ b/mysql-test/suite/galera/r/galera_ist_restart_joiner.result @@ -3,8 +3,9 @@ connection node_2; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)); INSERT INTO t1 VALUES (1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'a'),(6, 'a'); connection node_2; +SET SESSION wsrep_sync_wait=0; Unloading wsrep provider ... -SET GLOBAL wsrep_provider = 'none'; +SET GLOBAL wsrep_cluster_address = ''; connection node_1; UPDATE t1 SET f2 = 'b' WHERE f1 > 1; UPDATE t1 SET f2 = 'c' WHERE f1 > 2; diff --git a/mysql-test/suite/galera/t/galera_ist_restart_joiner.test b/mysql-test/suite/galera/t/galera_ist_restart_joiner.test index 633318629a660..15b47a328fccf 100644 --- a/mysql-test/suite/galera/t/galera_ist_restart_joiner.test +++ b/mysql-test/suite/galera/t/galera_ist_restart_joiner.test @@ -21,7 +21,8 @@ INSERT INTO t1 VALUES (1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'a'),(6, 'a'); # Disconnect node #2 --connection node_2 ---source suite/galera/include/galera_unload_provider.inc +SET SESSION wsrep_sync_wait=0; +--source suite/galera/include/galera_stop_replication.inc --connection node_1 UPDATE t1 SET f2 = 'b' WHERE f1 > 1; @@ -45,7 +46,6 @@ UPDATE t1 SET f2 = 'c' WHERE f1 > 2; --disable_query_log # base_port setting is lost for some reason when unloading provider, so we need to restore it --eval SET GLOBAL wsrep_provider_options= 'base_port=$NODE_GALERAPORT_2'; ---eval SET GLOBAL wsrep_provider = '$wsrep_provider_orig'; # Make sure IST will block ... --let $galera_sync_point = recv_IST_after_apply_trx --source include/galera_set_sync_point.inc diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup_lost_found.test b/mysql-test/suite/galera/t/galera_sst_mariabackup_lost_found.test index d1c3065613936..e8dcbd849d82f 100644 --- a/mysql-test/suite/galera/t/galera_sst_mariabackup_lost_found.test +++ b/mysql-test/suite/galera/t/galera_sst_mariabackup_lost_found.test @@ -10,7 +10,7 @@ --connection node_2 #--connection node_2 -#--source suite/galera/include/galera_unload_provider.inc +#--source suite/galera/include/galera_stop_replication.inc --echo Shutting down server ... --source include/shutdown_mysqld.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.test index 4904a49c73baf..79551aa185d72 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mysqldump.test @@ -37,7 +37,7 @@ SET GLOBAL wsrep_sst_method = 'mysqldump'; # #--connection node_2 -#--source suite/galera/include/galera_unload_provider.inc +#--source suite/galera/include/galera_stop_replication.inc --echo Shutting down server ... --source include/shutdown_mysqld.inc @@ -62,7 +62,7 @@ INSERT INTO t1 VALUES (1); --let $start_mysqld_params = --wsrep_sst_auth=sst: --wsrep_sst_method=mysqldump --wsrep-sst-receive-address=[::1].1:$NODE_MYPORT_2 --source include/start_mysqld.inc -#--source suite/galera/include/galera_load_provider.inc +#--source suite/galera/include/galera_start_replication.inc --let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' --source include/wait_condition.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test index ebc756d60b102..0032f8d6ee1af 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test @@ -29,10 +29,10 @@ INSERT INTO t1 VALUES (01), (02), (03), (04), (05); # Disconnect nodes #2 and #3 --connection node_2 ---source suite/galera/include/galera_unload_provider.inc +--source suite/galera/include/galera_stop_replication.inc --connection node_3 ---source suite/galera/include/galera_unload_provider.inc +--source suite/galera/include/galera_stop_replication.inc --connection node_1 --source include/wait_until_connected_again.inc From c4807c107a46597f52565243a722992467383a73 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 23 Mar 2021 21:53:27 +0100 Subject: [PATCH 15/25] MDEV-24879 Client crash on undefined charsetsdir --- client/mysql.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/mysql.cc b/client/mysql.cc index f61fab416d5cc..2eb44d465120d 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -4720,7 +4720,11 @@ sql_real_connect(char *host,char *database,char *user,char *password, return -1; // Retryable } - charset_info= get_charset_by_name(mysql.charset->name, MYF(0)); + if (!(charset_info= get_charset_by_name(mysql.charset->name, MYF(0)))) + { + put_info("Unknown default character set", INFO_ERROR); + return 1; + } connected=1; From 480a06718d137c9ee7784012ccb609b9e79ff08c Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 23 Mar 2021 20:54:54 -0700 Subject: [PATCH 16/25] MDEV-25128 Wrong result from join with materialized semi-join and splittable derived If one of joined tables of the processed query is a materialized derived table (or view or CTE) with GROUP BY clause then under some conditions it can be subject to split optimization. With this optimization new equalities are injected into the WHERE condition of the SELECT that specifies this derived table. The injected equalities are generated for all join orders with which the split optimization can employed. After the best join order has been chosen only certain of this equalities are really needed. The others can be safely removed. If it's not done and some of injected equalities involve expressions over semi-joins with look-up access then the query may return a wrong result set. This patch effectively removes equalities injected for split optimization that are needed only at the optimization stage and not needed for execution. Approved by serg@mariadb.com --- mysql-test/main/derived_cond_pushdown.result | 211 +++++++++++++++++++ mysql-test/main/derived_cond_pushdown.test | 37 ++++ sql/opt_split.cc | 48 ++++- sql/sql_select.cc | 17 ++ 4 files changed, 307 insertions(+), 6 deletions(-) diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index 27ffffd758107..f3d63b5887fdf 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -17134,4 +17134,215 @@ a 3 DROP VIEW v1; DROP TABLE t1; +# +# MDEV-25128: Split optimization for join with materialized semi-join +# +create table t1 (id int, a int, index (a), index (id, a)) engine=myisam; +insert into t1 values +(17,1),(17,3010),(17,3013),(17,3053),(21,2446),(21,2467),(21,2); +create table t2 (a int) engine=myisam; +insert into t2 values (1),(2),(3); +create table t3 (id int) engine=myisam; +insert into t3 values (1),(2); +analyze table t1,t2,t3; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK +test.t3 analyze status OK +set optimizer_switch="split_materialized=off"; +select * from t1, (select a from t1 cp2 group by a) dt, t3 +where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2); +id a a id +17 1 1 1 +21 2 2 2 +explain select * from t1, (select a from t1 cp2 group by a) dt, t3 +where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY t1 ref a a 5 test.t3.id 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +1 PRIMARY ref key0 key0 5 test.t3.id 2 +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +2 DERIVED cp2 index NULL a 5 NULL 7 Using index +explain format=json select * from t1, (select a from t1 cp2 group by a) dt, t3 +where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t3", + "access_type": "ALL", + "rows": 2, + "filtered": 100, + "attached_condition": "t3.`id` is not null and t3.`id` is not null" + }, + "table": { + "table_name": "t1", + "access_type": "ref", + "possible_keys": ["a"], + "key": "a", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t3.id"], + "rows": 1, + "filtered": 100 + }, + "table": { + "table_name": "", + "access_type": "eq_ref", + "possible_keys": ["distinct_key"], + "key": "distinct_key", + "key_length": "4", + "used_key_parts": ["a"], + "ref": ["func"], + "rows": 1, + "filtered": 100, + "materialized": { + "unique": 1, + "query_block": { + "select_id": 3, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + } + }, + "table": { + "table_name": "", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t3.id"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 2, + "table": { + "table_name": "cp2", + "access_type": "index", + "key": "a", + "key_length": "5", + "used_key_parts": ["a"], + "rows": 7, + "filtered": 100, + "using_index": true + } + } + } + } + } +} +set optimizer_switch="split_materialized=default"; +select * from t1, (select a from t1 cp2 group by a) dt, t3 +where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2); +id a a id +17 1 1 1 +21 2 2 2 +explain select * from t1, (select a from t1 cp2 group by a) dt, t3 +where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY t1 ref a a 5 test.t3.id 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +1 PRIMARY ref key0 key0 5 test.t3.id 2 +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 +2 LATERAL DERIVED cp2 ref a a 5 test.t1.a 1 Using index +explain format=json select * from t1, (select a from t1 cp2 group by a) dt, t3 +where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t3", + "access_type": "ALL", + "rows": 2, + "filtered": 100, + "attached_condition": "t3.`id` is not null and t3.`id` is not null" + }, + "table": { + "table_name": "t1", + "access_type": "ref", + "possible_keys": ["a"], + "key": "a", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t3.id"], + "rows": 1, + "filtered": 100 + }, + "table": { + "table_name": "", + "access_type": "eq_ref", + "possible_keys": ["distinct_key"], + "key": "distinct_key", + "key_length": "4", + "used_key_parts": ["a"], + "ref": ["func"], + "rows": 1, + "filtered": 100, + "materialized": { + "unique": 1, + "query_block": { + "select_id": 3, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + } + }, + "table": { + "table_name": "", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t3.id"], + "rows": 2, + "filtered": 100, + "materialized": { + "lateral": 1, + "query_block": { + "select_id": 2, + "outer_ref_condition": "t1.a is not null", + "table": { + "table_name": "cp2", + "access_type": "ref", + "possible_keys": ["a"], + "key": "a", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t1.a"], + "rows": 1, + "filtered": 100, + "using_index": true + } + } + } + } + } +} +prepare stmt from "select * from t1, (select a from t1 cp2 group by a) dt, t3 +where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2)"; +execute stmt; +id a a id +17 1 1 1 +21 2 2 2 +execute stmt; +id a a id +17 1 1 1 +21 2 2 2 +deallocate prepare stmt; +drop table t1,t2,t3; # End of 10.3 tests diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test index 12d34a8326a81..5936447fc88c3 100644 --- a/mysql-test/main/derived_cond_pushdown.test +++ b/mysql-test/main/derived_cond_pushdown.test @@ -3479,4 +3479,41 @@ SELECT * from v1 WHERE a=3; DROP VIEW v1; DROP TABLE t1; +--echo # +--echo # MDEV-25128: Split optimization for join with materialized semi-join +--echo # + +create table t1 (id int, a int, index (a), index (id, a)) engine=myisam; +insert into t1 values +(17,1),(17,3010),(17,3013),(17,3053),(21,2446),(21,2467),(21,2); + +create table t2 (a int) engine=myisam; +insert into t2 values (1),(2),(3); + +create table t3 (id int) engine=myisam; +insert into t3 values (1),(2); + +analyze table t1,t2,t3; + +let $q= +select * from t1, (select a from t1 cp2 group by a) dt, t3 + where dt.a = t1.a and t1.a = t3.id and t1.a in (select a from t2); + +set optimizer_switch="split_materialized=off"; +eval $q; +eval explain $q; +eval explain format=json $q; + +set optimizer_switch="split_materialized=default"; +eval $q; +eval explain $q; +eval explain format=json $q; + +eval prepare stmt from "$q"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +drop table t1,t2,t3; + --echo # End of 10.3 tests diff --git a/sql/opt_split.cc b/sql/opt_split.cc index fd7836f55ccf2..c3a2d03a93b65 100644 --- a/sql/opt_split.cc +++ b/sql/opt_split.cc @@ -236,6 +236,8 @@ class SplM_opt_info : public Sql_alloc SplM_field_info *spl_fields; /* The number of elements in the above list */ uint spl_field_cnt; + /* The list of equalities injected into WHERE for split optimization */ + List inj_cond_list; /* Contains the structures to generate all KEYUSEs for pushable equalities */ List added_key_fields; /* The cache of evaluated execution plans for 'join' with pushed equalities */ @@ -1047,22 +1049,22 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count, bool JOIN::inject_best_splitting_cond(table_map remaining_tables) { Item *inj_cond= 0; - List inj_cond_list; + List *inj_cond_list= &spl_opt_info->inj_cond_list; List_iterator li(spl_opt_info->added_key_fields); KEY_FIELD *added_key_field; while ((added_key_field= li++)) { if (remaining_tables & added_key_field->val->used_tables()) continue; - if (inj_cond_list.push_back(added_key_field->cond, thd->mem_root)) + if (inj_cond_list->push_back(added_key_field->cond, thd->mem_root)) return true; } - DBUG_ASSERT(inj_cond_list.elements); - switch (inj_cond_list.elements) { + DBUG_ASSERT(inj_cond_list->elements); + switch (inj_cond_list->elements) { case 1: - inj_cond= inj_cond_list.head(); break; + inj_cond= inj_cond_list->head(); break; default: - inj_cond= new (thd->mem_root) Item_cond_and(thd, inj_cond_list); + inj_cond= new (thd->mem_root) Item_cond_and(thd, *inj_cond_list); if (!inj_cond) return true; } @@ -1080,6 +1082,40 @@ bool JOIN::inject_best_splitting_cond(table_map remaining_tables) } +/** + @brief + Test if equality is injected for split optimization + + @param + eq_item equality to to test + + @retval + true eq_item is equality injected for split optimization + false otherwise +*/ + +bool is_eq_cond_injected_for_split_opt(Item_func_eq *eq_item) +{ + Item *left_item= eq_item->arguments()[0]->real_item(); + if (left_item->type() != Item::FIELD_ITEM) + return false; + Field *field= ((Item_field *) left_item)->field; + if (!field->table->reginfo.join_tab) + return false; + JOIN *join= field->table->reginfo.join_tab->join; + if (!join->spl_opt_info) + return false; + List_iterator_fast li(join->spl_opt_info->inj_cond_list); + Item *item; + while ((item= li++)) + { + if (item == eq_item) + return true; + } + return false; +} + + /** @brief Fix the splitting chosen for a splittable table in the final query plan diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5f8bd24032f1b..1eb23781da28c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -292,6 +292,8 @@ void set_postjoin_aggr_write_func(JOIN_TAB *tab); static Item **get_sargable_cond(JOIN *join, TABLE *table); +bool is_eq_cond_injected_for_split_opt(Item_func_eq *eq_item); + #ifndef DBUG_OFF /* @@ -21787,6 +21789,21 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond, cond->marker=3; // Checked when read return (COND*) 0; } + /* + If cond is an equality injected for split optimization then + a. when retain_ref_cond == false : cond is removed unconditionally + (cond that supports ref access is removed by the preceding code) + b. when retain_ref_cond == true : cond is removed if it does not + support ref access + */ + if (left_item->type() == Item::FIELD_ITEM && + is_eq_cond_injected_for_split_opt((Item_func_eq *) cond) && + (!retain_ref_cond || + !test_if_ref(root_cond, (Item_field*) left_item,right_item))) + { + cond->marker=3; + return (COND*) 0; + } } cond->marker=2; cond->set_join_tab_idx(join_tab_idx_arg); From cdb86faf82772e0c3f4d2532f91afbc6aa451a93 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 24 Mar 2021 08:55:36 +0100 Subject: [PATCH 17/25] MDEV-23740 postfix - potentially uninitialized variable passed to vio_socket_io_wait. Thanks to Daniel Black for reporting. --- vio/viossl.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/vio/viossl.c b/vio/viossl.c index 8fdc8a3d68c10..bdd3c9ca024db 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -97,13 +97,14 @@ static void ssl_set_sys_error(int ssl_error) @param vio VIO object representing a SSL connection. @param ret Value returned by a SSL I/O function. @param event[out] The type of I/O event to wait/retry. + @param should_wait[out] whether to wait for 'event' @return Whether a SSL I/O operation should be deferred. @retval TRUE Temporary failure, retry operation. @retval FALSE Indeterminate failure. */ -static my_bool ssl_should_retry(Vio *vio, int ret, enum enum_vio_io_event *event) +static my_bool ssl_should_retry(Vio *vio, int ret, enum enum_vio_io_event *event, my_bool *should_wait) { int ssl_error; SSL *ssl= vio->ssl_arg; @@ -120,6 +121,7 @@ static my_bool ssl_should_retry(Vio *vio, int ret, enum enum_vio_io_event *event ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) { ERR_clear_error(); + *should_wait= FALSE; return TRUE; } #endif @@ -132,12 +134,15 @@ static my_bool ssl_should_retry(Vio *vio, int ret, enum enum_vio_io_event *event { case SSL_ERROR_WANT_READ: *event= VIO_IO_EVENT_READ; + *should_wait= TRUE; break; case SSL_ERROR_WANT_WRITE: *event= VIO_IO_EVENT_WRITE; + *should_wait= TRUE; break; default: should_retry= FALSE; + *should_wait= FALSE; ssl_set_sys_error(ssl_error); #ifndef HAVE_YASSL ERR_clear_error(); @@ -165,12 +170,13 @@ size_t vio_ssl_read(Vio *vio, uchar *buf, size_t size) while ((ret= SSL_read(ssl, buf, (int)size)) < 0) { enum enum_vio_io_event event; + my_bool should_wait; /* Process the SSL I/O error. */ - if (!ssl_should_retry(vio, ret, &event)) + if (!ssl_should_retry(vio, ret, &event, &should_wait)) break; /* Attempt to wait for an I/O event. */ - if (vio_socket_io_wait(vio, event)) + if (should_wait && vio_socket_io_wait(vio, event)) break; } } @@ -198,13 +204,12 @@ size_t vio_ssl_write(Vio *vio, const uchar *buf, size_t size) while ((ret= SSL_write(ssl, buf, (int)size)) < 0) { enum enum_vio_io_event event; - + my_bool should_wait; /* Process the SSL I/O error. */ - if (!ssl_should_retry(vio, ret, &event)) + if (!ssl_should_retry(vio, ret, &event, &should_wait)) break; - /* Attempt to wait for an I/O event. */ - if (vio_socket_io_wait(vio, event)) + if (should_wait && vio_socket_io_wait(vio, event)) break; } } @@ -312,13 +317,13 @@ static int ssl_handshake_loop(Vio *vio, SSL *ssl, ssl_handshake_func_t func) while ((ret= func(ssl)) < 1) { enum enum_vio_io_event event; + my_bool should_wait; /* Process the SSL I/O error. */ - if (!ssl_should_retry(vio, ret, &event)) + if (!ssl_should_retry(vio, ret, &event, &should_wait)) break; - /* Wait for I/O so that the handshake can proceed. */ - if (vio_socket_io_wait(vio, event)) + if (should_wait && vio_socket_io_wait(vio, event)) break; } From 5a79807119974c37b4e9d3d46f8d68d29cfdba9e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 24 Mar 2021 23:12:16 +0100 Subject: [PATCH 18/25] MDEV-25242 Server crashes in check_grant upon invoking function with userstat enabled use check_grant(..., number_of_tables=1, ...) if you only need to check privileges for one table --- mysql-test/r/userstat.result | 13 ++++++++++++- mysql-test/t/userstat.test | 19 ++++++++++++++----- plugin/userstat/table_stats.cc | 3 +-- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/userstat.result b/mysql-test/r/userstat.result index 01a66aa78eca3..804d5451252e8 100644 --- a/mysql-test/r/userstat.result +++ b/mysql-test/r/userstat.result @@ -1,4 +1,3 @@ -DROP TABLE IF EXISTS t1; select variable_value from information_schema.global_status where variable_name="handler_read_key" into @global_read_key; show columns from information_schema.client_statistics; Field Type Null Key Default Extra @@ -234,3 +233,15 @@ select @@in_transaction; 0 drop table t1; set @@global.general_log=@save_general_log; +# +# MDEV-25242 Server crashes in check_grant upon invoking function with userstat enabled +# +create function f() returns int return (select 1 from performance_schema.threads); +set global userstat= 1; +select f() from information_schema.table_statistics; +ERROR 21000: Subquery returns more than 1 row +set global userstat= 0; +drop function f; +# +# End of 10.2 tests +# diff --git a/mysql-test/t/userstat.test b/mysql-test/t/userstat.test index 547138cfeaa05..42fe1c2ad174a 100644 --- a/mysql-test/t/userstat.test +++ b/mysql-test/t/userstat.test @@ -6,10 +6,6 @@ -- source include/have_innodb.inc -- source include/have_log_bin.inc ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - select variable_value from information_schema.global_status where variable_name="handler_read_key" into @global_read_key; show columns from information_schema.client_statistics; show columns from information_schema.user_statistics; @@ -115,5 +111,18 @@ set @@autocommit=1; select @@in_transaction; drop table t1; -# Cleanup set @@global.general_log=@save_general_log; + +--echo # +--echo # MDEV-25242 Server crashes in check_grant upon invoking function with userstat enabled +--echo # +create function f() returns int return (select 1 from performance_schema.threads); +set global userstat= 1; +--error ER_SUBQUERY_NO_1_ROW +select f() from information_schema.table_statistics; +set global userstat= 0; +drop function f; + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/plugin/userstat/table_stats.cc b/plugin/userstat/table_stats.cc index 7b522a388d7d1..241855bdc8618 100644 --- a/plugin/userstat/table_stats.cc +++ b/plugin/userstat/table_stats.cc @@ -31,8 +31,7 @@ static int table_stats_fill(THD *thd, TABLE_LIST *tables, COND *cond) tmp_table.grant.privilege= 0; if (check_access(thd, SELECT_ACL, tmp_table.db, &tmp_table.grant.privilege, NULL, 0, 1) || - check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, - 1)) + check_grant(thd, SELECT_ACL, &tmp_table, 1, 1, 1)) continue; table->field[0]->store(table_stats->table, schema_length, From 161f4036c4c641635cba9772141e61beab20c9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 25 Mar 2021 07:37:50 +0200 Subject: [PATCH 19/25] MDEV-24954 : 10.5.9 crashes on int wsrep::client_state::ordered_commit(): Assertion `owning_thread_id_ == wsrep::this_thread::get_id()' failed. Binlog group commit could lead to a situation where group commit leader accesses participant thd's wsrep client state concurrently with the thread executing the participant thd. This is because of race condition in MYSQL_BIN_LOG::write_transaction_to_binlog_events(), and was fixed by moving wsrep_ordered_commit() to happen in MYSQL_BIN_LOG::queue_for_group_commit() under protection of LOCK_prepare_ordered mutex. --- sql/log.cc | 59 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 2a1142d8391b5..09804b75cdb84 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -7471,6 +7471,8 @@ MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd, new transaction directly to participate in the group commit. @retval < 0 Error + @retval -2 WSREP error with commit ordering + @retval -3 WSREP return code to mark the leader @retval > 0 If queued as the first entry in the queue (meaning this is the leader) @retval 0 Otherwise (queued as participant, leader handles the commit) @@ -7768,6 +7770,22 @@ MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry *orig_entry) cur= entry->thd->wait_for_commit_ptr; } +#ifdef WITH_WSREP + if (wsrep_is_active(entry->thd) && + wsrep_run_commit_hook(entry->thd, entry->all)) + { + /* Release commit order here */ + if (wsrep_ordered_commit(entry->thd, entry->all, wsrep_apply_error())) + result= -2; + + /* return -3, if this is leader */ + if (orig_queue == NULL) + result= -3; + } + else + DBUG_ASSERT(result != -2 && result != -3); +#endif /* WITH_WSREP */ + if (opt_binlog_commit_wait_count > 0 && orig_queue != NULL) mysql_cond_signal(&COND_prepare_ordered); mysql_mutex_unlock(&LOCK_prepare_ordered); @@ -7789,25 +7807,32 @@ MYSQL_BIN_LOG::write_transaction_to_binlog_events(group_commit_entry *entry) { int is_leader= queue_for_group_commit(entry); #ifdef WITH_WSREP - if (wsrep_is_active(entry->thd) && - wsrep_run_commit_hook(entry->thd, entry->all)) - { - /* - Release commit order and if leader, wait for prior commit to - complete. This establishes total order for group leaders. - */ - if (wsrep_ordered_commit(entry->thd, entry->all, wsrep_apply_error())) - { - entry->thd->wakeup_subsequent_commits(1); - return 1; - } - if (is_leader) - { - if (entry->thd->wait_for_prior_commit()) - return 1; - } + /* commit order was released in queue_for_group_commit() call, + here we check if wsrep_commit_ordered() failed or if we are leader */ + switch (is_leader) + { + case -2: /* wsrep_ordered_commit() has failed */ + DBUG_ASSERT(wsrep_is_active(entry->thd)); + DBUG_ASSERT(wsrep_run_commit_hook(entry->thd, entry->all)); + entry->thd->wakeup_subsequent_commits(1); + return true; + case -3: /* this is leader, wait for prior commit to + complete. This establishes total order for group leaders + */ + DBUG_ASSERT(wsrep_is_active(entry->thd)); + DBUG_ASSERT(wsrep_run_commit_hook(entry->thd, entry->all)); + if (entry->thd->wait_for_prior_commit()) + return true; + + /* retain the correct is_leader value */ + is_leader= 1; + break; + + default: /* native MariaDB cases */ + break; } #endif /* WITH_WSREP */ + /* The first in the queue handles group commit for all; the others just wait to be signalled when group commit is done. From d1ff2c583f452d8e1899f800609c329c998f0a33 Mon Sep 17 00:00:00 2001 From: mkaruza Date: Tue, 16 Mar 2021 12:53:40 +0100 Subject: [PATCH 20/25] MDEV-21697: Galera assertion !wsrep_has_changes(thd) || (thd->lex->sql_command == SQLCOM_CREATE_TABLE && !thd->is_current_stmt_binlog_format_row()) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent adding WSREP keys with CTAS when table is is not InnoDB. Reviewed-by: Jan Lindström --- mysql-test/suite/galera/r/galera_ctas.result | 88 ++++++++++++++++++++ mysql-test/suite/galera/t/galera_ctas.test | 39 +++++++++ sql/sql_insert.cc | 3 +- 3 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/galera/r/galera_ctas.result create mode 100644 mysql-test/suite/galera/t/galera_ctas.test diff --git a/mysql-test/suite/galera/r/galera_ctas.result b/mysql-test/suite/galera/r/galera_ctas.result new file mode 100644 index 0000000000000..f044f807410b3 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_ctas.result @@ -0,0 +1,88 @@ +connection node_2; +connection node_1; +connection node_1; +create table t1_Aria(a int, count int, b int, key(b)) engine=Aria; +INSERT INTO t1_Aria values (1,1,1); +create table t1_MyISAM(a int, count int, b int, key(b)) engine=MyISAM; +INSERT INTO t1_MyISAM values (1,1,1); +create table t1_InnoDB(a int, count int, b int, key(b)) engine=InnoDB; +INSERT INTO t1_InnoDB values (1,1,1); +SET SESSION default_storage_engine=MyISAM; +CREATE TABLE t2 AS SELECT * FROM t1_Aria; +CREATE TABLE t3 AS SELECT * FROM t1_MyISAM; +CREATE TABLE t4 AS SELECT * FROM t1_InnoDB; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL, + `count` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` int(11) DEFAULT NULL, + `count` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SHOW CREATE TABLE t4; +Table Create Table +t4 CREATE TABLE `t4` ( + `a` int(11) DEFAULT NULL, + `count` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2, t3,t4; +SET SESSION default_storage_engine=Aria; +CREATE TABLE t2 AS SELECT * FROM t1_Aria; +CREATE TABLE t3 AS SELECT * FROM t1_MyISAM; +CREATE TABLE t4 AS SELECT * FROM t1_InnoDB; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL, + `count` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` int(11) DEFAULT NULL, + `count` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +SHOW CREATE TABLE t4; +Table Create Table +t4 CREATE TABLE `t4` ( + `a` int(11) DEFAULT NULL, + `count` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +DROP TABLE t2, t3,t4; +SET SESSION default_storage_engine=InnoDB; +CREATE TABLE t2 AS SELECT * FROM t1_Aria; +CREATE TABLE t3 AS SELECT * FROM t1_MyISAM; +CREATE TABLE t4 AS SELECT * FROM t1_InnoDB; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL, + `count` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` int(11) DEFAULT NULL, + `count` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SHOW CREATE TABLE t4; +Table Create Table +t4 CREATE TABLE `t4` ( + `a` int(11) DEFAULT NULL, + `count` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t2, t3,t4; +DROP TABLE t1_MyISAM, t1_Aria,t1_InnoDB; diff --git a/mysql-test/suite/galera/t/galera_ctas.test b/mysql-test/suite/galera/t/galera_ctas.test new file mode 100644 index 0000000000000..8b9ad9c4a20e9 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_ctas.test @@ -0,0 +1,39 @@ +--source include/galera_cluster.inc + +--connection node_1 +create table t1_Aria(a int, count int, b int, key(b)) engine=Aria; +INSERT INTO t1_Aria values (1,1,1); +create table t1_MyISAM(a int, count int, b int, key(b)) engine=MyISAM; +INSERT INTO t1_MyISAM values (1,1,1); +create table t1_InnoDB(a int, count int, b int, key(b)) engine=InnoDB; +INSERT INTO t1_InnoDB values (1,1,1); + +SET SESSION default_storage_engine=MyISAM; +CREATE TABLE t2 AS SELECT * FROM t1_Aria; +CREATE TABLE t3 AS SELECT * FROM t1_MyISAM; +CREATE TABLE t4 AS SELECT * FROM t1_InnoDB; +SHOW CREATE TABLE t2; +SHOW CREATE TABLE t3; +SHOW CREATE TABLE t4; +DROP TABLE t2, t3,t4; + +SET SESSION default_storage_engine=Aria; +CREATE TABLE t2 AS SELECT * FROM t1_Aria; +CREATE TABLE t3 AS SELECT * FROM t1_MyISAM; +CREATE TABLE t4 AS SELECT * FROM t1_InnoDB; +SHOW CREATE TABLE t2; +SHOW CREATE TABLE t3; +SHOW CREATE TABLE t4; +DROP TABLE t2, t3,t4; + +SET SESSION default_storage_engine=InnoDB; +CREATE TABLE t2 AS SELECT * FROM t1_Aria; +CREATE TABLE t3 AS SELECT * FROM t1_MyISAM; +CREATE TABLE t4 AS SELECT * FROM t1_InnoDB; +SHOW CREATE TABLE t2; +SHOW CREATE TABLE t3; +SHOW CREATE TABLE t4; + +DROP TABLE t2, t3,t4; +DROP TABLE t1_MyISAM, t1_Aria,t1_InnoDB; + diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index a321162918070..c969725bea485 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -4724,7 +4724,8 @@ bool select_create::send_eof() if (!table->s->tmp_table) { #ifdef WITH_WSREP - if (WSREP(thd)) + if (WSREP(thd) && + table->file->ht->db_type == DB_TYPE_INNODB) { if (thd->wsrep_trx_id() == WSREP_UNDEFINED_TRX_ID) { From da26e2e673970761d5000501f6171910f248d829 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 25 Mar 2021 08:41:27 +0100 Subject: [PATCH 21/25] Cleanup - reduce duplicate code, in SSL IO error handling. --- vio/viossl.c | 52 +++++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/vio/viossl.c b/vio/viossl.c index bdd3c9ca024db..ebcc5246a1c0d 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -154,6 +154,32 @@ static my_bool ssl_should_retry(Vio *vio, int ret, enum enum_vio_io_event *event } +/** + Handle SSL io error. + + @param[in] vio Vio + @param[in] ret return from the failed IO operation + + @return 0 - should retry last read/write operation + 1 - some error has occured +*/ +static int handle_ssl_io_error(Vio *vio, int ret) +{ + enum enum_vio_io_event event; + my_bool should_wait; + + /* Process the SSL I/O error. */ + if (!ssl_should_retry(vio, ret, &event, &should_wait)) + return 1; + + if (!should_wait) + return 1; + + /* Attempt to wait for an I/O event. */ + return vio_socket_io_wait(vio, event); +} + + size_t vio_ssl_read(Vio *vio, uchar *buf, size_t size) { int ret; @@ -169,14 +195,7 @@ size_t vio_ssl_read(Vio *vio, uchar *buf, size_t size) { while ((ret= SSL_read(ssl, buf, (int)size)) < 0) { - enum enum_vio_io_event event; - my_bool should_wait; - - /* Process the SSL I/O error. */ - if (!ssl_should_retry(vio, ret, &event, &should_wait)) - break; - /* Attempt to wait for an I/O event. */ - if (should_wait && vio_socket_io_wait(vio, event)) + if (handle_ssl_io_error(vio,ret)) break; } } @@ -203,13 +222,7 @@ size_t vio_ssl_write(Vio *vio, const uchar *buf, size_t size) { while ((ret= SSL_write(ssl, buf, (int)size)) < 0) { - enum enum_vio_io_event event; - my_bool should_wait; - /* Process the SSL I/O error. */ - if (!ssl_should_retry(vio, ret, &event, &should_wait)) - break; - /* Attempt to wait for an I/O event. */ - if (should_wait && vio_socket_io_wait(vio, event)) + if (handle_ssl_io_error(vio,ret)) break; } } @@ -316,14 +329,7 @@ static int ssl_handshake_loop(Vio *vio, SSL *ssl, ssl_handshake_func_t func) /* Initiate the SSL handshake. */ while ((ret= func(ssl)) < 1) { - enum enum_vio_io_event event; - my_bool should_wait; - - /* Process the SSL I/O error. */ - if (!ssl_should_retry(vio, ret, &event, &should_wait)) - break; - /* Wait for I/O so that the handshake can proceed. */ - if (should_wait && vio_socket_io_wait(vio, event)) + if (handle_ssl_io_error(vio,ret)) break; } From a6d66fe75e9ce3ea2c43c311d0c8298fecbacff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 26 Mar 2021 14:12:39 +0200 Subject: [PATCH 22/25] MDEV-24786: row_upd_clust_step() skips mtr_t::commit() on virtual column error The function row_upd_clust_step() is invoking several static functions, some of which used to commit the mini-transaction in some cases. If innobase_get_computed_value() would fail due to some reason, we would fail to invoke mtr_t::commit() and release buffer pool page latches. This would likely lead to a hanging server later. This regression was introduced in commit 97db6c15ea3e83a21df137c222dbd5a40fbe7c82 (MDEV-20618). row_upd_index_is_referenced(), row_upd_sec_index_entry(), row_upd_sec_index_entry(): Cleanup: Replace some ibool with bool. row_upd_clust_rec_by_insert(), row_upd_clust_rec(): Guarantee that the mini-transaction will always remain in active state. row_upd_del_mark_clust_rec(): Guarantee that the mini-transaction will always remain in active state. This fixes one "leak" of mini-transaction on DB_COMPUTE_VALUE_FAILED. row_upd_clust_step(): Use only one return path, which will always invoke mtr.commit(). After a failed row_upd_store_row() call, we will no longer "leak" the mini-transaction. This fix was verified by RQG on 10.6 (depending on MDEV-371 that was introduced in 10.4). Unfortunately, it is challenging to create a regression test for this, and a test case could soon become invalid as more bugs in virtual column evaluation are fixed. --- storage/innobase/row/row0upd.cc | 126 ++++++++++++-------------------- 1 file changed, 46 insertions(+), 80 deletions(-) diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 51e8246e80a28..4b81d1478b0bc 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -126,25 +126,23 @@ NOTE that since we do not hold dict_operation_lock when leaving the function, it may be that the referencing table has been dropped when we leave this function: this function is only for heuristic use! -@return TRUE if referenced */ +@return true if referenced */ static -ibool +bool row_upd_index_is_referenced( /*========================*/ dict_index_t* index, /*!< in: index */ trx_t* trx) /*!< in: transaction */ { dict_table_t* table = index->table; - ibool froze_data_dict = FALSE; - ibool is_referenced = FALSE; if (table->referenced_set.empty()) { - return(FALSE); + return false; } - if (trx->dict_operation_lock_mode == 0) { + const bool froze_data_dict = !trx->dict_operation_lock_mode; + if (froze_data_dict) { row_mysql_freeze_data_dictionary(trx); - froze_data_dict = TRUE; } dict_foreign_set::iterator it @@ -152,13 +150,13 @@ row_upd_index_is_referenced( table->referenced_set.end(), dict_foreign_with_index(index)); - is_referenced = (it != table->referenced_set.end()); + const bool is_referenced = (it != table->referenced_set.end()); if (froze_data_dict) { row_mysql_unfreeze_data_dictionary(trx); } - return(is_referenced); + return is_referenced; } #ifdef WITH_WSREP @@ -2278,7 +2276,6 @@ row_upd_sec_index_entry( dtuple_t* entry; dict_index_t* index; btr_cur_t* btr_cur; - ibool referenced; dberr_t err = DB_SUCCESS; trx_t* trx = thr_get_trx(thr); ulint mode; @@ -2289,7 +2286,7 @@ row_upd_sec_index_entry( index = node->index; - referenced = row_upd_index_is_referenced(index, trx); + const bool referenced = row_upd_index_is_referenced(index, trx); #ifdef WITH_WSREP bool foreign = wsrep_row_upd_index_is_foreign(index, trx); #endif /* WITH_WSREP */ @@ -2690,12 +2687,13 @@ row_upd_clust_rec_by_insert( upd_node_t* node, /*!< in/out: row update node */ dict_index_t* index, /*!< in: clustered index of the record */ que_thr_t* thr, /*!< in: query thread */ - ibool referenced,/*!< in: TRUE if index may be referenced in + bool referenced,/*!< in: whether index may be referenced in a foreign key constraint */ #ifdef WITH_WSREP bool foreign,/*!< in: whether this is a foreign key */ #endif - mtr_t* mtr) /*!< in/out: mtr; gets committed here */ + mtr_t* mtr) /*!< in/out: mini-transaction, + may be committed and restarted */ { mem_heap_t* heap; btr_pcur_t* pcur; @@ -2760,10 +2758,7 @@ row_upd_clust_rec_by_insert( btr_cur_get_block(btr_cur), rec, index, offsets, thr, node->row, mtr); if (err != DB_SUCCESS) { -err_exit: - mtr_commit(mtr); - mem_heap_free(heap); - return(err); + goto err_exit; } /* If the the new row inherits externally stored @@ -2822,14 +2817,14 @@ row_upd_clust_rec_by_insert( } } - mtr_commit(mtr); + mtr->commit(); + mtr->start(); + node->state = UPD_NODE_INSERT_CLUSTERED; err = row_ins_clust_index_entry( index, entry, thr, dtuple_get_n_ext(entry)); - node->state = UPD_NODE_INSERT_CLUSTERED; - +err_exit: mem_heap_free(heap); - return(err); } @@ -2849,7 +2844,8 @@ row_upd_clust_rec( mem_heap_t** offsets_heap, /*!< in/out: memory heap, can be emptied */ que_thr_t* thr, /*!< in: query thread */ - mtr_t* mtr) /*!< in: mtr; gets committed here */ + mtr_t* mtr) /*!< in,out: mini-transaction; may be + committed and restarted here */ { mem_heap_t* heap = NULL; big_rec_t* big_rec = NULL; @@ -2895,16 +2891,15 @@ row_upd_clust_rec( goto success; } - mtr_commit(mtr); - if (buf_LRU_buf_pool_running_out()) { - err = DB_LOCK_TABLE_FULL; goto func_exit; } + /* We may have to modify the tree structure: do a pessimistic descent down the index tree */ + mtr->commit(); mtr->start(); if (index->table->is_temporary()) { @@ -2954,7 +2949,6 @@ row_upd_clust_rec( } } - mtr_commit(mtr); func_exit: if (heap) { mem_heap_free(heap); @@ -2979,17 +2973,17 @@ row_upd_del_mark_clust_rec( rec_offs* offsets,/*!< in/out: rec_get_offsets() for the record under the cursor */ que_thr_t* thr, /*!< in: query thread */ - ibool referenced, - /*!< in: TRUE if index may be referenced in + bool referenced, + /*!< in: whether index may be referenced in a foreign key constraint */ #ifdef WITH_WSREP bool foreign,/*!< in: whether this is a foreign key */ #endif - mtr_t* mtr) /*!< in: mtr; gets committed here */ + mtr_t* mtr) /*!< in,out: mini-transaction; + will be committed and restarted */ { btr_pcur_t* pcur; btr_cur_t* btr_cur; - dberr_t err; rec_t* rec; trx_t* trx = thr_get_trx(thr); @@ -3005,8 +2999,7 @@ row_upd_del_mark_clust_rec( if (!row_upd_store_row(node, trx->mysql_thd, thr->prebuilt && thr->prebuilt->table == node->table ? thr->prebuilt->m_mysql_table : NULL)) { - err = DB_COMPUTE_VALUE_FAILED; - return err; + return DB_COMPUTE_VALUE_FAILED; } /* Mark the clustered index record deleted; we do not have to check @@ -3014,7 +3007,7 @@ row_upd_del_mark_clust_rec( rec = btr_cur_get_rec(btr_cur); - err = btr_cur_del_mark_set_clust_rec( + dberr_t err = btr_cur_del_mark_set_clust_rec( btr_cur_get_block(btr_cur), rec, index, offsets, thr, node->row, mtr); @@ -3051,8 +3044,6 @@ row_upd_del_mark_clust_rec( #endif /* WITH_WSREP */ } - mtr_commit(mtr); - return(err); } @@ -3069,22 +3060,19 @@ row_upd_clust_step( { dict_index_t* index; btr_pcur_t* pcur; - ibool success; dberr_t err; mtr_t mtr; rec_t* rec; mem_heap_t* heap = NULL; rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; rec_offs* offsets; - ibool referenced; trx_t* trx = thr_get_trx(thr); rec_offs_init(offsets_); index = dict_table_get_first_index(node->table); - referenced = row_upd_index_is_referenced(index, trx); - + const bool referenced = row_upd_index_is_referenced(index, trx); #ifdef WITH_WSREP const bool foreign = wsrep_row_upd_index_is_foreign(index, trx); #endif @@ -3125,14 +3113,9 @@ row_upd_clust_step( mode = BTR_MODIFY_LEAF; } - success = btr_pcur_restore_position(mode, pcur, &mtr); - - if (!success) { + if (!btr_pcur_restore_position(mode, pcur, &mtr)) { err = DB_RECORD_NOT_FOUND; - - mtr_commit(&mtr); - - return(err); + goto exit_func; } /* If this is a row in SYS_INDEXES table of the data dictionary, @@ -3151,14 +3134,9 @@ row_upd_clust_step( mtr.start(); mtr.set_named_space(index->space); - success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, - &mtr); - if (!success) { + if (!btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, &mtr)) { err = DB_ERROR; - - mtr.commit(); - - return(err); + goto exit_func; } } @@ -3171,7 +3149,6 @@ row_upd_clust_step( 0, btr_pcur_get_block(pcur), rec, index, offsets, thr); if (err != DB_SUCCESS) { - mtr.commit(); goto exit_func; } } @@ -3180,8 +3157,6 @@ row_upd_clust_step( btr_pcur_get_block(pcur), page_rec_get_heap_no(rec))); - /* NOTE: the following function calls will also commit mtr */ - if (node->is_delete) { err = row_upd_del_mark_clust_rec( node, index, offsets, thr, referenced, @@ -3189,13 +3164,7 @@ row_upd_clust_step( foreign, #endif &mtr); - - if (err == DB_SUCCESS) { - node->state = UPD_NODE_UPDATE_ALL_SEC; - node->index = dict_table_get_next_index(index); - } - - goto exit_func; + goto all_done; } /* If the update is made for MySQL, we already have the update vector @@ -3210,14 +3179,13 @@ row_upd_clust_step( } if (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) { - err = row_upd_clust_rec( flags, node, index, offsets, &heap, thr, &mtr); goto exit_func; } - if(!row_upd_store_row(node, trx->mysql_thd, - thr->prebuilt ? thr->prebuilt->m_mysql_table : NULL)) { + if (!row_upd_store_row(node, trx->mysql_thd, thr->prebuilt + ? thr->prebuilt->m_mysql_table : NULL)) { err = DB_COMPUTE_VALUE_FAILED; goto exit_func; } @@ -3242,31 +3210,29 @@ row_upd_clust_step( foreign, #endif &mtr); - if (err != DB_SUCCESS) { - - goto exit_func; +all_done: + if (err == DB_SUCCESS) { + node->state = UPD_NODE_UPDATE_ALL_SEC; +success: + node->index = dict_table_get_next_index(index); } - - node->state = UPD_NODE_UPDATE_ALL_SEC; } else { err = row_upd_clust_rec( flags, node, index, offsets, &heap, thr, &mtr); - if (err != DB_SUCCESS) { - - goto exit_func; + if (err == DB_SUCCESS) { + ut_ad(!node->is_delete); + node->state = UPD_NODE_UPDATE_SOME_SEC; + goto success; } - - node->state = UPD_NODE_UPDATE_SOME_SEC; } - node->index = dict_table_get_next_index(index); - exit_func: - if (heap) { + mtr.commit(); + if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } - return(err); + return err; } /***********************************************************//** From dfae51de361a1604a97d93181df5e8669a1c2f85 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Wed, 24 Mar 2021 13:15:03 +0300 Subject: [PATCH 23/25] MDEV-25238 add support for -fsanitize-address-use-after-scope Use like this: cmake -DWITH_ASAN=ON -DWITH_ASAN_SCOPE=ON --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 466b2a5bc3a2b..ab5959da7b9bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -202,7 +202,13 @@ IF (WITH_ASAN) SET(HAVE_C_FSANITIZE ${have_C__fsanitize_address__fPIC}) SET(HAVE_CXX_FSANITIZE ${have_CXX__fsanitize_address__fPIC}) IF(HAVE_C_FSANITIZE AND HAVE_CXX_FSANITIZE) + OPTION(WITH_ASAN_SCOPE "Enable -fsanitize-address-use-after-scope" OFF) SET(WITH_ASAN_OK 1) + IF(WITH_ASAN_SCOPE) + MY_CHECK_AND_SET_COMPILER_FLAG( + "-fsanitize=address -fsanitize-address-use-after-scope" + DEBUG RELWITHDEBINFO) + ENDIF() ELSE() # older versions of clang MY_CHECK_AND_SET_COMPILER_FLAG("-faddress-sanitizer -fPIC" From 36a05268e7059163752ab91d1cbe1180dbd90b93 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Wed, 24 Mar 2021 13:17:49 +0300 Subject: [PATCH 24/25] cmake cleanup: drop support for ancient clang in WITH_ASAN option --- CMakeLists.txt | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab5959da7b9bd..80f87af2cb54a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -196,7 +196,6 @@ OPTION(WITH_ASAN "Enable address sanitizer" OFF) IF (WITH_ASAN) # this flag might be set by default on some OS MY_CHECK_AND_SET_COMPILER_FLAG("-U_FORTIFY_SOURCE" DEBUG RELWITHDEBINFO) - # gcc 4.8.1 and new versions of clang MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=address -fPIC" DEBUG RELWITHDEBINFO) SET(HAVE_C_FSANITIZE ${have_C__fsanitize_address__fPIC}) @@ -209,15 +208,6 @@ IF (WITH_ASAN) "-fsanitize=address -fsanitize-address-use-after-scope" DEBUG RELWITHDEBINFO) ENDIF() - ELSE() - # older versions of clang - MY_CHECK_AND_SET_COMPILER_FLAG("-faddress-sanitizer -fPIC" - DEBUG RELWITHDEBINFO) - SET(HAVE_C_FADDRESS ${have_C__faddress_sanitizer__fPIC}) - SET(HAVE_CXX_FADDRESS ${have_CXX__faddress_sanitizer__fPIC}) - IF(HAVE_C_FADDRESS AND HAVE_CXX_FADDRESS) - SET(WITH_ASAN_OK 1) - ENDIF() ENDIF() IF(NOT WITH_ASAN_OK) From 48141f3c1787de941d969ad1e6675611b2b650c2 Mon Sep 17 00:00:00 2001 From: Michael Okoko Date: Fri, 26 Mar 2021 20:48:59 +0100 Subject: [PATCH 25/25] Replace mallinfo with mallinfo2 on supported systems `mallinfo` is deprecated since glibc 2.33 and has been replaced by mallinfo2. The deprecation causes building the server to fail if glibc version is > 2.33. Check if mallinfo2 exist on the system and use it instead. --- config.h.cmake | 1 + configure.cmake | 1 + sql/sql_test.cc | 8 ++++++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/config.h.cmake b/config.h.cmake index 0e19dd446949f..c74592b4a65a8 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -177,6 +177,7 @@ #cmakedefine HAVE_DECL_MADVISE 1 #cmakedefine HAVE_DECL_MHA_MAPSIZE_VA 1 #cmakedefine HAVE_MALLINFO 1 +#cmakedefine HAVE_MALLINFO2 1 #cmakedefine HAVE_MEMCPY 1 #cmakedefine HAVE_MEMMOVE 1 #cmakedefine HAVE_MKSTEMP 1 diff --git a/configure.cmake b/configure.cmake index 58e1111bfc702..1aa0827a503a0 100644 --- a/configure.cmake +++ b/configure.cmake @@ -358,6 +358,7 @@ CHECK_FUNCTION_EXISTS (localtime_r HAVE_LOCALTIME_R) CHECK_FUNCTION_EXISTS (lstat HAVE_LSTAT) CHECK_FUNCTION_EXISTS (madvise HAVE_MADVISE) CHECK_FUNCTION_EXISTS (mallinfo HAVE_MALLINFO) +CHECK_FUNCTION_EXISTS (mallinfo2 HAVE_MALLINFO2) CHECK_FUNCTION_EXISTS (memcpy HAVE_MEMCPY) CHECK_FUNCTION_EXISTS (memmove HAVE_MEMMOVE) CHECK_FUNCTION_EXISTS (mkstemp HAVE_MKSTEMP) diff --git a/sql/sql_test.cc b/sql/sql_test.cc index c0e6222766523..d877eb2158865 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -616,8 +616,12 @@ Next alarm time: %lu\n", (ulong)alarm_info.next_alarm_time); #endif display_table_locks(); -#ifdef HAVE_MALLINFO - struct mallinfo info= mallinfo(); +#if defined(HAVE_MALLINFO2) + struct mallinfo2 info = mallinfo2(); +#elif defined(HAVE_MALLINFO) + struct mallinfo info= mallinfo(); +#endif +#if defined(HAVE_MALLINFO) || defined(HAVE_MALLINFO2) char llbuff[10][22]; printf("\nMemory status:\n\ Non-mmapped space allocated from system: %s\n\