From d072a29601834cd61252158c95f068aa13eb55fa Mon Sep 17 00:00:00 2001 From: Galina Shalygina Date: Wed, 24 Jul 2024 13:55:55 +0200 Subject: [PATCH 01/27] MDEV-23983: Crash caused by query containing constant having clause Before this patch the crash occured when a single row dataset is used and Item::remove_eq_conds() is called for HAVING. This function is not supposed to be called after the elimination of multiple equalities. To fix this problem instead of Item::remove_eq_conds() Item::val_int() is used. In this case the optimizer tries to evaluate the condition for the single row dataset and discovers impossible HAVING immediately. So, the execution phase is skipped. Approved by Igor Babaev --- mysql-test/main/having.result | 44 ++++++++++++++++++++++++++++++++++ mysql-test/main/having.test | 45 +++++++++++++++++++++++++++++++++++ sql/sql_select.cc | 19 ++++++++------- 3 files changed, 100 insertions(+), 8 deletions(-) diff --git a/mysql-test/main/having.result b/mysql-test/main/having.result index 95497a59c20..9f8a1c6e73c 100644 --- a/mysql-test/main/having.result +++ b/mysql-test/main/having.result @@ -955,3 +955,47 @@ DROP TABLE t; # # End of 10.4 tests # +# +# MDEV-23983: Crash caused by query containing constant having clause +# +CREATE TABLE t1 (id INT PRIMARY KEY, a INT, b TEXT, c INT); +INSERT INTO t1 VALUES (3, 7, 'b', 1), (4, 7, 'b', 1); +SELECT * FROM t1 +WHERE t1.id = 3 +GROUP BY t1.a +HAVING t1.b = 'b' and t1.c = 1; +id a b c +3 7 b 1 +SELECT * FROM t1 +WHERE t1.id = 3 +GROUP BY t1.a +HAVING t1.b = 'b' and t1.c = 2; +id a b c +explain SELECT * FROM t1 +WHERE t1.id = 3 +GROUP BY t1.a +HAVING t1.b = 'b' and t1.c = 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING noticed after reading const tables +DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM; +CREATE TABLE t2 (id INT, b TEXT, c INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (3, 'b', 1); +SELECT t2.* FROM t2 LEFT JOIN t1 ON t2.id = t1.a +GROUP BY t2.id +HAVING t2.b = 'b' and t2.c = 1; +id b c +3 b 1 +SELECT t2.* FROM t2 LEFT JOIN t1 ON t2.id = t1.a +GROUP BY t2.id +HAVING t2.b = 'b' and t2.c = 2; +id b c +explain SELECT t2.* FROM t2 LEFT JOIN t1 ON t2.id = t1.a +GROUP BY t2.id +HAVING t2.b = 'b' and t2.c = 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING noticed after reading const tables +DROP TABLE t1,t2; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/having.test b/mysql-test/main/having.test index b114070c60f..812038b2d60 100644 --- a/mysql-test/main/having.test +++ b/mysql-test/main/having.test @@ -1011,3 +1011,48 @@ DROP TABLE t; --echo # --echo # End of 10.4 tests --echo # + +--echo # +--echo # MDEV-23983: Crash caused by query containing constant having clause +--echo # + +CREATE TABLE t1 (id INT PRIMARY KEY, a INT, b TEXT, c INT); +INSERT INTO t1 VALUES (3, 7, 'b', 1), (4, 7, 'b', 1); + +SELECT * FROM t1 +WHERE t1.id = 3 +GROUP BY t1.a +HAVING t1.b = 'b' and t1.c = 1; + +let $q= +SELECT * FROM t1 +WHERE t1.id = 3 +GROUP BY t1.a +HAVING t1.b = 'b' and t1.c = 2; + +eval $q; +eval explain $q; + +DROP TABLE t1; + +CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM; +CREATE TABLE t2 (id INT, b TEXT, c INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (3, 'b', 1); + +SELECT t2.* FROM t2 LEFT JOIN t1 ON t2.id = t1.a +GROUP BY t2.id +HAVING t2.b = 'b' and t2.c = 1; + +let $q= +SELECT t2.* FROM t2 LEFT JOIN t1 ON t2.id = t1.a +GROUP BY t2.id +HAVING t2.b = 'b' and t2.c = 2; + +eval $q; +eval explain $q; + +DROP TABLE t1,t2; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b86ffed8619..93b53699c9a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2971,19 +2971,22 @@ int JOIN::optimize_stage2() which do not use aggregate functions. In such case temporary table may not be used and const condition elements may be lost during further having - condition transformation in JOIN::exec. + condition transformation. */ if (having && const_table_map && !having->with_sum_func()) { having->update_used_tables(); - having= having->remove_eq_conds(thd, &select_lex->having_value, true); - if (select_lex->having_value == Item::COND_FALSE) + if (having->const_item() && !having->is_expensive()) { - having= new (thd->mem_root) Item_bool(thd, false); - zero_result_cause= "Impossible HAVING noticed after reading const tables"; - error= 0; - select_lex->mark_const_derived(zero_result_cause); - goto setup_subq_exit; + bool having_value= having->val_int(); + having= new (thd->mem_root) Item_bool(thd, having_value); + if (!having_value) + { + zero_result_cause= "Impossible HAVING noticed after reading const tables"; + error= 0; + select_lex->mark_const_derived(zero_result_cause); + goto setup_subq_exit; + } } } From 37119cd2567cdc710e3d0fd097a10b6bb9def3c8 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Thu, 1 Aug 2024 17:44:54 +0530 Subject: [PATCH 02/27] MDEV-29010 Table cannot be loaded after instant ALTER Reason: ====== - InnoDB fails to load the instant alter table metadata from clustered index while loading the table definition. The reason is that InnoDB metadata blob has the column length exceeds maximum fixed length column size. Fix: === - InnoDB should treat the long fixed length column as variable length fields that needs external storage while initializing the field map for instant alter operation --- mysql-test/suite/innodb/r/instant_alter_bugs.result | 9 +++++++++ mysql-test/suite/innodb/t/instant_alter_bugs.test | 11 +++++++++++ storage/innobase/handler/handler0alter.cc | 7 +++++++ 3 files changed, 27 insertions(+) diff --git a/mysql-test/suite/innodb/r/instant_alter_bugs.result b/mysql-test/suite/innodb/r/instant_alter_bugs.result index dc64a041c3c..c74730599d3 100644 --- a/mysql-test/suite/innodb/r/instant_alter_bugs.result +++ b/mysql-test/suite/innodb/r/instant_alter_bugs.result @@ -521,3 +521,12 @@ COUNT(*) 1 DROP TABLE t1; # End of 10.4 tests +# +# MDEV-29010 Table cannot be loaded after instant ALTER +# +CREATE TABLE t1 (a CHAR(255), b INT, +c INT as (b) VIRTUAL)ENGINE=InnoDB CHARACTER SET utf32; +ALTER TABLE t1 DROP COLUMN a; +ALTER TABLE t1 DROP COLUMN c; +DROP TABLE t1; +# End of 10.5 tests diff --git a/mysql-test/suite/innodb/t/instant_alter_bugs.test b/mysql-test/suite/innodb/t/instant_alter_bugs.test index db04ac711b2..c1b999dbc74 100644 --- a/mysql-test/suite/innodb/t/instant_alter_bugs.test +++ b/mysql-test/suite/innodb/t/instant_alter_bugs.test @@ -553,3 +553,14 @@ SELECT COUNT(*) FROM t1; DROP TABLE t1; --echo # End of 10.4 tests + +--echo # +--echo # MDEV-29010 Table cannot be loaded after instant ALTER +--echo # +CREATE TABLE t1 (a CHAR(255), b INT, + c INT as (b) VIRTUAL)ENGINE=InnoDB CHARACTER SET utf32; +ALTER TABLE t1 DROP COLUMN a; +ALTER TABLE t1 DROP COLUMN c; +DROP TABLE t1; + +--echo # End of 10.5 tests diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index b5a76bfcdc2..d3a7e3d3749 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -181,6 +181,13 @@ inline void dict_table_t::init_instant(const dict_table_t& table) auto fixed_len = dict_col_get_fixed_size( f.col, not_redundant()); + + /* Long fixed length can be treated as variable + length fields that needs external storage */ + if (fixed_len > DICT_MAX_FIXED_COL_LEN) { + fixed_len = 0; + } + field_map_it->set_dropped(); if (!f.col->is_nullable()) { field_map_it->set_not_null(); From 00862b688c90057256f3b2fdc2a69e788bcf100d Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Fri, 2 Aug 2024 14:34:31 +0700 Subject: [PATCH 03/27] MDEV-14959: Control over memory allocated for SP/PS The final touch to fixing memory leaks for PS/SP. This patch turns on by default the option WITH_PROTECT_STATEMENT_MEMROOT in order to build server with memory leaks detection mechanism switched on. --- CMakeLists.txt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cc34e04b98d..c2e98317763 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -192,11 +192,7 @@ ELSE() ENDIF() -IF("${MYSQL_NO_DASH_VERSION}" VERSION_LESS 11.2) - SET(MEMPROTECT_DEFAULT ON) -ELSE() - SET(MEMPROTECT_DEFAULT OFF) -ENDIF() +SET(MEMPROTECT_DEFAULT ON) OPTION(WITH_PROTECT_STATEMENT_MEMROOT "Enable protection of statement's memory root after first SP/PS execution. Turned into account only for debug build" ${MEMPROTECT_DEFAULT}) From cf202decde475933dfa6b0aadfa5e04e667bfab7 Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Fri, 2 Aug 2024 18:48:29 +0700 Subject: [PATCH 04/27] MDEV-34683 Types mismatch when cloning items causes debug assertion New runtime type diagnostic (MDEV-34490) has detected that classes Item_func_eq, Item_default_value and Item_date_literal_for_invalid_dates incorrectly return an instance of its ancestor classes when being cloned. This commit fixes that. Additionally, it fixes a bug at Item_func_case_simple::do_build_clone() which led to an endless loop of cloning functions calls. Reviewer: Oleksandr Byelkin --- mysql-test/main/item_types.result | 14 ++++++++++++++ mysql-test/main/item_types.test | 18 ++++++++++++++++++ sql/item.h | 7 ++++++- sql/item_cmpfunc.cc | 10 ++++++++++ sql/item_cmpfunc.h | 3 ++- 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/item_types.result b/mysql-test/main/item_types.result index 865b4f612ae..40db01f2609 100644 --- a/mysql-test/main/item_types.result +++ b/mysql-test/main/item_types.result @@ -14,3 +14,17 @@ SELECT * FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.c<=>5; c c DROP TABLE t1, t2; SET optimizer_switch=default; +# +# MDEV-34683 Types mismatch when cloning items causes debug assertion +# +CREATE TABLE t1 (a date); +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; +SELECT a FROM v1 WHERE a IN ('a', 'b', 'c'); +a +CREATE VIEW v2 AS SELECT '' as a; +SELECT * FROM v2 WHERE a='' AND CASE '' WHEN '' THEN '' ELSE a END=''; +a + +DROP TABLE t1; +DROP VIEW v1, v2; +# End of 10.5 tests diff --git a/mysql-test/main/item_types.test b/mysql-test/main/item_types.test index f43bfe1a8ac..6f10d6bf71a 100644 --- a/mysql-test/main/item_types.test +++ b/mysql-test/main/item_types.test @@ -13,3 +13,21 @@ SELECT * FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.c<=>5; DROP TABLE t1, t2; SET optimizer_switch=default; + +--echo # +--echo # MDEV-34683 Types mismatch when cloning items causes debug assertion +--echo # + +CREATE TABLE t1 (a date); +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; +--disable_warnings +SELECT a FROM v1 WHERE a IN ('a', 'b', 'c'); +--enable_warnings + +CREATE VIEW v2 AS SELECT '' as a; +SELECT * FROM v2 WHERE a='' AND CASE '' WHEN '' THEN '' ELSE a END=''; + +DROP TABLE t1; +DROP VIEW v1, v2; + +--echo # End of 10.5 tests diff --git a/sql/item.h b/sql/item.h index b531647e8bf..796b2ec9eee 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5225,6 +5225,9 @@ public: cached_time.copy_to_mysql_time(ltime); return (null_value= false); } + Item *do_get_copy(THD *thd) const override + { return get_item_copy(thd, this); } + Item *do_build_clone(THD *thd) const override { return get_copy(thd); } }; @@ -6699,7 +6702,9 @@ public: description */ bool associate_with_target_field(THD *thd, Item_field *field) override; - + Item *do_get_copy(THD *thd) const override + { return get_item_copy(thd, this); } + Item* do_build_clone(THD *thd) const override { return get_copy(thd); } private: bool tie_field(THD *thd); }; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 2f9da57cdba..c4c96f6f7ae 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1814,6 +1814,16 @@ longlong Item_func_eq::val_int() } +Item *Item_func_eq::do_build_clone(THD *thd) const +{ + /* + Clone the parent and cast to the child class since there is nothing + specific for Item_func_eq + */ + return (Item_func_eq*) Item_bool_rowready_func2::do_build_clone(thd); +} + + /** Same as Item_func_eq, but NULL = NULL. */ bool Item_func_equal::fix_length_and_dec() diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index d394d932adf..adbb00147dc 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -765,6 +765,7 @@ public: friend class Arg_comparator; Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } + Item *do_build_clone(THD *thd) const override; }; class Item_func_equal final :public Item_bool_rowready_func2 @@ -2324,7 +2325,7 @@ public: Item *do_build_clone(THD *thd) const override { Item_func_case_simple *clone= (Item_func_case_simple *) - Item_func_case::build_clone(thd); + Item_func_case::do_build_clone(thd); uint ncases= when_count(); if (clone && clone->Predicant_to_list_comparator::init_clone(thd, ncases)) return NULL; From 83040474dcb6e9468bb0a7e42f3a31dc6e156d1a Mon Sep 17 00:00:00 2001 From: Andre F de Miranda Date: Fri, 24 May 2024 22:51:01 +1000 Subject: [PATCH 05/27] MDEV-34234: make lsof optional on RPM Signed-off-by: Julius Goryavsky --- cmake/cpack_rpm.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake index 65a739dc03e..66645a6676d 100644 --- a/cmake/cpack_rpm.cmake +++ b/cmake/cpack_rpm.cmake @@ -220,8 +220,9 @@ SETA(CPACK_RPM_server_PACKAGE_REQUIRES IF(WITH_WSREP) SETA(CPACK_RPM_server_PACKAGE_REQUIRES - "galera-4" "rsync" "lsof" "grep" "gawk" "iproute" + "galera-4" "rsync" "grep" "gawk" "iproute" "coreutils" "findutils" "tar") + SETA(CPACK_RPM_server_PACKAGE_RECOMMENDS "lsof") ENDIF() SET(CPACK_RPM_server_PRE_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-prein.sh) From 0ba6068a82bbce0abf2540dfc0c6954cb281250f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 1 Aug 2024 08:28:28 +0300 Subject: [PATCH 06/27] MDEV-32782 : galera_sst_mysqldump_with_key test failed Modified test configuration file to use wsrep_sync_wait to make sure committed transactions are replicated before next operation. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/disabled.def | 1 - mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.cnf | 5 +++++ mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.test | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 4f3f9884997..1fdde67fd3d 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -16,5 +16,4 @@ galera_sequences : MDEV-32561 WSREP FSM failure: no such a transition REPLICATIN galera_concurrent_ctas : MDEV-32779 galera_concurrent_ctas: assertion in the galera::ReplicatorSMM::finish_cert() galera_as_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() galera_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() -galera_sst_mysqldump_with_key : MDEV-32782 galera_sst_mysqldump_with_key test failed galera_var_ignore_apply_errors : MENT-1997 galera_var_ignore_apply_errors test freezes diff --git a/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.cnf b/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.cnf index 52ec6af7e74..da04a605291 100644 --- a/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.cnf +++ b/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.cnf @@ -3,6 +3,11 @@ # We do not set mysqldump-related SST options here because doing so on startup # causes the first MTR connection to be forefully dropped by Galera, which in turn confuses MTR +[mysqld] +wsrep-debug=1 +wsrep-sync_wait=15 +loose-galera_sst_mysqldump_with_key=1 + [mysqld.1] wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' diff --git a/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.test b/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.test index 3e0e944b0df..31a88777150 100644 --- a/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.test +++ b/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.test @@ -6,6 +6,7 @@ --source include/galera_cluster.inc --source include/have_innodb.inc --source include/have_ssl_communication.inc +--source include/force_restart.inc --source suite/galera/include/galera_sst_set_mysqldump.inc --let $node_1=node_1 From cb80ef93a9b0a7b4f80fde519629f3ad93fcea15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 31 Jul 2024 14:45:32 +0300 Subject: [PATCH 07/27] MDEV-32778 : galera_ssl_reload failed with warning message Fixed used configuration and added suppression for warning message. Test case changes only. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera_3nodes/disabled.def | 1 - .../galera_3nodes/r/galera_ssl_reload.result | 6 ++++++ .../galera_3nodes/t/galera_ssl_reload.cnf | 10 +++++++--- .../galera_3nodes/t/galera_ssl_reload.test | 20 +++++++++++++------ 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/mysql-test/suite/galera_3nodes/disabled.def b/mysql-test/suite/galera_3nodes/disabled.def index bcd0fb03478..cbadf6dd5c1 100644 --- a/mysql-test/suite/galera_3nodes/disabled.def +++ b/mysql-test/suite/galera_3nodes/disabled.def @@ -11,7 +11,6 @@ ############################################################################## galera_2_cluster : MDEV-32631 galera_2_cluster: before_rollback(): Assertion `0' failed -galera_ssl_reload : MDEV-32778 galera_ssl_reload failed with warning message galera_pc_bootstrap : temporarily disabled at the request of Codership galera_ipv6_mariabackup_section : temporarily disabled at the request of Codership GCF-354 : MDEV-25614 Galera test failure on GCF-354 diff --git a/mysql-test/suite/galera_3nodes/r/galera_ssl_reload.result b/mysql-test/suite/galera_3nodes/r/galera_ssl_reload.result index 1daf3bedf4f..fffc4f3f5b5 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_ssl_reload.result +++ b/mysql-test/suite/galera_3nodes/r/galera_ssl_reload.result @@ -14,3 +14,9 @@ connection node_3; # restart: with restart_parameters connection node_2; FLUSH SSL; +connection node_3; +call mtr.add_suppression("WSREP: Handshake failed: unexpected eof while reading"); +connection node_2; +call mtr.add_suppression("WSREP: Handshake failed: unexpected eof while reading"); +connection node_1; +call mtr.add_suppression("WSREP: Handshake failed: unexpected eof while reading"); diff --git a/mysql-test/suite/galera_3nodes/t/galera_ssl_reload.cnf b/mysql-test/suite/galera_3nodes/t/galera_ssl_reload.cnf index 65d1599268d..d4c654e2bf8 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ssl_reload.cnf +++ b/mysql-test/suite/galera_3nodes/t/galera_ssl_reload.cnf @@ -1,10 +1,14 @@ !include ../galera_3nodes.cnf +[mysqld] +wsrep-debug=1 +loose-galera-ssl-reload=1 + [mysqld.1] -wsrep_provider_options='base_port=@mysqld.1.#galera_port;socket.ssl=yes;socket.ssl_ca=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.root.crt;socket.ssl_cert=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.1.crt;socket.ssl_key=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.1.key' +wsrep_provider_options='base_port=@mysqld.1.#galera_port;socket.ssl=yes;socket.ssl_ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem;socket.ssl_cert=@ENV.MYSQL_TEST_DIR/std_data/client-cert.pem;socket.ssl_key=@ENV.MYSQL_TEST_DIR/std_data/client-key.pem' [mysqld.2] -wsrep_provider_options='base_port=@mysqld.2.#galera_port;socket.ssl=yes;socket.ssl_ca=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.root.crt;socket.ssl_cert=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.1.crt;socket.ssl_key=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.1.key' +wsrep_provider_options='base_port=@mysqld.2.#galera_port;socket.ssl=yes;socket.ssl_ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem;socket.ssl_cert=@ENV.MYSQL_TEST_DIR/std_data/client-cert.pem;socket.ssl_key=@ENV.MYSQL_TEST_DIR/std_data/client-key.pem' [mysqld.3] -wsrep_provider_options='base_port=@mysqld.3.#galera_port;socket.ssl=yes;socket.ssl_ca=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.root.crt;socket.ssl_cert=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.1.crt;socket.ssl_key=@ENV.MYSQL_TEST_DIR/std_data/galera_certs/galera.1.key' +wsrep_provider_options='base_port=@mysqld.3.#galera_port;socket.ssl=yes;socket.ssl_ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem;socket.ssl_cert=@ENV.MYSQL_TEST_DIR/std_data/client-cert.pem;socket.ssl_key=@ENV.MYSQL_TEST_DIR/std_data/client-key.pem' diff --git a/mysql-test/suite/galera_3nodes/t/galera_ssl_reload.test b/mysql-test/suite/galera_3nodes/t/galera_ssl_reload.test index 714d4b3f75c..f7bed23294d 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ssl_reload.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ssl_reload.test @@ -5,6 +5,7 @@ --source include/galera_cluster.inc --source include/have_openssl.inc --source include/have_ssl_communication.inc +--source include/force_restart.inc --let $galera_version=26.4.8 source ../../wsrep/include/check_galera_version.inc; @@ -31,22 +32,22 @@ let $ssl_cert = $MYSQLTEST_VARDIR/tmp/ssl_cert.pem; let $ssl_key = $MYSQLTEST_VARDIR/tmp/ssl_key.pem; let $ssl_ca = $MYSQLTEST_VARDIR/tmp/ssl_ca.pem; -copy_file std_data/galera_certs/galera.root.crt $ssl_ca; -copy_file std_data/galera_certs/galera.1.crt $ssl_cert; -copy_file std_data/galera_certs/galera.1.key $ssl_key; +copy_file std_data/cacert.pem $ssl_ca; +copy_file std_data/client-cert.pem $ssl_cert; +copy_file std_data/client-key.pem $ssl_key; --connection node_2 --source include/shutdown_mysqld.inc --let $restart_noprint=1 ---let $restart_parameters = --wsrep_cluster_address=gcomm://127.0.0.1:$NODE_GALERAPORT_1 --wsrep_provider_options=base_port=$NODE_GALERAPORT_2;socket.ssl=yes;socket.ssl_ca=$MYSQL_TEST_DIR/std_data/galera_certs/galera.root.crt;socket.ssl_cert=$MYSQLTEST_VARDIR/tmp/ssl_cert.pem;socket.ssl_key=$MYSQLTEST_VARDIR/tmp/ssl_key.pem +--let $restart_parameters = --wsrep_cluster_address=gcomm://127.0.0.1:$NODE_GALERAPORT_1 --wsrep_provider_options=base_port=$NODE_GALERAPORT_2;socket.ssl=yes;socket.ssl_ca=$MYSQL_TEST_DIR/std_data/cacert.pem;socket.ssl_cert=$MYSQLTEST_VARDIR/tmp/ssl_cert.pem;socket.ssl_key=$MYSQLTEST_VARDIR/tmp/ssl_key.pem --source include/start_mysqld.inc --source include/galera_wait_ready.inc # Set certificate and key and reload by setting directly `wsrep_provider_options` remove_file $ssl_cert; remove_file $ssl_key; -copy_file std_data/galera_certs/galera.2.crt $ssl_cert; -copy_file std_data/galera_certs/galera.2.key $ssl_key; +copy_file std_data/client-cert.pem $ssl_cert; +copy_file std_data/client-key.pem $ssl_key; SET GLOBAL wsrep_provider_options = 'socket.ssl_reload=1'; --connection node_3 @@ -67,5 +68,12 @@ remove_file $ssl_ca; remove_file $ssl_cert; remove_file $ssl_key; +--connection node_3 +call mtr.add_suppression("WSREP: Handshake failed: unexpected eof while reading"); +--connection node_2 +call mtr.add_suppression("WSREP: Handshake failed: unexpected eof while reading"); +--connection node_1 +call mtr.add_suppression("WSREP: Handshake failed: unexpected eof while reading"); + # Restore original auto_increment_offset values. --source ../galera/include/auto_increment_offset_restore.inc From eb30a9d63391359e686cfffb36b4c0e4a7e2f5a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Fri, 26 Jul 2024 09:04:30 +0300 Subject: [PATCH 08/27] MDEV-34647 : 'INSERT...SELECT' on MyISAM table suddenly replicated by Galera Replication of MyISAM and Aria DML is experimental and best effort only. Earlier change make INSERT SELECT on both MyISAM and Aria to replicate using TOI and STATEMENT replication. Replication should happen only if user has set needed wsrep_mode setting. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/r/MDEV-34647.result | 100 ++++++++++++++++++++ mysql-test/suite/galera/r/mdev-22063.result | 16 ++-- mysql-test/suite/galera/t/MDEV-34647.test | 53 +++++++++++ mysql-test/suite/galera/t/mdev-22063.test | 8 +- sql/sql_parse.cc | 8 +- 5 files changed, 172 insertions(+), 13 deletions(-) create mode 100644 mysql-test/suite/galera/r/MDEV-34647.result create mode 100644 mysql-test/suite/galera/t/MDEV-34647.test diff --git a/mysql-test/suite/galera/r/MDEV-34647.result b/mysql-test/suite/galera/r/MDEV-34647.result new file mode 100644 index 00000000000..5a1d4530e52 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-34647.result @@ -0,0 +1,100 @@ +connection node_2; +connection node_1; +create table t1(id serial, val varchar(100)) engine=myisam; +insert into t1 values(null, 'a'); +insert into t1 values(null, 'b'); +insert into t1 select null, 'c'; +insert into t1 select null, 'd' from t1; +select * from t1; +id val +1 a +3 b +5 c +7 d +9 d +11 d +create table t2(id serial, val varchar(100)) engine=aria; +insert into t2 values(null, 'a'); +insert into t2 values(null, 'b'); +insert into t2 select null, 'c'; +insert into t2 select null, 'd' from t2; +select * from t2; +id val +1 a +3 b +5 c +7 d +9 d +11 d +create table t3(id serial, val varchar(100)) engine=innodb; +insert into t3 values(null, 'a'); +insert into t3 values(null, 'b'); +insert into t3 select null, 'c'; +insert into t3 select null, 'd' from t3; +select * from t3; +id val +1 a +3 b +5 c +7 d +9 d +11 d +set global wsrep_replicate_myisam=ON; +create table t4(id serial, val varchar(100)) engine=myisam; +insert into t4 values(null, 'a'); +insert into t4 values(null, 'b'); +insert into t4 select null, 'c'; +insert into t4 select null, 'd' from t4; +select * from t4; +id val +1 a +2 b +3 c +4 d +5 d +6 d +create table t5(id serial, val varchar(100)) engine=myisam; +insert into t5 values(null, 'a'); +insert into t5 values(null, 'b'); +insert into t5 select null, 'c'; +insert into t5 select null, 'd' from t5; +select * from t2; +id val +1 a +3 b +5 c +7 d +9 d +11 d +connection node_2; +select * from t1; +id val +select * from t2; +id val +select * from t3; +id val +1 a +3 b +5 c +7 d +9 d +11 d +select * from t4; +id val +1 a +2 b +3 c +4 d +5 d +6 d +select * from t5; +id val +1 a +2 b +3 c +4 d +5 d +6 d +connection node_1; +drop table t1,t2,t3,t4,t5; +set global wsrep_replicate_myisam=default; diff --git a/mysql-test/suite/galera/r/mdev-22063.result b/mysql-test/suite/galera/r/mdev-22063.result index 5773e70cc9d..f5007b2656c 100644 --- a/mysql-test/suite/galera/r/mdev-22063.result +++ b/mysql-test/suite/galera/r/mdev-22063.result @@ -114,7 +114,7 @@ EXPECT_1000 1000 SELECT COUNT(*) AS EXPECT_1000 FROM t3; EXPECT_1000 -1000 +0 SELECT COUNT(*) AS EXPECT_1000 FROM t4; EXPECT_1000 1000 @@ -127,9 +127,9 @@ EXPECT_1000 SELECT COUNT(*) AS EXPECT_1000 FROM t7; EXPECT_1000 1000 -SELECT COUNT(*) AS EXPECT_1000 FROM t8; -EXPECT_1000 -1000 +SELECT COUNT(*) AS EXPECT_0 FROM t8; +EXPECT_0 +0 connection node_1; DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8; # Bigger INSERT INTO ... SELECT test @@ -182,7 +182,7 @@ EXPECT_1000 1000 SELECT COUNT(*) AS EXPECT_1000 FROM t3; EXPECT_1000 -1000 +0 SELECT COUNT(*) AS EXPECT_1000 FROM t4; EXPECT_1000 1000 @@ -195,9 +195,9 @@ EXPECT_1000 SELECT COUNT(*) AS EXPECT_1000 FROM t7; EXPECT_1000 1000 -SELECT COUNT(*) AS EXPECT_1000 FROM t8; -EXPECT_1000 -1000 +SELECT COUNT(*) AS EXPECT_0 FROM t8; +EXPECT_0 +0 connection node_1; DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8; CREATE TABLE t1(pk int not null primary key) engine=innodb; diff --git a/mysql-test/suite/galera/t/MDEV-34647.test b/mysql-test/suite/galera/t/MDEV-34647.test new file mode 100644 index 00000000000..1697bf05f28 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-34647.test @@ -0,0 +1,53 @@ +--source include/galera_cluster.inc +--source include/have_aria.inc + +create table t1(id serial, val varchar(100)) engine=myisam; +insert into t1 values(null, 'a'); +insert into t1 values(null, 'b'); +insert into t1 select null, 'c'; +insert into t1 select null, 'd' from t1; +select * from t1; + +create table t2(id serial, val varchar(100)) engine=aria; +insert into t2 values(null, 'a'); +insert into t2 values(null, 'b'); +insert into t2 select null, 'c'; +insert into t2 select null, 'd' from t2; +select * from t2; + +create table t3(id serial, val varchar(100)) engine=innodb; +insert into t3 values(null, 'a'); +insert into t3 values(null, 'b'); +insert into t3 select null, 'c'; +insert into t3 select null, 'd' from t3; +select * from t3; + +set global wsrep_replicate_myisam=ON; + +create table t4(id serial, val varchar(100)) engine=myisam; +insert into t4 values(null, 'a'); +insert into t4 values(null, 'b'); +insert into t4 select null, 'c'; +insert into t4 select null, 'd' from t4; +select * from t4; + +create table t5(id serial, val varchar(100)) engine=myisam; +insert into t5 values(null, 'a'); +insert into t5 values(null, 'b'); +insert into t5 select null, 'c'; +insert into t5 select null, 'd' from t5; +select * from t2; + + +--connection node_2 +select * from t1; +select * from t2; +select * from t3; +select * from t4; +select * from t5; + + +--connection node_1 +drop table t1,t2,t3,t4,t5; +set global wsrep_replicate_myisam=default; + diff --git a/mysql-test/suite/galera/t/mdev-22063.test b/mysql-test/suite/galera/t/mdev-22063.test index ef16c0c8716..c3a7af7e0bb 100644 --- a/mysql-test/suite/galera/t/mdev-22063.test +++ b/mysql-test/suite/galera/t/mdev-22063.test @@ -97,7 +97,7 @@ SELECT COUNT(*) AS EXPECT_1000 FROM t8; --connection node_2 --let $wait_condition = SELECT COUNT(*) = 8 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME LIKE 't_' --source include/wait_condition.inc ---let $wait_condition = SELECT COUNT(*) = 1000 FROM test.t8; +--let $wait_condition = SELECT COUNT(*) = 1000 FROM test.t7; --source include/wait_condition.inc SELECT COUNT(*) AS EXPECT_1000 FROM t1; @@ -107,7 +107,7 @@ SELECT COUNT(*) AS EXPECT_1000 FROM t4; SELECT COUNT(*) AS EXPECT_1000 FROM t5; SELECT COUNT(*) AS EXPECT_1000 FROM t6; SELECT COUNT(*) AS EXPECT_1000 FROM t7; -SELECT COUNT(*) AS EXPECT_1000 FROM t8; +SELECT COUNT(*) AS EXPECT_0 FROM t8; --connection node_1 DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8; @@ -145,7 +145,7 @@ SELECT COUNT(*) AS EXPECT_1000 FROM t8; --connection node_2 --let $wait_condition = SELECT COUNT(*) = 8 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME LIKE 't_' --source include/wait_condition.inc ---let $wait_condition = SELECT COUNT(*) = 1000 FROM test.t8; +--let $wait_condition = SELECT COUNT(*) = 1000 FROM test.t7; --source include/wait_condition.inc SELECT COUNT(*) AS EXPECT_1000 FROM t1; @@ -155,7 +155,7 @@ SELECT COUNT(*) AS EXPECT_1000 FROM t4; SELECT COUNT(*) AS EXPECT_1000 FROM t5; SELECT COUNT(*) AS EXPECT_1000 FROM t6; SELECT COUNT(*) AS EXPECT_1000 FROM t7; -SELECT COUNT(*) AS EXPECT_1000 FROM t8; +SELECT COUNT(*) AS EXPECT_0 FROM t8; --connection node_1 DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8a218290114..2d6c7621f7b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4761,7 +4761,13 @@ mysql_execute_command(THD *thd) // For !InnoDB we start TOI if it is not yet started and hope for the best if (!is_innodb && !wsrep_toi) - WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL); + { + const legacy_db_type db_type= first_table->table->file->partition_ht()->db_type; + + /* Currently we support TOI for MyISAM only. */ + if (db_type == DB_TYPE_MYISAM && wsrep_replicate_myisam) + WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL); + } } #endif /* WITH_WSREP */ /* From 71f289e5d1691a060148d7063c663730f580f26d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 30 Jul 2024 12:30:39 +0300 Subject: [PATCH 09/27] MDEV-25614 : Galera test failure on GCF-354 Modified node config with longer timeouts for suspect, inactive, install and wait_prim timeout. Increased node_1 weight to keep it primary component when other nodes are voted out. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera_3nodes/disabled.def | 1 - mysql-test/suite/galera_3nodes/r/GCF-354.result | 9 ++++++--- mysql-test/suite/galera_3nodes/t/GCF-354.cnf | 11 +++++++++++ mysql-test/suite/galera_3nodes/t/GCF-354.test | 10 ++++------ 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/mysql-test/suite/galera_3nodes/disabled.def b/mysql-test/suite/galera_3nodes/disabled.def index cbadf6dd5c1..b7f0d8da8c1 100644 --- a/mysql-test/suite/galera_3nodes/disabled.def +++ b/mysql-test/suite/galera_3nodes/disabled.def @@ -13,4 +13,3 @@ galera_2_cluster : MDEV-32631 galera_2_cluster: before_rollback(): Assertion `0' failed galera_pc_bootstrap : temporarily disabled at the request of Codership galera_ipv6_mariabackup_section : temporarily disabled at the request of Codership -GCF-354 : MDEV-25614 Galera test failure on GCF-354 diff --git a/mysql-test/suite/galera_3nodes/r/GCF-354.result b/mysql-test/suite/galera_3nodes/r/GCF-354.result index 3fdd44fe9d3..c69de54747f 100644 --- a/mysql-test/suite/galera_3nodes/r/GCF-354.result +++ b/mysql-test/suite/galera_3nodes/r/GCF-354.result @@ -1,17 +1,20 @@ connection node_2; connection node_1; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; connection node_1; connection node_2; connection node_3; connection node_2; -SET SESSION wsrep_on=OFF; +SET wsrep_on=OFF; DROP SCHEMA test; connection node_3; -SET SESSION wsrep_on=OFF; +SET wsrep_on=OFF; CREATE TABLE test.t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb; connection node_1; CREATE TABLE test.t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb; -INSERT INTO test.t1 values (1); +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +VARIABLE_VALUE +1 SHOW STATUS LIKE 'wsrep_cluster_status'; Variable_name Value wsrep_cluster_status Primary diff --git a/mysql-test/suite/galera_3nodes/t/GCF-354.cnf b/mysql-test/suite/galera_3nodes/t/GCF-354.cnf index 4c5e4854606..e87e65ca58c 100644 --- a/mysql-test/suite/galera_3nodes/t/GCF-354.cnf +++ b/mysql-test/suite/galera_3nodes/t/GCF-354.cnf @@ -3,3 +3,14 @@ [mysqld] wsrep-ignore-apply-errors=0 wsrep_sync_wait=0 +loose-gcf-354=0 +wsrep-debug=1 + +[mysqld.1] +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.wait_prim_timeout=PT60S;gcache.size=1G;pc.weight=4' + +[mysqld.2] +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.wait_prim_timeout=PT60S;gcache.size=1G' + +[mysqld.3] +wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.wait_prim_timeout=PT60S;gcache.size=1G' diff --git a/mysql-test/suite/galera_3nodes/t/GCF-354.test b/mysql-test/suite/galera_3nodes/t/GCF-354.test index 44dfa3deeb7..372f6329e8e 100644 --- a/mysql-test/suite/galera_3nodes/t/GCF-354.test +++ b/mysql-test/suite/galera_3nodes/t/GCF-354.test @@ -2,9 +2,7 @@ --source include/have_innodb.inc --source include/force_restart.inc ---let $galera_connection_name = node_3 ---let $galera_server_number = 3 ---source include/galera_connect.inc +--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 # Save original auto_increment_offset values. --let $node_1=node_1 @@ -16,11 +14,11 @@ # 1. Create different inconsistencies on nodes 2 and 3 # --connection node_2 -SET SESSION wsrep_on=OFF; +SET wsrep_on=OFF; DROP SCHEMA test; --connection node_3 -SET SESSION wsrep_on=OFF; +SET wsrep_on=OFF; CREATE TABLE test.t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb; # # 2. The following should generate different errors on nodes 2 and 3 and @@ -29,10 +27,10 @@ CREATE TABLE test.t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb; # --connection node_1 CREATE TABLE test.t1 (f1 INTEGER NOT NULL PRIMARY KEY) engine=innodb; -INSERT INTO test.t1 values (1); --let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' --source include/wait_condition.inc +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status' --source include/wait_condition.inc SHOW STATUS LIKE 'wsrep_cluster_status'; From 8b51d34462370b96af420587fdc07934abcea8ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 23 Jul 2024 11:57:01 +0300 Subject: [PATCH 10/27] MDEV-34640 : galera_var_ignore_apply_errors test freezes Test improvements only to make test more robust. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/disabled.def | 1 - .../r/galera_var_ignore_apply_errors.result | 83 +++++++++---- .../t/galera_var_ignore_apply_errors.cnf | 7 +- .../t/galera_var_ignore_apply_errors.test | 116 +++++++----------- 4 files changed, 104 insertions(+), 103 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 1fdde67fd3d..e00bdbf85c0 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -16,4 +16,3 @@ galera_sequences : MDEV-32561 WSREP FSM failure: no such a transition REPLICATIN galera_concurrent_ctas : MDEV-32779 galera_concurrent_ctas: assertion in the galera::ReplicatorSMM::finish_cert() galera_as_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() galera_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() -galera_var_ignore_apply_errors : MENT-1997 galera_var_ignore_apply_errors test freezes diff --git a/mysql-test/suite/galera/r/galera_var_ignore_apply_errors.result b/mysql-test/suite/galera/r/galera_var_ignore_apply_errors.result index 0b32f43704f..ea8510581bb 100644 --- a/mysql-test/suite/galera/r/galera_var_ignore_apply_errors.result +++ b/mysql-test/suite/galera/r/galera_var_ignore_apply_errors.result @@ -7,27 +7,60 @@ SET GLOBAL wsrep_on = OFF; CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = ON; DROP TABLE t1; +connection node_2; +SHOW TABLES; +Tables_in_test +connection node_1; SET GLOBAL wsrep_on = OFF; CREATE SCHEMA s1; SET GLOBAL wsrep_on = ON; DROP SCHEMA s1; +connection node_2; +SHOW SCHEMAS; +Database +information_schema +mtr +mysql +performance_schema +test +connection node_1; CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; CREATE INDEX idx1 ON t1 (f1); SET GLOBAL wsrep_on = ON; DROP INDEX idx1 ON t1; +connection node_2; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci DROP TABLE t1; +connection node_1; CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; CREATE INDEX idx1 ON t1 (f1); SET GLOBAL wsrep_on = ON; ALTER TABLE t1 DROP INDEX idx1; +connection node_2; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci DROP TABLE t1; +connection node_1; CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; ALTER TABLE t1 ADD COLUMN f2 INTEGER; SET GLOBAL wsrep_on = ON; ALTER TABLE t1 DROP COLUMN f2; +connection node_2; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci DROP TABLE t1; connection node_2; SET GLOBAL wsrep_ignore_apply_errors = 2; @@ -37,12 +70,11 @@ SET GLOBAL wsrep_on = OFF; INSERT INTO t1 VALUES (1); SET GLOBAL wsrep_on = ON; DELETE FROM t1 WHERE f1 = 1; -connection node_1; -SELECT COUNT(*) as expect_0 FROM t1; +SELECT COUNT(*) AS expect_0 FROM t1; expect_0 0 connection node_2; -SELECT COUNT(*) as expect_0 FROM t1; +SELECT COUNT(*) AS expect_0 FROM t1; expect_0 0 DROP TABLE t1; @@ -57,12 +89,11 @@ INSERT INTO t1 VALUES (3); DELETE FROM t1 WHERE f1 = 1; DELETE FROM t1 WHERE f1 = 2; COMMIT; -connection node_1; -SELECT COUNT(*) as expect_1 FROM t1; +SELECT COUNT(*) AS expect_1 FROM t1; expect_1 1 connection node_2; -SELECT COUNT(*) as expect_1 FROM t1; +SELECT COUNT(*) AS expect_1 FROM t1; expect_1 1 DROP TABLE t1; @@ -75,14 +106,14 @@ DELETE FROM t1 WHERE f1 = 3; SET SESSION wsrep_on = ON; connection node_1; DELETE FROM t1; -SELECT COUNT(*) as expect_0 FROM t1; +SELECT COUNT(*) AS expect_0 FROM t1; expect_0 0 connection node_2; -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -VARIABLE_VALUE = 'Primary' -1 -SELECT COUNT(*) as expect_0 FROM t1; +SELECT VARIABLE_VALUE expect_Primary FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +expect_Primary +Primary +SELECT COUNT(*) AS expect_0 FROM t1; expect_0 0 DROP TABLE t1; @@ -103,14 +134,14 @@ DELETE FROM t1 WHERE f1 = 4; DELETE FROM t1 WHERE f1 = 5; COMMIT; SET AUTOCOMMIT=ON; -SELECT COUNT(*) as expect_0 FROM t1; +SELECT COUNT(*) AS expect_0 FROM t1; expect_0 0 connection node_2; -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -VARIABLE_VALUE = 'Primary' -1 -SELECT COUNT(*) as expect_0 FROM t1; +SELECT VARIABLE_VALUE expect_Primary FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +expect_Primary +Primary +SELECT COUNT(*) AS expect_0 FROM t1; expect_0 0 DROP TABLE t1; @@ -126,14 +157,14 @@ DELETE FROM t1 WHERE f1 = 3; SET SESSION wsrep_on = ON; connection node_1; DELETE t1, t2 FROM t1 JOIN t2 WHERE t1.f1 = t2.f1; -SELECT COUNT(*) as expect_0 FROM t1; +SELECT COUNT(*) expect_0 FROM t1; expect_0 0 connection node_2; -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT VARIABLE_VALUE = 'Primary' FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 -SELECT COUNT(*) as expect_0 FROM t1; +SELECT COUNT(*) expect_0 FROM t1; expect_0 0 DROP TABLE t1,t2; @@ -148,20 +179,20 @@ DELETE FROM child WHERE parent_id = 2; SET SESSION wsrep_on = ON; connection node_1; DELETE FROM parent; -SELECT COUNT(*) as expect_0 FROM parent; +SELECT COUNT(*) AS expect_0 FROM parent; expect_0 0 -SELECT COUNT(*) as expect_0 FROM child; +SELECT COUNT(*) AS expect_0 FROM child; expect_0 0 connection node_2; -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT VARIABLE_VALUE = 'Primary' FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 -SELECT COUNT(*) as expect_0 FROM parent; +SELECT COUNT(*) AS expect_0 FROM parent; expect_0 0 -SELECT COUNT(*) as expect_0 FROM child; +SELECT COUNT(*) AS expect_0 FROM child; expect_0 0 DROP TABLE child, parent; @@ -175,8 +206,10 @@ connection node_1; CREATE TABLE t1 (f1 INTEGER, f2 INTEGER); DROP TABLE t1; connection node_2; +SELECT * FROM t1; +ERROR 42S02: Table 'test.t1' doesn't exist SET GLOBAL wsrep_ignore_apply_errors = 7; -CALL mtr.add_suppression("Can't find record in 't.*'"); +CALL mtr.add_suppression("Can't find record in "); CALL mtr.add_suppression("Slave SQL: Could not execute Delete_rows event"); CALL mtr.add_suppression("Slave SQL: Error 'Unknown table 'test\\.t1'' on query\\. Default database: 'test'\\. Query: 'DROP TABLE t1', Error_code: 1051"); CALL mtr.add_suppression("Slave SQL: Error 'Can't drop database 's1'; database doesn't exist' on query\\. Default database: 'test'\\. Query: 'DROP SCHEMA s1', Error_code: 1008"); diff --git a/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.cnf b/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.cnf index 545cc8147e0..1d02401decc 100644 --- a/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.cnf +++ b/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.cnf @@ -1,7 +1,6 @@ !include ../galera_2nodes.cnf -[mysqld.1] -wsrep_debug=1 - -[mysqld.2] +[mysqld] wsrep_debug=1 +wsrep_sync_wait=15 +loose-galera-var-ignore-apply-errors=1 diff --git a/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.test b/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.test index e5bff5d8dc4..d5c6521add4 100644 --- a/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.test +++ b/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.test @@ -3,7 +3,7 @@ # --source include/galera_cluster.inc - +--source include/force_restart.inc # # Ignore reconciling DDL errors on node_2 @@ -17,41 +17,55 @@ SET GLOBAL wsrep_ignore_apply_errors = 1; SET GLOBAL wsrep_on = OFF; CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = ON; ---source include/galera_wait_ready.inc DROP TABLE t1; +--connection node_2 +SHOW TABLES; + # Drop schema that does not exist +--connection node_1 SET GLOBAL wsrep_on = OFF; CREATE SCHEMA s1; SET GLOBAL wsrep_on = ON; ---source include/galera_wait_ready.inc DROP SCHEMA s1; +--connection node_2 +SHOW SCHEMAS; + # Drop index that does not exist using DROP INDEX +--connection node_1 CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; CREATE INDEX idx1 ON t1 (f1); SET GLOBAL wsrep_on = ON; ---source include/galera_wait_ready.inc DROP INDEX idx1 ON t1; + +--connection node_2 +SHOW CREATE TABLE t1; DROP TABLE t1; # Drop index that does not exist using ALTER TABLE +--connection node_1 CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; CREATE INDEX idx1 ON t1 (f1); SET GLOBAL wsrep_on = ON; ---source include/galera_wait_ready.inc ALTER TABLE t1 DROP INDEX idx1; + +--connection node_2 +SHOW CREATE TABLE t1; DROP TABLE t1; # Drop column that does not exist +--connection node_1 CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; ALTER TABLE t1 ADD COLUMN f2 INTEGER; SET GLOBAL wsrep_on = ON; ---source include/galera_wait_ready.inc ALTER TABLE t1 DROP COLUMN f2; + +--connection node_2 +SHOW CREATE TABLE t1; DROP TABLE t1; @@ -68,21 +82,11 @@ CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; INSERT INTO t1 VALUES (1); SET GLOBAL wsrep_on = ON; ---source include/galera_wait_ready.inc DELETE FROM t1 WHERE f1 = 1; +SELECT COUNT(*) AS expect_0 FROM t1; ---connection node_1 ---let $wait_condition = SELECT COUNT(*) = 0 FROM t1; ---source include/wait_condition.inc -SELECT COUNT(*) as expect_0 FROM t1; --connection node_2 ---source include/galera_wait_ready.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; ---source include/wait_condition.inc ---let $wait_condition = SELECT COUNT(*) = 0 FROM t1; ---source include/wait_condition.inc -SELECT COUNT(*) as expect_0 FROM t1; - +SELECT COUNT(*) AS expect_0 FROM t1; DROP TABLE t1; # Delete row that does not exist in a multi statement transaction @@ -92,25 +96,15 @@ INSERT INTO t1 VALUES (2); SET GLOBAL wsrep_on = OFF; INSERT INTO t1 VALUES (1); SET GLOBAL wsrep_on = ON; ---source include/galera_wait_ready.inc START TRANSACTION; INSERT INTO t1 VALUES (3); DELETE FROM t1 WHERE f1 = 1; DELETE FROM t1 WHERE f1 = 2; COMMIT; +SELECT COUNT(*) AS expect_1 FROM t1; ---connection node_1 ---let $wait_condition = SELECT COUNT(*) = 1 FROM t1; ---source include/wait_condition.inc -SELECT COUNT(*) as expect_1 FROM t1; --connection node_2 ---source include/galera_wait_ready.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; ---source include/wait_condition.inc ---let $wait_condition = SELECT COUNT(*) = 1 FROM t1; ---source include/wait_condition.inc -SELECT COUNT(*) as expect_1 FROM t1; - +SELECT COUNT(*) AS expect_1 FROM t1; DROP TABLE t1; # @@ -127,21 +121,16 @@ INSERT INTO t1 VALUES (1),(2),(3),(4),(5); SET SESSION wsrep_on = OFF; DELETE FROM t1 WHERE f1 = 3; SET SESSION wsrep_on = ON; ---source include/galera_wait_ready.inc + --connection node_1 DELETE FROM t1; +SELECT COUNT(*) AS expect_0 FROM t1; -SELECT COUNT(*) as expect_0 FROM t1; --connection node_2 ---source include/galera_wait_ready.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; ---source include/wait_condition.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; ---source include/wait_condition.inc -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; --let $wait_condition = SELECT COUNT(*) = 0 FROM t1; --source include/wait_condition.inc -SELECT COUNT(*) as expect_0 FROM t1; +SELECT VARIABLE_VALUE expect_Primary FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT COUNT(*) AS expect_0 FROM t1; DROP TABLE t1; # @@ -158,10 +147,8 @@ INSERT INTO t1 VALUES (1),(2),(3),(4),(5); SET SESSION wsrep_on = OFF; DELETE FROM t1 WHERE f1 = 3; SET SESSION wsrep_on = ON; ---source include/galera_wait_ready.inc --connection node_1 - SET AUTOCOMMIT=OFF; START TRANSACTION; DELETE FROM t1 WHERE f1 = 1; @@ -171,18 +158,13 @@ DELETE FROM t1 WHERE f1 = 4; DELETE FROM t1 WHERE f1 = 5; COMMIT; SET AUTOCOMMIT=ON; +SELECT COUNT(*) AS expect_0 FROM t1; -SELECT COUNT(*) as expect_0 FROM t1; --connection node_2 ---source include/galera_wait_ready.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; ---source include/wait_condition.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; ---source include/wait_condition.inc -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; --let $wait_condition = SELECT COUNT(*) = 0 FROM t1; --source include/wait_condition.inc -SELECT COUNT(*) as expect_0 FROM t1; +SELECT VARIABLE_VALUE expect_Primary FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT COUNT(*) AS expect_0 FROM t1; DROP TABLE t1; # @@ -203,22 +185,16 @@ SET SESSION wsrep_on = OFF; DELETE FROM t2 WHERE f1 = 2; DELETE FROM t1 WHERE f1 = 3; SET SESSION wsrep_on = ON; ---source include/galera_wait_ready.inc --connection node_1 DELETE t1, t2 FROM t1 JOIN t2 WHERE t1.f1 = t2.f1; -SELECT COUNT(*) as expect_0 FROM t1; +SELECT COUNT(*) expect_0 FROM t1; --connection node_2 ---source include/galera_wait_ready.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; ---source include/wait_condition.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; ---source include/wait_condition.inc -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; --let $wait_condition = SELECT COUNT(*) = 0 FROM t1; --source include/wait_condition.inc -SELECT COUNT(*) as expect_0 FROM t1; +SELECT VARIABLE_VALUE = 'Primary' FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT COUNT(*) expect_0 FROM t1; DROP TABLE t1,t2; # @@ -238,26 +214,18 @@ INSERT INTO child VALUES (1,1),(2,2),(3,3); SET SESSION wsrep_on = OFF; DELETE FROM child WHERE parent_id = 2; SET SESSION wsrep_on = ON; ---source include/galera_wait_ready.inc --connection node_1 DELETE FROM parent; -SELECT COUNT(*) as expect_0 FROM parent; -SELECT COUNT(*) as expect_0 FROM child; +SELECT COUNT(*) AS expect_0 FROM parent; +SELECT COUNT(*) AS expect_0 FROM child; --connection node_2 ---source include/galera_wait_ready.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; ---source include/wait_condition.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; ---source include/wait_condition.inc -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; ---let $wait_condition = SELECT COUNT(*) = 0 FROM parent; ---source include/wait_condition.inc --let $wait_condition = SELECT COUNT(*) = 0 FROM child; --source include/wait_condition.inc -SELECT COUNT(*) as expect_0 FROM parent; -SELECT COUNT(*) as expect_0 FROM child; +SELECT VARIABLE_VALUE = 'Primary' FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT COUNT(*) AS expect_0 FROM parent; +SELECT COUNT(*) AS expect_0 FROM child; DROP TABLE child, parent; # @@ -272,15 +240,17 @@ SET GLOBAL wsrep_ignore_apply_errors = 4; SET GLOBAL wsrep_on = OFF; CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = ON; ---source include/galera_wait_ready.inc + --connection node_1 CREATE TABLE t1 (f1 INTEGER, f2 INTEGER); DROP TABLE t1; --connection node_2 +--error ER_NO_SUCH_TABLE +SELECT * FROM t1; SET GLOBAL wsrep_ignore_apply_errors = 7; -CALL mtr.add_suppression("Can't find record in 't.*'"); +CALL mtr.add_suppression("Can't find record in "); CALL mtr.add_suppression("Slave SQL: Could not execute Delete_rows event"); CALL mtr.add_suppression("Slave SQL: Error 'Unknown table 'test\\.t1'' on query\\. Default database: 'test'\\. Query: 'DROP TABLE t1', Error_code: 1051"); CALL mtr.add_suppression("Slave SQL: Error 'Can't drop database 's1'; database doesn't exist' on query\\. Default database: 'test'\\. Query: 'DROP SCHEMA s1', Error_code: 1008"); From bce3f3f6287f706e90e067b16f9a8203f64a30a7 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Fri, 2 Aug 2024 10:29:08 +1000 Subject: [PATCH 11/27] MDEV-34682 Reset spider_hton_ptr in error mode of spider_db_init() --- .../spider/bugfix/r/mdev_34682.result | 19 +++++++++++++++++++ .../spider/bugfix/t/mdev_34682.test | 14 ++++++++++++++ .../spider/include/clean_up_spider.inc | 10 +++++----- storage/spider/spd_table.cc | 1 + 4 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_34682.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_34682.test diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_34682.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_34682.result new file mode 100644 index 00000000000..7253e136488 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_34682.result @@ -0,0 +1,19 @@ +set @old_aria_encrypt_tables=@@global.aria_encrypt_tables; +set global aria_encrypt_tables=ON; +CREATE FUNCTION spider_direct_sql RETURNS INT SONAME 'ha_spider.so'; +call mtr.add_suppression(".*\\[ERROR\\] SPIDER plugin initialization failed at.* by 'Initialization of encryption failed for"); +call mtr.add_suppression(".*\\[ERROR\\] Plugin 'SPIDER' registration as a STORAGE ENGINE failed."); +INSTALL PLUGIN spider SONAME 'ha_spider.so'; +ERROR HY000: Can't initialize function 'spider'; Plugin initialization function failed. +SELECT spider_direct_sql ('SELECT * FROM s','a','srv "b"'); +ERROR HY000: Can't initialize function 'spider_direct_sql'; Plugin 'SPIDER' is not loaded +Warnings: +Note 1305 FUNCTION test.spider_flush_table_mon_cache does not exist +Warnings: +Note 1305 FUNCTION test.spider_copy_tables does not exist +Warnings: +Note 1305 FUNCTION test.spider_ping_table does not exist +Warnings: +Note 1305 FUNCTION test.spider_bg_direct_sql does not exist +Warnings: +Note 1305 SONAME ha_spider.so does not exist diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_34682.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_34682.test new file mode 100644 index 00000000000..d61f7db4330 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_34682.test @@ -0,0 +1,14 @@ +set @old_aria_encrypt_tables=@@global.aria_encrypt_tables; +set global aria_encrypt_tables=ON; + +CREATE FUNCTION spider_direct_sql RETURNS INT SONAME 'ha_spider.so'; +call mtr.add_suppression(".*\\[ERROR\\] SPIDER plugin initialization failed at.* by 'Initialization of encryption failed for"); +call mtr.add_suppression(".*\\[ERROR\\] Plugin 'SPIDER' registration as a STORAGE ENGINE failed."); +--error ER_CANT_INITIALIZE_UDF +INSTALL PLUGIN spider SONAME 'ha_spider.so'; +--error ER_CANT_INITIALIZE_UDF +SELECT spider_direct_sql ('SELECT * FROM s','a','srv "b"'); + +--disable_query_log +--source ../../include/clean_up_spider.inc +set global aria_encrypt_tables=@old_aria_encrypt_tables; diff --git a/storage/spider/mysql-test/spider/include/clean_up_spider.inc b/storage/spider/mysql-test/spider/include/clean_up_spider.inc index 249606ec774..5b016e731d9 100644 --- a/storage/spider/mysql-test/spider/include/clean_up_spider.inc +++ b/storage/spider/mysql-test/spider/include/clean_up_spider.inc @@ -1,8 +1,8 @@ -DROP FUNCTION spider_flush_table_mon_cache; -DROP FUNCTION spider_copy_tables; -DROP FUNCTION spider_ping_table; -DROP FUNCTION spider_bg_direct_sql; -DROP FUNCTION spider_direct_sql; +DROP FUNCTION IF EXISTS spider_flush_table_mon_cache; +DROP FUNCTION IF EXISTS spider_copy_tables; +DROP FUNCTION IF EXISTS spider_ping_table; +DROP FUNCTION IF EXISTS spider_bg_direct_sql; +DROP FUNCTION IF EXISTS spider_direct_sql; UNINSTALL SONAME IF EXISTS 'ha_spider'; DROP TABLE IF EXISTS mysql.spider_xa; DROP TABLE IF EXISTS mysql.spider_xa_member; diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index 461e47dd012..c1166c4e7d5 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -6805,6 +6805,7 @@ error_pt_attr_setstate: pthread_attr_destroy(&spider_pt_attr); error_pt_attr_init: #endif + spider_hton_ptr= NULL; DBUG_RETURN(error_num); } From fa8ce92cc004f8db65ebb208aa1c212c1e64397d Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Fri, 2 Aug 2024 10:31:08 +1000 Subject: [PATCH 12/27] MDEV-34682 Return the return value of ddl recovery done in ha_initialize_handlerton Otherwise it could cause false negative when ddl recovery done is part of the plugin initialization --- sql/handler.cc | 2 +- storage/spider/spd_table.cc | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 8239e44b841..a21556d8181 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -782,7 +782,7 @@ int ha_initialize_handlerton(st_plugin_int *plugin) update_discovery_counters(hton, 1); if (ddl_recovery_done && hton->signal_ddl_recovery_done) - hton->signal_ddl_recovery_done(hton); + ret= hton->signal_ddl_recovery_done(hton); DBUG_RETURN(ret); diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index a138fd21598..0a38e8056af 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -6511,8 +6511,10 @@ bool spider_init_system_tables() /* - Spider is typically loaded before ddl_recovery, but DDL statements - cannot be executed before ddl_recovery, so we delay system table creation. + Spider may be loaded before ddl_recovery (e.g. with + --plugin-load-add), but DDL statements in spider init queries cannot + be executed before ddl_recovery, so we execute these queries only + after ddl recovery. */ static int spider_after_ddl_recovery(handlerton *) { From 25e2d0a6bbd64e9b509f4a2d00a9d8736367965e Mon Sep 17 00:00:00 2001 From: Nikita Malyavin Date: Tue, 6 Aug 2024 15:26:55 +0200 Subject: [PATCH 13/27] MDEV-34632 Assertion failed in handler::assert_icp_limitations Assertion `table->field[0]->ptr >= table->record[0] && table->field[0]->ptr <= table->record[0] + table->s->reclength' failed in handler::assert_icp_limitations. table->move_fields has some limitations: 1. It cannot be used in cascade 2. It should always have a restoring pair. Rule 1 is covered by assertions in handler::assert_icp_limitations and handler::ptr_in_record (commit 30894fe9a9). Rule 2 should be manually maintained with care. Hopefully, the rule 1 assertions may sometimes help as well. In ha_myisam::repair, both rules are broken. table->move_fields is used asymmetrically there: it is set on every param->fix_record call (i.e. in compute_vcols) but is restored only once, in the end of repair. The reason to updating field ptr's for every call is that compute_vcols can (supposedly) be called in parallel, that is, with the same table, but different records. The condition to "unmove" the pointers in ha_myisam::restore_vcos_after_repair is incorrect, when stored vcols are available, and myisam stores a VIRTUAL field if it's the only field in the table (the record cannot be of zero length). This patch solves the problem by "unmoving" the pointers symmetrically, in compute_vcols. That is, both rules will be preserved maintained. --- mysql-test/suite/vcol/inc/vcol_keys.inc | 17 +++++++ .../suite/vcol/r/vcol_keys_innodb.result | 19 ++++++++ .../suite/vcol/r/vcol_keys_myisam.result | 19 ++++++++ storage/myisam/ha_myisam.cc | 47 ++++++------------- storage/myisam/ha_myisam.h | 1 - 5 files changed, 70 insertions(+), 33 deletions(-) diff --git a/mysql-test/suite/vcol/inc/vcol_keys.inc b/mysql-test/suite/vcol/inc/vcol_keys.inc index 8ec89daff0b..d209e24811b 100644 --- a/mysql-test/suite/vcol/inc/vcol_keys.inc +++ b/mysql-test/suite/vcol/inc/vcol_keys.inc @@ -15,6 +15,8 @@ ################################################################################ +--source include/have_sequence.inc + --echo # - UNIQUE KEY --echo # - INDEX --echo # - FULLTEXT INDEX @@ -231,3 +233,18 @@ CREATE TABLE t1 ( DELETE FROM t1 WHERE vc IS NULL ORDER BY pk; DROP TABLE t1; +# +# MDEV-34632 Assertion `table->field[0]->ptr >= table->record[0] && +# table->field[0]->ptr <= table->record[0] + table->s->reclength' failed in +# void handler::assert_icp_limitations(uchar*) +# +SET sql_mode=''; +CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL,KEY(a)) ENGINE=MyISAM; +INSERT INTO t1 SELECT 1 FROM seq_1_to_2 ; +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL,KEY(a)) ENGINE=MyISAM; +INSERT INTO t1 SELECT 1 UNION SELECT 1; +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/suite/vcol/r/vcol_keys_innodb.result b/mysql-test/suite/vcol/r/vcol_keys_innodb.result index c07e00a5e20..51e97864a25 100644 --- a/mysql-test/suite/vcol/r/vcol_keys_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_keys_innodb.result @@ -215,6 +215,25 @@ INDEX(vc(32)) ); DELETE FROM t1 WHERE vc IS NULL ORDER BY pk; DROP TABLE t1; +SET sql_mode=''; +CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL,KEY(a)) ENGINE=MyISAM; +INSERT INTO t1 SELECT 1 FROM seq_1_to_2 ; +Warnings: +Warning 1906 The value specified for generated column 'a' in table 't1' has been ignored +Warning 1906 The value specified for generated column 'a' in table 't1' has been ignored +SELECT * FROM t1; +a +1 +1 +DROP TABLE t1; +CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL,KEY(a)) ENGINE=MyISAM; +INSERT INTO t1 SELECT 1 UNION SELECT 1; +Warnings: +Warning 1906 The value specified for generated column 'a' in table 't1' has been ignored +SELECT * FROM t1; +a +1 +DROP TABLE t1; # # MDEV-11737 Failing assertion: block->magic_n == MEM_BLOCK_MAGIC_N # diff --git a/mysql-test/suite/vcol/r/vcol_keys_myisam.result b/mysql-test/suite/vcol/r/vcol_keys_myisam.result index 0112c3986e8..2a05464846a 100644 --- a/mysql-test/suite/vcol/r/vcol_keys_myisam.result +++ b/mysql-test/suite/vcol/r/vcol_keys_myisam.result @@ -209,6 +209,25 @@ INDEX(vc(32)) ); DELETE FROM t1 WHERE vc IS NULL ORDER BY pk; DROP TABLE t1; +SET sql_mode=''; +CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL,KEY(a)) ENGINE=MyISAM; +INSERT INTO t1 SELECT 1 FROM seq_1_to_2 ; +Warnings: +Warning 1906 The value specified for generated column 'a' in table 't1' has been ignored +Warning 1906 The value specified for generated column 'a' in table 't1' has been ignored +SELECT * FROM t1; +a +1 +1 +DROP TABLE t1; +CREATE TABLE t1 (a INT GENERATED ALWAYS AS (1) VIRTUAL,KEY(a)) ENGINE=MyISAM; +INSERT INTO t1 SELECT 1 UNION SELECT 1; +Warnings: +Warning 1906 The value specified for generated column 'a' in table 't1' has been ignored +SELECT * FROM t1; +a +1 +DROP TABLE t1; # # Original test # diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 022a7bb6819..c5d13273b23 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -721,29 +721,32 @@ static void init_compute_vcols(void *table) static int compute_vcols(MI_INFO *info, uchar *record, int keynum) { + int error= 0; /* This mutex is needed for parallel repair */ mysql_mutex_lock(&info->s->intern_lock); TABLE *table= (TABLE*)(info->external_ref); - table->move_fields(table->field, record, table->field[0]->record_ptr()); + table->move_fields(table->field, record, table->record[0]); if (keynum == -1) // update all vcols { - int error= table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_READ); + error= table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_READ); if (table->update_virtual_fields(table->file, VCOL_UPDATE_INDEXED)) error= 1; - mysql_mutex_unlock(&info->s->intern_lock); - return error; } - // update only one key - KEY *key= table->key_info + keynum; - KEY_PART_INFO *kp= key->key_part, *end= kp + key->ext_key_parts; - for (; kp < end; kp++) + else { - Field *f= table->field[kp->fieldnr - 1]; - if (f->vcol_info && !f->vcol_info->stored_in_db) - table->update_virtual_field(f, false); + // update only one key + KEY *key= table->key_info + keynum; + KEY_PART_INFO *kp= key->key_part, *end= kp + key->ext_key_parts; + for (; kp < end; kp++) + { + Field *f= table->field[kp->fieldnr - 1]; + if (f->vcol_info && !f->vcol_info->stored_in_db) + table->update_virtual_field(f, false); + } } + table->move_fields(table->field, table->record[0], record); mysql_mutex_unlock(&info->s->intern_lock); - return 0; + return error; } } @@ -1025,16 +1028,6 @@ void ha_myisam::setup_vcols_for_repair(HA_CHECK *param) table->use_all_columns(); } -void ha_myisam::restore_vcos_after_repair() -{ - if (file->s->base.reclength < file->s->vreclength) - { - table->move_fields(table->field, table->record[0], - table->field[0]->record_ptr()); - table->default_column_bitmaps(); - } -} - int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) { if (!file) return HA_ADMIN_INTERNAL_ERROR; @@ -1131,8 +1124,6 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED; } - restore_vcos_after_repair(); - thd_proc_info(thd, old_proc_info); return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK; } @@ -1178,8 +1169,6 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) else if (!mi_is_crashed(file) && !thd->killed) mi_mark_crashed(file); - restore_vcos_after_repair(); - return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK; } @@ -1229,8 +1218,6 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) break; } - restore_vcos_after_repair(); - if (!error && start_records != file->state->records && !(check_opt->flags & T_VERY_SILENT)) { @@ -1268,8 +1255,6 @@ int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt) error= repair(thd,*param,1); } - restore_vcos_after_repair(); - return error; } @@ -1707,8 +1692,6 @@ int ha_myisam::enable_indexes(key_map map, bool persist) } info(HA_STATUS_CONST); thd_proc_info(thd, save_proc_info); - - restore_vcos_after_repair(); } DBUG_RETURN(error); } diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index 46202468475..e72636e9e22 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -49,7 +49,6 @@ class ha_myisam final : public handler bool can_enable_indexes; int repair(THD *thd, HA_CHECK ¶m, bool optimize); void setup_vcols_for_repair(HA_CHECK *param); - void restore_vcos_after_repair(); public: ha_myisam(handlerton *hton, TABLE_SHARE *table_arg); From 56fb04aa7c78c11649805df0a8ad9d7de08f374d Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Thu, 8 Aug 2024 17:56:56 -0400 Subject: [PATCH 14/27] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 05e6832c930..da85fbe02b8 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=26 +MYSQL_VERSION_PATCH=27 SERVER_MATURITY=stable From f15de4258583fdd4213b46d1ab1ecf5375a1a790 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Thu, 8 Aug 2024 17:58:51 -0400 Subject: [PATCH 15/27] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index a4214274a42..2933d080d5b 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=6 -MYSQL_VERSION_PATCH=19 +MYSQL_VERSION_PATCH=20 SERVER_MATURITY=stable From d1713666b06ae5525f85afe5a5c3e46ab2c26a0a Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 19 Jul 2024 21:44:34 +0200 Subject: [PATCH 16/27] Fix incorrect setting of opt_local_file in mysqlimport, for named pipe For named pipe, server and client are on the same machine, and opt_local_infile just adds unnecessary copying via "load data local infile" --- client/mysqlimport.c | 1 - 1 file changed, 1 deletion(-) diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 3a9f9005cb6..405eda8cc10 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -249,7 +249,6 @@ get_one_option(const struct my_option *opt, const char *argument, #ifdef __WIN__ case 'W': opt_protocol = MYSQL_PROTOCOL_PIPE; - opt_local_file=1; break; #endif case OPT_MYSQL_PROTOCOL: From b619be35693b531bf34cdb00cf41318975cbf87b Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 29 Jul 2024 01:03:17 +0200 Subject: [PATCH 17/27] Support -DCONC_WITH_SSL parameter passed to CMake Usually it is not needed, but sometimes we need to testing interoperability, e.g OpenSSL server / SCHANNEL client, or WolfSSL server / OpenSSL client. --- cmake/mariadb_connector_c.cmake | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/cmake/mariadb_connector_c.cmake b/cmake/mariadb_connector_c.cmake index b4f56597775..9b4f25498fd 100644 --- a/cmake/mariadb_connector_c.cmake +++ b/cmake/mariadb_connector_c.cmake @@ -8,15 +8,17 @@ SET(CONC_WITH_SIGNCODE ${SIGNCODE}) SET(SIGN_OPTIONS ${SIGNTOOL_PARAMETERS}) SET(CONC_WITH_EXTERNAL_ZLIB ON) -IF(SSL_DEFINES MATCHES "WOLFSSL") - IF(WIN32) - SET(CONC_WITH_SSL "SCHANNEL") +IF(NOT CONC_WITH_SSL) + IF(SSL_DEFINES MATCHES "WOLFSSL") + IF(WIN32) + SET(CONC_WITH_SSL "SCHANNEL") + ELSE() + SET(CONC_WITH_SSL "GNUTLS") # that's what debian wants, right? + ENDIF() ELSE() - SET(CONC_WITH_SSL "GNUTLS") # that's what debian wants, right? + SET(CONC_WITH_SSL "OPENSSL") + SET(OPENSSL_FOUND TRUE) ENDIF() -ELSE() - SET(CONC_WITH_SSL "OPENSSL") - SET(OPENSSL_FOUND TRUE) ENDIF() SET(CONC_WITH_CURL OFF) From 62fd7b4cd2cd0a8527c30e3661fc917b7e07522b Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 29 Jul 2024 01:10:32 +0200 Subject: [PATCH 18/27] OpenSSL - set all heap functions in CRYPTO_set_mem_functions. The reason is that on Windows, OpenSSL can be built with different C runtime than the server (e.g Debug runtime in debug vcpkg build). Overwriting only malloc(), with CRT that server is using can cause mixup of incompatible malloc() and free() inside openssl. To fix, overwrite all memory functions. --- mysys_ssl/openssl.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/mysys_ssl/openssl.c b/mysys_ssl/openssl.c index 8adaeae4069..e0271817309 100644 --- a/mysys_ssl/openssl.c +++ b/mysys_ssl/openssl.c @@ -47,12 +47,25 @@ static void *coc_malloc(size_t size, const char *f __attribute__((unused)), return malloc(size); } +static void *coc_realloc(void *addr, size_t num, + const char *file __attribute__((unused)), + int line __attribute__((unused))) +{ + return realloc(addr, num); +} + +static void coc_free(void *addr, const char *file __attribute__((unused)), + int line __attribute__((unused))) +{ + free(addr); +} + int check_openssl_compatibility() { EVP_CIPHER_CTX *evp_ctx; EVP_MD_CTX *md5_ctx; - if (!CRYPTO_set_mem_functions(coc_malloc, NULL, NULL)) + if (!CRYPTO_set_mem_functions(coc_malloc, coc_realloc, coc_free)) return 0; testing= 1; From 4a67bd5105188d10de45521ef19ea11772eed1dc Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 8 Aug 2024 11:13:41 +0200 Subject: [PATCH 19/27] Fix server on windows, so it does not write to error log byte-by-byte fprintf() on Windows, when used on unbuffered FILE*, writes bytewise. This can make crash handler messages harder to read, if they are mixed up with other error log output. Fixed , on Windows, by using a small buffer for formatting, and fwrite instead of fprintf, if buffer is large enough for message. --- sql/log.cc | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/sql/log.cc b/sql/log.cc index 01700cc048d..4f74900e59a 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -9215,6 +9215,25 @@ static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, #ifndef EMBEDDED_LIBRARY +#ifndef _WIN32 +#define fprintf_stderr(format, ...) fprintf(stderr, format, __VA_ARGS__) +#else +/* + On Windows, if FILE* is unbuffered, fprintf() writes output byte by byte. + This is suboptimal for printing to error log, we want full message at once. +*/ +#define fprintf_stderr(format, ...) \ + do \ + { \ + char buf[256]; \ + size_t len= snprintf(buf, sizeof(buf), format, __VA_ARGS__); \ + if (len >= sizeof(buf)) \ + fprintf(stderr, format, __VA_ARGS__); \ + else \ + fwrite(buf, len, 1, stderr); \ + } while (0) +#endif + static void print_buffer_to_file(enum loglevel level, const char *buffer, size_t length) { @@ -9248,7 +9267,7 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer, localtime_r(&skr, &tm_tmp); start=&tm_tmp; - fprintf(stderr, "%d-%02d-%02d %2d:%02d:%02d %lu [%s] %.*s%.*s\n", + fprintf_stderr( "%d-%02d-%02d %2d:%02d:%02d %lu [%s] %.*s%.*s\n", start->tm_year + 1900, start->tm_mon+1, start->tm_mday, From e997bf58fbefa06d47403001482ab81502f764dd Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 6 Aug 2024 14:35:39 +0200 Subject: [PATCH 20/27] MDEV-34714 perror-win test failure on localized Windows Let perror produce OS error messages in English --- extra/perror.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extra/perror.c b/extra/perror.c index d678d46d1be..4710b28035a 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -206,7 +206,8 @@ static my_bool print_win_error_msg(DWORD error, my_bool verbose) char *s; if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, error, 0, (char *)&s, 0, + NULL, error, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + (char *) &s, 0, NULL)) { char* end = s + strlen(s) - 1; From c83ba513da0e3d38f8001fdf4fa55e8a812e6103 Mon Sep 17 00:00:00 2001 From: Ian Gilfillan Date: Tue, 6 Aug 2024 20:34:33 +0200 Subject: [PATCH 21/27] Update sponsors --- CREDITS | 63 ++++++++++++++++++++--------- mysql-test/main/contributors.result | 46 ++++++++++++++++----- sql/contributors.h | 48 ++++++++++++++++------ 3 files changed, 115 insertions(+), 42 deletions(-) diff --git a/CREDITS b/CREDITS index 35604064980..42f1697f992 100644 --- a/CREDITS +++ b/CREDITS @@ -1,20 +1,48 @@ MariaDB is brought to you by the MariaDB Foundation, a non profit organization registered in the USA. -The current main sponsors of the MariaDB Foundation are: +As of August 2024, the main sponsors of the MariaDB Foundation are: -Alibaba Cloud https://www.alibabacloud.com/ (2017) -Intel https://www.intel.com (2022) -MariaDB Corporation https://www.mariadb.com (2013) -Microsoft https://microsoft.com/ (2017) -ServiceNow https://servicenow.com (2019) -SIT https://sit.org (2022) -Tencent Cloud https://cloud.tencent.com (2017) -Development Bank of Singapore https://dbs.com (2016) -IBM https://www.ibm.com (2017) -Automattic https://automattic.com (2019) -Galera Cluster https://galeracluster.com (2020) -Percona https://www.percona.com (2018) +Amazon https://amazon.com +Acronis https://www.acronis.com +Alibaba Cloud https://www.alibabacloud.com +C>onstructor https://constructor.org +Development Bank of Singapore https://www.dbs.com +Intel https://www.intel.com +MariaDB plc https://www.mariadb.com +ServiceNow https://servicenow.com +WebPros https://webpros.com +IBM https://www.ibm.com +IONOS https://www.ionos.com +Automattic https://automattic.com +SkySQL https://skysql.com +team.blue https://team.blue +Tencent Cloud https://cloud.tencent.com +Wikimedia Foundation https://www.wikimediafoundation.org +Cyber Leo https://cyberleo.com +Hetzner https://www.hetzner.com +Rumahweb https://www.rumahweb.com +Tasjeel.ae https://www.tasjeel.ae +Galera Cluster https://galeracluster.com +Percona https://www.percona.com +Vettabase https://vettabase.com + +Previous sponsors include: + +Booking.com +Jelastic.com +Microsoft +Nexedi +Open Query +Planeetta Web Hosting +SpringbokSQL +Tencent Games +Tencent Game DBA +Tencent TDSQL +Verkkokauppa +Virtuozzo +Visma +Webyog For a full list of sponsors, see https://mariadb.org/about/#sponsors @@ -27,7 +55,7 @@ For all corporate sponsorships please contact the MariaDB Foundation Board via foundation@mariadb.org. The MariaDB Foundation is responsible for the MariaDB source -repository, the official MariaDB binaries and http://mariadb.org. +repository, the official MariaDB binaries and https://mariadb.org. The MariaDB Foundation also provides, among other things, the following services to the MariaDB community: @@ -37,8 +65,8 @@ following services to the MariaDB community: - Merging MySQL patches into MariaDB - Bug fixing in MariaDB (for bugs that affects a large part of the community) - Building the official MariaDB binaries -- Maintaining http://mariadb.org -- Documenting MariaDB in the MariaDB Knowledge Base http://mariadb.com/kb +- Maintaining https://mariadb.org +- Documenting MariaDB in the MariaDB Knowledge Base https://mariadb.com/kb To be able to do the above we need help from corporations and individuals! @@ -49,8 +77,5 @@ go to https://mariadb.org/donate/ You can get a list of all the main authors of MariaDB / MySQL by running SHOW AUTHORS; -You can get a list sponsors and contributors by running -SHOW CONTRIBUTORS; - You can read more about the MariaDB Foundation at: https://mariadb.org/about/ diff --git a/mysql-test/main/contributors.result b/mysql-test/main/contributors.result index 8d72373696c..9126385faa0 100644 --- a/mysql-test/main/contributors.result +++ b/mysql-test/main/contributors.result @@ -1,18 +1,42 @@ SHOW CONTRIBUTORS; Name Location Comment +Amazon https://www.amazon.com/ Diamond Sponsor of the MariaDB Foundation +Acronis https://www.acronis.com/ Platinum Sponsor of the MariaDB Foundation Alibaba Cloud https://www.alibabacloud.com/ Platinum Sponsor of the MariaDB Foundation -Tencent Cloud https://cloud.tencent.com Platinum Sponsor of the MariaDB Foundation -Microsoft https://microsoft.com/ Platinum Sponsor of the MariaDB Foundation -MariaDB Corporation https://mariadb.com Founding member, Platinum Sponsor of the MariaDB Foundation -ServiceNow https://servicenow.com Platinum Sponsor of the MariaDB Foundation -Intel https://www.intel.com Platinum Sponsor of the MariaDB Foundation -SIT https://sit.org Platinum Sponsor of the MariaDB Foundation -Visma https://visma.com Gold Sponsor of the MariaDB Foundation -DBS https://dbs.com Gold Sponsor of the MariaDB Foundation -IBM https://www.ibm.com Gold Sponsor of the MariaDB Foundation -Automattic https://automattic.com Silver Sponsor of the MariaDB Foundation +C Date: Wed, 12 Jun 2024 16:53:15 +0400 Subject: [PATCH 22/27] MDEV-34376 Wrong data types when mixing an utf8 *TEXT column and a short binary A mixture of a multi-byte *TEXT column and a short binary column produced a too large column. For example, COALESCE(tinytext_utf8mb4, short_varbinary) produced a BLOB column instead of an expected TINYBLOB. - Adding a virtual method Type_all_attributes::character_octet_length(), returning max_length by default. - Overriding Item_field::character_octet_length() to extract the octet length from the underlying Field. - Overriding Item_ref::character_octet_length() to extract the octet length from the references Item (e.g. as VIEW fields). - Fixing Type_numeric_attributes::find_max_octet_length() to take the octet length using the new method character_octet_length() instead of accessing max_length directly. --- mysql-test/main/ctype_utf8mb4.result | 121 +++++++++++++++++++++++++++ mysql-test/main/ctype_utf8mb4.test | 93 ++++++++++++++++++++ sql/item.h | 12 +++ sql/sql_type.cc | 2 +- sql/sql_type.h | 1 + 5 files changed, 228 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/ctype_utf8mb4.result b/mysql-test/main/ctype_utf8mb4.result index 64f28bd4bf3..bc370b2a694 100644 --- a/mysql-test/main/ctype_utf8mb4.result +++ b/mysql-test/main/ctype_utf8mb4.result @@ -4165,5 +4165,126 @@ SELECT 1 COLLATE utf8mb4_bin; SELECT 1 COLLATE latin1_swedish_ci; ERROR 42000: COLLATION 'latin1_swedish_ci' is not valid for CHARACTER SET 'utf8mb4' # +# MDEV-34376 Wrong data types when mixing an utf8 *TEXT column and a short binary +# +CREATE TABLE t1 ( +c_tinytext tinytext, +c_text text, +c_mediumtext mediumtext, +c_longtext longtext +) CHARACTER SET utf8mb4; +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE VIEW v2 AS SELECT * FROM v1; +# Using table fields +CREATE TABLE t2 AS SELECT +COALESCE(c_tinytext, CAST('binary data' AS BINARY)) AS mix_tinytext_binary, +COALESCE(c_text, CAST('binary data' AS BINARY)) AS mix_text_binary, +COALESCE(c_mediumtext, CAST('binary data' AS BINARY)) AS mix_mediumtext_binary, +COALESCE(c_longtext, CAST('binary data' AS BINARY)) AS mix_longtext_binary +FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `mix_tinytext_binary` tinyblob DEFAULT NULL, + `mix_text_binary` blob DEFAULT NULL, + `mix_mediumtext_binary` mediumblob DEFAULT NULL, + `mix_longtext_binary` longblob DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t2; +CREATE TABLE t2 AS SELECT +c_tinytext AS mix_tinytext_binary, +c_text AS mix_text_binary, +c_mediumtext AS mix_mediumtext_binary, +c_longtext AS mix_longtext_binary +FROM t1 +UNION SELECT +CAST('binary data' AS BINARY), +CAST('binary data' AS BINARY), +CAST('binary data' AS BINARY), +CAST('binary data' AS BINARY); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `mix_tinytext_binary` tinyblob DEFAULT NULL, + `mix_text_binary` blob DEFAULT NULL, + `mix_mediumtext_binary` mediumblob DEFAULT NULL, + `mix_longtext_binary` longblob DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t2; +# Using view fields +CREATE TABLE t2 AS SELECT +COALESCE(c_tinytext, CAST('binary data' AS BINARY)) AS mix_tinytext_binary, +COALESCE(c_text, CAST('binary data' AS BINARY)) AS mix_text_binary, +COALESCE(c_mediumtext, CAST('binary data' AS BINARY)) AS mix_mediumtext_binary, +COALESCE(c_longtext, CAST('binary data' AS BINARY)) AS mix_longtext_binary +FROM v1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `mix_tinytext_binary` tinyblob DEFAULT NULL, + `mix_text_binary` blob DEFAULT NULL, + `mix_mediumtext_binary` mediumblob DEFAULT NULL, + `mix_longtext_binary` longblob DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t2; +CREATE TABLE t2 AS SELECT +c_tinytext AS mix_tinytext_binary, +c_text AS mix_text_binary, +c_mediumtext AS mix_mediumtext_binary, +c_longtext AS mix_longtext_binary +FROM v1 +UNION SELECT +CAST('binary data' AS BINARY), +CAST('binary data' AS BINARY), +CAST('binary data' AS BINARY), +CAST('binary data' AS BINARY); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `mix_tinytext_binary` tinyblob DEFAULT NULL, + `mix_text_binary` blob DEFAULT NULL, + `mix_mediumtext_binary` mediumblob DEFAULT NULL, + `mix_longtext_binary` longblob DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t2; +# Using view on view fields +CREATE TABLE t2 AS SELECT +COALESCE(c_tinytext, CAST('binary data' AS BINARY)) AS mix_tinytext_binary, +COALESCE(c_text, CAST('binary data' AS BINARY)) AS mix_text_binary, +COALESCE(c_mediumtext, CAST('binary data' AS BINARY)) AS mix_mediumtext_binary, +COALESCE(c_longtext, CAST('binary data' AS BINARY)) AS mix_longtext_binary +FROM v2; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `mix_tinytext_binary` tinyblob DEFAULT NULL, + `mix_text_binary` blob DEFAULT NULL, + `mix_mediumtext_binary` mediumblob DEFAULT NULL, + `mix_longtext_binary` longblob DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t2; +CREATE TABLE t2 AS SELECT +c_tinytext AS mix_tinytext_binary, +c_text AS mix_text_binary, +c_mediumtext AS mix_mediumtext_binary, +c_longtext AS mix_longtext_binary +FROM v2 +UNION SELECT +CAST('binary data' AS BINARY), +CAST('binary data' AS BINARY), +CAST('binary data' AS BINARY), +CAST('binary data' AS BINARY); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `mix_tinytext_binary` tinyblob DEFAULT NULL, + `mix_text_binary` blob DEFAULT NULL, + `mix_mediumtext_binary` mediumblob DEFAULT NULL, + `mix_longtext_binary` longblob DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t2; +DROP VIEW v2, v1; +DROP TABLE t1; +# # End of 10.5 tests # diff --git a/mysql-test/main/ctype_utf8mb4.test b/mysql-test/main/ctype_utf8mb4.test index c0c5568b3bd..6361252ab80 100644 --- a/mysql-test/main/ctype_utf8mb4.test +++ b/mysql-test/main/ctype_utf8mb4.test @@ -2062,6 +2062,99 @@ SELECT 1 COLLATE utf8mb4_bin; --error ER_COLLATION_CHARSET_MISMATCH SELECT 1 COLLATE latin1_swedish_ci; +--echo # +--echo # MDEV-34376 Wrong data types when mixing an utf8 *TEXT column and a short binary +--echo # + +CREATE TABLE t1 ( + c_tinytext tinytext, + c_text text, + c_mediumtext mediumtext, + c_longtext longtext +) CHARACTER SET utf8mb4; +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE VIEW v2 AS SELECT * FROM v1; + +--echo # Using table fields + +CREATE TABLE t2 AS SELECT + COALESCE(c_tinytext, CAST('binary data' AS BINARY)) AS mix_tinytext_binary, + COALESCE(c_text, CAST('binary data' AS BINARY)) AS mix_text_binary, + COALESCE(c_mediumtext, CAST('binary data' AS BINARY)) AS mix_mediumtext_binary, + COALESCE(c_longtext, CAST('binary data' AS BINARY)) AS mix_longtext_binary +FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2; + +CREATE TABLE t2 AS SELECT + c_tinytext AS mix_tinytext_binary, + c_text AS mix_text_binary, + c_mediumtext AS mix_mediumtext_binary, + c_longtext AS mix_longtext_binary +FROM t1 +UNION SELECT + CAST('binary data' AS BINARY), + CAST('binary data' AS BINARY), + CAST('binary data' AS BINARY), + CAST('binary data' AS BINARY); +SHOW CREATE TABLE t2; +DROP TABLE t2; + + +--echo # Using view fields + +CREATE TABLE t2 AS SELECT + COALESCE(c_tinytext, CAST('binary data' AS BINARY)) AS mix_tinytext_binary, + COALESCE(c_text, CAST('binary data' AS BINARY)) AS mix_text_binary, + COALESCE(c_mediumtext, CAST('binary data' AS BINARY)) AS mix_mediumtext_binary, + COALESCE(c_longtext, CAST('binary data' AS BINARY)) AS mix_longtext_binary +FROM v1; +SHOW CREATE TABLE t2; +DROP TABLE t2; + +CREATE TABLE t2 AS SELECT + c_tinytext AS mix_tinytext_binary, + c_text AS mix_text_binary, + c_mediumtext AS mix_mediumtext_binary, + c_longtext AS mix_longtext_binary +FROM v1 +UNION SELECT + CAST('binary data' AS BINARY), + CAST('binary data' AS BINARY), + CAST('binary data' AS BINARY), + CAST('binary data' AS BINARY); +SHOW CREATE TABLE t2; +DROP TABLE t2; + + +--echo # Using view on view fields + +CREATE TABLE t2 AS SELECT + COALESCE(c_tinytext, CAST('binary data' AS BINARY)) AS mix_tinytext_binary, + COALESCE(c_text, CAST('binary data' AS BINARY)) AS mix_text_binary, + COALESCE(c_mediumtext, CAST('binary data' AS BINARY)) AS mix_mediumtext_binary, + COALESCE(c_longtext, CAST('binary data' AS BINARY)) AS mix_longtext_binary +FROM v2; +SHOW CREATE TABLE t2; +DROP TABLE t2; + +CREATE TABLE t2 AS SELECT + c_tinytext AS mix_tinytext_binary, + c_text AS mix_text_binary, + c_mediumtext AS mix_mediumtext_binary, + c_longtext AS mix_longtext_binary +FROM v2 +UNION SELECT + CAST('binary data' AS BINARY), + CAST('binary data' AS BINARY), + CAST('binary data' AS BINARY), + CAST('binary data' AS BINARY); +SHOW CREATE TABLE t2; +DROP TABLE t2; + +DROP VIEW v2, v1; +DROP TABLE t1; + --echo # --echo # End of 10.5 tests --echo # diff --git a/sql/item.h b/sql/item.h index 796b2ec9eee..9af0a077f75 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3576,6 +3576,10 @@ public: return &type_handler_null; return field->type_handler(); } + uint32 character_octet_length() const override + { + return field->character_octet_length(); + } Field *create_tmp_field_from_item_field(MEM_ROOT *root, TABLE *new_table, Item_ref *orig_item, const Tmp_field_param *param); @@ -5578,6 +5582,10 @@ public: { return (*ref)->type_handler(); } const Type_handler *real_type_handler() const override { return (*ref)->real_type_handler(); } + uint32 character_octet_length() const override + { + return Item_ref::real_item()->character_octet_length(); + } Field *get_tmp_table_field() override { return result_field ? result_field : (*ref)->get_tmp_table_field(); } Item *get_tmp_table_item(THD *thd) override; @@ -5616,6 +5624,10 @@ public: (*ref)->save_in_field(result_field, no_conversions); } Item *real_item() override { return ref ? (*ref)->real_item() : this; } + const Item *real_item() const + { + return const_cast(this)->Item_ref::real_item(); + } const TYPELIB *get_typelib() const override { return ref ? (*ref)->get_typelib() : NULL; diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 9ede9e2582d..44475e29bcc 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -1221,7 +1221,7 @@ uint32 Type_numeric_attributes::find_max_octet_length(Item **item, uint nitems) { uint32 octet_length= 0; for (uint i= 0; i < nitems ; i++) - set_if_bigger(octet_length, item[i]->max_length); + set_if_bigger(octet_length, item[i]->character_octet_length()); return octet_length; } diff --git a/sql/sql_type.h b/sql/sql_type.h index 874623e4316..859b63b5ad1 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -3345,6 +3345,7 @@ public: { } virtual ~Type_all_attributes() = default; virtual void set_maybe_null(bool maybe_null_arg)= 0; + virtual uint32 character_octet_length() const { return max_length; } // Returns total number of decimal digits virtual uint decimal_precision() const= 0; virtual const TYPELIB *get_typelib() const= 0; From cd8b8bb964c1f1faffecb124ed3030144e658f00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 18 Jul 2024 10:10:26 +0300 Subject: [PATCH 23/27] MDEV-34594 : Assertion `client_state.transaction().active()' failed in int wsrep_thd_append_key(THD*, const wsrep_key*, int, Wsrep_service_key_type) CREATE TABLE [SELECT|REPLACE SELECT] is CTAS and idea was that we force ROW format. However, it was not correctly enforced and keys were appended before wsrep transaction was started. At THD::decide_logging_format we should force used stmt binlog format to ROW in CTAS case and produce a warning if used binlog format was not ROW. At ha_innodb::update_row we should not append keys similarly as in ha_innodb::write_row if sql_command is SQLCOM_CREATE_TABLE. Improved error logging on ::write_row, ::update_row and ::delete_row if wsrep key append fails. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/r/MDEV-34594.result | 88 +++++++++++++++++++ mysql-test/suite/galera/t/MDEV-34594.test | 68 ++++++++++++++ mysql-test/suite/wsrep/r/binlog_format.result | 8 ++ sql/sql_class.cc | 18 ++++ storage/innobase/handler/ha_innodb.cc | 24 +++-- 5 files changed, 199 insertions(+), 7 deletions(-) create mode 100644 mysql-test/suite/galera/r/MDEV-34594.result create mode 100644 mysql-test/suite/galera/t/MDEV-34594.test diff --git a/mysql-test/suite/galera/r/MDEV-34594.result b/mysql-test/suite/galera/r/MDEV-34594.result new file mode 100644 index 00000000000..f9caeba8e59 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-34594.result @@ -0,0 +1,88 @@ +connection node_2; +connection node_1; +# +# Case 1: test with binlog_format ROW +# +connection node_1; +SET @@binlog_format=ROW; +CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c; +CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c; +SELECT * FROM t1; +a b +1 2 +2 3 +SELECT * FROM t2; +a b +1 3 +connection node_2; +SELECT * FROM t1; +a b +1 2 +2 3 +SELECT * FROM t2; +a b +1 3 +DROP TABLE t1,t2; +# +# Case 2: test with binlog_format MIXED +# +connection node_1; +SET @@binlog_format=MIXED; +Warnings: +Warning 1105 MariaDB Galera and flashback do not support binlog format: MIXED +CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c; +Warnings: +Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW +Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW +CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c; +Warnings: +Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW +Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW +SELECT * FROM t1; +a b +1 2 +2 3 +SELECT * FROM t2; +a b +1 3 +connection node_2; +SELECT * FROM t1; +a b +1 2 +2 3 +SELECT * FROM t2; +a b +1 3 +DROP TABLE t1,t2; +# +# Case 3: test with binlog_format STATEMENT +# +connection node_1; +SET @@binlog_format=STATEMENT; +Warnings: +Warning 1105 MariaDB Galera and flashback do not support binlog format: STATEMENT +CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c; +Warnings: +Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW +Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW +CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c; +Warnings: +Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW +Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW +SELECT * FROM t1; +a b +1 2 +2 3 +SELECT * FROM t2; +a b +1 3 +connection node_2; +SELECT * FROM t1; +a b +1 2 +2 3 +SELECT * FROM t2; +a b +1 3 +DROP TABLE t1,t2; +connection node_1; diff --git a/mysql-test/suite/galera/t/MDEV-34594.test b/mysql-test/suite/galera/t/MDEV-34594.test new file mode 100644 index 00000000000..256070cf40d --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-34594.test @@ -0,0 +1,68 @@ +--source include/galera_cluster.inc +--source include/log_bin.inc + +--echo # +--echo # Case 1: test with binlog_format ROW +--echo # +--connection node_1 +SET @@binlog_format=ROW; +CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c; +# +# Note that this has two rows (1,2) and (1,3) where (1,3) contains duplicate key +# but we requested REPLACE --> ::update_row() is called to update (1,2) --> (1,3) +# +CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c; +SELECT * FROM t1; +SELECT * FROM t2; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2' +--source include/wait_condition.inc + +SELECT * FROM t1; +SELECT * FROM t2; +DROP TABLE t1,t2; + +--echo # +--echo # Case 2: test with binlog_format MIXED +--echo # +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2' +--source include/wait_condition.inc +SET @@binlog_format=MIXED; +CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c; +CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c; +SELECT * FROM t1; +SELECT * FROM t2; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2' +--source include/wait_condition.inc + +SELECT * FROM t1; +SELECT * FROM t2; +DROP TABLE t1,t2; + +--echo # +--echo # Case 3: test with binlog_format STATEMENT +--echo # +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2' +--source include/wait_condition.inc +SET @@binlog_format=STATEMENT; +CREATE TABLE t1 (a INT UNIQUE) SELECT 1 AS a,2 AS b UNION SELECT 2 AS a,3 AS c; +CREATE TABLE t2 (a INT UNIQUE) REPLACE SELECT 1 AS a,2 AS b UNION SELECT 1 AS a,3 AS c; +SELECT * FROM t1; +SELECT * FROM t2; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2' OR TABLE_NAME = 't1' +--source include/wait_condition.inc + +SELECT * FROM t1; +SELECT * FROM t2; +DROP TABLE t1,t2; + +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2' +--source include/wait_condition.inc diff --git a/mysql-test/suite/wsrep/r/binlog_format.result b/mysql-test/suite/wsrep/r/binlog_format.result index 079ceb975dd..ce4b45319bc 100644 --- a/mysql-test/suite/wsrep/r/binlog_format.result +++ b/mysql-test/suite/wsrep/r/binlog_format.result @@ -16,6 +16,9 @@ SHOW VARIABLES LIKE 'binlog_format'; Variable_name Value binlog_format STATEMENT CREATE TABLE IF NOT EXISTS test.t1 AS SELECT * FROM information_schema.routines WHERE 1 = 0; +Warnings: +Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW +Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW SET binlog_format=MIXED; Warnings: Warning 1105 MariaDB Galera and flashback do not support binlog format: MIXED @@ -26,9 +29,14 @@ SHOW VARIABLES LIKE 'binlog_format'; Variable_name Value binlog_format MIXED CREATE TABLE IF NOT EXISTS test.t2 AS SELECT * FROM information_schema.routines WHERE 1 = 0; +Warnings: +Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW +Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW SET binlog_format=ROW; SHOW WARNINGS; Level Code Message +Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW +Warning 1105 Galera does not support binlog_format = MIXED in CREATE TABLE [SELECT|REPLACE] forcing ROW SHOW VARIABLES LIKE 'binlog_format'; Variable_name Value binlog_format ROW diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 124ed6e051d..fc04f5436f3 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -6372,6 +6372,24 @@ int THD::decide_logging_format(TABLE_LIST *tables) } set_current_stmt_binlog_format_row(); } + + /* If user has requested binlog_format STMT OR MIXED + in CREATE TABLE [SELECT|REPLACE] we will fall back + to ROW. + + Note that we can't use local binlog_format variable + here because wsrep_binlog_format sets it to ROW. + */ + if (wsrep_ctas && variables.binlog_format != BINLOG_FORMAT_ROW) + { + push_warning_printf(this, Sql_condition::WARN_LEVEL_WARN, + ER_UNKNOWN_ERROR, + "Galera does not support binlog_format = %s " + "in CREATE TABLE [SELECT|REPLACE] forcing ROW", + binlog_format == BINLOG_FORMAT_STMT ? + "STMT" : "MIXED"); + set_current_stmt_binlog_format_row(); + } #endif /* WITH_WSREP */ if (WSREP_EMULATE_BINLOG_NNULL(this) || diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 08229b21839..d249cb205f4 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -7858,7 +7858,10 @@ set_max_autoinc: if (wsrep_append_keys(m_user_thd, WSREP_SERVICE_KEY_EXCLUSIVE, record, NULL)) { - DBUG_PRINT("wsrep", ("row key failed")); + WSREP_DEBUG("::write_rows::wsrep_append_keys failed THD %ld for %s.%s", + thd_get_thread_id(m_user_thd), + table->s->db.str, + table->s->table_name.str); error_result = HA_ERR_INTERNAL_ERROR; goto func_exit; } @@ -8558,16 +8561,20 @@ func_exit: #ifdef WITH_WSREP if (error == DB_SUCCESS && trx->is_wsrep() && wsrep_thd_is_local(m_user_thd) - && !wsrep_thd_ignore_table(m_user_thd)) { - DBUG_PRINT("wsrep", ("update row key")); + && !wsrep_thd_ignore_table(m_user_thd) + && (thd_sql_command(m_user_thd) != SQLCOM_CREATE_TABLE) + && (thd_sql_command(m_user_thd) != SQLCOM_LOAD || + thd_binlog_format(m_user_thd) == BINLOG_FORMAT_ROW)) { if (wsrep_append_keys(m_user_thd, wsrep_protocol_version >= 4 ? WSREP_SERVICE_KEY_UPDATE : WSREP_SERVICE_KEY_EXCLUSIVE, - old_row, new_row)){ - WSREP_DEBUG("WSREP: UPDATE_ROW_KEY FAILED"); - DBUG_PRINT("wsrep", ("row key failed")); + old_row, new_row)) { + WSREP_DEBUG("::update_rows::wsrep_append_keys failed THD %ld for %s.%s", + thd_get_thread_id(m_user_thd), + table->s->db.str, + table->s->table_name.str); DBUG_RETURN(HA_ERR_INTERNAL_ERROR); } } @@ -8620,7 +8627,10 @@ ha_innobase::delete_row( if (wsrep_append_keys(m_user_thd, WSREP_SERVICE_KEY_EXCLUSIVE, record, NULL)) { - DBUG_PRINT("wsrep", ("delete fail")); + WSREP_DEBUG("::delete_rows::wsrep_append_keys failed THD %ld for %s.%s", + thd_get_thread_id(m_user_thd), + table->s->db.str, + table->s->table_name.str); DBUG_RETURN(HA_ERR_INTERNAL_ERROR); } } From 2c5d8376cdfd25d7510c85b3896b506715f96590 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Wed, 7 Aug 2024 16:40:35 +0200 Subject: [PATCH 24/27] MDEV-30686: Endless loop when trying to establish connection With wsrep_sst_rsync, node goes into endless loop when trying to establish connection to donor for IST/SST if the database is bind on specific IP address, not the "*". This commit fixes this problem. Separate tests are not required - the problem can occur in normal configurations on a number of systems when selecting a bing address other than "*", especially on FreeBSD and with the IPv6 addresses. --- scripts/wsrep_sst_rsync.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index e386930c5b7..b05f4bc2efd 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -100,10 +100,9 @@ check_pid_and_port() local busy=0 if [ $lsof_available -ne 0 ]; then - port_info=$(lsof -Pnl -i ":$port" 2>/dev/null | \ - grep -F '(LISTEN)') + port_info=$(lsof -Pnl -i ":$port" 2>/dev/null | grep -F '(LISTEN)') echo "$port_info" | \ - grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port[[:space:]]" && busy=1 + grep -q -E "[[:space:]]\\[?(\\*|[[:xdigit:]]*(:[[:xdigit:]]*)+)(\\](%[^:]+)?)?:$port[[:space:]]" && busy=1 else local filter='([^[:space:]]+[[:space:]]+){4}[^[:space:]]+' if [ $sockstat_available -ne 0 ]; then @@ -122,7 +121,7 @@ check_pid_and_port() grep -F 'users:(' | grep -o -E "$filter") fi echo "$port_info" | \ - grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port\$" && busy=1 + grep -q -E "[[:space:]]\\[?(\\*|[[:xdigit:]]*(:[[:xdigit:]]*)+)(\\](%[^:]+)?)?:$port\$" && busy=1 fi if [ $busy -eq 0 ]; then From b304ec30308a86d87f29e509b988d3120b940f58 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 13 Aug 2024 15:22:09 +0530 Subject: [PATCH 25/27] MDEV-14231 MATCH() AGAINST( IN BOOLEAN MODE), results mismatch - Added plugin_debug.test, multiple_index.test to innodb_fts suite from mysql-5.7. - commit c5b28e55f6ff2a77bf67a2052cc4f4ddd73bc151 removes the warning for InnoDB rebuilding table to add FTS_DOC_ID - multiple_index test case has MATCH(a) values are smaller than in MySQL because ROLLBACK updates the stat_n_rows. - st_mysql_ftparser_boolean_info structure conveys boolean metadata to mysql search engine for every word in the query. This structure misses the position value to store the correct offset of every word. So phrase search queries in plugin_debug test case with boolean mode for simple parser throws wrong result. --- .../suite/innodb_fts/r/multiple_index.result | 210 ++++++++++++ .../suite/innodb_fts/r/plugin_debug.result | 318 ++++++++++++++++++ .../suite/innodb_fts/t/multiple_index.test | 169 ++++++++++ .../suite/innodb_fts/t/plugin_debug.test | 308 +++++++++++++++++ 4 files changed, 1005 insertions(+) create mode 100644 mysql-test/suite/innodb_fts/r/multiple_index.result create mode 100644 mysql-test/suite/innodb_fts/r/plugin_debug.result create mode 100644 mysql-test/suite/innodb_fts/t/multiple_index.test create mode 100644 mysql-test/suite/innodb_fts/t/plugin_debug.test diff --git a/mysql-test/suite/innodb_fts/r/multiple_index.result b/mysql-test/suite/innodb_fts/r/multiple_index.result new file mode 100644 index 00000000000..5608ce4bf4a --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/multiple_index.result @@ -0,0 +1,210 @@ +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB STATS_PERSISTENT=0; +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx_1 (a); +ALTER TABLE t1 ADD FULLTEXT INDEX idx_2 (b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `a` varchar(200) DEFAULT NULL, + `b` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `idx_1` (`a`), + FULLTEXT KEY `idx_2` (`b`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=0 +START TRANSACTION; +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +ROLLBACK; +SELECT * FROM t1 WHERE MATCH (a) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +select * from t1 where MATCH(a) AGAINST("+mysql +Tutorial" IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +select * from t1 where MATCH(b) AGAINST("+Tutorial" IN BOOLEAN MODE); +id a b +3 Optimizing MySQL In this tutorial we will show ... +select * from t1 where MATCH(b) AGAINST("+stands +(DataBase)" IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +select * from t1 where MATCH(b) AGAINST("+DataBase -(comparison)" IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +select *, MATCH(a) AGAINST("Optimizing MySQL" IN BOOLEAN MODE) as x from t1; +id a b x +1 MySQL Tutorial DBMS stands for DataBase ... 0.000000001885928302414186 +2 How To Use MySQL Well After you went through a ... 0.000000001885928302414186 +3 Optimizing MySQL In this tutorial we will show ... 0.22764469683170319 +select *, MATCH(b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1; +id a b x +1 MySQL Tutorial DBMS stands for DataBase ... 0 +2 How To Use MySQL Well After you went through a ... 0 +3 Optimizing MySQL In this tutorial we will show ... 0 +select * from t1 where MATCH a AGAINST ("+Optimiz* +Optimiz*" IN BOOLEAN MODE); +id a b +3 Optimizing MySQL In this tutorial we will show ... +select * from t1 where MATCH b AGAINST ('"DBMS stands"' IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +select * from t1 where MATCH b AGAINST ('"DBMS STANDS"' IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +select * from t1 where MATCH(b) AGAINST ("DataBase" WITH QUERY EXPANSION); +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +select * from t1 where MATCH(a) AGAINST ("Security" WITH QUERY EXPANSION); +id a b +ALTER TABLE t1 DROP INDEX idx_1; +ALTER TABLE t1 DROP INDEX idx_2; +ALTER TABLE t1 ADD FULLTEXT INDEX idx_1 (a); +ALTER TABLE t1 ADD FULLTEXT INDEX idx_2 (b); +SELECT * FROM t1 WHERE MATCH (a) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +select * from t1 where MATCH(a) AGAINST("+mysql +Tutorial" IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +select * from t1 where MATCH(b) AGAINST("+Tutorial" IN BOOLEAN MODE); +id a b +3 Optimizing MySQL In this tutorial we will show ... +select * from t1 where MATCH(b) AGAINST("+stands +(DataBase)" IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +select * from t1 where MATCH(b) AGAINST("+DataBase -(comparison)" IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +select *, MATCH(a) AGAINST("Optimizing MySQL" IN BOOLEAN MODE) as x from t1; +id a b x +1 MySQL Tutorial DBMS stands for DataBase ... 0.000000001885928302414186 +2 How To Use MySQL Well After you went through a ... 0.000000001885928302414186 +3 Optimizing MySQL In this tutorial we will show ... 0.22764469683170319 +select *, MATCH(b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1; +id a b x +1 MySQL Tutorial DBMS stands for DataBase ... 0 +2 How To Use MySQL Well After you went through a ... 0 +3 Optimizing MySQL In this tutorial we will show ... 0 +select * from t1 where MATCH a AGAINST ("+Optimiz* +Optimiz*" IN BOOLEAN MODE); +id a b +3 Optimizing MySQL In this tutorial we will show ... +select * from t1 where MATCH b AGAINST ('"DBMS stands"' IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +select * from t1 where MATCH b AGAINST ('"DBMS STANDS"' IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +select * from t1 where MATCH(b) AGAINST ("DataBase" WITH QUERY EXPANSION); +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +select * from t1 where MATCH(a) AGAINST ("Security" WITH QUERY EXPANSION); +id a b +INSERT INTO t1 (a,b) VALUES ('test query expansion','for database ...'); +INSERT INTO t1 (a,b) VALUES +('test proximity search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO t1 (a,b) VALUES +('test proximity fts search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO t1 (a,b) VALUES +('test more of proximity for fts search, test, more proximity and phrase', +'search, with proximity innodb'); +SELECT * FROM t1 +WHERE MATCH (a) +AGAINST ('"proximity search"@3' IN BOOLEAN MODE); +id a b +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test proximity fts search, test, proximity and phrase search, with proximity innodb +SELECT * FROM t1 +WHERE MATCH (a) +AGAINST ('"proximity search"@2' IN BOOLEAN MODE); +id a b +8 test proximity search, test, proximity and phrase search, with proximity innodb +SELECT * FROM t1 +WHERE MATCH (b) +AGAINST ('"proximity innodb"@4' IN BOOLEAN MODE); +id a b +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test proximity fts search, test, proximity and phrase search, with proximity innodb +10 test more of proximity for fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM t1 +WHERE MATCH (a) +AGAINST ('"test proximity"@3' IN BOOLEAN MODE); +id a b +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test proximity fts search, test, proximity and phrase search, with proximity innodb +10 test more of proximity for fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM t1 +WHERE MATCH (a) +AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); +id a b +10 test more of proximity for fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM t1 +WHERE MATCH (a) +AGAINST ('"more test proximity"@2' IN BOOLEAN MODE); +id a b +SELECT * FROM t1 +WHERE MATCH (a) +AGAINST ('"more fts proximity"@02' IN BOOLEAN MODE); +id a b +SELECT * FROM t1 WHERE CONCAT(t1.a,t1.b) IN ( +SELECT CONCAT(a,b) FROM t1 AS t2 WHERE +MATCH (t2.a) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) +) OR t1.id = 3 ; +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t1 WHERE CONCAT(t1.a,t1.b) IN ( +SELECT CONCAT(a,b) FROM t1 AS t2 +WHERE MATCH (t2.a) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) +AND t2.id != 3) ; +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +SELECT * FROM t1 WHERE id IN (SELECT MIN(id) FROM t1 WHERE +MATCH (b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)) OR id = 3 ; +id a b +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t1 WHERE id NOT IN (SELECT MIN(id) FROM t1 +WHERE MATCH (b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)) ; +id a b +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +7 test query expansion for database ... +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test proximity fts search, test, proximity and phrase search, with proximity innodb +10 test more of proximity for fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM t1 WHERE EXISTS (SELECT t2.id FROM t1 AS t2 WHERE +MATCH (t2.b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) +AND t1.id = t2.id) ; +id a b +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t1 WHERE NOT EXISTS (SELECT t2.id FROM t1 AS t2 WHERE +MATCH (t2.a) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) +AND t1.id = t2.id) ; +id a b +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +7 test query expansion for database ... +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test proximity fts search, test, proximity and phrase search, with proximity innodb +10 test more of proximity for fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM t1 WHERE t1.id = (SELECT MAX(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.a) AGAINST ('"proximity search"@3' IN BOOLEAN MODE)); +id a b +9 test proximity fts search, test, proximity and phrase search, with proximity innodb +SELECT * FROM t1 WHERE t1.id > (SELECT MIN(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.b) AGAINST ('"proximity innodb"@3' IN BOOLEAN MODE)); +id a b +9 test proximity fts search, test, proximity and phrase search, with proximity innodb +10 test more of proximity for fts search, test, more proximity and phrase search, with proximity innodb +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/r/plugin_debug.result b/mysql-test/suite/innodb_fts/r/plugin_debug.result new file mode 100644 index 00000000000..6f12e2b0809 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/plugin_debug.result @@ -0,0 +1,318 @@ +INSTALL PLUGIN simple_parser SONAME 'mypluglib'; +# Test Part 2: Create Index Test(CREATE TABLE WITH FULLTEXT INDEX) +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title, body) WITH PARSER simple_parser +) ENGINE=InnoDB; +INSERT INTO articles (title, body) VALUES +('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','How to use full-text search engine'), +('Go MySQL Tricks','How to use full text search engine'); +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('mysql'); +id title body +1 MySQL Tutorial DBMS stands for MySQL DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks How to use full-text search engine +5 Go MySQL Tricks How to use full text search engine +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('will go'); +id title body +# Test plugin parser tokenizer difference +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('full-text'); +id title body +4 1001 MySQL Tricks How to use full-text search engine +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('full text'); +id title body +5 Go MySQL Tricks How to use full text search engine +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE); +id title body +DROP TABLE articles; +# Test Part 3: Row Merge Create Index Test(ALTER TABLE ADD FULLTEXT INDEX) +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT +) ENGINE=InnoDB; +INSERT INTO articles (title, body) VALUES +('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','How to use full-text search engine'), +('Go MySQL Tricks','How to use full text search engine'); +ALTER TABLE articles ADD FULLTEXT INDEX (title, body) WITH PARSER simple_parser; +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('mysql'); +id title body +1 MySQL Tutorial DBMS stands for MySQL DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks How to use full-text search engine +5 Go MySQL Tricks How to use full text search engine +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('will go'); +id title body +# Test plugin parser tokenizer difference +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('full-text'); +id title body +4 1001 MySQL Tricks How to use full-text search engine +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('full text'); +id title body +5 Go MySQL Tricks How to use full text search engine +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('full-text' WITH QUERY EXPANSION); +id title body +4 1001 MySQL Tricks How to use full-text search engine +5 Go MySQL Tricks How to use full text search engine +2 How To Use MySQL Well After you went through a ... +1 MySQL Tutorial DBMS stands for MySQL DataBase ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('full text' WITH QUERY EXPANSION); +id title body +5 Go MySQL Tricks How to use full text search engine +4 1001 MySQL Tricks How to use full-text search engine +2 How To Use MySQL Well After you went through a ... +1 MySQL Tutorial DBMS stands for MySQL DataBase ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE); +id title body +DROP TABLE articles; +# Test Part 3 END +SET SESSION debug="+d,fts_instrument_use_default_parser"; +# Test Part 4: Create Index Test with Default/Internal Parser +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title, body) WITH PARSER simple_parser +) ENGINE=InnoDB; +INSERT INTO articles (title, body) VALUES +('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','How to use full-text search engine'), +('Go MySQL Tricks','How to use full text search engine'); +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('mysql'); +id title body +1 MySQL Tutorial DBMS stands for MySQL DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks How to use full-text search engine +5 Go MySQL Tricks How to use full text search engine +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('will go'); +id title body +# Test plugin parser tokenizer difference +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('full-text'); +id title body +4 1001 MySQL Tricks How to use full-text search engine +5 Go MySQL Tricks How to use full text search engine +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('full text'); +id title body +4 1001 MySQL Tricks How to use full-text search engine +5 Go MySQL Tricks How to use full text search engine +# simple parser st_mysql_ftparser_boolean_info doesn't +# store position of every word in boolean metadata. +# This leads to empty result +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE); +id title body +DROP TABLE articles; +# Test Part 5: Row Merge Create Index Test with Default/Internal Parser +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT +) ENGINE=InnoDB; +INSERT INTO articles (title, body) VALUES +('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','How to use full-text search engine'), +('Go MySQL Tricks','How to use full text search engine'); +ALTER TABLE articles ADD FULLTEXT INDEX (title, body) WITH PARSER simple_parser; +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('mysql'); +id title body +1 MySQL Tutorial DBMS stands for MySQL DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks How to use full-text search engine +5 Go MySQL Tricks How to use full text search engine +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('will go'); +id title body +# Test plugin parser tokenizer difference +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('full-text'); +id title body +4 1001 MySQL Tricks How to use full-text search engine +5 Go MySQL Tricks How to use full text search engine +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('full text'); +id title body +4 1001 MySQL Tricks How to use full-text search engine +5 Go MySQL Tricks How to use full text search engine +# simple parser st_mysql_ftparser_boolean_info doesn't +# store position of every word in boolean metadata. +# This leads to empty result +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE); +id title body +DROP TABLE articles; +# Test Part 6: Test Query Parser with Default/Internal Parser +SET GLOBAL innodb_ft_enable_diag_print = 1; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title, body) WITH PARSER simple_parser +) ENGINE=InnoDB; +INSERT INTO articles (title, body) VALUES +('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), +('MySQL Tutorial','DBMS stands for MySQL good one DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','How to use full-text search engine'); +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('+mysql -database' IN BOOLEAN MODE); +id title body +3 How To Use MySQL Well After you went through a ... +4 Optimizing MySQL In this tutorial we will show ... +5 1001 MySQL Tricks How to use full-text search engine +SELECT * FROM articles WHERE +MATCH(title, body) AGAINST('>mysql (SELECT MIN(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.b) AGAINST ('"proximity innodb"@3' IN BOOLEAN MODE)); + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/plugin_debug.test b/mysql-test/suite/innodb_fts/t/plugin_debug.test new file mode 100644 index 00000000000..4bf6d98d883 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/plugin_debug.test @@ -0,0 +1,308 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_simple_parser.inc + +# Install fts parser plugin +INSTALL PLUGIN simple_parser SONAME 'mypluglib'; + +-- echo # Test Part 2: Create Index Test(CREATE TABLE WITH FULLTEXT INDEX) +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title, body) WITH PARSER simple_parser + ) ENGINE=InnoDB; + +INSERT INTO articles (title, body) VALUES + ('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','How to use full-text search engine'), + ('Go MySQL Tricks','How to use full text search engine'); + +# Simple term search +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('mysql'); + +# Test stopword and word len less than fts_min_token_size +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('will go'); + +-- echo # Test plugin parser tokenizer difference +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('full-text'); + +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('full text'); + +# No result here, we get '"mysql' 'database"' by simple parser +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE); + +DROP TABLE articles; + +-- echo # Test Part 3: Row Merge Create Index Test(ALTER TABLE ADD FULLTEXT INDEX) +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT + ) ENGINE=InnoDB; + +INSERT INTO articles (title, body) VALUES + ('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','How to use full-text search engine'), + ('Go MySQL Tricks','How to use full text search engine'); + +# Create fulltext index +ALTER TABLE articles ADD FULLTEXT INDEX (title, body) WITH PARSER simple_parser; + +# Simple term search +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('mysql'); + +# Test stopword and word len less than fts_min_token_size +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('will go'); + +-- echo # Test plugin parser tokenizer difference +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('full-text'); + +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('full text'); + +# Test query expansion +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('full-text' WITH QUERY EXPANSION); + +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('full text' WITH QUERY EXPANSION); + +# No result here, we get '"mysql' 'database"' by simple parser +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE); + +DROP TABLE articles; +-- echo # Test Part 3 END + +# Use default parser +SET SESSION debug="+d,fts_instrument_use_default_parser"; + +-- echo # Test Part 4: Create Index Test with Default/Internal Parser +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title, body) WITH PARSER simple_parser + ) ENGINE=InnoDB; + +INSERT INTO articles (title, body) VALUES + ('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','How to use full-text search engine'), + ('Go MySQL Tricks','How to use full text search engine'); + +# Simple term search +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('mysql'); + +# Test stopword and word len less than fts_min_token_size +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('will go'); + +-- echo # Test plugin parser tokenizer difference +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('full-text'); + +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('full text'); + +# Phrase search +--echo # simple parser st_mysql_ftparser_boolean_info doesn't +--echo # store position of every word in boolean metadata. +--echo # This leads to empty result +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE); + +DROP TABLE articles; + +# Disable query parse using plugin parser +-- echo # Test Part 5: Row Merge Create Index Test with Default/Internal Parser +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT + ) ENGINE=InnoDB; + +INSERT INTO articles (title, body) VALUES + ('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','How to use full-text search engine'), + ('Go MySQL Tricks','How to use full text search engine'); + +# Create fulltext index +ALTER TABLE articles ADD FULLTEXT INDEX (title, body) WITH PARSER simple_parser; + +# Simple term search +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('mysql'); + +# Test stopword and word len less than fts_min_token_size +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('will go'); + +-- echo # Test plugin parser tokenizer difference +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('full-text'); + +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('full text'); + +# Phrase search +--echo # simple parser st_mysql_ftparser_boolean_info doesn't +--echo # store position of every word in boolean metadata. +--echo # This leads to empty result +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('"mysql database"' IN BOOLEAN MODE); + +DROP TABLE articles; + +-- echo # Test Part 6: Test Query Parser with Default/Internal Parser +let $innodb_ft_enable_diag_print_orig = `SELECT @@innodb_ft_enable_diag_print`; +# Enable diag print to print query parse tree +SET GLOBAL innodb_ft_enable_diag_print = 1; + +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title, body) WITH PARSER simple_parser + ) ENGINE=InnoDB; + +INSERT INTO articles (title, body) VALUES + ('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), + ('MySQL Tutorial','DBMS stands for MySQL good one DataBase ...'), + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','How to use full-text search engine'); + +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('+mysql -database' IN BOOLEAN MODE); + +SELECT * FROM articles WHERE + MATCH(title, body) AGAINST('>mysql Date: Wed, 14 Aug 2024 07:54:15 +0300 Subject: [PATCH 26/27] MDEV-34678 pthread_mutex_init() without pthread_mutex_destroy() When SUX_LOCK_GENERIC is defined, the srw_mutex, srw_lock, sux_lock are implemented based on pthread_mutex_t and pthread_cond_t. This is the only option for systems that lack a futex-like system call. In the SUX_LOCK_GENERIC mode, if pthread_mutex_init() is allocating some resources that need to be freed by pthread_mutex_destroy(), a memory leak could occur when we are repeatedly invoking pthread_mutex_init() without a pthread_mutex_destroy() in between. pthread_mutex_wrapper::initialized: A debug field to track whether pthread_mutex_init() has been invoked. This also helps find bugs like the one that was fixed by commit 1c8af2ae53a3a48d64b4167d21b20ff5e1caef36 (MDEV-34422); one simply needs to add -DSUX_LOCK_GENERIC to the CMAKE_CXX_FLAGS to catch that particular bug on the initial server bootstrap. buf_block_init(), buf_page_init_for_read(): Invoke block_lock::init() because buf_page_t::init() will no longer do that. buf_page_t::init(): Instead of invoking lock.init(), assert that it has already been invoked (the lock is vacant). add_fts_index(), build_fts_hidden_table(): Explicitly invoke index_lock::init() in order to avoid a pthread_mutex_destroy() invocation on an uninitialized object. srw_lock_debug::destroy(): Invoke readers_lock.destroy(). trx_sys_t::create(): Invoke trx_rseg_t::init() on all rollback segments in order to guarantee a deterministic state for shutdown, even if InnoDB fails to start up. trx_rseg_array_init(), trx_temp_rseg_create(), trx_rseg_create(): Invoke trx_rseg_t::destroy() before trx_rseg_t::init() in order to balance pthread_mutex_init() and pthread_mutex_destroy() calls. --- storage/innobase/buf/buf0buf.cc | 1 + storage/innobase/buf/buf0rea.cc | 1 + storage/innobase/include/buf0buf.h | 2 +- storage/innobase/include/srw_lock.h | 23 ++++++++++++++++++----- storage/innobase/row/row0import.cc | 2 ++ storage/innobase/sync/srw_lock.cc | 1 + storage/innobase/trx/trx0rseg.cc | 2 ++ storage/innobase/trx/trx0sys.cc | 14 +++++++------- 8 files changed, 33 insertions(+), 13 deletions(-) diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 61941592fab..44b093e93ed 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -842,6 +842,7 @@ buf_block_init(buf_block_t* block, byte* frame) MEM_MAKE_DEFINED(&block->modify_clock, sizeof block->modify_clock); ut_ad(!block->modify_clock); MEM_MAKE_DEFINED(&block->page.lock, sizeof block->page.lock); + block->page.lock.init(); block->page.init(buf_page_t::NOT_USED, page_id_t(~0ULL)); #ifdef BTR_CUR_HASH_ADAPT MEM_MAKE_DEFINED(&block->index, sizeof block->index); diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc index 7279497e14c..ee6bffd4031 100644 --- a/storage/innobase/buf/buf0rea.cc +++ b/storage/innobase/buf/buf0rea.cc @@ -212,6 +212,7 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id, page_zip_set_size(&bpage->zip, zip_size); bpage->zip.data = (page_zip_t*) data; + bpage->lock.init(); bpage->init(buf_page_t::READ_FIX, page_id); bpage->lock.x_lock(true); diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index be614ce2fa2..0996046cda0 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -648,10 +648,10 @@ public: void init(uint32_t state, page_id_t id) { ut_ad(state < REMOVE_HASH || state >= UNFIXED); + ut_ad(!lock.is_locked_or_waiting()); id_= id; zip.fix= state; oldest_modification_= 0; - lock.init(); ut_d(in_zip_hash= false); ut_d(in_free_list= false); ut_d(in_LRU_list= false); diff --git a/storage/innobase/include/srw_lock.h b/storage/innobase/include/srw_lock.h index 40bf9f8b0c2..72b78df146c 100644 --- a/storage/innobase/include/srw_lock.h +++ b/storage/innobase/include/srw_lock.h @@ -40,32 +40,45 @@ template class pthread_mutex_wrapper final { pthread_mutex_t lock; +#ifdef UNIV_DEBUG + /** whether the mutex is usable; set by init(); cleared by destroy() */ + bool initialized{false}; +public: + ~pthread_mutex_wrapper() { ut_ad(!initialized); } +#endif public: void init() { + ut_ad(!initialized); + ut_d(initialized= true); if (spinloop) pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST); else pthread_mutex_init(&lock, nullptr); } - void destroy() { pthread_mutex_destroy(&lock); } + void destroy() + { + ut_ad(initialized); ut_d(initialized=false); + pthread_mutex_destroy(&lock); + } # ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP - void wr_lock() { pthread_mutex_lock(&lock); } + void wr_lock() { ut_ad(initialized); pthread_mutex_lock(&lock); } # else private: void wr_wait(); public: inline void wr_lock(); # endif - void wr_unlock() { pthread_mutex_unlock(&lock); } - bool wr_lock_try() { return !pthread_mutex_trylock(&lock); } + void wr_unlock() { ut_ad(initialized); pthread_mutex_unlock(&lock); } + bool wr_lock_try() + { ut_ad(initialized); return !pthread_mutex_trylock(&lock); } }; # ifndef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP template<> void pthread_mutex_wrapper::wr_wait(); template<> inline void pthread_mutex_wrapper::wr_lock() -{ pthread_mutex_lock(&lock); } +{ ut_ad(initialized); pthread_mutex_lock(&lock); } template<> inline void pthread_mutex_wrapper::wr_lock() { if (!wr_lock_try()) wr_wait(); } diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index eecfac18017..b130675da15 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -3212,6 +3212,7 @@ static void add_fts_index(dict_table_t *table) { dict_index_t *fts_index= dict_mem_index_create( table, FTS_DOC_ID_INDEX_NAME, DICT_UNIQUE, 2); + fts_index->lock.SRW_LOCK_INIT(index_tree_rw_lock_key); fts_index->page= FIL_NULL; fts_index->cached= 1; fts_index->n_uniq= 1; @@ -3293,6 +3294,7 @@ static dict_table_t *build_fts_hidden_table( new_table, old_index->name, old_index->type, old_index->n_fields + is_clustered); + new_index->lock.SRW_LOCK_INIT(index_tree_rw_lock_key); new_index->id= old_index->id; new_index->n_uniq= old_index->n_uniq; new_index->type= old_index->type; diff --git a/storage/innobase/sync/srw_lock.cc b/storage/innobase/sync/srw_lock.cc index c1e32f26d51..eac3db19152 100644 --- a/storage/innobase/sync/srw_lock.cc +++ b/storage/innobase/sync/srw_lock.cc @@ -661,6 +661,7 @@ void srw_lock_debug::destroy() ut_ad(r->empty()); delete r; } + readers_lock.destroy(); srw_lock::destroy(); } diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc index 86f5b064b7f..e3173e1eff2 100644 --- a/storage/innobase/trx/trx0rseg.cc +++ b/storage/innobase/trx/trx0rseg.cc @@ -631,6 +631,7 @@ dberr_t trx_rseg_array_init() sys, rseg_id); if (page_no != FIL_NULL) { trx_rseg_t& rseg = trx_sys.rseg_array[rseg_id]; + rseg.destroy(); rseg.init(fil_space_get( trx_sysf_rseg_get_space( sys, rseg_id)), @@ -715,6 +716,7 @@ dberr_t trx_temp_rseg_create(mtr_t *mtr) mtr->commit(); return err; } + trx_sys.temp_rsegs[i].destroy(); trx_sys.temp_rsegs[i].init(fil_system.temp_space, rblock->page.id().page_no()); mtr->commit(); diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc index 33c408707cc..76f3ba79baf 100644 --- a/storage/innobase/trx/trx0sys.cc +++ b/storage/innobase/trx/trx0sys.cc @@ -152,6 +152,10 @@ void trx_sys_t::create() m_initialised= true; trx_list.create(); rw_trx_hash.init(); + for (auto &rseg : temp_rsegs) + rseg.init(nullptr, FIL_NULL); + for (auto &rseg : rseg_array) + rseg.init(nullptr, FIL_NULL); } size_t trx_sys_t::history_size() @@ -230,6 +234,7 @@ static trx_rseg_t *trx_rseg_create(ulint space_id) ? nullptr : trx_rseg_header_create(space, rseg_id, 0, &mtr, &err)) { rseg= &trx_sys.rseg_array[rseg_id]; + rseg->destroy(); rseg->init(space, rblock->page.id().page_no()); ut_ad(rseg->is_persistent()); mtr.write<4,mtr_t::MAYBE_NOP> @@ -329,13 +334,8 @@ trx_sys_t::close() rw_trx_hash.destroy(); /* There can't be any active transactions. */ - - for (ulint i = 0; i < array_elements(temp_rsegs); ++i) { - temp_rsegs[i].destroy(); - } - for (ulint i = 0; i < array_elements(rseg_array); ++i) { - rseg_array[i].destroy(); - } + for (auto& rseg : temp_rsegs) rseg.destroy(); + for (auto& rseg : rseg_array) rseg.destroy(); ut_a(trx_list.empty()); trx_list.close(); From ecd910ae3a2c0b29d49602aa71f400be3794184f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 14 Aug 2024 08:43:08 +0300 Subject: [PATCH 27/27] MDEV-34755 g++- -Wstringop-truncation due to safe_strcpy() The #pragma that was removed in commit e255837eaf90e72eaf122d88b30011db17f7ecf2 (MDEV-34266) turns out to be necessary for silencing all cases of -Wstringop-truncation. --- include/m_string.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/m_string.h b/include/m_string.h index 3da252b0912..ddfaf84b2d0 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -255,9 +255,20 @@ static inline void safe_strcpy(char *dst, size_t dst_size, const char *src) * * 2) IF there is no 0 byte in the first dst_size bytes of src, strncpy will * copy dst_size bytes, and the final byte won't be 0. + * + * In GCC 8+, the `-Wstringop-truncation` warning may object to strncpy() + * being used in this way, so we need to disable this warning for this + * single statement. */ +#if defined __GNUC__ && __GNUC__ >= 8 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-truncation" +#endif strncpy(dst, src, dst_size); +#if defined __GNUC__ && __GNUC__ >= 8 +#pragma GCC diagnostic pop +#endif dst[dst_size - 1]= 0; }