From 8b0fb154f767daf0870d751957a402fe12622848 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 10 Jan 2024 00:32:50 +0100 Subject: [PATCH 01/61] MDEV-33093 plugin/disks/information_schema_disks.cc doesn't compile on Solaris second part of the fix by Rainer Orth --- config.h.cmake | 1 + plugin/disks/CMakeLists.txt | 2 ++ plugin/disks/information_schema_disks.cc | 9 ++++----- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/config.h.cmake b/config.h.cmake index da2fc539bab..56c2bc3bcdc 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -72,6 +72,7 @@ #cmakedefine HAVE_SYS_IPC_H 1 #cmakedefine HAVE_SYS_MALLOC_H 1 #cmakedefine HAVE_SYS_MMAN_H 1 +#cmakedefine HAVE_SYS_MNTENT_H 1 #cmakedefine HAVE_SYS_NDIR_H 1 #cmakedefine HAVE_SYS_PTE_H 1 #cmakedefine HAVE_SYS_PTEM_H 1 diff --git a/plugin/disks/CMakeLists.txt b/plugin/disks/CMakeLists.txt index e4cf0dc1de3..408a4324d1b 100644 --- a/plugin/disks/CMakeLists.txt +++ b/plugin/disks/CMakeLists.txt @@ -5,6 +5,8 @@ CHECK_SYMBOL_EXISTS (getmntent "sys/mnttab.h" HAVE_GETMNTENT_IN_SYS_MNTAB) CHECK_SYMBOL_EXISTS (setmntent "mntent.h" HAVE_SETMNTENT) CHECK_SYMBOL_EXISTS (getmntinfo "sys/types.h;sys/mount.h" HAVE_GETMNTINFO) +CHECK_INCLUDE_FILES (sys/mntent.h HAVE_SYS_MNTENT_H) + IF (HAVE_GETMNTINFO) CHECK_CXX_SOURCE_COMPILES(" #include diff --git a/plugin/disks/information_schema_disks.cc b/plugin/disks/information_schema_disks.cc index 1be8fce37fa..cbc749ff603 100644 --- a/plugin/disks/information_schema_disks.cc +++ b/plugin/disks/information_schema_disks.cc @@ -19,19 +19,18 @@ #include #if defined(HAVE_GETMNTENT) #include -#elif defined(HAVE_SYS_MNTENT) -#include -#elif !defined(HAVE_GETMNTINFO_TAKES_statvfs) +#elif defined(HAVE_GETMNTINFO) && !defined(HAVE_GETMNTINFO_TAKES_statvfs) /* getmntinfo (the not NetBSD variants) */ #include -#if defined(HAVE_SYS_UCRED) #include -#endif #include #endif #if defined(HAVE_GETMNTENT_IN_SYS_MNTAB) #include #define HAVE_GETMNTENT +#if defined(HAVE_SYS_MNTENT_H) +#include +#endif #endif #include #include From d277a63c749bd49c9025da4efdd3008d22180dc0 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Tue, 28 Nov 2023 14:56:23 +1100 Subject: [PATCH 02/61] MDEV-31101 Re-enable spider/bugfix.mdev_29904 The spider init bug fixes remove any race conditions during spider init. Also remove the add_suppressions in spider/bugfix.mdev_27575 which is a similar issue. --- storage/spider/mysql-test/spider/bugfix/disabled.def | 1 - storage/spider/mysql-test/spider/bugfix/r/mdev_27575.result | 2 -- storage/spider/mysql-test/spider/bugfix/t/mdev_27575.test | 4 ---- 3 files changed, 7 deletions(-) diff --git a/storage/spider/mysql-test/spider/bugfix/disabled.def b/storage/spider/mysql-test/spider/bugfix/disabled.def index 99443c854e5..e19ea07b76b 100644 --- a/storage/spider/mysql-test/spider/bugfix/disabled.def +++ b/storage/spider/mysql-test/spider/bugfix/disabled.def @@ -1,2 +1 @@ wait_timeout : MDEV-26045 -mdev_29904 : MDEV-31101 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_27575.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_27575.result index 4899f191ada..91af2c8f1e0 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_27575.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_27575.result @@ -4,8 +4,6 @@ for master_1 for child2 for child3 -call mtr.add_suppression("\\[ERROR\\] Table 'mysql.spider_table_sts' doesn't exist"); -call mtr.add_suppression("\\[ERROR\\] Server shutdown in progress"); SET GLOBAL default_tmp_storage_engine=spider; # restart SET GLOBAL default_storage_engine=Spider; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27575.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_27575.test index 6f291c6f690..79a08489bae 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_27575.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27575.test @@ -7,10 +7,6 @@ --enable_result_log --enable_query_log -# These suppressions are a workaround and should not be needed once -# MDEV-29870 is done. -call mtr.add_suppression("\\[ERROR\\] Table 'mysql.spider_table_sts' doesn't exist"); -call mtr.add_suppression("\\[ERROR\\] Server shutdown in progress"); SET GLOBAL default_tmp_storage_engine=spider; --source include/restart_mysqld.inc From 88c46aba753c0094ea16dc707bb76cc5254806c8 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Thu, 11 Jan 2024 12:32:26 +1100 Subject: [PATCH 03/61] MDEV-32997 Disable spider/bugfix.mdev_27575 until we find a solution The failure described in MDEV-32997 is happening a bit too often and polluting the CI results. --- storage/spider/mysql-test/spider/bugfix/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/spider/mysql-test/spider/bugfix/disabled.def b/storage/spider/mysql-test/spider/bugfix/disabled.def index e19ea07b76b..559feeff4bd 100644 --- a/storage/spider/mysql-test/spider/bugfix/disabled.def +++ b/storage/spider/mysql-test/spider/bugfix/disabled.def @@ -1 +1,2 @@ wait_timeout : MDEV-26045 +mdev_27575 : MDEV-32997 From f807a9f874a8079d95bc71c9f27216e4d952f157 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 11 Jan 2024 11:21:32 +0100 Subject: [PATCH 04/61] MDEV-31523 Using two temporary tables in OPTIMIZE TABLE lead to crash Fixed typo in mysql_admin_table which cused call of close_unused_temporary_table_instances alwas for the first table instead of the current table. Added ASSERT that close_unused_temporary_table_instances should not remove all instances of user created temporary table. --- mysql-test/main/temp_table.result | 16 ++++++++++++++++ mysql-test/main/temp_table.test | 16 ++++++++++++++++ sql/sql_admin.cc | 2 +- sql/temporary_tables.cc | 5 +++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/temp_table.result b/mysql-test/main/temp_table.result index e5bb0d54306..33ea1700474 100644 --- a/mysql-test/main/temp_table.result +++ b/mysql-test/main/temp_table.result @@ -602,3 +602,19 @@ DROP TEMPORARY TABLE t1; # # End of 10.2 tests # +# +# MDEV-31523: Using two temporary tables in OPTIMIZE TABLE lead to crash +# +CREATE TEMPORARY TABLE t1 (c INT) ENGINE=MyISAM; +CREATE TEMPORARY TABLE t2 (c INT) ENGINE=MyISAM; +optimize TABLE t1,t2; +Table Op Msg_type Msg_text +test.t1 optimize status Table is already up to date +test.t2 optimize status Table is already up to date +SHOW TABLES; +Tables_in_test +# in 11.2 and above here should be listed above used temporary tables +DROP TEMPORARY TABLE t1, t2; +# +# End of 10.4 tests +# diff --git a/mysql-test/main/temp_table.test b/mysql-test/main/temp_table.test index 9e639ffce2c..e1e671f5ae9 100644 --- a/mysql-test/main/temp_table.test +++ b/mysql-test/main/temp_table.test @@ -661,3 +661,19 @@ DROP TEMPORARY TABLE t1; --echo # --echo # End of 10.2 tests --echo # + +--echo # +--echo # MDEV-31523: Using two temporary tables in OPTIMIZE TABLE lead to crash +--echo # + +CREATE TEMPORARY TABLE t1 (c INT) ENGINE=MyISAM; +CREATE TEMPORARY TABLE t2 (c INT) ENGINE=MyISAM; +optimize TABLE t1,t2; +SHOW TABLES; +--echo # in 11.2 and above here should be listed above used temporary tables + +DROP TEMPORARY TABLE t1, t2; + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 66dfc93f45d..09deef9f590 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -776,7 +776,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, if (lock_type == TL_WRITE && table->mdl_request.type > MDL_SHARED_WRITE) { if (table->table->s->tmp_table) - thd->close_unused_temporary_table_instances(tables); + thd->close_unused_temporary_table_instances(table); else { if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED)) diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc index 05e32d78b7f..4ffae3d53bf 100644 --- a/sql/temporary_tables.cc +++ b/sql/temporary_tables.cc @@ -1577,6 +1577,11 @@ void THD::close_unused_temporary_table_instances(const TABLE_LIST *tl) { /* Note: removing current list element doesn't invalidate iterator. */ share->all_tmp_tables.remove(table); + /* + At least one instance should be left (guaratead by calling this + function for table which is opened and the table is under processing) + */ + DBUG_ASSERT(share->all_tmp_tables.front()); free_temporary_table(table); } } From 653cb195d30bca678b5b175157f0f34206c3761d Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Mon, 15 Jan 2024 13:01:22 +0530 Subject: [PATCH 05/61] MDEV-26740 Inplace alter rebuild increases file size PageBulk::init(): Unnecessary reserves the extent before allocating a page for bulk insert. btr_page_alloc() capable of handing the extending of tablespace. --- .../suite/innodb_zip/r/innochecksum_3.result | 2 -- storage/innobase/btr/btr0bulk.cc | 17 ++++------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/mysql-test/suite/innodb_zip/r/innochecksum_3.result b/mysql-test/suite/innodb_zip/r/innochecksum_3.result index 7de90721d64..89830fbbf62 100644 --- a/mysql-test/suite/innodb_zip/r/innochecksum_3.result +++ b/mysql-test/suite/innodb_zip/r/innochecksum_3.result @@ -173,7 +173,6 @@ Filename::tab#.ibd #::# | Index page | index id=#, page level=#, No. of records=#, garbage=#, - #::# | Index page | index id=#, page level=#, No. of records=#, garbage=#, - #::# | Index page | index id=#, page level=#, No. of records=#, garbage=#, - -#::# | Freshly allocated page | - # Variables used by page type dump for ibdata1 Variables (--variable-name=value) @@ -208,7 +207,6 @@ Filename::tab#.ibd #::# | Index page | index id=#, page level=#, No. of records=#, garbage=#, - #::# | Index page | index id=#, page level=#, No. of records=#, garbage=#, - #::# | Index page | index id=#, page level=#, No. of records=#, garbage=#, - -#::# | Freshly allocated page | - [6]: check the valid lower bound values for option # allow-mismatches,page,start-page,end-page [9]: check the both short and long options "page" and "start-page" when diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc index f7afc575ed5..a39a96b4b04 100644 --- a/storage/innobase/btr/btr0bulk.cc +++ b/storage/innobase/btr/btr0bulk.cc @@ -70,24 +70,15 @@ PageBulk::init() alloc_mtr.start(); m_index->set_modified(alloc_mtr); - ulint n_reserved; - bool success; - success = fsp_reserve_free_extents(&n_reserved, - m_index->table->space, - 1, FSP_NORMAL, &alloc_mtr); - if (!success) { - alloc_mtr.commit(); - m_mtr.commit(); - return(DB_OUT_OF_FILE_SPACE); - } - /* Allocate a new page. */ new_block = btr_page_alloc(m_index, 0, FSP_UP, m_level, &alloc_mtr, &m_mtr); - m_index->table->space->release_free_extents(n_reserved); - alloc_mtr.commit(); + if (!new_block) { + m_mtr.commit(); + return DB_OUT_OF_FILE_SPACE; + } new_page = buf_block_get_frame(new_block); new_page_zip = buf_block_get_page_zip(new_block); From 9c059a4f1cbff28634cced9f02da5a0279e6f242 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Wed, 17 Jan 2024 10:33:02 +1100 Subject: [PATCH 06/61] Spider: no need to check for ubsan when running ubsan tests It's ok to run these tests without ubsan too, and we get some tests for free. --- .../mysql-test/spider/bugfix/r/mdev_26541.result | 15 --------------- .../mysql-test/spider/bugfix/t/mdev_26541.test | 6 ++---- .../mysql-test/spider/bugfix/t/mdev_28998.test | 5 +---- .../mysql-test/spider/bugfix/t/mdev_30981.test | 11 ++++------- 4 files changed, 7 insertions(+), 30 deletions(-) diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_26541.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_26541.result index 72921d2e695..35a9d9167a6 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_26541.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_26541.result @@ -2,18 +2,3 @@ # MDEV-26541 Undefined symbol: _ZTI12ha_partition when attempting to use ha_spider.so in UBSAN builds # INSTALL SONAME 'ha_spider.so'; -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; -UNINSTALL SONAME IF EXISTS "ha_spider"; -DROP TABLE IF EXISTS mysql.spider_xa; -DROP TABLE IF EXISTS mysql.spider_xa_member; -DROP TABLE IF EXISTS mysql.spider_xa_failed_log; -DROP TABLE IF EXISTS mysql.spider_tables; -DROP TABLE IF EXISTS mysql.spider_link_mon_servers; -DROP TABLE IF EXISTS mysql.spider_link_failed_log; -DROP TABLE IF EXISTS mysql.spider_table_position_for_recovery; -DROP TABLE IF EXISTS mysql.spider_table_sts; -DROP TABLE IF EXISTS mysql.spider_table_crd; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_26541.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_26541.test index bf6cb255d02..add5f621441 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_26541.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26541.test @@ -2,10 +2,7 @@ --echo # MDEV-26541 Undefined symbol: _ZTI12ha_partition when attempting to use ha_spider.so in UBSAN builds --echo # -if (`select not(count(*)) from information_schema.system_variables where variable_name='have_sanitizer' and global_value like "%UBSAN%"`) -{ ---skip test needs to be run with UBSAN -} +# this test should be checked with ubsan # init spider @@ -20,4 +17,5 @@ while (!$PLUGIN_EXIST) `SELECT COUNT(*) FROM mysql.func WHERE name = '$PLUGIN_NAME'`; } +--disable_query_log --source ../../include/clean_up_spider.inc diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28998.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_28998.test index 66e3a15addb..51d4c5c9660 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_28998.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28998.test @@ -2,10 +2,7 @@ --echo # MDEV-28998 ASAN errors in spider_fields::free_conn_holder or spider_create_group_by_handler --echo # -if (`select not(count(*)) from information_schema.system_variables where variable_name='have_sanitizer' and global_value like "%ASAN%"`) -{ ---skip test needs to be run with ASAN -} +# this test should be checked with ubsan --disable_query_log --disable_result_log diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_30981.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_30981.test index cc24ce82ce4..ca3f000c819 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_30981.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_30981.test @@ -2,21 +2,18 @@ --echo # MDEV-30981 Spider UBSAN: null pointer passed as argument 2, which is declared to never be null in spider_create_trx_alter_table on ALTER --echo # -if (`select not(count(*)) from information_schema.system_variables where variable_name='have_sanitizer' and global_value like "%UBSAN%"`) -{ ---skip test needs to be run with UBSAN -} - +# this test should be checked with ubsan + --disable_query_log --disable_result_log --source ../../t/test_init.inc --enable_result_log --enable_query_log - + CREATE TABLE t (c INT) ENGINE=Spider PARTITION BY LIST (c) (PARTITION p VALUES IN (1,2)); ALTER TABLE t ENGINE=InnoDB; drop table t; - + --disable_query_log --disable_result_log --source ../t/test_deinit.inc From 8e337e016ff882862d4d2f32488b5142370ff8da Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 17 Jan 2024 10:45:05 +0100 Subject: [PATCH 07/61] new WolfSSL v5.6.6-stable --- extra/wolfssl/user_settings.h.in | 5 +++++ extra/wolfssl/wolfssl | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/extra/wolfssl/user_settings.h.in b/extra/wolfssl/user_settings.h.in index 425f6f154b9..baa64fcdfbe 100644 --- a/extra/wolfssl/user_settings.h.in +++ b/extra/wolfssl/user_settings.h.in @@ -28,6 +28,11 @@ #define NO_OLD_TIMEVAL_NAME #define HAVE_SECURE_RENEGOTIATION #define HAVE_EXTENDED_MASTER +/* + Following is workaround about a WolfSSL 5.6.6 bug. + The bug is about undefined sessionCtxSz during compilation. +*/ +#define WOLFSSL_SESSION_ID_CTX /* TLSv1.3 definitions (all needed to build) */ #define WOLFSSL_TLS13 diff --git a/extra/wolfssl/wolfssl b/extra/wolfssl/wolfssl index 3b3c175af0e..66596ad9e1d 160000 --- a/extra/wolfssl/wolfssl +++ b/extra/wolfssl/wolfssl @@ -1 +1 @@ -Subproject commit 3b3c175af0e993ffaae251871421e206cc41963f +Subproject commit 66596ad9e1d7efa8479656872cf09c9c1870a02e From 615f4a8c9e6679322c4b788d8bbc573e53267f05 Mon Sep 17 00:00:00 2001 From: Robin Newhouse Date: Thu, 7 Dec 2023 00:16:28 +0000 Subject: [PATCH 08/61] MDEV-32587 Allow json exponential notation starting with zero Modify the NS_ZERO state in the JSON number parser to allow exponential notation with a zero coefficient (e.g. 0E-4). The NS_ZERO state transition on 'E' was updated to move to the NS_EX state rather than returning a syntax error. Similar change was made for the NS_ZE1 (negative zero) starter state. This allows accepted number grammar to include cases like: - 0E4 - -0E-10 which were previously disallowed. Numeric parsing remains the same for all other states. Test cases are added to func_json.test to validate parsing for various exponential numbers starting with zero coefficients. All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services. --- mysql-test/main/func_json.result | 33 ++++++++++++++++++++++++++++++++ mysql-test/main/func_json.test | 16 ++++++++++++++++ strings/json_lib.c | 6 +++--- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index 4b42c1def16..5d80ad2a7fc 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -1300,5 +1300,38 @@ f foo SET @@COLLATION_CONNECTION= @old_collation_connection; # +# MDEV-32587 JSON_VALID fail to validate integer zero in scientific notation +# +select JSON_VALID(' {"number": 1E-4}'); +JSON_VALID(' {"number": 1E-4}') +1 +select JSON_VALID(' {"number": 0E-4}'); +JSON_VALID(' {"number": 0E-4}') +1 +select JSON_VALID(' {"number": 0.0}'); +JSON_VALID(' {"number": 0.0}') +1 +select JSON_VALID(' {"number": 0.1E-4}'); +JSON_VALID(' {"number": 0.1E-4}') +1 +select JSON_VALID(' {"number": 0e-4}'); +JSON_VALID(' {"number": 0e-4}') +1 +select JSON_VALID(' {"number": -0E-4}'); +JSON_VALID(' {"number": -0E-4}') +1 +select JSON_VALUE(' {"number": 0E-4}', '$.number'); +JSON_VALUE(' {"number": 0E-4}', '$.number') +0E-4 +select JSON_VALID(' {"number": 00E-4}'); +JSON_VALID(' {"number": 00E-4}') +0 +select JSON_VALID(' {"number": 01E-4}'); +JSON_VALID(' {"number": 01E-4}') +0 +select JSON_VALID(' {"number": 0E-4.0}'); +JSON_VALID(' {"number": 0E-4.0}') +0 +# # End of 10.4 tests # diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index eed433aa118..a271dac3dca 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -840,6 +840,22 @@ SELECT JSON_VALUE('["foo"]', '$**[0]') AS f; SET @@COLLATION_CONNECTION= @old_collation_connection; +--echo # +--echo # MDEV-32587 JSON_VALID fail to validate integer zero in scientific notation +--echo # +# Passing +select JSON_VALID(' {"number": 1E-4}'); +select JSON_VALID(' {"number": 0E-4}'); +select JSON_VALID(' {"number": 0.0}'); +select JSON_VALID(' {"number": 0.1E-4}'); +select JSON_VALID(' {"number": 0e-4}'); +select JSON_VALID(' {"number": -0E-4}'); +select JSON_VALUE(' {"number": 0E-4}', '$.number'); +# Failing +select JSON_VALID(' {"number": 00E-4}'); +select JSON_VALID(' {"number": 01E-4}'); +select JSON_VALID(' {"number": 0E-4.0}'); + --echo # --echo # End of 10.4 tests --echo # diff --git a/strings/json_lib.c b/strings/json_lib.c index 781172f0340..3b9b169e2d1 100644 --- a/strings/json_lib.c +++ b/strings/json_lib.c @@ -467,12 +467,12 @@ enum json_num_states { static int json_num_states[NS_NUM_STATES][N_NUM_CLASSES]= { -/* - + 0 1..9 POINT E END_OK ERROR */ +/* - + 0 1..9 POINT E END_OK ERROR */ /*OK*/ { JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_BAD_CHR }, /*GO*/ { NS_GO1, JE_SYN, NS_Z, NS_INT, JE_SYN, JE_SYN, JE_SYN, JE_BAD_CHR }, /*GO1*/ { JE_SYN, JE_SYN, NS_Z1, NS_INT, JE_SYN, JE_SYN, JE_SYN, JE_BAD_CHR }, -/*ZERO*/ { JE_SYN, JE_SYN, JE_SYN, JE_SYN, NS_FRAC, JE_SYN, NS_OK, JE_BAD_CHR }, -/*ZE1*/ { JE_SYN, JE_SYN, JE_SYN, JE_SYN, NS_FRAC, JE_SYN, NS_OK, JE_BAD_CHR }, +/*ZERO*/ { JE_SYN, JE_SYN, JE_SYN, JE_SYN, NS_FRAC, NS_EX, NS_OK, JE_BAD_CHR }, +/*ZE1*/ { JE_SYN, JE_SYN, JE_SYN, JE_SYN, NS_FRAC, NS_EX, NS_OK, JE_BAD_CHR }, /*INT*/ { JE_SYN, JE_SYN, NS_INT, NS_INT, NS_FRAC, NS_EX, NS_OK, JE_BAD_CHR }, /*FRAC*/ { JE_SYN, JE_SYN, NS_FRAC, NS_FRAC,JE_SYN, NS_EX, NS_OK, JE_BAD_CHR }, /*EX*/ { NS_EX, NS_EX, NS_EX1, NS_EX1, JE_SYN, JE_SYN, JE_SYN, JE_BAD_CHR }, From ee1407f74dc063a851e1fe41b980ccc1ce4c01bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 18 Jan 2024 11:00:27 +0200 Subject: [PATCH 09/61] MDEV-32268: GNU libc posix_fallocate() may be extremely slow os_file_set_size(): Let us invoke the Linux system call fallocate(2) directly, because the GNU libc posix_fallocate() implements a fallback that writes to the file 1 byte every 4096 or fewer bytes. In one environment, invoking fallocate() directly would lead to 4 times the file growth rate during ALTER TABLE. Presumably, what happened was that the NFS server used a smaller allocation block size than 4096 bytes and therefore created a heavily fragmented sparse file when posix_fallocate() was used. For example, extending a file by 4 MiB would create 1,024 file fragments. When the file is actually being written to with data, it would be "unsparsed". The built-in EOPNOTSUPP fallback in os_file_set_size() writes a buffer of 1 MiB of NUL bytes. This was always used on musl libc and other Linux implementations of posix_fallocate(). --- storage/innobase/os/os0file.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 71e48da0dec..075f838ebb1 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -4934,8 +4934,18 @@ fallback: return true; } current_size &= ~4095ULL; +# ifdef __linux__ + if (!fallocate(file, 0, current_size, + size - current_size)) { + err = 0; + break; + } + + err = errno; +# else err = posix_fallocate(file, current_size, size - current_size); +# endif } } while (err == EINTR && srv_shutdown_state <= SRV_SHUTDOWN_INITIATED); From 2ef01d003483edd01ff1c524b6e5f52238c7abec Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Sat, 30 Dec 2023 19:42:10 -0500 Subject: [PATCH 10/61] wsrep scripts fixes for working on OpenBSD --- scripts/wsrep_sst_common.sh | 6 +++--- scripts/wsrep_sst_rsync.sh | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 4e177073872..63d2d4ef6d1 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -1166,9 +1166,9 @@ is_local_ip() # the domain name check: if [ "${2:-0}" -eq 0 ]; then # We consider all the names of a given host to be local addresses: - [ "$1" = "$(hostname -s)" -o \ - "$1" = "$(hostname -f)" -o \ - "$1" = "$(hostname -d)" ] && return 0 + [ "$1" = "$(hostname -s 2>/dev/null)" -o \ + "$1" = "$(hostname -f 2>/dev/null)" -o \ + "$1" = "$(hostname -d 2>/dev/null)" ] && return 0 fi # If the address contains anything other than digits # and separators, it is not a local address: diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index ade9bb491e5..3dc5da7a48e 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -475,9 +475,9 @@ EOF # Preparing binlog files for transfer: wsrep_log_info "Preparing binlog files for transfer:" tar_type=0 - if tar --help | grep -qw -F -- '--transform'; then + if tar --help 2>/dev/null | grep -qw -F -- '--transform'; then tar_type=1 - elif tar --version | grep -qw -E '^bsdtar'; then + elif tar --version 2>/dev/null | grep -qw -E '^bsdtar'; then tar_type=2 fi if [ $tar_type -eq 2 ]; then @@ -980,7 +980,7 @@ EOF fi # Extracting binlog files: wsrep_log_info "Extracting binlog files:" - if tar --version | grep -qw -E '^bsdtar'; then + if tar --version 2>/dev/null | grep -qw -E '^bsdtar'; then tar -tf "$BINLOG_TAR_FILE" > "$tmpfile" && \ tar -xvf "$BINLOG_TAR_FILE" > /dev/null || RC=$? else From e8041c70656d2ebfcee8cf7343f944148b17946b Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 18 Jan 2024 20:59:00 -0800 Subject: [PATCH 11/61] MDEV-33270 Failure to call SP invoking another SP with parameter requiring type conversion This patch corrects the fix for MDEV-32569. The latter has not taken into account the fact not each statement uses the SELECT_LEX structure. In particular CALL statements do not use such structure. However the parameter passed to the stored procedure used in such a statement may require an invocation of Type_std_attributes::agg_item_set_converter(). Approved by Oleksandr Byelkin --- mysql-test/main/sp.result | 15 +++++++++++++++ mysql-test/main/sp.test | 20 ++++++++++++++++++++ sql/item.cc | 5 ++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/sp.result b/mysql-test/main/sp.result index 567597383bb..2f733107e8a 100644 --- a/mysql-test/main/sp.result +++ b/mysql-test/main/sp.result @@ -8960,5 +8960,20 @@ DROP FUNCTION f1; DROP FUNCTION f2; DROP FUNCTION f3; DROP VIEW v1; +# +# MDEV-33270: Call of SP invoking another SP with a parameter +# requiring type conversion +# +SET NAMES latin1; +CREATE PROCEDURE p1 (a text) BEGIN SELECT a; END | +CREATE PROCEDURE p2 () CALL p1(concat('x',_utf8'x')) | +CALL p2(); +a +xx +CALL p2(); +a +xx +DROP PROCEDURE p1; +DROP PROCEDURE p2; # End of 10.4 tests # diff --git a/mysql-test/main/sp.test b/mysql-test/main/sp.test index c11ea23080b..50d9a611db9 100644 --- a/mysql-test/main/sp.test +++ b/mysql-test/main/sp.test @@ -10567,5 +10567,25 @@ DROP FUNCTION f2; DROP FUNCTION f3; DROP VIEW v1; +--echo # +--echo # MDEV-33270: Call of SP invoking another SP with a parameter +--echo # requiring type conversion +--echo # + +SET NAMES latin1; + +--delimiter | + +CREATE PROCEDURE p1 (a text) BEGIN SELECT a; END | +CREATE PROCEDURE p2 () CALL p1(concat('x',_utf8'x')) | + +--delimiter ; + +CALL p2(); +CALL p2(); + +DROP PROCEDURE p1; +DROP PROCEDURE p2; + --echo # End of 10.4 tests --echo # diff --git a/sql/item.cc b/sql/item.cc index 6d30d63bc11..04b689f51af 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2586,7 +2586,10 @@ bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll, return TRUE; if (!thd->stmt_arena->is_conventional() && - thd->lex->current_select->first_cond_optimization) + ((!thd->lex->current_select && + (thd->stmt_arena->is_stmt_prepare_or_first_sp_execute() || + thd->stmt_arena->is_stmt_prepare_or_first_stmt_execute())) || + thd->lex->current_select->first_cond_optimization)) { Query_arena *arena, backup; arena= thd->activate_stmt_arena_if_needed(&backup); From 7e8e51eb3ad1ffd1bf8ec9c5dc23038e0e2e4b9c Mon Sep 17 00:00:00 2001 From: Sisi Huang Date: Thu, 11 Jan 2024 23:02:34 -0800 Subject: [PATCH 12/61] MDEV-32990 federatedx time_zone round trips Modified `federatedx_io_mysql::actual_query` to set the time zone to '+00:00' only upon establishing a new connection instead of with each query execution. --- storage/federatedx/federatedx_io_mysql.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/storage/federatedx/federatedx_io_mysql.cc b/storage/federatedx/federatedx_io_mysql.cc index cf620d59986..5c96982cf59 100644 --- a/storage/federatedx/federatedx_io_mysql.cc +++ b/storage/federatedx/federatedx_io_mysql.cc @@ -451,11 +451,14 @@ int federatedx_io_mysql::actual_query(const char *buffer, size_t length) get_port(), get_socket(), 0)) DBUG_RETURN(ER_CONNECT_TO_FOREIGN_DATA_SOURCE); + + if ((error= mysql_real_query(&mysql, STRING_WITH_LEN("set time_zone='+00:00'")))) + DBUG_RETURN(error); + mysql.reconnect= 1; } - if (!(error= mysql_real_query(&mysql, STRING_WITH_LEN("set time_zone='+00:00'")))) - error= mysql_real_query(&mysql, buffer, (ulong)length); + error= mysql_real_query(&mysql, buffer, (ulong)length); DBUG_RETURN(error); } From 3cd8875145b2c1dffe1f12510fbf92bf1a8f2fbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Tue, 16 Jan 2024 08:02:32 +0200 Subject: [PATCH 13/61] MDEV-14448: Ctrl-C should not exit the client This patch introduces the following behaviour for Linux while maintaining old behaviour for Windows: Ctrl + C (sigint) clears the current buffer and redraws the prompt. Ctrl-C no longer exits the client if no query is running. Ctrl-C kills the current running query if there is one. If there is an error communicating with the server while trying to issue a KILL QUERY, the client exits. This is in line with the past behaviour of Ctrl-C. On Linux Ctrl-D can be used to close the client. On Windows Ctrl-C and Ctrl-BREAK still exits the client if no query is running. Windows can also exit the client via \q or exit. == Implementation details == The Linux implementation has two corner cases, based on which library is used: libreadline or libedit, both are handled in code to achieve the same user experience. Additional code is taken from MySQL, ensuring there is identical behaviour on Windows, to MySQL's mysql client implementation for other CTRL- related signals. * The CTRL_CLOSE, CTRL_LOGOFF, CTRL_SHUTDOWN will issue the equivalent of CTRL-C and "end" the program. This ensures that the query is killed when the client is closed by closing the terminal, logging off the user or shutting down the system. The latter two signals are not sent for interactive applications, but it handles the case when a user has defined a service to use mysql client to issue a command. See https://learn.microsoft.com/en-us/windows/console/handlerroutine This patch is built on top of the initial work done by Anel Husakovic . Closes #2815 --- client/mysql.cc | 173 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 139 insertions(+), 34 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 214b0d51a32..befa0e9b113 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -89,6 +89,7 @@ extern "C" { #undef bcmp // Fix problem with new readline #if defined(__WIN__) #include +#include #else # ifdef __APPLE__ # include @@ -170,6 +171,9 @@ static int connect_flag=CLIENT_INTERACTIVE; static my_bool opt_binary_mode= FALSE; static my_bool opt_connect_expired_password= FALSE; static int interrupted_query= 0; +#ifdef USE_LIBEDIT_INTERFACE +static int sigint_received= 0; +#endif static char *current_host,*current_db,*current_user=0,*opt_password=0, *current_prompt=0, *delimiter_str= 0, *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME, @@ -1072,7 +1076,32 @@ extern "C" sig_handler handle_sigint(int sig); static sig_handler window_resize(int sig); #endif +static void end_in_sig_handler(int sig); +static bool kill_query(const char *reason); +#ifdef _WIN32 +static BOOL WINAPI ctrl_handler_windows(DWORD fdwCtrlType) +{ + switch (fdwCtrlType) + { + // Handle the CTRL-C signal. + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + handle_sigint(SIGINT); + return TRUE; // this means that the signal is handled + case CTRL_CLOSE_EVENT: + case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: + kill_query("Terminate"); + end_in_sig_handler(SIGINT + 1); + aborted= 1; + } + // This means to pass the signal to the next handler. This allows + // my_cgets and the internal ReadConsole call to exit and gracefully + // abort the program. + return FALSE; +} +#endif const char DELIMITER_NAME[]= "delimiter"; const uint DELIMITER_NAME_LEN= sizeof(DELIMITER_NAME) - 1; inline bool is_delimiter_command(char *name, ulong len) @@ -1205,11 +1234,12 @@ int main(int argc,char *argv[]) if (!status.batch) ignore_errors=1; // Don't abort monitor - if (opt_sigint_ignore) - signal(SIGINT, SIG_IGN); - else - signal(SIGINT, handle_sigint); // Catch SIGINT to clean up - signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up +#ifndef _WIN32 + signal(SIGINT, handle_sigint); // Catch SIGINT to clean up + signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up +#else + SetConsoleCtrlHandler(ctrl_handler_windows, TRUE); +#endif #if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL) /* Readline will call this if it installs a handler */ @@ -1376,30 +1406,35 @@ static bool do_connect(MYSQL *mysql, const char *host, const char *user, } -/* - This function handles sigint calls - If query is in process, kill query - If 'source' is executed, abort source command - no query in process, terminate like previous behavior - */ +void end_in_sig_handler(int sig) +{ +#ifdef _WIN32 + /* + When SIGINT is raised on Windows, the OS creates a new thread to handle the + interrupt. Once that thread completes, the main thread continues running + only to find that it's resources have already been free'd when the sigint + handler called mysql_end(). + */ + mysql_thread_end(); +#else + mysql_end(sig); +#endif +} -sig_handler handle_sigint(int sig) + +/* + Kill a running query. Returns true if we were unable to connect to the server. +*/ +bool kill_query(const char *reason) { char kill_buffer[40]; MYSQL *kill_mysql= NULL; - /* terminate if no query being executed, or we already tried interrupting */ - if (!executing_query || (interrupted_query == 2)) - { - tee_fprintf(stdout, "Ctrl-C -- exit!\n"); - goto err; - } - kill_mysql= mysql_init(kill_mysql); if (!do_connect(kill_mysql,current_host, current_user, opt_password, "", 0)) { - tee_fprintf(stdout, "Ctrl-C -- sorry, cannot connect to server to kill query, giving up ...\n"); - goto err; + tee_fprintf(stdout, "%s -- sorry, cannot connect to server to kill query, giving up ...\n", reason); + return true; } /* First time try to kill the query, second time the connection */ @@ -1414,27 +1449,65 @@ sig_handler handle_sigint(int sig) (interrupted_query == 1) ? "QUERY " : "", mysql_thread_id(&mysql)); if (verbose) - tee_fprintf(stdout, "Ctrl-C -- sending \"%s\" to server ...\n", + tee_fprintf(stdout, "%s -- sending \"%s\" to server ...\n", reason, kill_buffer); mysql_real_query(kill_mysql, kill_buffer, (uint) strlen(kill_buffer)); mysql_close(kill_mysql); - tee_fprintf(stdout, "Ctrl-C -- query killed. Continuing normally.\n"); + if (interrupted_query == 1) + tee_fprintf(stdout, "%s -- query killed.\n", reason); + else + tee_fprintf(stdout, "%s -- connection killed.\n", reason); + if (in_com_source) aborted= 1; // Abort source command - return; + return false; +} + +/* + This function handles sigint calls + If query is in process, kill query + If 'source' is executed, abort source command + no query in process, regenerate prompt. +*/ +sig_handler handle_sigint(int sig) +{ + if (opt_sigint_ignore) + return; -err: -#ifdef _WIN32 /* - When SIGINT is raised on Windows, the OS creates a new thread to handle the - interrupt. Once that thread completes, the main thread continues running - only to find that it's resources have already been free'd when the sigint - handler called mysql_end(). + On Unix only, if no query is being executed just clear the prompt, + don't exit. On Windows we exit. */ - mysql_thread_end(); + if (!executing_query) + { +#ifndef _WIN32 + tee_fprintf(stdout, "^C\n"); +#ifdef USE_LIBEDIT_INTERFACE + /* Libedit will regenerate it outside of the signal handler. */ + sigint_received= 1; #else - mysql_end(sig); -#endif + rl_on_new_line(); // Regenerate the prompt on a newline + rl_replace_line("", 0); // Clear the previous text + rl_redisplay(); +#endif +#else // WIN32 + tee_fprintf(stdout, "Ctrl-C -- exit!\n"); + end_in_sig_handler(sig); +#endif + return; + } + + /* + When executing a query, this newline makes the prompt look like so: + ^C + Ctrl-C -- query killed. + */ + tee_fprintf(stdout, "\n"); + if (kill_query("Ctrl-C")) + { + aborted= 1; + end_in_sig_handler(sig); + } } @@ -1973,6 +2046,12 @@ static int get_options(int argc, char **argv) return(0); } +static inline void reset_prompt(char *in_string, bool *ml_comment) { + glob_buffer.length(0); + *ml_comment = false; + *in_string = 0; +} + static int read_and_execute(bool interactive) { #if defined(__WIN__) @@ -2063,7 +2142,7 @@ static int read_and_execute(bool interactive) size_t clen; do { - line= my_cgets((char*)tmpbuf.ptr(), tmpbuf.alloced_length()-1, &clen); + line= my_cgets((char*)tmpbuf.ptr(), tmpbuf.alloced_length()-1, &clen); buffer.append(line, clen); /* if we got buffer fully filled than there is a chance that @@ -2085,8 +2164,34 @@ static int read_and_execute(bool interactive) the readline/libedit library. */ if (line) + { free(line); + glob_buffer.length(0); + } line= readline(prompt); +#ifdef USE_LIBEDIT_INTERFACE + /* + libedit handles interrupts different than libreadline. + libreadline has its own signal handlers, thus a sigint during readline + doesn't force readline to return null string. + + However libedit returns null if the interrupt signal is raised. + We can also get an empty string when ctrl+d is pressed (EoF). + + We need this sigint_received flag, to differentiate between the two + cases. This flag is only set during our handle_sigint function when + LIBEDIT_INTERFACE is used. + */ + if (!line && sigint_received) + { + // User asked to clear the input. + sigint_received= 0; + reset_prompt(&in_string, &ml_comment); + continue; + } + // For safety, we always mark this as cleared. + sigint_received= 0; +#endif #endif /* defined(__WIN__) */ /* From 207c85783b2c7831e1851fe9d0a4228b18d3d3fd Mon Sep 17 00:00:00 2001 From: Brandon Nesterenko Date: Fri, 19 Jan 2024 10:31:45 -0700 Subject: [PATCH 14/61] MDEV-33283: Binlog Checksum is Zeroed by Zlib if Part of Event Data is Empty An existing binlog checksum can be overridden to 0 if writing a NULL payload when using Zlib for the computation. That is, calling into Zlib's crc32 with empty data initializes an incremental CRC computation to 0. This patch changes the Log_event_writer::write_data() to exit immediately if there is nothing to write, thereby bypassing the checksum computation. This follows the pattern of Log_event_writer::encrypt_and_write(), which also exits immediately if there is no data to write. Reviewed By: ============ Andrei Elkin --- sql/log_event_server.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index 2a22021cc95..f51f5b7deec 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -916,6 +916,10 @@ int Log_event_writer::write_header(uchar *pos, size_t len) int Log_event_writer::write_data(const uchar *pos, size_t len) { DBUG_ENTER("Log_event_writer::write_data"); + + if (!len) + DBUG_RETURN(0); + if (checksum_len) crc= my_checksum(crc, pos, len); From 01ca57ec1615015e163123fa1882bcc278c81b9a Mon Sep 17 00:00:00 2001 From: Brandon Nesterenko Date: Wed, 17 Jan 2024 07:14:11 -0700 Subject: [PATCH 15/61] MDEV-32168: Postpush fix for rpl_domain_id_filter_master_crash While a replica may be reading events from the primary, the primary is killed. Left to its own devices, the IO thread may or may not stop in error, depending on what it is doing when its connection to the primary is killed (e.g. a failed read results in an error, whereas if the IO thread is idly waiting for events when the connection dies, it will enter into a reconnect loop and reconnect). MDEV-32168 changed the test to always wait for the reconnect, thus breaking the error case, as the IO thread would be stopped at a time of expecting it to be running. The fix is to manually stop/start the IO thread to ensure it is in a consistent state. Note that rpl_domain_id_filter_master_crash.test will need additional changes after fixing MDEV-33268 Reviewed By: ============ Kristian Nielsen --- .../rpl_domain_id_filter_master_crash.result | 5 +++-- .../t/rpl_domain_id_filter_master_crash.test | 20 +++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_domain_id_filter_master_crash.result b/mysql-test/suite/rpl/r/rpl_domain_id_filter_master_crash.result index 4169a2ddc26..a54ff99b591 100644 --- a/mysql-test/suite/rpl/r/rpl_domain_id_filter_master_crash.result +++ b/mysql-test/suite/rpl/r/rpl_domain_id_filter_master_crash.result @@ -38,8 +38,9 @@ connection master; include/rpl_start_server.inc [server_number=1] # Master has restarted successfully connection slave; -include/wait_for_slave_io_to_start.inc -include/wait_for_slave_sql_to_start.inc +include/stop_slave_sql.inc +include/stop_slave_io.inc +include/start_slave.inc select * from ti; a 1 diff --git a/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test b/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test index b1fa9af33a4..cdfdc098f5a 100644 --- a/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test +++ b/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test @@ -67,10 +67,26 @@ connection master; save_master_pos; --connection slave + +# Left to its own devices, the IO thread may or may not stop in error, +# depending on what it is doing when its connection to the primary is killed +# (e.g. a failed read results in an error, whereas if the IO thread is idly +# waiting for events when the connection dies, it will enter into a reconnect +# loop and reconnect). So we manually stop/start the IO thread to ensure it is +# in a consistent state +# +# FIXME: We shouldn't need to stop/start the SQL thread here, but due to +# MDEV-33268, we have to. So after fixing 33268, this should only stop/start +# the IO thread. Note the SQL thread must be stopped first due to an invalid +# DBUG_ASSERT in the IO thread's stop logic that depends on the state of the +# SQL thread (also reported and to be fixed in the same ticket). +# +--source include/stop_slave_sql.inc --let rpl_allow_error=1 ---source include/wait_for_slave_io_to_start.inc +--source include/stop_slave_io.inc --let rpl_allow_error= ---source include/wait_for_slave_sql_to_start.inc +--source include/start_slave.inc + sync_with_master; select * from ti; select * from tm; From 19f3796ec372f2c096c853120d4e2a81df1e5bb1 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 22 Jan 2024 15:57:05 +0100 Subject: [PATCH 16/61] new CC 3.3 --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index 26cef16b25f..e714a674827 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 26cef16b25f01c1b159b0c73e3f6d9bcfcac90d5 +Subproject commit e714a674827fbb8373dd71da634dd04736d7b5a6 From a9172b8a436a9e403aee63a16f9a5655b9c98e9b Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 22 Jan 2024 15:27:58 +0100 Subject: [PATCH 17/61] Update minizip files for connect enginbe from last zlib 1.3. --- storage/connect/zip.c | 369 ++++++++++++++++++------------------------ storage/connect/zip.h | 292 ++++++++++++++++----------------- 2 files changed, 303 insertions(+), 358 deletions(-) diff --git a/storage/connect/zip.c b/storage/connect/zip.c index f6a10601968..3d3d4caddef 100644 --- a/storage/connect/zip.c +++ b/storage/connect/zip.c @@ -14,8 +14,8 @@ Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data - It is used when recreting zip archive with RAW when deleting items from a zip. - ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed. + It is used when recreating zip archive with RAW when deleting items from a zip. + ZIP64 data is automatically added to items that needs it, and existing ZIP64 data need to be removed. Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer @@ -25,15 +25,13 @@ #include #include #include +#include #include #include "zlib.h" #include "zip.h" -#include "my_attribute.h" #ifdef STDC # include -# include -# include #endif #ifdef NO_ERRNO_H extern int errno; @@ -48,7 +46,7 @@ /* compile with -Dlocal if your debugger can't find static symbols */ #ifndef VERSIONMADEBY -# define VERSIONMADEBY (0x0) /* platform depedent */ +# define VERSIONMADEBY (0x0) /* platform dependent */ #endif #ifndef Z_BUFSIZE @@ -62,9 +60,6 @@ #ifndef ALLOC # define ALLOC(size) (malloc(size)) #endif -#ifndef TRYFREE -# define TRYFREE(p) {if (p) free(p);} -#endif /* #define SIZECENTRALDIRITEM (0x2e) @@ -117,7 +112,7 @@ typedef struct linkedlist_datablock_internal_s struct linkedlist_datablock_internal_s* next_datablock; uLong avail_in_this_block; uLong filled_in_this_block; - uLong unused; /* for future use and alignement */ + uLong unused; /* for future use and alignment */ unsigned char data[SIZEDATA_INDATABLOCK]; } linkedlist_datablock_internal; @@ -139,40 +134,40 @@ typedef struct uInt pos_in_buffered_data; /* last written byte in buffered_data */ ZPOS64_T pos_local_header; /* offset of the local header of the file - currenty writing */ + currently writing */ char* central_header; /* central header data for the current file */ uLong size_centralExtra; uLong size_centralheader; /* size of the central header for cur file */ uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ uLong flag; /* flag of the file currently writing */ - int method; /* compression method of file currenty wr.*/ + int method; /* compression method of file currently wr.*/ int raw; /* 1 for directly writing raw data */ Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ uLong dosDate; uLong crc32; int encrypt; - int zip64; /* Add ZIP64 extened information in the extra field */ + int zip64; /* Add ZIP64 extended information in the extra field */ ZPOS64_T pos_zip64extrainfo; ZPOS64_T totalCompressedData; ZPOS64_T totalUncompressedData; #ifndef NOCRYPT unsigned long keys[3]; /* keys defining the pseudo-random sequence */ const z_crc_t* pcrc_32_tab; - int crypt_header_size; + unsigned crypt_header_size; #endif } curfile64_info; typedef struct { zlib_filefunc64_32_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ + voidpf filestream; /* io structure of the zipfile */ linkedlist_data central_dir;/* datablock with central dir in construction*/ int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ - curfile64_info ci; /* info on the file curretly writing */ + curfile64_info ci; /* info on the file currently writing */ ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ - ZPOS64_T add_position_when_writting_offset; + ZPOS64_T add_position_when_writing_offset; ZPOS64_T number_entry; #ifndef NO_ADDFILEINEXISTINGZIP @@ -187,8 +182,7 @@ typedef struct #include "crypt.h" #endif -local linkedlist_datablock_internal* allocate_new_datablock() -{ +local linkedlist_datablock_internal* allocate_new_datablock(void) { linkedlist_datablock_internal* ldi; ldi = (linkedlist_datablock_internal*) ALLOC(sizeof(linkedlist_datablock_internal)); @@ -201,30 +195,26 @@ local linkedlist_datablock_internal* allocate_new_datablock() return ldi; } -local void free_datablock(linkedlist_datablock_internal* ldi) -{ +local void free_datablock(linkedlist_datablock_internal* ldi) { while (ldi!=NULL) { linkedlist_datablock_internal* ldinext = ldi->next_datablock; - TRYFREE(ldi); + free(ldi); ldi = ldinext; } } -local void init_linkedlist(linkedlist_data* ll) -{ +local void init_linkedlist(linkedlist_data* ll) { ll->first_block = ll->last_block = NULL; } -local void free_linkedlist(linkedlist_data* ll) -{ +local void free_linkedlist(linkedlist_data* ll) { free_datablock(ll->first_block); ll->first_block = ll->last_block = NULL; } -local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) -{ +local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) { linkedlist_datablock_internal* ldi; const unsigned char* from_copy; @@ -239,7 +229,7 @@ local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) } ldi = ll->last_block; - from_copy = (unsigned char*)buf; + from_copy = (const unsigned char*)buf; while (len>0) { @@ -284,9 +274,7 @@ local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) */ -local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); -local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) -{ +local int zip64local_putValue(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) { unsigned char buf[8]; int n; for (n = 0; n < nbByte; n++) @@ -302,15 +290,13 @@ local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, } } - if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) + if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,(uLong)nbByte)!=(uLong)nbByte) return ZIP_ERRNO; else return ZIP_OK; } -local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); -local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) -{ +local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) { unsigned char* buf=(unsigned char*)dest; int n; for (n = 0; n < nbByte; n++) { @@ -330,25 +316,21 @@ local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) /****************************************************************************/ -local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) -{ +local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) { uLong year = (uLong)ptm->tm_year; if (year>=1980) year-=1980; else if (year>=80) year-=80; return - (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | - ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); + (uLong) (((uLong)(ptm->tm_mday) + (32 * (uLong)(ptm->tm_mon+1)) + (512 * year)) << 16) | + (((uLong)ptm->tm_sec/2) + (32 * (uLong)ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); } /****************************************************************************/ -local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); - -local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) -{ +local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int* pi) { unsigned char c; int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); if (err==1) @@ -369,10 +351,7 @@ local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,vo /* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets */ -local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); - -local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) -{ +local int zip64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) { uLong x ; int i = 0; int err; @@ -391,10 +370,7 @@ local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, return err; } -local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); - -local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) -{ +local int zip64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) { uLong x ; int i = 0; int err; @@ -421,11 +397,8 @@ local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, return err; } -local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); - -local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) -{ +local int zip64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) { ZPOS64_T x; int i = 0; int err; @@ -476,10 +449,7 @@ local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def Locate the Central directory of a zipfile (at the end, just before the global comment) */ -local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); - -local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) -{ +local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { unsigned char* buf; ZPOS64_T uSizeFile; ZPOS64_T uBackRead; @@ -519,18 +489,18 @@ local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) break; - for (i=(int)uReadSize-3; (i--)>0;) { + for (i=(int)uReadSize-3; (i--)>0;) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) { - uPosFound = uReadPos+i; + uPosFound = uReadPos+(unsigned)i; break; } - } + if (uPosFound!=0) break; } - TRYFREE(buf); + free(buf); return uPosFound; } @@ -538,10 +508,7 @@ local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before the global comment) */ -local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); - -local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) -{ +local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { unsigned char* buf; ZPOS64_T uSizeFile; ZPOS64_T uBackRead; @@ -587,7 +554,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib // Signature "0x07064b50" Zip64 end of central directory locater if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) { - uPosFound = uReadPos+i; + uPosFound = uReadPos+(unsigned)i; break; } } @@ -596,7 +563,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib break; } - TRYFREE(buf); + free(buf); if (uPosFound == 0) return 0; @@ -638,8 +605,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib return relativeOffset; } -static int LoadCentralDirectoryRecord(zip64_internal* pziinit) -{ +local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { int err=ZIP_OK; ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ @@ -649,9 +615,9 @@ static int LoadCentralDirectoryRecord(zip64_internal* pziinit) uLong uL; uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ + spanning ZIP, unsupported, always 0*/ uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ + for spanning ZIP, unsupported, always 0*/ ZPOS64_T number_entry; ZPOS64_T number_entry_CD; /* total number of entries in the central dir @@ -808,7 +774,7 @@ static int LoadCentralDirectoryRecord(zip64_internal* pziinit) } byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); - pziinit->add_position_when_writting_offset = byte_before_the_zipfile; + pziinit->add_position_when_writing_offset = byte_before_the_zipfile; { ZPOS64_T size_central_dir_to_read = size_central_dir; @@ -831,7 +797,7 @@ static int LoadCentralDirectoryRecord(zip64_internal* pziinit) size_central_dir_to_read-=read_this; } - TRYFREE(buf_read); + free(buf_read); } pziinit->begin_pos = byte_before_the_zipfile; pziinit->number_entry = number_entry_CD; @@ -847,8 +813,7 @@ static int LoadCentralDirectoryRecord(zip64_internal* pziinit) /************************************************************/ -static zipFile zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) -{ +extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) { zip64_internal ziinit; zip64_internal* zi; int err=ZIP_OK; @@ -876,7 +841,7 @@ static zipFile zipOpen3 (const void *pathname, int append, zipcharpc* globalcomm ziinit.in_opened_file_inzip = 0; ziinit.ci.stream_initialised = 0; ziinit.number_entry = 0; - ziinit.add_position_when_writting_offset = 0; + ziinit.add_position_when_writing_offset = 0; init_linkedlist(&(ziinit.central_dir)); @@ -906,9 +871,9 @@ static zipFile zipOpen3 (const void *pathname, int append, zipcharpc* globalcomm if (err != ZIP_OK) { # ifndef NO_ADDFILEINEXISTINGZIP - TRYFREE(ziinit.globalcomment); + free(ziinit.globalcomment); # endif /* !NO_ADDFILEINEXISTINGZIP*/ - TRYFREE(zi); + free(zi); return NULL; } else @@ -918,8 +883,7 @@ static zipFile zipOpen3 (const void *pathname, int append, zipcharpc* globalcomm } } -extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) -{ +extern zipFile ZEXPORT zipOpen2(const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) { if (pzlib_filefunc32_def != NULL) { zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; @@ -930,8 +894,7 @@ extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* gl return zipOpen3(pathname, append, globalcomment, NULL); } -extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) -{ +extern zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) { if (pzlib_filefunc_def != NULL) { zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; @@ -946,18 +909,15 @@ extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* -extern zipFile ZEXPORT zipOpen (const char* pathname, int append) -{ +extern zipFile ZEXPORT zipOpen(const char* pathname, int append) { return zipOpen3((const void*)pathname,append,NULL,NULL); } -extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) -{ +extern zipFile ZEXPORT zipOpen64(const void* pathname, int append) { return zipOpen3(pathname,append,NULL,NULL); } -static int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) -{ +local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) { /* write the local header */ int err; uInt size_filename = (uInt)strlen(filename); @@ -1035,8 +995,8 @@ static int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)HeaderID,2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)DataSize,2); err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); @@ -1053,24 +1013,24 @@ static int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize unnecessary allocations. */ -extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting __attribute__((unused)), - uLong versionMadeBy, uLong flagBase, int zip64) -{ +extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase, int zip64) { zip64_internal* zi; uInt size_filename; uInt size_comment; uInt i; int err = ZIP_OK; -#ifdef NOCRYPT +# ifdef NOCRYPT + (crcForCrypting); if (password != NULL) return ZIP_PARAMERROR; -#endif +# endif if (file == NULL) return ZIP_PARAMERROR; @@ -1164,7 +1124,7 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, if(zi->ci.pos_local_header >= 0xffffffff) zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); else - zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writing_offset,4); for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); @@ -1262,35 +1222,33 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, return err; } -extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting, - uLong versionMadeBy, uLong flagBase) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, versionMadeBy, flagBase, 0); +extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase) { + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, versionMadeBy, flagBase, 0); } -extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, VERSIONMADEBY, 0, 0); +extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting) { + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, 0); } extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, @@ -1298,70 +1256,64 @@ extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, c const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting, int zip64) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, VERSIONMADEBY, 0, zip64); + const char* password, uLong crcForCrypting, int zip64) { + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, zip64); } extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, 0); + const char* comment, int method, int level, int raw) { + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); } extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, int zip64) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, zip64); + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, int zip64) { + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); } -extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void*extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int zip64) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, 0, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, zip64); +extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int zip64) { + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); } -extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void*extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, 0, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, 0); +extern int ZEXPORT zipOpenNewFileInZip(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level) { + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); } -local int zip64FlushWriteBuffer(zip64_internal* zi) -{ +local int zip64FlushWriteBuffer(zip64_internal* zi) { int err=ZIP_OK; if (zi->ci.encrypt != 0) @@ -1399,8 +1351,7 @@ local int zip64FlushWriteBuffer(zip64_internal* zi) return err; } -extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) -{ +extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void* buf, unsigned int len) { zip64_internal* zi; int err=ZIP_OK; @@ -1450,7 +1401,7 @@ extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned in else #endif { - zi->ci.stream.next_in = (Bytef*)buf; + zi->ci.stream.next_in = (Bytef*)(uintptr_t)buf; zi->ci.stream.avail_in = len; while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) @@ -1501,17 +1452,15 @@ extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned in return err; } -extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) -{ +extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uLong uncompressed_size, uLong crc32) { return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); } -extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) -{ +extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_size, uLong crc32) { zip64_internal* zi; ZPOS64_T compressed_size; uLong invalidValue = 0xffffffff; - short datasize = 0; + unsigned datasize = 0; int err=ZIP_OK; if (file == NULL) @@ -1742,15 +1691,13 @@ extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_s return err; } -extern int ZEXPORT zipCloseFileInZip (zipFile file) -{ +extern int ZEXPORT zipCloseFileInZip(zipFile file) { return zipCloseFileInZipRaw (file,0,0); } -static int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) -{ +local int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) { int err = ZIP_OK; - ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; + ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writing_offset; err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); @@ -1769,8 +1716,7 @@ static int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T return err; } -static int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) -{ +local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) { int err = ZIP_OK; uLong Zip64DataSize = 44; @@ -1803,13 +1749,13 @@ static int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ { - ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); } return err; } -static int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) -{ + +local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) { int err = ZIP_OK; /*signature*/ @@ -1844,20 +1790,19 @@ static int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_cent if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ { - ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; if(pos >= 0xffffffff) { err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); } else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writing_offset),4); } return err; } -static int Write_GlobalComment(zip64_internal* zi, const char* global_comment) -{ +local int Write_GlobalComment(zip64_internal* zi, const char* global_comment) { int err = ZIP_OK; uInt size_global_comment = 0; @@ -1874,8 +1819,7 @@ static int Write_GlobalComment(zip64_internal* zi, const char* global_comment) return err; } -extern int ZEXPORT zipClose (zipFile file, const char* global_comment) -{ +extern int ZEXPORT zipClose(zipFile file, const char* global_comment) { zip64_internal* zi; int err = 0; uLong size_centraldir = 0; @@ -1916,7 +1860,7 @@ extern int ZEXPORT zipClose (zipFile file, const char* global_comment) } free_linkedlist(&(zi->central_dir)); - pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) { ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); @@ -1936,15 +1880,14 @@ extern int ZEXPORT zipClose (zipFile file, const char* global_comment) err = ZIP_ERRNO; #ifndef NO_ADDFILEINEXISTINGZIP - TRYFREE(zi->globalcomment); + free(zi->globalcomment); #endif - TRYFREE(zi); + free(zi); return err; } -extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) -{ +extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHeader) { char* p = pData; int size = 0; char* pNewHeader; @@ -1954,10 +1897,10 @@ extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHe int retVal = ZIP_OK; - if(pData == NULL || *dataLen < 4) + if(pData == NULL || dataLen == NULL || *dataLen < 4) return ZIP_PARAMERROR; - pNewHeader = (char*)ALLOC(*dataLen); + pNewHeader = (char*)ALLOC((unsigned)*dataLen); pTmp = pNewHeader; while(p < (pData + *dataLen)) @@ -1996,7 +1939,7 @@ extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHe else retVal = ZIP_ERRNO; - TRYFREE(pNewHeader); + free(pNewHeader); return retVal; } diff --git a/storage/connect/zip.h b/storage/connect/zip.h index 8aaebb62343..5fc08413241 100644 --- a/storage/connect/zip.h +++ b/storage/connect/zip.h @@ -88,12 +88,12 @@ typedef voidp zipFile; /* tm_zip contain date/time info */ typedef struct tm_zip_s { - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ + int tm_sec; /* seconds after the minute - [0,59] */ + int tm_min; /* minutes after the hour - [0,59] */ + int tm_hour; /* hours since midnight - [0,23] */ + int tm_mday; /* day of the month - [1,31] */ + int tm_mon; /* months since January - [0,11] */ + int tm_year; /* years - [1980..2044] */ } tm_zip; typedef struct @@ -113,8 +113,8 @@ typedef const char* zipcharpc; #define APPEND_STATUS_CREATEAFTER (1) #define APPEND_STATUS_ADDINZIP (2) -extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); -extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); +extern zipFile ZEXPORT zipOpen(const char *pathname, int append); +extern zipFile ZEXPORT zipOpen64(const void *pathname, int append); /* Create a zipfile. pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on @@ -131,41 +131,46 @@ extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); /* Note : there is no delete function into a zipfile. If you want delete file into a zipfile, you must open a zipfile, and create another - Of couse, you can use RAW reading and writing to copy the file you did not want delte + Of course, you can use RAW reading and writing to copy the file you did not want delete */ -extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, +extern zipFile ZEXPORT zipOpen2(const char *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc_def); + +extern zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc* globalcomment, - zlib_filefunc_def* pzlib_filefunc_def)); + zlib_filefunc64_def* pzlib_filefunc_def); -extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, - int append, - zipcharpc* globalcomment, - zlib_filefunc64_def* pzlib_filefunc_def)); +extern zipFile ZEXPORT zipOpen3(const void *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc64_32_def* pzlib_filefunc64_32_def); -extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level)); +extern int ZEXPORT zipOpenNewFileInZip(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level); -extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int zip64)); +extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int zip64); /* Open a file in the ZIP for writing. @@ -184,70 +189,69 @@ extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, */ -extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw)); +extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw); -extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int zip64)); +extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int zip64); /* Same than zipOpenNewFileInZip, except if raw=1, we write raw file */ -extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting)); +extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting); -extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - int zip64 - )); +extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + int zip64); /* Same than zipOpenNewFileInZip2, except @@ -256,47 +260,45 @@ extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, crcForCrypting : crc of file to compress (needed for crypting) */ -extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - uLong versionMadeBy, - uLong flagBase - )); +extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase); -extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - uLong versionMadeBy, - uLong flagBase, - int zip64 - )); +extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase, + int zip64); /* Same than zipOpenNewFileInZip4, except versionMadeBy : value for Version made by field @@ -304,25 +306,25 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, */ -extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, - const void* buf, - unsigned len)); +extern int ZEXPORT zipWriteInFileInZip(zipFile file, + const void* buf, + unsigned len); /* Write data in the zipfile */ -extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); +extern int ZEXPORT zipCloseFileInZip(zipFile file); /* Close the current file in the zipfile */ -extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, - uLong uncompressed_size, - uLong crc32)); +extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, + uLong uncompressed_size, + uLong crc32); -extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, - ZPOS64_T uncompressed_size, - uLong crc32)); +extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, + ZPOS64_T uncompressed_size, + uLong crc32); /* Close the current file in the zipfile, for file opened with @@ -330,14 +332,14 @@ extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, uncompressed_size and crc32 are value for the uncompressed size */ -extern int ZEXPORT zipClose OF((zipFile file, - const char* global_comment)); +extern int ZEXPORT zipClose(zipFile file, + const char* global_comment); /* Close the zipfile */ -extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); +extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHeader); /* zipRemoveExtraInfoBlock - Added by Mathias Svensson From 15bd7e0b89eef3c85fbca61b4d738decbbc27dd3 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 22 Jan 2024 15:39:09 +0100 Subject: [PATCH 18/61] "New" version of CC (in fact no changes) --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index ae565eea90d..f1a72768d42 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit ae565eea90dd3053a5a7857e7cdad93342dbc645 +Subproject commit f1a72768d4256416e5c0bf01b254c303f6135bd0 From 117388225c1361c0a5b67d6115db1a6b54b43c2c Mon Sep 17 00:00:00 2001 From: Rex Date: Fri, 12 Jan 2024 09:32:34 +1200 Subject: [PATCH 19/61] MDEV-33165 Incorrect result interceptor passed to mysql_explain_union() Statements affect by this bug are all SQL statements that 1) prefixed with "EXPLAIN" 2) have a lower level join structure created for a union subquery. A bug in select_describe() passed an incorrect "result" object to mysql_explain_union(), resulting in unpredictable behaviour and out of context calls. Reviewed by: Oleksandr Byelkin, sanja@mariadb.com --- mysql-test/main/explain.result | 40 ++++++++++++++++++++++++++++++++++ mysql-test/main/explain.test | 23 +++++++++++++++++++ sql/sql_select.cc | 3 +-- 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/explain.result b/mysql-test/main/explain.result index 8a9fd3c5390..85d889a8c5f 100644 --- a/mysql-test/main/explain.result +++ b/mysql-test/main/explain.result @@ -459,3 +459,43 @@ id select_type table type possible_keys key key_len ref rows Extra NULL UNION RESULT ALL NULL NULL NULL NULL NULL Warnings: Note 1249 Select 4 was reduced during optimization +# +# End of 10.4 tests +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (3),(4); +EXPLAIN SELECT * FROM t1, t2 WHERE t2.b IN (SELECT 5 UNION SELECT 6); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +EXPLAIN DELETE t2 FROM t1, t2 WHERE t2.b IN (SELECT 5 UNION SELECT 6); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +prepare stmt from "EXPLAIN DELETE t2 FROM t1, t2 WHERE t2.b IN (SELECT 5 UNION SELECT 6)"; +execute stmt; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +execute stmt; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +DROP TABLE t1, t2; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/explain.test b/mysql-test/main/explain.test index fc789601788..a546242d6aa 100644 --- a/mysql-test/main/explain.test +++ b/mysql-test/main/explain.test @@ -370,3 +370,26 @@ drop table t1; explain VALUES ( (VALUES (2))) UNION VALUES ( (SELECT 3)); + +--echo # +--echo # End of 10.4 tests +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (3),(4); + +EXPLAIN SELECT * FROM t1, t2 WHERE t2.b IN (SELECT 5 UNION SELECT 6); +EXPLAIN DELETE t2 FROM t1, t2 WHERE t2.b IN (SELECT 5 UNION SELECT 6); +prepare stmt from "EXPLAIN DELETE t2 FROM t1, t2 WHERE t2.b IN (SELECT 5 UNION SELECT 6)"; +execute stmt; +execute stmt; + +# Cleanup + +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 21132651b07..2794c8d51e9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -27953,7 +27953,6 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, bool distinct,const char *message) { THD *thd=join->thd; - select_result *result=join->result; DBUG_ENTER("select_describe"); if (join->select_lex->pushdown_select) @@ -27988,7 +27987,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, if (unit->explainable()) { - if (mysql_explain_union(thd, unit, result)) + if (mysql_explain_union(thd, unit, unit->result)) DBUG_VOID_RETURN; } } From 13e49b783f4572d89badadb05f793d4333c881ac Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Fri, 19 Jan 2024 18:40:53 +0700 Subject: [PATCH 20/61] sql_test.cc compile fix --- sql/sql_test.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 1474099c030..47acdaf8d7c 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -29,14 +29,17 @@ #include #include "sql_connect.h" #include "thread_cache.h" -#if defined(HAVE_MALLINFO) || defined(HAVE_MALLINFO2) + #if defined(HAVE_MALLOC_H) #include -#elif defined(HAVE_SYS_MALLOC_H) -#include -#elif defined(HAVE_MALLOC_ZONE) -#include #endif + +#if defined(HAVE_SYS_MALLOC_H) +#include +#endif + +#if defined(HAVE_MALLOC_ZONE) +#include #endif #ifdef HAVE_EVENT_SCHEDULER From 5ce6a352b6e7b84b96dadebb943132c8b2f97391 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 22 Jan 2024 14:23:44 +1100 Subject: [PATCH 21/61] MDEV-33290: Disable ColumnStore based on boost version MCOL-5611 supporting with Boost-1.80, the version "next_prime" disappears from https://github.com/boostorg/unordered/blob/boost-1.79.0/include/boost/unordered/detail/implementation.hpp makes it the currenly highest supported versions. Lets check this version. While CMake-3.19+ supports version ranges in package determinations this isn't supported for Boost in Cmake-3.28. So we check for the 1.80 and don't compile ColumnStore. --- storage/columnstore/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/storage/columnstore/CMakeLists.txt b/storage/columnstore/CMakeLists.txt index 81690f14b15..644f0ca8984 100644 --- a/storage/columnstore/CMakeLists.txt +++ b/storage/columnstore/CMakeLists.txt @@ -15,6 +15,13 @@ IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64") add_subdirectory(columnstore) + # https://jira.mariadb.org/browse/MCOL-5611 + FIND_PACKAGE(Boost 1.80.0 COMPONENTS system filesystem thread regex date_time chrono atomic) + IF (Boost_FOUND) + MESSAGE_ONCE(CS_NO_BOOST "Boost Libraries >= 1.80.0 not supported!") + return() + ENDIF() + IF(TARGET columnstore) # Needed to bump the component changes up to the main scope APPEND_FOR_CPACK(CPACK_COMPONENTS_ALL) From 90cd712b84d69d64a8e6fa162b560602be87903a Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Mon, 13 Nov 2023 23:21:49 +0530 Subject: [PATCH 22/61] MDEV-27087: Add thread ID and database / table, where the error occured to SQL error plugin New plugin variable "with_db_and_thread_info" is added which prints the thread id and databse name to the logfile. the value is stored in variable "with_db_and_thread_info" log_sql_errors() is responsible for printing in the log. If detailed is enabled, print thread id and database name both, otherwise skip it. --- mysql-test/include/read_head.inc | 30 +++++++++++++++++++ mysql-test/suite/plugins/r/mdev_27087.result | 12 ++++++++ .../suite/plugins/r/sql_error_log.result | 1 + mysql-test/suite/plugins/t/mdev_27087.opt | 1 + mysql-test/suite/plugins/t/mdev_27087.test | 18 +++++++++++ plugin/sql_errlog/sql_errlog.c | 24 +++++++++++++-- 6 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 mysql-test/include/read_head.inc create mode 100644 mysql-test/suite/plugins/r/mdev_27087.result create mode 100644 mysql-test/suite/plugins/t/mdev_27087.opt create mode 100644 mysql-test/suite/plugins/t/mdev_27087.test diff --git a/mysql-test/include/read_head.inc b/mysql-test/include/read_head.inc new file mode 100644 index 00000000000..98818d76703 --- /dev/null +++ b/mysql-test/include/read_head.inc @@ -0,0 +1,30 @@ +# Purpose: +# Print first LINES_TO_READ from a file. +# The environment variables SEARCH_FILE and LINES_TO_READ must be set +# before sourcing this routine. +# Use: +# When the test is slow ( example because of ASAN build) then it +# may not flush the lines when 'cat' command is called and the +# test could fail with missing lines. Hence this can be used to +# to print first N lines. +# + +perl; + +use strict; + +my $search_file = $ENV{SEARCH_FILE} or die "SEARCH_FILE not set"; +my $lines_to_read = $ENV{LINES_TO_READ} or die "LINES_TO_READ not set"; + +open(FILE, '<', $search_file) or die "Can't open file $search_file: $!"; + +my $line_count = 0; +while ($line_count < $lines_to_read and my $line = ) +{ + print $line; + $line_count++; +} + +close(FILE); + +EOF diff --git a/mysql-test/suite/plugins/r/mdev_27087.result b/mysql-test/suite/plugins/r/mdev_27087.result new file mode 100644 index 00000000000..9cffceaa4db --- /dev/null +++ b/mysql-test/suite/plugins/r/mdev_27087.result @@ -0,0 +1,12 @@ +show variables like 'sql_error_log%'; +Variable_name Value +sql_error_log_filename sql_errors.log +sql_error_log_rate 1 +sql_error_log_rotate OFF +sql_error_log_rotations 9 +sql_error_log_size_limit 1000000 +sql_error_log_with_db_and_thread_info ON +set global sql_error_log_rate=1; +select * from t_doesnt_exist; +ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist +THREAD_ID DATABASE_NAME TIME HOSTNAME ERROR 1146: Table 'test.t_doesnt_exist' doesn't exist : select * from t_doesnt_exist diff --git a/mysql-test/suite/plugins/r/sql_error_log.result b/mysql-test/suite/plugins/r/sql_error_log.result index 98dfe0374fd..585457f5ee2 100644 --- a/mysql-test/suite/plugins/r/sql_error_log.result +++ b/mysql-test/suite/plugins/r/sql_error_log.result @@ -8,6 +8,7 @@ sql_error_log_rate 1 sql_error_log_rotate OFF sql_error_log_rotations 9 sql_error_log_size_limit 1000000 +sql_error_log_with_db_and_thread_info OFF set global sql_error_log_rate=1; select * from t_doesnt_exist; ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist diff --git a/mysql-test/suite/plugins/t/mdev_27087.opt b/mysql-test/suite/plugins/t/mdev_27087.opt new file mode 100644 index 00000000000..53c8ec8f812 --- /dev/null +++ b/mysql-test/suite/plugins/t/mdev_27087.opt @@ -0,0 +1 @@ +--plugin-load-add=$SQL_ERRLOG_SO --sql-error-log-with-db-and-thread-info=1 diff --git a/mysql-test/suite/plugins/t/mdev_27087.test b/mysql-test/suite/plugins/t/mdev_27087.test new file mode 100644 index 00000000000..ddd677b6681 --- /dev/null +++ b/mysql-test/suite/plugins/t/mdev_27087.test @@ -0,0 +1,18 @@ +--source include/not_embedded.inc + +if (!$SQL_ERRLOG_SO) { + skip No SQL_ERROR_LOG plugin; +} + +show variables like 'sql_error_log%'; +set global sql_error_log_rate=1; +--error ER_NO_SUCH_TABLE +select * from t_doesnt_exist; + +let $MYSQLD_DATADIR= `SELECT @@datadir`; +--let SEARCH_FILE= $MYSQLD_DATADIR/sql_errors.log +--let LINES_TO_READ=1 +--replace_regex /[1-9]* test [1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [^E]*/THREAD_ID DATABASE_NAME TIME HOSTNAME / +--source include/read_head.inc + +remove_file $MYSQLD_DATADIR/sql_errors.log; diff --git a/plugin/sql_errlog/sql_errlog.c b/plugin/sql_errlog/sql_errlog.c index e0ebd6b7737..619dc2e227e 100644 --- a/plugin/sql_errlog/sql_errlog.c +++ b/plugin/sql_errlog/sql_errlog.c @@ -39,6 +39,7 @@ static unsigned int rate; static unsigned long long size_limit; static unsigned int rotations; static char rotate; +static char with_db_and_thread_info; static unsigned int count; LOGGER_HANDLE *logfile; @@ -67,12 +68,19 @@ static MYSQL_SYSVAR_STR(filename, filename, "The file to log sql errors to", NULL, NULL, "sql_errors.log"); +static MYSQL_SYSVAR_BOOL(with_db_and_thread_info, with_db_and_thread_info, + PLUGIN_VAR_READONLY | PLUGIN_VAR_OPCMDARG, + "Show details about thread id and database name in the log", + NULL, NULL, + 0); + static struct st_mysql_sys_var* vars[] = { MYSQL_SYSVAR(rate), MYSQL_SYSVAR(size_limit), MYSQL_SYSVAR(rotations), MYSQL_SYSVAR(rotate), MYSQL_SYSVAR(filename), + MYSQL_SYSVAR(with_db_and_thread_info), NULL }; @@ -93,12 +101,24 @@ static void log_sql_errors(MYSQL_THD thd __attribute__((unused)), count = 0; (void) localtime_r(&event_time, &t); - logger_printf(logfile, "%04d-%02d-%02d %2d:%02d:%02d " + if (with_db_and_thread_info) + { + logger_printf(logfile, "%llu %s %04d-%02d-%02d %2d:%02d:%02d " + "%s ERROR %d: %s : %s \n", + event->general_thread_id, event->database.str, t.tm_year + 1900, + t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, + event->general_user, event->general_error_code, + event->general_command, event->general_query); + } + else + { + logger_printf(logfile, "%04d-%02d-%02d %2d:%02d:%02d " "%s ERROR %d: %s : %s\n", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, event->general_user, event->general_error_code, event->general_command, event->general_query); + } } } } @@ -157,7 +177,7 @@ maria_declare_plugin(sql_errlog) 0x0100, NULL, vars, - "1.0", + "1.1", MariaDB_PLUGIN_MATURITY_STABLE } maria_declare_plugin_end; From ee7cc0a466ac8a781f326d35cfa52d352a3ffc8c Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Tue, 9 Jan 2024 15:19:29 +0530 Subject: [PATCH 23/61] MDEV-32906: The SQL error plugin prints (null) as database if the mariadb client is not using any database to execute the SQL. Analysis: When there is no database, the database string is NULL so (null) gets printed. Fix: Print NULL instead of (null) because when there is no database SELECT DATABASE() return NULL. SO NULL is more appropriate choice. --- mysql-test/suite/plugins/r/mdev_27087.result | 12 ----- .../plugins/r/sql_error_log_withdbinfo.result | 37 ++++++++++++++ mysql-test/suite/plugins/t/mdev_27087.test | 18 ------- ...27087.opt => sql_error_log_withdbinfo.opt} | 2 +- .../plugins/t/sql_error_log_withdbinfo.test | 49 +++++++++++++++++++ plugin/sql_errlog/sql_errlog.c | 20 ++++++-- 6 files changed, 104 insertions(+), 34 deletions(-) delete mode 100644 mysql-test/suite/plugins/r/mdev_27087.result create mode 100644 mysql-test/suite/plugins/r/sql_error_log_withdbinfo.result delete mode 100644 mysql-test/suite/plugins/t/mdev_27087.test rename mysql-test/suite/plugins/t/{mdev_27087.opt => sql_error_log_withdbinfo.opt} (62%) create mode 100644 mysql-test/suite/plugins/t/sql_error_log_withdbinfo.test diff --git a/mysql-test/suite/plugins/r/mdev_27087.result b/mysql-test/suite/plugins/r/mdev_27087.result deleted file mode 100644 index 9cffceaa4db..00000000000 --- a/mysql-test/suite/plugins/r/mdev_27087.result +++ /dev/null @@ -1,12 +0,0 @@ -show variables like 'sql_error_log%'; -Variable_name Value -sql_error_log_filename sql_errors.log -sql_error_log_rate 1 -sql_error_log_rotate OFF -sql_error_log_rotations 9 -sql_error_log_size_limit 1000000 -sql_error_log_with_db_and_thread_info ON -set global sql_error_log_rate=1; -select * from t_doesnt_exist; -ERROR 42S02: Table 'test.t_doesnt_exist' doesn't exist -THREAD_ID DATABASE_NAME TIME HOSTNAME ERROR 1146: Table 'test.t_doesnt_exist' doesn't exist : select * from t_doesnt_exist diff --git a/mysql-test/suite/plugins/r/sql_error_log_withdbinfo.result b/mysql-test/suite/plugins/r/sql_error_log_withdbinfo.result new file mode 100644 index 00000000000..649d91269b6 --- /dev/null +++ b/mysql-test/suite/plugins/r/sql_error_log_withdbinfo.result @@ -0,0 +1,37 @@ +show variables like 'sql_error_log%'; +Variable_name Value +sql_error_log_filename sql_errors.log +sql_error_log_rate 1 +sql_error_log_rotate OFF +sql_error_log_rotations 9 +sql_error_log_size_limit 1000000 +sql_error_log_with_db_and_thread_info ON +set global sql_error_log_rate=1; +# Trying to set the variable at runtime +SET sql_error_log_with_db_and_thread_info=OFF; +ERROR HY000: Variable 'sql_error_log_with_db_and_thread_info' is a read only variable +# +# Using test database from mtr +# +DROP DATABASE db; +ERROR HY000: Can't drop database 'db'; database doesn't exist +# +# Using no database at all +# +DROP DATABASE test; +DROP DATABASE db; +ERROR HY000: Can't drop database 'db'; database doesn't exist +# +# Using database with name `NULL` +# +CREATE DATABASE `NULL`; +USE `NULL`; +DROP DATABASE db; +ERROR HY000: Can't drop database 'db'; database doesn't exist +THREAD_ID `test` TIME HOSTNAME ERROR 1238: Variable 'sql_error_log_with_db_and_thread_info' is a read only variable : SET sql_error_log_with_db_and_thread_info=OFF +THREAD_ID `test` TIME HOSTNAME ERROR 1008: Can't drop database 'db'; database doesn't exist : DROP DATABASE db +THREAD_ID NULL TIME HOSTNAME ERROR 1008: Can't drop database 'db'; database doesn't exist : DROP DATABASE db +THREAD_ID `NULL` TIME HOSTNAME ERROR 1008: Can't drop database 'db'; database doesn't exist : DROP DATABASE db +DROP DATABASE `NULL`; +# Reset +CREATE DATABASE test; diff --git a/mysql-test/suite/plugins/t/mdev_27087.test b/mysql-test/suite/plugins/t/mdev_27087.test deleted file mode 100644 index ddd677b6681..00000000000 --- a/mysql-test/suite/plugins/t/mdev_27087.test +++ /dev/null @@ -1,18 +0,0 @@ ---source include/not_embedded.inc - -if (!$SQL_ERRLOG_SO) { - skip No SQL_ERROR_LOG plugin; -} - -show variables like 'sql_error_log%'; -set global sql_error_log_rate=1; ---error ER_NO_SUCH_TABLE -select * from t_doesnt_exist; - -let $MYSQLD_DATADIR= `SELECT @@datadir`; ---let SEARCH_FILE= $MYSQLD_DATADIR/sql_errors.log ---let LINES_TO_READ=1 ---replace_regex /[1-9]* test [1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [^E]*/THREAD_ID DATABASE_NAME TIME HOSTNAME / ---source include/read_head.inc - -remove_file $MYSQLD_DATADIR/sql_errors.log; diff --git a/mysql-test/suite/plugins/t/mdev_27087.opt b/mysql-test/suite/plugins/t/sql_error_log_withdbinfo.opt similarity index 62% rename from mysql-test/suite/plugins/t/mdev_27087.opt rename to mysql-test/suite/plugins/t/sql_error_log_withdbinfo.opt index 53c8ec8f812..7d502896977 100644 --- a/mysql-test/suite/plugins/t/mdev_27087.opt +++ b/mysql-test/suite/plugins/t/sql_error_log_withdbinfo.opt @@ -1 +1 @@ ---plugin-load-add=$SQL_ERRLOG_SO --sql-error-log-with-db-and-thread-info=1 +--plugin-load-add=$SQL_ERRLOG_SO --sql-error-log-with-db-and-thread-info=1 --lower_case_table_names=2 diff --git a/mysql-test/suite/plugins/t/sql_error_log_withdbinfo.test b/mysql-test/suite/plugins/t/sql_error_log_withdbinfo.test new file mode 100644 index 00000000000..bddcc14e275 --- /dev/null +++ b/mysql-test/suite/plugins/t/sql_error_log_withdbinfo.test @@ -0,0 +1,49 @@ +--source include/not_embedded.inc + +if (!$SQL_ERRLOG_SO) { + skip No SQL_ERROR_LOG plugin; +} + +show variables like 'sql_error_log%'; +set global sql_error_log_rate=1; + +let $MYSQLD_DATADIR= `SELECT @@datadir`; + +--echo # Trying to set the variable at runtime + +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SET sql_error_log_with_db_and_thread_info=OFF; + +--echo # +--echo # Using test database from mtr +--echo # + +--error ER_DB_DROP_EXISTS +DROP DATABASE db; + +--echo # +--echo # Using no database at all +--echo # + +DROP DATABASE test; +--error ER_DB_DROP_EXISTS +DROP DATABASE db; + +--echo # +--echo # Using database with name `NULL` +--echo # +CREATE DATABASE `NULL`; +USE `NULL`; +--error ER_DB_DROP_EXISTS +DROP DATABASE db; + + +--let SEARCH_FILE= $MYSQLD_DATADIR/sql_errors.log +--let LINES_TO_READ=4 +--replace_regex /[1-9]* `NULL` [1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [^E]*/THREAD_ID `NULL` TIME HOSTNAME / /[1-9]* `test` [1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [^E]*/THREAD_ID `test` TIME HOSTNAME / /[1-9]* NULL [1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [^E]*/THREAD_ID NULL TIME HOSTNAME / +--source include/read_head.inc + +DROP DATABASE `NULL`; + +--echo # Reset +CREATE DATABASE test; diff --git a/plugin/sql_errlog/sql_errlog.c b/plugin/sql_errlog/sql_errlog.c index 619dc2e227e..a3f36fc966e 100644 --- a/plugin/sql_errlog/sql_errlog.c +++ b/plugin/sql_errlog/sql_errlog.c @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -91,6 +92,7 @@ static void log_sql_errors(MYSQL_THD thd __attribute__((unused)), { const struct mysql_event_general *event = (const struct mysql_event_general*)ev; + if (rate && event->event_subclass == MYSQL_AUDIT_GENERAL_ERROR) { @@ -103,12 +105,24 @@ static void log_sql_errors(MYSQL_THD thd __attribute__((unused)), (void) localtime_r(&event_time, &t); if (with_db_and_thread_info) { - logger_printf(logfile, "%llu %s %04d-%02d-%02d %2d:%02d:%02d " + if (event->database.str) + { + logger_printf(logfile, "%llu %`s %04d-%02d-%02d %2d:%02d:%02d " "%s ERROR %d: %s : %s \n", event->general_thread_id, event->database.str, t.tm_year + 1900, - t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, - event->general_user, event->general_error_code, + t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, + t.tm_sec, event->general_user, event->general_error_code, event->general_command, event->general_query); + } + else + { + logger_printf(logfile, "%llu %s %04d-%02d-%02d %2d:%02d:%02d " + "%s ERROR %d: %s : %s \n", + event->general_thread_id, "NULL", t.tm_year + 1900, + t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, + t.tm_sec, event->general_user, event->general_error_code, + event->general_command, event->general_query); + } } else { From 81d01855fecbf60b87dbac5b44d3db7c0e6f37ef Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 23 Jan 2024 13:22:58 +0400 Subject: [PATCH 24/61] MDEV-28651 quote(NULL) returns incorrect result in view ('NU' instead of 'NULL') Item_func_quote did not calculate its max_length correctly for nullable arguments. Fix: In case if the argument is nullable, reserve at least 4 characters so the string "NULL" fits. --- mysql-test/main/func_str.result | 27 +++++++++++++++++++++++++++ mysql-test/main/func_str.test | 22 ++++++++++++++++++++++ sql/item_strfunc.h | 3 +++ 3 files changed, 52 insertions(+) diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index b4f25c34848..a47c149fb0d 100644 --- a/mysql-test/main/func_str.result +++ b/mysql-test/main/func_str.result @@ -5286,3 +5286,30 @@ ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' # # End of 10.4 tests # +# +# Start of 10.5 tests +# +# +# MDEV-28651 quote(NULL) returns incorrect result in view ('NU' instead of 'NULL') +# +CREATE VIEW v1 AS SELECT quote(NULL); +SELECT * FROM v1; +quote(NULL) +NULL +DESCRIBE v1; +Field Type Null Key Default Extra +quote(NULL) varbinary(4) YES NULL +CREATE TABLE t1 AS SELECT * FROM v1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `quote(NULL)` varbinary(4) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * FROM t1; +quote(NULL) +NULL +DROP TABLE t1; +DROP VIEW v1; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test index b452ed1fe90..69161349720 100644 --- a/mysql-test/main/func_str.test +++ b/mysql-test/main/func_str.test @@ -2329,3 +2329,25 @@ SELECT DECODE(NULL, NULL, NULL); --echo # --echo # End of 10.4 tests --echo # + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-28651 quote(NULL) returns incorrect result in view ('NU' instead of 'NULL') +--echo # + +CREATE VIEW v1 AS SELECT quote(NULL); +SELECT * FROM v1; +DESCRIBE v1; +CREATE TABLE t1 AS SELECT * FROM v1; +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; +DROP VIEW v1; + + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index f9dba473e71..e770c3bff98 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -1504,6 +1504,9 @@ public: collation.set(args[0]->collation); ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 + 2 * collation.collation->mbmaxlen; + // NULL argument is returned as a string "NULL" without quotes + if (args[0]->maybe_null) + set_if_bigger(max_result_length, 4 * collation.collation->mbmaxlen); max_length= (uint32) MY_MIN(max_result_length, MAX_BLOB_WIDTH); return FALSE; } From 7af50e4df456761c433838f0e65e88b9117f298c Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Wed, 8 Nov 2023 16:57:58 -0700 Subject: [PATCH 25/61] MDEV-32551: "Read semi-sync reply magic number error" warnings on master MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rpl_semi_sync_slave_enabled_consistent.test and the first part of the commit message comes from Brandon Nesterenko. A test to show how to induce the "Read semi-sync reply magic number error" message on a primary. In short, if semi-sync is turned on during the hand-shake process between a primary and replica, but later a user negates the rpl_semi_sync_slave_enabled variable while the replica's IO thread is running; if the io thread exits, the replica can skip a necessary call to kill_connection() in repl_semisync_slave.slave_stop() due to its reliance on a global variable. Then, the replica will send a COM_QUIT packet to the primary on an active semi-sync connection, causing the magic number error. The test in this patch exits the IO thread by forcing an error; though note a call to STOP SLAVE could also do this, but it ends up needing more synchronization. That is, the STOP SLAVE command also tries to kill the VIO of the replica, which makes a race with the IO thread to try and send the COM_QUIT before this happens (which would need more debug_sync to get around). See THD::awake_no_mutex for details as to the killing of the replica’s vio. Notes: - The MariaDB documentation does not make it clear that when one enables semi-sync replication it does not matter if one enables it first in the master or slave. Any order works. Changes done: - The rpl_semi_sync_slave_enabled variable is now a default value for when semisync is started. The variable does not anymore affect semisync if it is already running. This fixes the original reported bug. Internally we now use repl_semisync_slave.get_slave_enabled() instead of rpl_semi_sync_slave_enabled. To check if semisync is active on should check the @@rpl_semi_sync_slave_status variable (as before). - The semisync protocol conflicts in the way that the original MySQL/MariaDB client-server protocol was designed (client-server send and reply packets are strictly ordered and includes a packet number to allow one to check if a packet is lost). When using semi-sync the master and slave can send packets at 'any time', so packet numbering does not work. The 'solution' has been that each communication starts with packet number 1, but in some cases there is still a chance that the packet number check can fail. Fixed by adding a flag (pkt_nr_can_be_reset) in the NET struct that one can use to signal that packet number checking should not be done. This is flag is set when semi-sync is used. - Added Master_info::semi_sync_reply_enabled to allow one to configure some slaves with semisync and other other slaves without semisync. Removed global variable semi_sync_need_reply that would not work with multi-master. - Repl_semi_sync_master::report_reply_packet() can now recognize the COM_QUIT packet from semisync slave and not give a "Read semi-sync reply magic number error" error for this case. The slave will be removed from the Ack listener. - On Windows, don't stop semisync Ack listener just because one slave connection is using socket_id > FD_SETSIZE. - Removed busy loop in Ack_receiver::run() by using "Self-pipe trick" to signal new slave and stop Ack_receiver. - Changed some Repl_semi_sync_slave functions that always returns 0 from int to void. - Added Repl_semi_sync_slave::slave_reconnect(). - Removed dummy_function Repl_semi_sync_slave::reset_slave(). - Removed some duplicate semisync notes from the error log. - Add test of "if (get_slave_enabled() && semi_sync_need_reply)" before calling Repl_semi_sync_slave::slave_reply(). (Speeds up the code as we can skip all initializations). - If epl_semisync_slave.slave_reply() fails, we disable semisync for that connection. - We do not call semisync.switch_off() if there are no active slaves. Instead we check in Repl_semi_sync_master::commit_trx() if there are no active threads. This simplices the code. - Changed assert() to DBUG_ASSERT() to ensure that the DBUG log is flushed in case of asserts. - Removed the internal rpl_semi_sync_slave_status as it is not needed anymore. The @@rpl_semi_sync_slave_status status variable is now mapped to rpl_semi_sync_enabled. - Removed rpl_semi_sync_slave_enabled as it is not needed anymore. Repl_semi_sync_slave::get_slave_enabled() contains the active status. - Added checking that we do not add a slave twice with Ack_receiver::add_slave(). This could happen with old code. - Removed Repl_semi_sync_master::check_and_switch() as it is not needed anymore. - Ensure that when we call Ack_receiver::remove_slave() that the slave is removed from the listener before function returns. - Call listener.listen_on_sockets() outside of mutex for better performance and less contested mutex. - Ensure that listening is ignoring newly added slaves when checking for responses. - Fixed the master ack_receiver listener is not killed if there are no connected slaves (and thus stop semisync handling of future connections). This could happen if all slaves sockets where would be marked as unreliable. - Added unlink() to base_ilist_iterator and remove() to I_List_iterator. This enables us to remove 'dead' slaves in Ack_recever::run(). - kill_zombie_dump_threads() now does killing of dump threads properly. - It can now kill several threads (should be impossible but could happen if IO slaves reconnects very fast). - We now wait until the dump thread is done before starting the dump. - Added an error if kill_zombie_dump_threads() fails. - Set thd->variables.server_id before calling kill_zombie_dump_threads(). This simplies the code. - Added a lot of comments both in code and tests. - Removed DBUG_EVALUATE_IF "failed_slave_start" as it is not used. Test changes: - rpl.rpl_session_var2 added which runs rpl.rpl_session_var test with semisync enabled. - Some timings changed slight with startup of slave which caused rpl_binlog_dump_slave_gtid_state_info.text to fail as it checked the error log file before the slave had started properly. Fixed by adding wait_for_pattern_in_file.inc that allows waiting for the pattern to appear in the log file. - Tests have been updated so that we first set rpl_semi_sync_master_enabled on the master and then set rpl_semi_sync_slave_enabled on the slaves (this is according to how the MariaDB documentation document how to setup semi-sync). - Error text "Master server does not have semi-sync enabled" has been replaced with "Master server does not support semi-sync" for the case when the master supports semi-sync but semi-sync is not enabled. Other things: - Some trivial cleanups in Repl_semi_sync_master::update_sync_header(). - We should in 11.3 changed the default value for rpl-semi-sync-master-wait-no-slave from TRUE to FALSE as the TRUE does not make much sense as default. The main difference with using FALSE is that we do not wait for semisync Ack if there are no slave threads. In the case of TRUE we wait once, which did not bring any notable benefits except slower startup of master configured for using semisync. Co-author: Brandon Nesterenko This solves the problem reported in MDEV-32960 where a new slave may not be registered in time and the master disables semi sync because of that. --- include/mysql_com.h | 2 +- mysql-test/include/search_pattern_in_file.inc | 40 +++- .../include/wait_for_pattern_in_file.inc | 56 ++++++ mysql-test/main/mysqld--help.result | 2 +- .../binlog_encryption/rpl_semi_sync.result | 13 +- ...l_binlog_dump_slave_gtid_state_info.result | 4 + .../suite/rpl/r/rpl_circular_semi_sync.result | 4 + .../suite/rpl/r/rpl_delayed_slave.result | 3 + mysql-test/suite/rpl/r/rpl_semi_sync.result | 13 +- .../rpl/r/rpl_semi_sync_after_sync.result | 13 +- .../rpl/r/rpl_semi_sync_after_sync_row.result | 13 +- .../suite/rpl/r/rpl_semi_sync_event.result | 1 - .../r/rpl_semi_sync_event_after_sync.result | 1 - .../rpl/r/rpl_semi_sync_fail_over.result | 2 +- ..._sync_no_missed_ack_after_add_slave.result | 48 +++++ ..._semi_sync_slave_enabled_consistent.result | 35 ++++ .../r/rpl_semi_sync_slave_reply_fail.result | 5 +- .../rpl/r/rpl_semisync_ali_issues.result | 3 +- mysql-test/suite/rpl/r/rpl_session_var.result | 11 ++ .../suite/rpl/r/rpl_session_var2.result | 69 +++++++ ...rpl_binlog_dump_slave_gtid_state_info.test | 8 +- .../suite/rpl/t/rpl_circular_semi_sync.test | 11 ++ mysql-test/suite/rpl/t/rpl_delayed_slave.test | 6 + .../rpl/t/rpl_mariadb_slave_capability.test | 2 +- mysql-test/suite/rpl/t/rpl_semi_sync.test | 20 +- .../suite/rpl/t/rpl_semi_sync_event.test | 1 - .../suite/rpl/t/rpl_semi_sync_fail_over.test | 2 +- ...emi_sync_no_missed_ack_after_add_slave.cnf | 12 ++ ...mi_sync_no_missed_ack_after_add_slave.test | 122 ++++++++++++ ...pl_semi_sync_slave_enabled_consistent.test | 73 ++++++++ .../rpl/t/rpl_semi_sync_slave_reply_fail.test | 5 +- .../suite/rpl/t/rpl_semisync_ali_issues.test | 1 - mysql-test/suite/rpl/t/rpl_session_var.test | 6 + .../suite/rpl/t/rpl_session_var2-master.opt | 1 + .../suite/rpl/t/rpl_session_var2-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_session_var2.test | 3 + .../t/rpl_shutdown_wait_semisync_slaves.test | 3 + .../r/sysvars_server_notembedded.result | 2 +- sql/log.cc | 2 +- sql/mysqld.cc | 2 +- sql/net_serv.cc | 33 +++- sql/rpl_mi.cc | 2 +- sql/rpl_mi.h | 6 + sql/semisync_master.cc | 175 +++++++++--------- sql/semisync_master.h | 2 - sql/semisync_master_ack_receiver.cc | 120 +++++++++--- sql/semisync_master_ack_receiver.h | 146 ++++++++++++--- sql/semisync_slave.cc | 153 ++++++++------- sql/semisync_slave.h | 22 ++- sql/slave.cc | 59 ++++-- sql/sql_class.cc | 8 - sql/sql_class.h | 9 + sql/sql_list.h | 18 +- sql/sql_parse.cc | 27 ++- sql/sql_repl.cc | 102 +++++++--- sql/sql_repl.h | 2 +- sql/sys_vars.cc | 26 +-- 57 files changed, 1171 insertions(+), 360 deletions(-) create mode 100644 mysql-test/include/wait_for_pattern_in_file.inc create mode 100644 mysql-test/suite/rpl/r/rpl_semi_sync_no_missed_ack_after_add_slave.result create mode 100644 mysql-test/suite/rpl/r/rpl_semi_sync_slave_enabled_consistent.result create mode 100644 mysql-test/suite/rpl/r/rpl_session_var2.result create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_no_missed_ack_after_add_slave.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_no_missed_ack_after_add_slave.test create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_slave_enabled_consistent.test create mode 100644 mysql-test/suite/rpl/t/rpl_session_var2-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_session_var2-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_session_var2.test diff --git a/include/mysql_com.h b/include/mysql_com.h index b837704c19d..2cdda8457ea 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -477,7 +477,7 @@ typedef struct st_net { char net_skip_rest_factor; my_bool thread_specific_malloc; unsigned char compress; - my_bool unused3; /* Please remove with the next incompatible ABI change. */ + my_bool pkt_nr_can_be_reset; /* Pointer to query object in query cache, do not equal NULL (0) for queries in cache that have not stored its results yet diff --git a/mysql-test/include/search_pattern_in_file.inc b/mysql-test/include/search_pattern_in_file.inc index a899a9294cc..3105f7f9077 100644 --- a/mysql-test/include/search_pattern_in_file.inc +++ b/mysql-test/include/search_pattern_in_file.inc @@ -51,12 +51,15 @@ # Created: 2011-11-11 mleich # +--error 0,1 perl; use strict; die "SEARCH_FILE not set" unless $ENV{SEARCH_FILE}; my @search_files= glob($ENV{SEARCH_FILE}); my $search_pattern= $ENV{SEARCH_PATTERN} or die "SEARCH_PATTERN not set"; my $search_range= $ENV{SEARCH_RANGE}; + my $silent= $ENV{SEARCH_SILENT}; + my $search_result= 0; my $content; foreach my $search_file (@search_files) { open(FILE, '<', $search_file) || die("Can't open file $search_file: $!"); @@ -89,16 +92,39 @@ perl; { @matches=($content =~ /$search_pattern/gm); } - my $res=@matches ? "FOUND " . scalar(@matches) : "NOT FOUND"; + my $res; + if (@matches) + { + $res="FOUND " . scalar(@matches); + $search_result= 1; + } + else + { + $res= "NOT FOUND"; + } $ENV{SEARCH_FILE} =~ s{^.*?([^/\\]+)$}{$1}; - if ($ENV{SEARCH_OUTPUT} eq "matches") { - foreach (@matches) { - print $_ . "\n"; - } - } else { - print "$res /$search_pattern/ in $ENV{SEARCH_FILE}\n"; + if (!$silent || $search_result) + { + if ($ENV{SEARCH_OUTPUT} eq "matches") + { + foreach (@matches) + { + print $_ . "\n"; + } + } + else + { + print "$res /$search_pattern/ in $ENV{SEARCH_FILE}\n"; + } } die "$ENV{SEARCH_ABORT}\n" if $ENV{SEARCH_ABORT} && $res =~ /^$ENV{SEARCH_ABORT}/; + exit($search_result != 1); EOF + +let $SEARCH_RESULT= 1; # Found pattern +if ($errno) +{ + let $SEARCH_RESULT= 0; # Did not find pattern +} diff --git a/mysql-test/include/wait_for_pattern_in_file.inc b/mysql-test/include/wait_for_pattern_in_file.inc new file mode 100644 index 00000000000..52226acd2da --- /dev/null +++ b/mysql-test/include/wait_for_pattern_in_file.inc @@ -0,0 +1,56 @@ +# ==== Purpose ==== +# +# Waits until pattern comes into log file or until a timeout is reached. +# This is a timeout wrapper for search_pattern_in_file.inc +# +# +# ==== Usage ==== +# +# [--let $timeout= NUMBER in seconds] +# For other parameters, check search_pattern_in_file.inc + +--let $wait_save_keep_include_silent=$keep_include_silent +--let $include_filename= wait_for_pattern_in_file.inc +--source include/begin_include_file.inc +--let $keep_include_silent= 1 + +let $_timeout= $timeout; +if (!$_timeout) +{ + let $_timeout= 10; + if ($VALGRIND_TEST) + { + let $_timeout= 30; + } +} + +let $_timeout_counter=`SELECT $_timeout * 10`; +let SEARCH_SILENT=1; + +let $_continue= 1; +while ($_continue) +{ + source include/search_pattern_in_file.inc; + if ($SEARCH_RESULT) + { + # Found match + let $_continue= 0; + } + if (!$SEARCH_RESULT) + { + dec $_timeout_counter; + if ($_timeout_counter == 1) + { + let $SEARCH_SILENT= 0; + } + if (!$_timeout_counter) + { + let $_continue= 0; + } + } +} + +let SEARCH_SILENT=0; + +--source include/end_include_file.inc +--let $keep_include_silent=$wait_save_keep_include_silent diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index 62119751ac2..219bad22528 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -1138,7 +1138,7 @@ The following specify which files/extra groups are read (specified before remain The tracing level for semi-sync replication. --rpl-semi-sync-master-wait-no-slave Wait until timeout when no semi-synchronous replication - slave available (enabled by default). + slave is available. (Defaults to on; use --skip-rpl-semi-sync-master-wait-no-slave to disable.) --rpl-semi-sync-master-wait-point=name Should transaction wait for semi-sync ack after having diff --git a/mysql-test/suite/binlog_encryption/rpl_semi_sync.result b/mysql-test/suite/binlog_encryption/rpl_semi_sync.result index d18bd1efda7..cff1a73996d 100644 --- a/mysql-test/suite/binlog_encryption/rpl_semi_sync.result +++ b/mysql-test/suite/binlog_encryption/rpl_semi_sync.result @@ -6,7 +6,6 @@ call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("mysqld: Got an error reading communication packets"); connection slave; -call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); connection master; @@ -26,7 +25,7 @@ set global rpl_semi_sync_slave_enabled= 0; # Main test of semi-sync replication start here # connection master; -set global rpl_semi_sync_master_timeout= 60000; +set global rpl_semi_sync_master_timeout= 2000; [ default state of semi-sync on master should be OFF ] show variables like 'rpl_semi_sync_master_enabled'; Variable_name Value @@ -161,11 +160,15 @@ connection slave; # Test semi-sync master will switch OFF after one transaction # timeout waiting for slave reply. # +connection master; +show status like "Rpl_semi_sync_master_status"; +Variable_name Value +Rpl_semi_sync_master_status ON connection slave; include/stop_slave.inc connection master; include/kill_binlog_dump_threads.inc -set global rpl_semi_sync_master_timeout= 5000; +set global rpl_semi_sync_master_timeout= 2000; [ master status should be ON ] show status like 'Rpl_semi_sync_master_no_tx'; Variable_name Value @@ -315,6 +318,8 @@ include/kill_binlog_dump_threads.inc connection slave; include/start_slave.inc connection master; +connection slave; +connection master; create table t1 (a int) engine = ENGINE_TYPE; insert into t1 values (1); insert into t1 values (2), (3); @@ -357,6 +362,8 @@ show status like 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status ON connection master; +connection slave; +connection master; [ master semi-sync should be ON ] show status like 'Rpl_semi_sync_master_clients'; Variable_name Value diff --git a/mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result b/mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result index 98688df7273..38a9afd4d02 100644 --- a/mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result +++ b/mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result @@ -8,6 +8,7 @@ CHANGE MASTER TO MASTER_USE_GTID=current_pos; include/start_slave.inc connection master; "Test Case 1: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('')" +include/wait_for_pattern_in_file.inc FOUND 1 /using_gtid\(1\), gtid\(\'\'\).*/ in mysqld.1.err connection slave; include/stop_slave.inc @@ -15,6 +16,7 @@ CHANGE MASTER TO MASTER_USE_GTID=no; include/start_slave.inc connection master; "Test Case 2: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(0), gtid('')" +include/wait_for_pattern_in_file.inc FOUND 1 /using_gtid\(0\), gtid\(\'\'\).*/ in mysqld.1.err CREATE TABLE t (f INT) ENGINE=INNODB; INSERT INTO t VALUES(10); @@ -25,6 +27,7 @@ CHANGE MASTER TO MASTER_USE_GTID=slave_pos; include/start_slave.inc connection master; "Test Case 3: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('0-1-2')" +include/wait_for_pattern_in_file.inc FOUND 1 /using_gtid\(1\), gtid\(\'0-1-2\'\).*/ in mysqld.1.err SET @@SESSION.gtid_domain_id=10; INSERT INTO t VALUES(20); @@ -35,6 +38,7 @@ CHANGE MASTER TO MASTER_USE_GTID=slave_pos; include/start_slave.inc connection master; "Test Case 4: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('0-1-2,10-1-1')" +include/wait_for_pattern_in_file.inc FOUND 1 /using_gtid\(1\), gtid\(\'0-1-2,10-1-1\'\).*/ in mysqld.1.err "===== Clean up =====" connection slave; diff --git a/mysql-test/suite/rpl/r/rpl_circular_semi_sync.result b/mysql-test/suite/rpl/r/rpl_circular_semi_sync.result index 5664b7913d2..2596d346479 100644 --- a/mysql-test/suite/rpl/r/rpl_circular_semi_sync.result +++ b/mysql-test/suite/rpl/r/rpl_circular_semi_sync.result @@ -1,5 +1,7 @@ include/master-slave.inc [connection master] +connection server_2; +call mtr.add_suppression("Timeout waiting for reply of binlog"); # Master server_1 and Slave server_2 initialization ... connection server_2; include/stop_slave.inc @@ -40,6 +42,8 @@ set @@global.rpl_semi_sync_master_enabled = 1; INSERT INTO t1(a) VALUES (2); include/save_master_gtid.inc connection server_1; +include/stop_slave.inc +include/start_slave.inc # # the successful sync is a required proof # diff --git a/mysql-test/suite/rpl/r/rpl_delayed_slave.result b/mysql-test/suite/rpl/r/rpl_delayed_slave.result index e7daa3328ce..a48e98b0006 100644 --- a/mysql-test/suite/rpl/r/rpl_delayed_slave.result +++ b/mysql-test/suite/rpl/r/rpl_delayed_slave.result @@ -67,6 +67,9 @@ include/stop_slave.inc # CHANGE MASTER TO MASTER_DELAY = 2*T include/start_slave.inc connection master; +INSERT INTO t1 VALUES ('Syncing slave', 5); +connection slave; +connection master; INSERT INTO t1 VALUES (delay_on_slave(1), 6); Warnings: Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system variable that may have a different value on the slave diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync.result b/mysql-test/suite/rpl/r/rpl_semi_sync.result index d18bd1efda7..cff1a73996d 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync.result @@ -6,7 +6,6 @@ call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("mysqld: Got an error reading communication packets"); connection slave; -call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); connection master; @@ -26,7 +25,7 @@ set global rpl_semi_sync_slave_enabled= 0; # Main test of semi-sync replication start here # connection master; -set global rpl_semi_sync_master_timeout= 60000; +set global rpl_semi_sync_master_timeout= 2000; [ default state of semi-sync on master should be OFF ] show variables like 'rpl_semi_sync_master_enabled'; Variable_name Value @@ -161,11 +160,15 @@ connection slave; # Test semi-sync master will switch OFF after one transaction # timeout waiting for slave reply. # +connection master; +show status like "Rpl_semi_sync_master_status"; +Variable_name Value +Rpl_semi_sync_master_status ON connection slave; include/stop_slave.inc connection master; include/kill_binlog_dump_threads.inc -set global rpl_semi_sync_master_timeout= 5000; +set global rpl_semi_sync_master_timeout= 2000; [ master status should be ON ] show status like 'Rpl_semi_sync_master_no_tx'; Variable_name Value @@ -315,6 +318,8 @@ include/kill_binlog_dump_threads.inc connection slave; include/start_slave.inc connection master; +connection slave; +connection master; create table t1 (a int) engine = ENGINE_TYPE; insert into t1 values (1); insert into t1 values (2), (3); @@ -357,6 +362,8 @@ show status like 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status ON connection master; +connection slave; +connection master; [ master semi-sync should be ON ] show status like 'Rpl_semi_sync_master_clients'; Variable_name Value diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync.result b/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync.result index f2240817489..301e4c819e4 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync.result @@ -7,7 +7,6 @@ call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("mysqld: Got an error reading communication packets"); connection slave; -call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); connection master; @@ -27,7 +26,7 @@ set global rpl_semi_sync_slave_enabled= 0; # Main test of semi-sync replication start here # connection master; -set global rpl_semi_sync_master_timeout= 60000; +set global rpl_semi_sync_master_timeout= 2000; [ default state of semi-sync on master should be OFF ] show variables like 'rpl_semi_sync_master_enabled'; Variable_name Value @@ -162,11 +161,15 @@ connection slave; # Test semi-sync master will switch OFF after one transaction # timeout waiting for slave reply. # +connection master; +show status like "Rpl_semi_sync_master_status"; +Variable_name Value +Rpl_semi_sync_master_status ON connection slave; include/stop_slave.inc connection master; include/kill_binlog_dump_threads.inc -set global rpl_semi_sync_master_timeout= 5000; +set global rpl_semi_sync_master_timeout= 2000; [ master status should be ON ] show status like 'Rpl_semi_sync_master_no_tx'; Variable_name Value @@ -316,6 +319,8 @@ include/kill_binlog_dump_threads.inc connection slave; include/start_slave.inc connection master; +connection slave; +connection master; create table t1 (a int) engine = ENGINE_TYPE; insert into t1 values (1); insert into t1 values (2), (3); @@ -358,6 +363,8 @@ show status like 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status ON connection master; +connection slave; +connection master; [ master semi-sync should be ON ] show status like 'Rpl_semi_sync_master_clients'; Variable_name Value diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync_row.result b/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync_row.result index fcced801d65..6c7db8ca342 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync_row.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_after_sync_row.result @@ -7,7 +7,6 @@ call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("mysqld: Got an error reading communication packets"); connection slave; -call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); connection master; @@ -27,7 +26,7 @@ set global rpl_semi_sync_slave_enabled= 0; # Main test of semi-sync replication start here # connection master; -set global rpl_semi_sync_master_timeout= 60000; +set global rpl_semi_sync_master_timeout= 2000; [ default state of semi-sync on master should be OFF ] show variables like 'rpl_semi_sync_master_enabled'; Variable_name Value @@ -162,11 +161,15 @@ connection slave; # Test semi-sync master will switch OFF after one transaction # timeout waiting for slave reply. # +connection master; +show status like "Rpl_semi_sync_master_status"; +Variable_name Value +Rpl_semi_sync_master_status ON connection slave; include/stop_slave.inc connection master; include/kill_binlog_dump_threads.inc -set global rpl_semi_sync_master_timeout= 5000; +set global rpl_semi_sync_master_timeout= 2000; [ master status should be ON ] show status like 'Rpl_semi_sync_master_no_tx'; Variable_name Value @@ -316,6 +319,8 @@ include/kill_binlog_dump_threads.inc connection slave; include/start_slave.inc connection master; +connection slave; +connection master; create table t1 (a int) engine = ENGINE_TYPE; insert into t1 values (1); insert into t1 values (2), (3); @@ -358,6 +363,8 @@ show status like 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status ON connection master; +connection slave; +connection master; [ master semi-sync should be ON ] show status like 'Rpl_semi_sync_master_clients'; Variable_name Value diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_event.result b/mysql-test/suite/rpl/r/rpl_semi_sync_event.result index 917e7c2b02b..b1eb623cc99 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_event.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_event.result @@ -7,7 +7,6 @@ call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("mysqld: Got an error reading communication packets"); connection slave; -call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); connection master; diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_event_after_sync.result b/mysql-test/suite/rpl/r/rpl_semi_sync_event_after_sync.result index 24daf0d72b5..34af8d31315 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_event_after_sync.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_event_after_sync.result @@ -8,7 +8,6 @@ call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("mysqld: Got an error reading communication packets"); connection slave; -call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); connection master; diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_fail_over.result b/mysql-test/suite/rpl/r/rpl_semi_sync_fail_over.result index 8956eee2d2f..1c94c239fc6 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_fail_over.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_fail_over.result @@ -5,6 +5,7 @@ include/stop_slave.inc connection server_1; RESET MASTER; SET @@global.max_binlog_size= 4096; +set @@global.rpl_semi_sync_master_enabled = 1; connection server_2; RESET MASTER; SET @@global.max_binlog_size= 4096; @@ -14,7 +15,6 @@ CHANGE MASTER TO master_use_gtid= slave_pos; include/start_slave.inc connection server_1; ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; -set @@global.rpl_semi_sync_master_enabled = 1; set @@global.rpl_semi_sync_master_wait_point=AFTER_SYNC; CREATE TABLE t1 (a INT PRIMARY KEY, b MEDIUMTEXT) ENGINE=Innodb; INSERT INTO t1 VALUES (1, 'dummy1'); diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_no_missed_ack_after_add_slave.result b/mysql-test/suite/rpl/r/rpl_semi_sync_no_missed_ack_after_add_slave.result new file mode 100644 index 00000000000..19fed30ffb7 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_no_missed_ack_after_add_slave.result @@ -0,0 +1,48 @@ +include/rpl_init.inc [topology=1->2,1->3] +connection server_1; +set @old_enabled= @@global.rpl_semi_sync_master_enabled; +set @old_timeout= @@global.rpl_semi_sync_master_timeout; +set global rpl_semi_sync_master_enabled= 1; +set global rpl_semi_sync_master_timeout= 500; +connection server_2; +include/stop_slave.inc +set @old_enabled= @@global.rpl_semi_sync_slave_enabled; +set @old_dbug= @@global.debug_dbug; +set global rpl_semi_sync_slave_enabled= 1; +set global debug_dbug="+d,simulate_delay_semisync_slave_reply"; +include/start_slave.inc +connection server_3; +include/stop_slave.inc +set @old_enabled= @@global.rpl_semi_sync_slave_enabled; +set global rpl_semi_sync_slave_enabled= 1; +include/start_slave.inc +# Ensure primary recognizes both replicas are semi-sync +connection server_1; +connection server_1; +create table t1 (a int); +connection server_2; +# Verifying server_2 did not send ACK +connection server_3; +# Verifying server_3 did send ACK +connection server_1; +# Verifying master's semi-sync status is still ON (This failed pre-MDEV-32960 fixes) +# Verifying rpl_semi_sync_master_yes_tx incremented +# +# Cleanup +connection server_2; +set global rpl_semi_sync_slave_enabled= @old_enabled; +set global debug_dbug= @old_dbug; +include/stop_slave.inc +connection server_3; +set global rpl_semi_sync_slave_enabled= @old_enabled; +include/stop_slave.inc +connection server_1; +set global rpl_semi_sync_master_enabled= @old_enabled; +set global rpl_semi_sync_master_timeout= @old_timeout; +drop table t1; +connection server_2; +include/start_slave.inc +connection server_3; +include/start_slave.inc +include/rpl_end.inc +# End of rpl_semi_sync_no_missed_ack_after_add_slave.test diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_slave_enabled_consistent.result b/mysql-test/suite/rpl/r/rpl_semi_sync_slave_enabled_consistent.result new file mode 100644 index 00000000000..99c3124957f --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_slave_enabled_consistent.result @@ -0,0 +1,35 @@ +include/master-slave.inc +[connection master] +call mtr.add_suppression("Replication event checksum verification failed"); +call mtr.add_suppression("could not queue event from master"); +# +# Set up a semisync connection +connection master; +set @@global.rpl_semi_sync_master_enabled= ON; +connection slave; +stop slave io_thread; +set @@global.rpl_semi_sync_slave_enabled= ON; +set @old_dbug= @@global.debug_dbug; +set @@global.debug_dbug= "+d,corrupt_queue_event"; +set @@global.debug_dbug= "+d,pause_before_io_read_event"; +set @@global.debug_dbug= "+d,placeholder"; +start slave io_thread; +# Disable semi-sync on the slave while the IO thread is active +set debug_sync='now wait_for io_thread_at_read_event'; +set @@global.rpl_semi_sync_slave_enabled= OFF; +set debug_sync='now signal io_thread_continue_read_event'; +# Waiting for the slave to stop with the error from corrupt_queue_event +connection slave; +include/wait_for_slave_io_error.inc [errno=1595,1743] +# Sleep 1 to give time for Ack_receiver to receive COM_QUIT +include/assert_grep.inc [Check that there is no 'Read semi-sync reply magic number error' in error log.] +# +# Cleanup +connection slave; +include/stop_slave.inc +set @@global.debug_dbug= @old_dbug; +include/start_slave.inc +connection master; +set @@global.rpl_semi_sync_master_enabled= default; +include/rpl_end.inc +# End of rpl_semi_sync_slave_enabled_consistent.test diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_slave_reply_fail.result b/mysql-test/suite/rpl/r/rpl_semi_sync_slave_reply_fail.result index e482da7d0fc..3c9cf71aeca 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_slave_reply_fail.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_slave_reply_fail.result @@ -4,6 +4,7 @@ connection slave; include/stop_slave.inc connection master; call mtr.add_suppression("Timeout waiting for reply of binlog*"); +call mtr.add_suppression("Master server does not read semi-sync messages*"); set global rpl_semi_sync_master_enabled = ON; SET @@GLOBAL.rpl_semi_sync_master_timeout=100; create table t1 (i int); @@ -15,8 +16,8 @@ SET GLOBAL debug_dbug="+d,semislave_failed_net_flush"; include/start_slave.inc connection master; connection slave; -"Assert that the net_fulsh() reply failed is present in slave error log. -FOUND 1 /Semi-sync slave net_flush\(\) reply failed/ in mysqld.2.err +"Assert that Master server does not read semi-sync messages" is present in slave error log. +FOUND 1 /Master server does not read semi-sync messages/ in mysqld.2.err "Assert that Slave IO thread is up and running." SHOW STATUS LIKE 'Slave_running'; Variable_name Value diff --git a/mysql-test/suite/rpl/r/rpl_semisync_ali_issues.result b/mysql-test/suite/rpl/r/rpl_semisync_ali_issues.result index 530bbac633b..d7f87ae5fd3 100644 --- a/mysql-test/suite/rpl/r/rpl_semisync_ali_issues.result +++ b/mysql-test/suite/rpl/r/rpl_semisync_ali_issues.result @@ -14,7 +14,6 @@ CALL mtr.add_suppression("Failed on request_dump()*"); CALL mtr.add_suppression("Semi-sync master failed on*"); CALL mtr.add_suppression("Master command COM_BINLOG_DUMP failed*"); CALL mtr.add_suppression("on master failed*"); -CALL mtr.add_suppression("Master server does not support semi-sync*"); CALL mtr.add_suppression("Semi-sync slave net_flush*"); CALL mtr.add_suppression("Failed to flush master info*"); CALL mtr.add_suppression("Request to stop slave SQL Thread received while apply*"); @@ -196,7 +195,7 @@ Variable_name Value Rpl_semi_sync_master_clients 0 show status like 'Rpl_semi_sync_master_status'; Variable_name Value -Rpl_semi_sync_master_status OFF +Rpl_semi_sync_master_status ON connection slave; START SLAVE IO_THREAD; include/wait_for_slave_io_to_start.inc diff --git a/mysql-test/suite/rpl/r/rpl_session_var.result b/mysql-test/suite/rpl/r/rpl_session_var.result index 67863583f8d..f9794df3be7 100644 --- a/mysql-test/suite/rpl/r/rpl_session_var.result +++ b/mysql-test/suite/rpl/r/rpl_session_var.result @@ -1,5 +1,16 @@ include/master-slave.inc [connection master] +select @@rpl_semi_sync_master_enabled; +@@rpl_semi_sync_master_enabled +0 +connection slave; +select @@rpl_semi_sync_slave_enabled; +@@rpl_semi_sync_slave_enabled +0 +show status like "rpl_semi_sync_slave_status"; +Variable_name Value +Rpl_semi_sync_slave_status OFF +connection master; drop table if exists t1; Warnings: Note 1051 Unknown table 'test.t1' diff --git a/mysql-test/suite/rpl/r/rpl_session_var2.result b/mysql-test/suite/rpl/r/rpl_session_var2.result new file mode 100644 index 00000000000..645eca02492 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_session_var2.result @@ -0,0 +1,69 @@ +include/master-slave.inc +[connection master] +select @@rpl_semi_sync_master_enabled; +@@rpl_semi_sync_master_enabled +1 +connection slave; +select @@rpl_semi_sync_slave_enabled; +@@rpl_semi_sync_slave_enabled +1 +show status like "rpl_semi_sync_slave_status"; +Variable_name Value +Rpl_semi_sync_slave_status ON +connection master; +drop table if exists t1; +Warnings: +Note 1051 Unknown table 'test.t1' +create table t1(a varchar(100),b int); +set @@session.sql_mode=pipes_as_concat; +insert into t1 values('My'||'SQL', 1); +set @@session.sql_mode=default; +insert into t1 values('1'||'2', 2); +select * from t1 where b<3 order by a; +a b +1 2 +MySQL 1 +connection slave; +select * from t1 where b<3 order by a; +a b +1 2 +MySQL 1 +connection master; +set @@session.sql_mode=ignore_space; +insert into t1 values(password ('MySQL'), 3); +set @@session.sql_mode=ansi_quotes; +create table "t2" ("a" int); +drop table t1, t2; +set @@session.sql_mode=default; +create table t1(a int auto_increment primary key); +create table t2(b int, a int); +set @@session.sql_auto_is_null=1; +insert into t1 values(null); +insert into t2 select 1,a from t1 where a is null; +set @@session.sql_auto_is_null=0; +insert into t1 values(null); +insert into t2 select 2,a from t1 where a is null; +select * from t2 order by b; +b a +1 1 +connection slave; +select * from t2 order by b; +b a +1 1 +connection master; +drop table t1,t2; +connection slave; +connection master; +CREATE TABLE t1 ( +`id` int(11) NOT NULL auto_increment, +`data` varchar(100), +PRIMARY KEY (`id`) +) ENGINE=MyISAM; +INSERT INTO t1(data) VALUES(SESSION_USER()); +connection slave; +SELECT length(data) < 100 FROM t1; +length(data) < 100 +1 +connection master; +drop table t1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test b/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test index f26e9565671..942a23576c4 100644 --- a/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test +++ b/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test @@ -59,7 +59,7 @@ if(!$log_error_) --let SEARCH_FILE=$log_error_ --let SEARCH_RANGE=-50000 --let SEARCH_PATTERN=using_gtid\(1\), gtid\(\'\'\).* ---source include/search_pattern_in_file.inc +--source include/wait_for_pattern_in_file.inc --connection slave --source include/stop_slave.inc @@ -71,7 +71,7 @@ CHANGE MASTER TO MASTER_USE_GTID=no; --let SEARCH_FILE=$log_error_ --let SEARCH_RANGE=-50000 --let SEARCH_PATTERN=using_gtid\(0\), gtid\(\'\'\).* ---source include/search_pattern_in_file.inc +--source include/wait_for_pattern_in_file.inc CREATE TABLE t (f INT) ENGINE=INNODB; INSERT INTO t VALUES(10); save_master_pos; @@ -89,7 +89,7 @@ CHANGE MASTER TO MASTER_USE_GTID=slave_pos; --let SEARCH_FILE=$log_error_ --let SEARCH_RANGE=-50000 --let SEARCH_PATTERN=using_gtid\(1\), gtid\(\'0-1-2\'\).* ---source include/search_pattern_in_file.inc +--source include/wait_for_pattern_in_file.inc SET @@SESSION.gtid_domain_id=10; INSERT INTO t VALUES(20); save_master_pos; @@ -107,7 +107,7 @@ CHANGE MASTER TO MASTER_USE_GTID=slave_pos; --let SEARCH_FILE=$log_error_ --let SEARCH_RANGE=-50000 --let SEARCH_PATTERN=using_gtid\(1\), gtid\(\'0-1-2,10-1-1\'\).* ---source include/search_pattern_in_file.inc +--source include/wait_for_pattern_in_file.inc --echo "===== Clean up =====" --connection slave diff --git a/mysql-test/suite/rpl/t/rpl_circular_semi_sync.test b/mysql-test/suite/rpl/t/rpl_circular_semi_sync.test index 267fa621945..e533c54bdc1 100644 --- a/mysql-test/suite/rpl/t/rpl_circular_semi_sync.test +++ b/mysql-test/suite/rpl/t/rpl_circular_semi_sync.test @@ -7,6 +7,9 @@ --source include/have_binlog_format_mixed.inc --source include/master-slave.inc +connection server_2; +call mtr.add_suppression("Timeout waiting for reply of binlog"); + # The following tests prove # A. # no out-of-order gtid error is done to the stict gtid mode semisync @@ -66,10 +69,18 @@ evalp CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_2, ma --connection server_2 set @@global.gtid_strict_mode = true; set @@global.rpl_semi_sync_master_enabled = 1; + +# The following command is likely to cause the slave master is not yet setup +# for semi-sync + INSERT INTO t1(a) VALUES (2); --source include/save_master_gtid.inc --connection server_1 +# Update slave to notice that server_2 now has rpl_semi_sync_master_enabled +--source include/stop_slave.inc +--source include/start_slave.inc + --echo # --echo # the successful sync is a required proof --echo # diff --git a/mysql-test/suite/rpl/t/rpl_delayed_slave.test b/mysql-test/suite/rpl/t/rpl_delayed_slave.test index 7dd7b9cf6d9..b1a5a2eaee2 100644 --- a/mysql-test/suite/rpl/t/rpl_delayed_slave.test +++ b/mysql-test/suite/rpl/t/rpl_delayed_slave.test @@ -189,6 +189,12 @@ eval CHANGE MASTER TO MASTER_DELAY = $time2; --enable_query_log --source include/start_slave.inc +# Ensure that slave has started properly +--connection master +INSERT INTO t1 VALUES ('Syncing slave', 5); +--save_master_pos +--sync_slave_with_master + --connection master INSERT INTO t1 VALUES (delay_on_slave(1), 6); --save_master_pos diff --git a/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test b/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test index 18228e75e2e..de6af2f7b2e 100644 --- a/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test +++ b/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test @@ -11,7 +11,7 @@ set @old_master_binlog_checksum= @@global.binlog_checksum; # empty Gtid_list event # # Test this by binlog rotation before we log any GTIDs. -connection slave; +sync_slave_with_master; --source include/stop_slave.inc --echo # Test slave with no capability gets dummy event, which is ignored. set @old_dbug= @@global.debug_dbug; diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync.test b/mysql-test/suite/rpl/t/rpl_semi_sync.test index c3cd918b5fc..12f2d473c2b 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync.test @@ -17,7 +17,6 @@ call mtr.add_suppression("Read semi-sync reply"); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); call mtr.add_suppression("mysqld: Got an error reading communication packets"); connection slave; -call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); connection master; @@ -51,7 +50,7 @@ set global rpl_semi_sync_slave_enabled= 0; connection master; -set global rpl_semi_sync_master_timeout= 60000; # 60s +set global rpl_semi_sync_master_timeout= 2000; # 2s echo [ default state of semi-sync on master should be OFF ]; show variables like 'rpl_semi_sync_master_enabled'; @@ -195,12 +194,16 @@ sync_slave_with_master; --echo # Test semi-sync master will switch OFF after one transaction --echo # timeout waiting for slave reply. --echo # + +connection master; +show status like "Rpl_semi_sync_master_status"; + connection slave; source include/stop_slave.inc; connection master; --source include/kill_binlog_dump_threads.inc -set global rpl_semi_sync_master_timeout= 5000; +set global rpl_semi_sync_master_timeout= 2000; # The first semi-sync check should be on because after slave stop, # there are no transactions on the master. @@ -232,8 +235,8 @@ show status like 'Rpl_semi_sync_master_status'; show status like 'Rpl_semi_sync_master_no_tx'; show status like 'Rpl_semi_sync_master_yes_tx'; -# Semi-sync status on master is now OFF, so all these transactions -# will be replicated asynchronously. +# Semi-sync status on master is now ON, but there are no slaves attached, +# so all these transactions will be replicated asynchronously. delete from t1 where a=10; delete from t1 where a=9; delete from t1 where a=8; @@ -367,6 +370,9 @@ let $status_var= Rpl_semi_sync_master_clients; let $status_var_value= 1; source include/wait_for_status_var.inc; +sync_slave_with_master; +connection master; + replace_result $engine_type ENGINE_TYPE; eval create table t1 (a int) engine = $engine_type; insert into t1 values (1); @@ -413,6 +419,10 @@ connection master; let $status_var= Rpl_semi_sync_master_clients; let $status_var_value= 1; source include/wait_for_status_var.inc; + +sync_slave_with_master; +connection master; + echo [ master semi-sync should be ON ]; show status like 'Rpl_semi_sync_master_clients'; show status like 'Rpl_semi_sync_master_status'; diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_event.test b/mysql-test/suite/rpl/t/rpl_semi_sync_event.test index d4df9b4041b..86e1522e6c4 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_event.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_event.test @@ -14,7 +14,6 @@ call mtr.add_suppression("Unsafe statement written to the binary log using state call mtr.add_suppression("mysqld: Got an error reading communication packets"); connection slave; -call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_fail_over.test b/mysql-test/suite/rpl/t/rpl_semi_sync_fail_over.test index 6a691ae04f6..17d7b50d614 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_fail_over.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_fail_over.test @@ -18,6 +18,7 @@ --connection server_1 RESET MASTER; SET @@global.max_binlog_size= 4096; +set @@global.rpl_semi_sync_master_enabled = 1; --connection server_2 RESET MASTER; @@ -29,7 +30,6 @@ CHANGE MASTER TO master_use_gtid= slave_pos; --connection server_1 ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; -set @@global.rpl_semi_sync_master_enabled = 1; set @@global.rpl_semi_sync_master_wait_point=AFTER_SYNC; CREATE TABLE t1 (a INT PRIMARY KEY, b MEDIUMTEXT) ENGINE=Innodb; diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_no_missed_ack_after_add_slave.cnf b/mysql-test/suite/rpl/t/rpl_semi_sync_no_missed_ack_after_add_slave.cnf new file mode 100644 index 00000000000..cb7062d5602 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_no_missed_ack_after_add_slave.cnf @@ -0,0 +1,12 @@ +!include include/default_mysqld.cnf + +[mysqld.1] + +[mysqld.2] + +[mysqld.3] + +[ENV] +SERVER_MYPORT_1= @mysqld.1.port +SERVER_MYPORT_2= @mysqld.2.port +SERVER_MYPORT_3= @mysqld.3.port diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_no_missed_ack_after_add_slave.test b/mysql-test/suite/rpl/t/rpl_semi_sync_no_missed_ack_after_add_slave.test new file mode 100644 index 00000000000..c8870e47e00 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_no_missed_ack_after_add_slave.test @@ -0,0 +1,122 @@ +# +# This test ensures that a primary will listen for ACKs by newly added +# semi-sync connections connections, after a pre-existing connection is already +# established. MDEV-32960 reported that the newly added slave's ACK can be +# ignored if listen_on_sockets() does not timeout before +# rpl_semi_sync_master_timeout, and if the existing semi-sync connections fail +# to send ACKs, semi-sync is switched off. +# +# This test ensures this in a two-replica setup with a semi-sync timeout of +# 500ms, and delaying the ACK reply of the first-established replica by 800ms +# to force a timeout, and allowing the second replica to immediately ACK. +# +# References: +# MDEV-32960: Semi-sync ACKed Transaction can Timeout and Switch Off +# Semi-sync with Multiple Replicas +# +--source include/have_debug.inc +# binlog_format independent +--source include/have_binlog_format_statement.inc + +--let $rpl_topology= 1->2,1->3 +--source include/rpl_init.inc + + +--connection server_1 +set @old_enabled= @@global.rpl_semi_sync_master_enabled; +set @old_timeout= @@global.rpl_semi_sync_master_timeout; +set global rpl_semi_sync_master_enabled= 1; +set global rpl_semi_sync_master_timeout= 500; + +--connection server_2 +--source include/stop_slave.inc +set @old_enabled= @@global.rpl_semi_sync_slave_enabled; +set @old_dbug= @@global.debug_dbug; +set global rpl_semi_sync_slave_enabled= 1; +set global debug_dbug="+d,simulate_delay_semisync_slave_reply"; +--source include/start_slave.inc + +--connection server_3 +--source include/stop_slave.inc +set @old_enabled= @@global.rpl_semi_sync_slave_enabled; +set global rpl_semi_sync_slave_enabled= 1; +--source include/start_slave.inc + +--echo # Ensure primary recognizes both replicas are semi-sync +--connection server_1 +--let $status_var_value= 2 +--let $status_var= rpl_semi_sync_master_clients +--source include/wait_for_status_var.inc + +--let $master_ss_status= query_get_value(SHOW STATUS LIKE 'rpl_semi_sync_master_status', Value, 1) +if (`SELECT strcmp("$master_ss_status", "ON") != 0`) +{ + SHOW STATUS LIKE 'rpl_semi_sync_master_status'; + --die rpl_semi_sync_master_status should be ON to start +} + +--connection server_1 +--let $init_master_yes_tx= query_get_value(SHOW STATUS LIKE 'rpl_semi_sync_master_yes_tx', Value, 1) +create table t1 (a int); + +--connection server_2 +--echo # Verifying server_2 did not send ACK +--let $slave1_sent_ack= query_get_value(SHOW STATUS LIKE 'rpl_semi_sync_slave_send_ack', Value, 1) +if (`SELECT $slave1_sent_ack`) +{ + SHOW STATUS LIKE 'rpl_semi_sync_slave_send_ack'; + --die server_2 should not have sent semi-sync ACK to primary +} + +--connection server_3 +--echo # Verifying server_3 did send ACK +--let $slave2_sent_ack= query_get_value(SHOW STATUS LIKE 'rpl_semi_sync_slave_send_ack', Value, 1) +if (`SELECT NOT $slave2_sent_ack`) +{ + SHOW STATUS LIKE 'rpl_semi_sync_slave_send_ack'; + --die server_3 should have sent semi-sync ACK to primary +} + +--connection server_1 +--echo # Verifying master's semi-sync status is still ON (This failed pre-MDEV-32960 fixes) +let $master_ss_status= query_get_value(SHOW STATUS LIKE 'rpl_semi_sync_master_status', Value, 1); +if (`SELECT strcmp("$master_ss_status", "ON") != 0`) +{ + SHOW STATUS LIKE 'rpl_semi_sync_master_status'; + --die rpl_semi_sync_master_status should not have switched off after server_3 ACKed transaction +} + +--echo # Verifying rpl_semi_sync_master_yes_tx incremented +--let $cur_master_yes_tx= query_get_value(SHOW STATUS LIKE 'rpl_semi_sync_master_yes_tx', Value, 1) +if (`SELECT $cur_master_yes_tx != ($init_master_yes_tx + 1)`) +{ + --echo # Initial yes_tx: $init_master_yes_tx + --echo # Current yes_tx: $cur_master_yes_tx + --die rpl_semi_sync_master_yes_tx should have been incremented by primary +} + + +--echo # +--echo # Cleanup + +--connection server_2 +set global rpl_semi_sync_slave_enabled= @old_enabled; +set global debug_dbug= @old_dbug; +--source include/stop_slave.inc + +--connection server_3 +set global rpl_semi_sync_slave_enabled= @old_enabled; +--source include/stop_slave.inc + +--connection server_1 +set global rpl_semi_sync_master_enabled= @old_enabled; +set global rpl_semi_sync_master_timeout= @old_timeout; +drop table t1; + +--connection server_2 +--source include/start_slave.inc +--connection server_3 +--source include/start_slave.inc + +--source include/rpl_end.inc +--echo # End of rpl_semi_sync_no_missed_ack_after_add_slave.test diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_slave_enabled_consistent.test b/mysql-test/suite/rpl/t/rpl_semi_sync_slave_enabled_consistent.test new file mode 100644 index 00000000000..9e388ab4419 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_slave_enabled_consistent.test @@ -0,0 +1,73 @@ +# +# MDEV-32551: "Read semi-sync reply magic number error" warnings on master +# +# Test that changing rpl_semi_sync_master_enabled after startup does not +# cause problems with semi-sync cleanup. +# + +--source include/have_debug.inc +--source include/have_debug_sync.inc + +# Test is binlog format independent, so save resources +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +call mtr.add_suppression("Replication event checksum verification failed"); +call mtr.add_suppression("could not queue event from master"); + +--echo # +--echo # Set up a semisync connection +--connection master +set @@global.rpl_semi_sync_master_enabled= ON; + +--connection slave +stop slave io_thread; +set @@global.rpl_semi_sync_slave_enabled= ON; +set @old_dbug= @@global.debug_dbug; + +# Force an error to abort out of the main IO thread loop +set @@global.debug_dbug= "+d,corrupt_queue_event"; + +# Pause the IO thread as soon as the main loop starts. Note we can't use +# processlist where "Waiting for master to send event" because the +# "corrupt_queue_event" will trigger before we can turn semisync OFF +set @@global.debug_dbug= "+d,pause_before_io_read_event"; + +# Because the other debug_dbug points are automatically negated when they are +# run, and there is a bug that if "-d" takes us to an empty debug string state, +# _all_ debug_print statements are output +set @@global.debug_dbug= "+d,placeholder"; + +start slave io_thread; + +--echo # Disable semi-sync on the slave while the IO thread is active +set debug_sync='now wait_for io_thread_at_read_event'; +set @@global.rpl_semi_sync_slave_enabled= OFF; +set debug_sync='now signal io_thread_continue_read_event'; + +--echo # Waiting for the slave to stop with the error from corrupt_queue_event +--connection slave +--let $slave_io_errno= 1595,1743 +--source include/wait_for_slave_io_error.inc + +--echo # Sleep 1 to give time for Ack_receiver to receive COM_QUIT +--sleep 1 + +--let $assert_text= Check that there is no 'Read semi-sync reply magic number error' in error log. +--let $assert_select=magic number error +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_count= 0 +--let $assert_only_after=CURRENT_TEST +--source include/assert_grep.inc + +--echo # +--echo # Cleanup +--connection slave +--source include/stop_slave.inc +set @@global.debug_dbug= @old_dbug; +--source include/start_slave.inc +--connection master +set @@global.rpl_semi_sync_master_enabled= default; + +--source include/rpl_end.inc +--echo # End of rpl_semi_sync_slave_enabled_consistent.test diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_slave_reply_fail.test b/mysql-test/suite/rpl/t/rpl_semi_sync_slave_reply_fail.test index 2ebc092e33d..84462ed6426 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_slave_reply_fail.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_slave_reply_fail.test @@ -31,6 +31,7 @@ --connection master call mtr.add_suppression("Timeout waiting for reply of binlog*"); +call mtr.add_suppression("Master server does not read semi-sync messages*"); --let $sav_timeout_master=`SELECT @@GLOBAL.rpl_semi_sync_master_timeout` set global rpl_semi_sync_master_enabled = ON; SET @@GLOBAL.rpl_semi_sync_master_timeout=100; @@ -54,9 +55,9 @@ if(!$log_error_) # does not know the location of its .err log, use default location let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.2.err; } ---echo "Assert that the net_fulsh() reply failed is present in slave error log. +--echo "Assert that Master server does not read semi-sync messages" is present in slave error log. --let SEARCH_FILE=$log_error_ ---let SEARCH_PATTERN=Semi-sync slave net_flush\(\) reply failed +--let SEARCH_PATTERN=Master server does not read semi-sync messages --source include/search_pattern_in_file.inc --echo "Assert that Slave IO thread is up and running." diff --git a/mysql-test/suite/rpl/t/rpl_semisync_ali_issues.test b/mysql-test/suite/rpl/t/rpl_semisync_ali_issues.test index 5e6f350b191..c5c1daa4672 100644 --- a/mysql-test/suite/rpl/t/rpl_semisync_ali_issues.test +++ b/mysql-test/suite/rpl/t/rpl_semisync_ali_issues.test @@ -16,7 +16,6 @@ CALL mtr.add_suppression("Failed on request_dump()*"); CALL mtr.add_suppression("Semi-sync master failed on*"); CALL mtr.add_suppression("Master command COM_BINLOG_DUMP failed*"); CALL mtr.add_suppression("on master failed*"); -CALL mtr.add_suppression("Master server does not support semi-sync*"); CALL mtr.add_suppression("Semi-sync slave net_flush*"); CALL mtr.add_suppression("Failed to flush master info*"); CALL mtr.add_suppression("Request to stop slave SQL Thread received while apply*"); diff --git a/mysql-test/suite/rpl/t/rpl_session_var.test b/mysql-test/suite/rpl/t/rpl_session_var.test index cf3faa6578c..3ea6d5dabae 100644 --- a/mysql-test/suite/rpl/t/rpl_session_var.test +++ b/mysql-test/suite/rpl/t/rpl_session_var.test @@ -7,6 +7,12 @@ disable_query_log; call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); enable_query_log; +select @@rpl_semi_sync_master_enabled; +connection slave; +select @@rpl_semi_sync_slave_enabled; +show status like "rpl_semi_sync_slave_status"; +connection master; + drop table if exists t1; create table t1(a varchar(100),b int); set @@session.sql_mode=pipes_as_concat; diff --git a/mysql-test/suite/rpl/t/rpl_session_var2-master.opt b/mysql-test/suite/rpl/t/rpl_session_var2-master.opt new file mode 100644 index 00000000000..edb0c915bd6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_session_var2-master.opt @@ -0,0 +1 @@ +--rpl_semi_sync_master_enabled=1 --rpl_semi_sync_slave_enabled=1 diff --git a/mysql-test/suite/rpl/t/rpl_session_var2-slave.opt b/mysql-test/suite/rpl/t/rpl_session_var2-slave.opt new file mode 100644 index 00000000000..c9f3082ed07 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_session_var2-slave.opt @@ -0,0 +1 @@ +--rpl_semi_sync_slave_enabled=1 diff --git a/mysql-test/suite/rpl/t/rpl_session_var2.test b/mysql-test/suite/rpl/t/rpl_session_var2.test new file mode 100644 index 00000000000..cbf8a5cf316 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_session_var2.test @@ -0,0 +1,3 @@ +# Replication of session variables when semi-sync is on + +--source rpl_session_var.test diff --git a/mysql-test/suite/rpl/t/rpl_shutdown_wait_semisync_slaves.test b/mysql-test/suite/rpl/t/rpl_shutdown_wait_semisync_slaves.test index 2c63df30fde..0547a97f681 100644 --- a/mysql-test/suite/rpl/t/rpl_shutdown_wait_semisync_slaves.test +++ b/mysql-test/suite/rpl/t/rpl_shutdown_wait_semisync_slaves.test @@ -28,6 +28,9 @@ while (`SELECT $i <= $slaves`) --inc $i } +# The following script will restart master and slaves. This will also set +# rpl_semi_sync_master_enabled=0 + --source include/rpl_shutdown_wait_slaves.inc --let i= 2 while (`SELECT $i <= $slaves`) diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 319b86583fc..00c66ddf072 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -3465,7 +3465,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME RPL_SEMI_SYNC_MASTER_WAIT_NO_SLAVE VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BOOLEAN -VARIABLE_COMMENT Wait until timeout when no semi-synchronous replication slave available (enabled by default). +VARIABLE_COMMENT Wait until timeout when no semi-synchronous replication slave is available. NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL diff --git a/sql/log.cc b/sql/log.cc index 518f4df3f94..3ca387d5ab9 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -11011,7 +11011,7 @@ Recovery_context::Recovery_context() : prev_event_pos(0), last_gtid_standalone(false), last_gtid_valid(false), last_gtid_no2pc(false), last_gtid_engines(0), - do_truncate(rpl_semi_sync_slave_enabled), + do_truncate(repl_semisync_slave.get_slave_enabled()), truncate_validated(false), truncate_reset_done(false), truncate_set_in_1st(false), id_binlog(MAX_binlog_id), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF), gtid_maybe_to_truncate(NULL) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 8b7888dfb79..2766bc00e3a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7404,7 +7404,7 @@ SHOW_VAR status_vars[]= { SHOW_FUNC_ENTRY("Rpl_semi_sync_master_net_avg_wait_time", &SHOW_FNAME(avg_net_wait_time)), {"Rpl_semi_sync_master_request_ack", (char*) &rpl_semi_sync_master_request_ack, SHOW_LONGLONG}, {"Rpl_semi_sync_master_get_ack", (char*)&rpl_semi_sync_master_get_ack, SHOW_LONGLONG}, - {"Rpl_semi_sync_slave_status", (char*) &rpl_semi_sync_slave_status, SHOW_BOOL}, + SHOW_FUNC_ENTRY("Rpl_semi_sync_slave_status", &rpl_semi_sync_enabled), {"Rpl_semi_sync_slave_send_ack", (char*) &rpl_semi_sync_slave_send_ack, SHOW_LONGLONG}, #endif /* HAVE_REPLICATION */ #ifdef HAVE_QUERY_CACHE diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 70e71d9a21b..3dff8442c6a 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -156,6 +156,7 @@ my_bool my_net_init(NET *net, Vio *vio, void *thd, uint my_flags) net->where_b = net->remain_in_buf=0; net->net_skip_rest_factor= 0; net->last_errno=0; + net->pkt_nr_can_be_reset= 0; net->thread_specific_malloc= MY_TEST(my_flags & MY_THREAD_SPECIFIC); net->thd= 0; #ifdef MYSQL_SERVER @@ -1057,8 +1058,10 @@ retry: { /* Probably in MIT threads */ if (retry_count++ < net->retry_count) continue; - EXTRA_DEBUG_fprintf(stderr, "%s: read looped with error %d, aborting thread\n", - my_progname,vio_errno(net->vio)); + EXTRA_DEBUG_fprintf(stderr, "%s: read looped with error %d on " + "file %lld, aborting thread\n", + my_progname, vio_errno(net->vio), + (longlong) vio_fd(net->vio)); } #ifndef MYSQL_SERVER if (length != 0 && vio_errno(net->vio) == SOCKET_EINTR) @@ -1094,19 +1097,31 @@ retry: #endif if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr) { -#ifndef MYSQL_SERVER - if (net->buff[net->where_b + 3] == (uchar) (net->pkt_nr -1)) + if (net->pkt_nr_can_be_reset) { /* - If the server was killed then the server may have missed the - last sent client packet and the packet numbering may be one off. + We are using a protocol like semi-sync where master and slave + sends packets in parallel. + Copy current one as it can be useful for debugging. */ - DBUG_PRINT("warning", ("Found possible out of order packets")); - expect_error_packet= 1; + net->pkt_nr= net->buff[net->where_b + 3]; } else + { +#ifndef MYSQL_SERVER + if (net->buff[net->where_b + 3] == (uchar) (net->pkt_nr -1)) + { + /* + If the server was killed then the server may have missed the + last sent client packet and the packet numbering may be one off. + */ + DBUG_PRINT("warning", ("Found possible out of order packets")); + expect_error_packet= 1; + } + else #endif - goto packets_out_of_order; + goto packets_out_of_order; + } } net->compress_pkt_nr= ++net->pkt_nr; #ifdef HAVE_COMPRESS diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 8322bcd3042..73c61af92c9 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -44,7 +44,7 @@ Master_info::Master_info(LEX_CSTRING *connection_name_arg, in_start_all_slaves(0), in_stop_all_slaves(0), in_flush_all_relay_logs(0), users(0), killed(0), total_ddl_groups(0), total_non_trans_groups(0), total_trans_groups(0), - do_accept_own_server_id(false) + do_accept_own_server_id(false), semi_sync_reply_enabled(0) { char *tmp; host[0] = 0; user[0] = 0; password[0] = 0; diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 92938ac2f94..5857e8e043d 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -376,6 +376,12 @@ class Master_info : public Slave_reporting_capability it must be ignored similarly to the replicate-same-server-id rule. */ bool do_accept_own_server_id; + /* + Set to 1 when semi_sync is enabled. Set to 0 if there is any transmit + problems to the slave, in which case any furter semi-sync reply is + ignored + */ + bool semi_sync_reply_enabled; }; int init_master_info(Master_info* mi, const char* master_info_fname, diff --git a/sql/semisync_master.cc b/sql/semisync_master.cc index 670a6d8d9ed..9f30a8206a4 100644 --- a/sql/semisync_master.cc +++ b/sql/semisync_master.cc @@ -91,7 +91,9 @@ Active_tranx::Active_tranx(mysql_mutex_t *lock, for (int idx = 0; idx < m_num_entries; ++idx) m_trx_htb[idx] = NULL; +#ifdef EXTRA_DEBUG sql_print_information("Semi-sync replication initialized for transactions."); +#endif } Active_tranx::~Active_tranx() @@ -352,8 +354,7 @@ Repl_semi_sync_master::Repl_semi_sync_master() m_state(0), m_wait_point(0) { - strcpy(m_reply_file_name, ""); - strcpy(m_wait_file_name, ""); + m_reply_file_name[0]= m_wait_file_name[0]= 0; } int Repl_semi_sync_master::init_object() @@ -379,20 +380,10 @@ int Repl_semi_sync_master::init_object() { result = enable_master(); if (!result) - { result= ack_receiver.start(); /* Start the ACK thread. */ - /* - If rpl_semi_sync_master_wait_no_slave is disabled, let's temporarily - switch off semisync to avoid hang if there's none active slave. - */ - if (!rpl_semi_sync_master_wait_no_slave) - switch_off(); - } } else - { disable_master(); - } return result; } @@ -441,7 +432,7 @@ void Repl_semi_sync_master::disable_master() */ switch_off(); - assert(m_active_tranxs != NULL); + DBUG_ASSERT(m_active_tranxs != NULL); delete m_active_tranxs; m_active_tranxs = NULL; @@ -450,7 +441,6 @@ void Repl_semi_sync_master::disable_master() m_commit_file_name_inited = false; set_master_enabled(false); - sql_print_information("Semi-sync replication disabled on the master."); } unlock(); @@ -537,31 +527,34 @@ void Repl_semi_sync_master::add_slave() void Repl_semi_sync_master::remove_slave() { lock(); - rpl_semi_sync_master_clients--; - - /* Only switch off if semi-sync is enabled and is on */ - if (get_master_enabled() && is_on()) + if (!(--rpl_semi_sync_master_clients) && !rpl_semi_sync_master_wait_no_slave) { - /* If user has chosen not to wait if no semi-sync slave available - and the last semi-sync slave exits, turn off semi-sync on master - immediately. - */ - if (!rpl_semi_sync_master_wait_no_slave && - rpl_semi_sync_master_clients == 0) - switch_off(); + /* + Signal transactions waiting in commit_trx() that they do not have to + wait anymore. + */ + cond_broadcast(); } unlock(); } + +/* + Check report package + + @retval 0 ok + @retval 1 Error + @retval -1 Slave is going down (ok) +*/ + int Repl_semi_sync_master::report_reply_packet(uint32 server_id, const uchar *packet, ulong packet_len) { - int result= -1; + int result= 1; // Assume error char log_file_name[FN_REFLEN+1]; my_off_t log_file_pos; ulong log_file_len = 0; - DBUG_ENTER("Repl_semi_sync_master::report_reply_packet"); DBUG_EXECUTE_IF("semisync_corrupt_magic", @@ -569,7 +562,14 @@ int Repl_semi_sync_master::report_reply_packet(uint32 server_id, if (unlikely(packet[REPLY_MAGIC_NUM_OFFSET] != Repl_semi_sync_master::k_packet_magic_num)) { - sql_print_error("Read semi-sync reply magic number error"); + if (packet[0] == COM_QUIT && packet_len == 1) + { + /* Slave sent COM_QUIT as part of IO thread going down */ + sql_print_information("slave IO thread has stopped"); + DBUG_RETURN(-1); + } + else + sql_print_error("Read semi-sync reply magic number error"); goto l_end; } @@ -597,14 +597,13 @@ int Repl_semi_sync_master::report_reply_packet(uint32 server_id, rpl_semi_sync_master_get_ack++; report_reply_binlog(server_id, log_file_name, log_file_pos); - result= 0; + DBUG_RETURN(0); l_end: - if (result == -1) { char buf[256]; - octet2hex(buf, (const char*) packet, std::min(static_cast(sizeof(buf)-1), - packet_len)); + octet2hex(buf, (const char*) packet, + MY_MIN(sizeof(buf)-1, (size_t) packet_len)); sql_print_information("First bytes of the packet from semisync slave " "server-id %d: %s", server_id, buf); @@ -668,7 +667,7 @@ int Repl_semi_sync_master::report_reply_binlog(uint32 server_id, m_reply_file_name_inited = true; /* Remove all active transaction nodes before this point. */ - assert(m_active_tranxs != NULL); + DBUG_ASSERT(m_active_tranxs != NULL); m_active_tranxs->clear_active_tranx_nodes(log_file_name, log_file_pos); DBUG_PRINT("semisync", ("%s: Got reply at (%s, %lu)", @@ -809,6 +808,8 @@ int Repl_semi_sync_master::dump_start(THD* thd, (long) thd->variables.server_id, log_file, (ulong) log_pos); + /* Mark that semi-sync net->pkt_nr is not reliable */ + thd->net.pkt_nr_can_be_reset= 1; return 0; } @@ -827,8 +828,15 @@ void Repl_semi_sync_master::dump_end(THD* thd) int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, my_off_t trx_wait_binlog_pos) { + bool success= 0; DBUG_ENTER("Repl_semi_sync_master::commit_trx"); + if (!rpl_semi_sync_master_clients && !rpl_semi_sync_master_wait_no_slave) + { + rpl_semi_sync_master_no_transactions++; + DBUG_RETURN(0); + } + if (get_master_enabled() && trx_wait_binlog_name) { struct timespec start_ts; @@ -836,7 +844,7 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, int wait_result; PSI_stage_info old_stage; THD *thd= current_thd; - + bool aborted= 0; set_timespec(start_ts, 0); DEBUG_SYNC(thd, "rpl_semisync_master_commit_trx_before_lock"); @@ -859,6 +867,13 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, while (is_on() && !thd_killed(thd)) { + /* We have to check these again as things may have changed */ + if (!rpl_semi_sync_master_clients && !rpl_semi_sync_master_wait_no_slave) + { + aborted= 1; + break; + } + if (m_reply_file_name_inited) { int cmp = Active_tranx::compare(m_reply_file_name, m_reply_file_pos, @@ -873,6 +888,7 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, "Repl_semi_sync_master::commit_trx", m_reply_file_name, (ulong)m_reply_file_pos)); + success= 1; break; } } @@ -973,13 +989,13 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, m_active_tranxs may be NULL if someone disabled semi sync during cond_timewait() */ - assert(thd_killed(thd) || !m_active_tranxs || - !m_active_tranxs->is_tranx_end_pos(trx_wait_binlog_name, - trx_wait_binlog_pos)); + DBUG_ASSERT(thd_killed(thd) || !m_active_tranxs || aborted || + !m_active_tranxs->is_tranx_end_pos(trx_wait_binlog_name, + trx_wait_binlog_pos)); l_end: /* Update the status counter. */ - if (is_on()) + if (success) rpl_semi_sync_master_yes_transactions++; else rpl_semi_sync_master_no_transactions++; @@ -1014,18 +1030,20 @@ void Repl_semi_sync_master::switch_off() { DBUG_ENTER("Repl_semi_sync_master::switch_off"); - m_state = false; + if (m_state) + { + m_state = false; - /* Clear the active transaction list. */ - assert(m_active_tranxs != NULL); - m_active_tranxs->clear_active_tranx_nodes(NULL, 0); - - rpl_semi_sync_master_off_times++; - m_wait_file_name_inited = false; - m_reply_file_name_inited = false; - sql_print_information("Semi-sync replication switched OFF."); - cond_broadcast(); /* wake up all waiting threads */ + /* Clear the active transaction list. */ + DBUG_ASSERT(m_active_tranxs != NULL); + m_active_tranxs->clear_active_tranx_nodes(NULL, 0); + rpl_semi_sync_master_off_times++; + m_wait_file_name_inited = false; + m_reply_file_name_inited = false; + sql_print_information("Semi-sync replication switched OFF."); + } + cond_broadcast(); /* wake up all waiting threads */ DBUG_VOID_RETURN; } @@ -1072,9 +1090,10 @@ int Repl_semi_sync_master::reserve_sync_header(String* packet) { DBUG_ENTER("Repl_semi_sync_master::reserve_sync_header"); - /* Set the magic number and the sync status. By default, no sync - * is required. - */ + /* + Set the magic number and the sync status. By default, no sync + is required. + */ packet->append(reinterpret_cast(k_sync_header), sizeof(k_sync_header)); DBUG_RETURN(0); @@ -1087,7 +1106,6 @@ int Repl_semi_sync_master::update_sync_header(THD* thd, unsigned char *packet, { int cmp = 0; bool sync = false; - DBUG_ENTER("Repl_semi_sync_master::update_sync_header"); /* If the semi-sync master is not enabled, or the slave is not a semi-sync @@ -1103,16 +1121,11 @@ int Repl_semi_sync_master::update_sync_header(THD* thd, unsigned char *packet, /* This is the real check inside the mutex. */ if (!get_master_enabled()) - { - assert(sync == false); goto l_end; - } if (is_on()) { /* semi-sync is ON */ - sync = false; /* No sync unless a transaction is involved. */ - if (m_reply_file_name_inited) { cmp = Active_tranx::compare(log_file_name, log_file_pos, @@ -1126,15 +1139,10 @@ int Repl_semi_sync_master::update_sync_header(THD* thd, unsigned char *packet, } } + cmp = 1; if (m_wait_file_name_inited) - { cmp = Active_tranx::compare(log_file_name, log_file_pos, m_wait_file_name, m_wait_file_pos); - } - else - { - cmp = 1; - } /* If we are already waiting for some transaction replies which * are later in binlog, do not wait for this one event. @@ -1144,7 +1152,7 @@ int Repl_semi_sync_master::update_sync_header(THD* thd, unsigned char *packet, /* * We only wait if the event is a transaction's ending event. */ - assert(m_active_tranxs != NULL); + DBUG_ASSERT(m_active_tranxs != NULL); sync = m_active_tranxs->is_tranx_end_pos(log_file_name, log_file_pos); } @@ -1172,13 +1180,12 @@ int Repl_semi_sync_master::update_sync_header(THD* thd, unsigned char *packet, l_end: unlock(); - /* We do not need to clear sync flag because we set it to 0 when we - * reserve the packet header. - */ + /* + We do not need to clear sync flag in packet because we set it to 0 when we + reserve the packet header. + */ if (sync) - { - (packet)[2] = k_packet_flag_sync; - } + packet[2]= k_packet_flag_sync; DBUG_RETURN(0); } @@ -1225,7 +1232,7 @@ int Repl_semi_sync_master::write_tranx_in_binlog(const char* log_file_name, if (is_on()) { - assert(m_active_tranxs != NULL); + DBUG_ASSERT(m_active_tranxs != NULL); if(m_active_tranxs->insert_tranx_node(log_file_name, log_file_pos)) { /* @@ -1256,7 +1263,7 @@ int Repl_semi_sync_master::flush_net(THD *thd, DBUG_ENTER("Repl_semi_sync_master::flush_net"); - assert((unsigned char)event_buf[1] == k_packet_magic_num); + DBUG_ASSERT((unsigned char)event_buf[1] == k_packet_magic_num); if ((unsigned char)event_buf[2] != k_packet_flag_sync) { /* current event does not require reply */ @@ -1274,6 +1281,11 @@ int Repl_semi_sync_master::flush_net(THD *thd, goto l_end; } + /* + We have to do a net_clear() as with semi-sync the slave_reply's are + interleaved with data from the master and then the net->pkt_nr + cannot be kept in sync. Better to start pkt_nr from 0 again. + */ net_clear(net, 0); net->pkt_nr++; net->compress_pkt_nr++; @@ -1300,11 +1312,7 @@ int Repl_semi_sync_master::after_reset_master() lock(); - if (rpl_semi_sync_master_clients == 0 && - !rpl_semi_sync_master_wait_no_slave) - m_state = 0; - else - m_state = get_master_enabled()? 1 : 0; + m_state = get_master_enabled() ? 1 : 0; m_wait_file_name_inited = false; m_reply_file_name_inited = false; @@ -1338,18 +1346,6 @@ int Repl_semi_sync_master::before_reset_master() DBUG_RETURN(result); } -void Repl_semi_sync_master::check_and_switch() -{ - lock(); - if (get_master_enabled() && is_on()) - { - if (!rpl_semi_sync_master_wait_no_slave - && rpl_semi_sync_master_clients == 0) - switch_off(); - } - unlock(); -} - void Repl_semi_sync_master::set_export_stats() { lock(); @@ -1363,7 +1359,6 @@ void Repl_semi_sync_master::set_export_stats() ((rpl_semi_sync_master_net_wait_num) ? (ulong)((double)rpl_semi_sync_master_net_wait_time / ((double)rpl_semi_sync_master_net_wait_num)) : 0); - unlock(); } diff --git a/sql/semisync_master.h b/sql/semisync_master.h index 5451ad512c6..99f46869354 100644 --- a/sql/semisync_master.h +++ b/sql/semisync_master.h @@ -633,8 +633,6 @@ class Repl_semi_sync_master /*called before reset master*/ int before_reset_master(); - void check_and_switch(); - /* Determines if the given thread is currently awaiting a semisync_ack. Note that the thread's value is protected by this class's LOCK_binlog, so this diff --git a/sql/semisync_master_ack_receiver.cc b/sql/semisync_master_ack_receiver.cc index a76e3447ac8..6453b7ef32a 100644 --- a/sql/semisync_master_ack_receiver.cc +++ b/sql/semisync_master_ack_receiver.cc @@ -24,7 +24,8 @@ extern PSI_cond_key key_COND_ack_receiver; #ifdef HAVE_PSI_THREAD_INTERFACE extern PSI_thread_key key_thread_ack_receiver; #endif -extern Repl_semi_sync_master repl_semisync; + +int global_ack_signal_fd= -1; /* Callback function of ack receive thread */ pthread_handler_t ack_receive_handler(void *arg) @@ -45,6 +46,7 @@ Ack_receiver::Ack_receiver() m_status= ST_DOWN; mysql_mutex_init(key_LOCK_ack_receiver, &m_mutex, NULL); mysql_cond_init(key_COND_ack_receiver, &m_cond, NULL); + mysql_cond_init(key_COND_ack_receiver, &m_cond_reply, NULL); m_pid= 0; DBUG_VOID_RETURN; @@ -57,6 +59,7 @@ void Ack_receiver::cleanup() stop(); mysql_mutex_destroy(&m_mutex); mysql_cond_destroy(&m_cond); + mysql_cond_destroy(&m_cond_reply); DBUG_VOID_RETURN; } @@ -104,6 +107,7 @@ void Ack_receiver::stop() if (m_status == ST_UP) { m_status= ST_STOPPING; + signal_listener(); // Signal listener thread to stop mysql_cond_broadcast(&m_cond); while (m_status == ST_STOPPING) @@ -118,6 +122,21 @@ void Ack_receiver::stop() DBUG_VOID_RETURN; } +#ifndef DBUG_OFF +void static dbug_verify_no_duplicate_slaves(Slave_ilist *m_slaves, THD *thd) +{ + I_List_iterator it(*m_slaves); + Slave *slave; + while ((slave= it++)) + { + DBUG_ASSERT(slave->thd->variables.server_id != thd->variables.server_id); + } +} +#else +#define dbug_verify_no_duplicate_slaves(A,B) do {} while(0) +#endif + + bool Ack_receiver::add_slave(THD *thd) { Slave *slave; @@ -126,17 +145,23 @@ bool Ack_receiver::add_slave(THD *thd) if (!(slave= new Slave)) DBUG_RETURN(true); + slave->active= 0; slave->thd= thd; slave->vio= *thd->net.vio; slave->vio.mysql_socket.m_psi= NULL; slave->vio.read_timeout= 1; mysql_mutex_lock(&m_mutex); + + dbug_verify_no_duplicate_slaves(&m_slaves, thd); + m_slaves.push_back(slave); m_slaves_changed= true; mysql_cond_broadcast(&m_cond); mysql_mutex_unlock(&m_mutex); + signal_listener(); // Inform listener that there are new slaves + DBUG_RETURN(false); } @@ -144,6 +169,7 @@ void Ack_receiver::remove_slave(THD *thd) { I_List_iterator it(m_slaves); Slave *slave; + bool slaves_changed= 0; DBUG_ENTER("Ack_receiver::remove_slave"); mysql_mutex_lock(&m_mutex); @@ -153,10 +179,23 @@ void Ack_receiver::remove_slave(THD *thd) if (slave->thd == thd) { delete slave; - m_slaves_changed= true; + slaves_changed= true; break; } } + if (slaves_changed) + { + m_slaves_changed= true; + mysql_cond_broadcast(&m_cond); + /* + Wait until Ack_receiver::run() acknowledges remove of slave + As this is only sent under the mutex and after listners has + been collected, we know that listener has ignored the found + slave. + */ + if (m_status != ST_DOWN) + mysql_cond_wait(&m_cond_reply, &m_mutex); + } mysql_mutex_unlock(&m_mutex); DBUG_VOID_RETURN; @@ -167,10 +206,15 @@ inline void Ack_receiver::set_stage_info(const PSI_stage_info &stage) (void)MYSQL_SET_STAGE(stage.m_key, __FILE__, __LINE__); } -inline void Ack_receiver::wait_for_slave_connection() +void Ack_receiver::wait_for_slave_connection(THD *thd) { - set_stage_info(stage_waiting_for_semi_sync_slave); - mysql_cond_wait(&m_cond, &m_mutex); + thd->enter_cond(&m_cond, &m_mutex, &stage_waiting_for_semi_sync_slave, + 0, __func__, __FILE__, __LINE__); + + while (m_status == ST_UP && m_slaves.is_empty()) + mysql_cond_wait(&m_cond, &m_mutex); + + thd->exit_cond(0, __func__, __FILE__, __LINE__); } /* Auxilary function to initialize a NET object with given net buffer. */ @@ -188,11 +232,10 @@ void Ack_receiver::run() THD *thd= new THD(next_thread_id()); NET net; unsigned char net_buff[REPLY_MESSAGE_MAX_LENGTH]; + DBUG_ENTER("Ack_receiver::run"); my_thread_init(); - DBUG_ENTER("Ack_receiver::run"); - #ifdef HAVE_POLL Poll_socket_listener listener(m_slaves); #else @@ -207,64 +250,76 @@ void Ack_receiver::run() thd->set_command(COM_DAEMON); init_net(&net, net_buff, REPLY_MESSAGE_MAX_LENGTH); - mysql_mutex_lock(&m_mutex); + /* + Mark that we have to setup the listener. Note that only this functions can + set m_slaves_changed to false + */ m_slaves_changed= true; - mysql_mutex_unlock(&m_mutex); while (1) { - int ret; - uint slave_count __attribute__((unused))= 0; + int ret, slave_count; Slave *slave; mysql_mutex_lock(&m_mutex); - if (unlikely(m_status == ST_STOPPING)) + if (unlikely(m_status != ST_UP)) goto end; - set_stage_info(stage_waiting_for_semi_sync_ack_from_slave); if (unlikely(m_slaves_changed)) { if (unlikely(m_slaves.is_empty())) { - wait_for_slave_connection(); - mysql_mutex_unlock(&m_mutex); + m_slaves_changed= false; + mysql_cond_broadcast(&m_cond_reply); // Signal remove_slave + wait_for_slave_connection(thd); + /* Wait for slave unlocks m_mutex */ continue; } + set_stage_info(stage_waiting_for_semi_sync_ack_from_slave); if ((slave_count= listener.init_slave_sockets()) == 0) + { + mysql_mutex_unlock(&m_mutex); + m_slaves_changed= true; + continue; // Retry + } + if (slave_count < 0) goto end; m_slaves_changed= false; + mysql_cond_broadcast(&m_cond_reply); // Signal remove_slave + } + #ifdef HAVE_POLL DBUG_PRINT("info", ("fd count %u", slave_count)); #else DBUG_PRINT("info", ("fd count %u, max_fd %d", slave_count, (int) listener.get_max_fd())); #endif - } + mysql_mutex_unlock(&m_mutex); ret= listener.listen_on_sockets(); + if (ret <= 0) { - mysql_mutex_unlock(&m_mutex); - ret= DBUG_EVALUATE_IF("rpl_semisync_simulate_select_error", -1, ret); if (ret == -1 && errno != EINTR) sql_print_information("Failed to wait on semi-sync sockets, " "error: errno=%d", socket_errno); - /* Sleep 1us, so other threads can catch the m_mutex easily. */ - my_sleep(1); continue; } + listener.clear_signal(); + mysql_mutex_lock(&m_mutex); set_stage_info(stage_reading_semi_sync_ack); Slave_ilist_iterator it(m_slaves); while ((slave= it++)) { - if (listener.is_socket_active(slave)) + if (slave->active) // Set in init_slave_sockets() { ulong len; + /* Semi-sync packets will always be sent with pkt_nr == 1 */ net_clear(&net, 0); net.vio= &slave->vio; /* @@ -275,29 +330,40 @@ void Ack_receiver::run() len= my_net_read(&net); if (likely(len != packet_error)) - repl_semisync_master.report_reply_packet(slave->server_id(), - net.read_pos, len); - else { - if (net.last_errno == ER_NET_READ_ERROR) + int res; + res= repl_semisync_master.report_reply_packet(slave->server_id(), + net.read_pos, len); + if (unlikely(res < 0)) { - listener.clear_socket_info(slave); + /* + Slave has sent COM_QUIT or other failure. + Delete it from listener + */ + it.remove(); } + } + else if (net.last_errno == ER_NET_READ_ERROR) + { if (net.last_errno > 0 && global_system_variables.log_warnings > 2) sql_print_warning("Semisync ack receiver got error %d \"%s\" " "from slave server-id %d", net.last_errno, ER_DEFAULT(net.last_errno), slave->server_id()); + it.remove(); } } } mysql_mutex_unlock(&m_mutex); } + end: sql_print_information("Stopping ack receiver thread"); m_status= ST_DOWN; - delete thd; mysql_cond_broadcast(&m_cond); + mysql_cond_broadcast(&m_cond_reply); mysql_mutex_unlock(&m_mutex); + + delete thd; DBUG_VOID_RETURN; } diff --git a/sql/semisync_master_ack_receiver.h b/sql/semisync_master_ack_receiver.h index d869bd2e6d4..d3d9de27b89 100644 --- a/sql/semisync_master_ack_receiver.h +++ b/sql/semisync_master_ack_receiver.h @@ -29,6 +29,7 @@ struct Slave :public ilink #ifdef HAVE_POLL uint m_fds_index; #endif + bool active; my_socket sock_fd() const { return vio.mysql_socket.fd; } uint server_id() const { return thd->variables.server_id; } }; @@ -46,6 +47,7 @@ typedef I_List_iterator Slave_ilist_iterator; add_slave: maintain a new semisync slave's information remove_slave: remove a semisync slave's information */ + class Ack_receiver : public Repl_semi_sync_base { public: @@ -96,15 +98,20 @@ public: { m_trace_level= trace_level; } + bool running() + { + return m_status != ST_DOWN; + } + private: enum status {ST_UP, ST_DOWN, ST_STOPPING}; - uint8 m_status; + enum status m_status; /* Protect m_status, m_slaves_changed and m_slaves. ack thread and other session may access the variables at the same time. */ mysql_mutex_t m_mutex; - mysql_cond_t m_cond; + mysql_cond_t m_cond, m_cond_reply; /* If slave list is updated(add or remove). */ bool m_slaves_changed; @@ -116,25 +123,73 @@ private: Ack_receiver& operator=(const Ack_receiver &ack_receiver); void set_stage_info(const PSI_stage_info &stage); - void wait_for_slave_connection(); + void wait_for_slave_connection(THD *thd); }; -#ifdef HAVE_POLL -#include -#include +extern int global_ack_signal_fd; -class Poll_socket_listener +class Ack_listener { public: - Poll_socket_listener(const Slave_ilist &slaves) + int local_read_signal; + const Slave_ilist &m_slaves; + + Ack_listener(const Slave_ilist &slaves) :m_slaves(slaves) { + int pipes[2]; + pipe(pipes); + global_ack_signal_fd= pipes[1]; + local_read_signal= pipes[0]; + fcntl(pipes[0], F_SETFL, O_NONBLOCK); + fcntl(pipes[1], F_SETFL, O_NONBLOCK); } + virtual ~Ack_listener() + { + close(global_ack_signal_fd); + close(local_read_signal); + global_ack_signal_fd= -1; + } + + virtual bool has_signal_data()= 0; + + /* Clear data sent by signal_listener() to abort read */ + void clear_signal() + { + if (has_signal_data()) + { + char buff[100]; + /* Clear the signal message */ + read(local_read_signal, buff, sizeof(buff)); + } + } +}; + +static inline void signal_listener() +{ + my_write(global_ack_signal_fd, (uchar*) "a", 1, MYF(0)); +} + +#ifdef HAVE_POLL +#include + +class Poll_socket_listener final : public Ack_listener +{ +private: + std::vector m_fds; + +public: + Poll_socket_listener(const Slave_ilist &slaves) + :Ack_listener(slaves) + {} + + virtual ~Poll_socket_listener() = default; + bool listen_on_sockets() { - return poll(m_fds.data(), m_fds.size(), 1000 /*1 Second timeout*/); + return poll(m_fds.data(), m_fds.size(), -1); } bool is_socket_active(const Slave *slave) @@ -148,15 +203,29 @@ public: m_fds[slave->m_fds_index].events= 0; } - uint init_slave_sockets() + bool has_signal_data() override + { + /* The signal fd is always first */ + return (m_fds[0].revents & POLLIN); + } + + int init_slave_sockets() { Slave_ilist_iterator it(const_cast(m_slaves)); Slave *slave; uint fds_index= 0; + pollfd poll_fd; m_fds.clear(); + /* First put in the signal socket */ + poll_fd.fd= local_read_signal; + poll_fd.events= POLLIN; + m_fds.push_back(poll_fd); + fds_index++; + while ((slave= it++)) { + slave->active= 1; pollfd poll_fd; poll_fd.fd= slave->sock_fd(); poll_fd.events= POLLIN; @@ -165,29 +234,30 @@ public: } return fds_index; } - -private: - const Slave_ilist &m_slaves; - std::vector m_fds; }; #else //NO POLL -class Select_socket_listener +class Select_socket_listener final : public Ack_listener { +private: + my_socket m_max_fd; + fd_set m_init_fds; + fd_set m_fds; + public: Select_socket_listener(const Slave_ilist &slaves) - :m_slaves(slaves), m_max_fd(INVALID_SOCKET) - { - } + :Ack_listener(slaves), m_max_fd(INVALID_SOCKET) + {} + + virtual ~Select_socket_listener() = default; bool listen_on_sockets() { /* Reinitialize the fds with active fds before calling select */ m_fds= m_init_fds; - struct timeval tv= {1,0}; /* select requires max fd + 1 for the first argument */ - return select((int) m_max_fd+1, &m_fds, NULL, NULL, &tv); + return select((int) m_max_fd+1, &m_fds, NULL, NULL, NULL); } bool is_socket_active(const Slave *slave) @@ -195,43 +265,61 @@ public: return FD_ISSET(slave->sock_fd(), &m_fds); } + bool has_signal_data() override + { + return FD_ISSET(local_read_signal, &m_fds); + } + void clear_socket_info(const Slave *slave) { FD_CLR(slave->sock_fd(), &m_init_fds); } - uint init_slave_sockets() + int init_slave_sockets() { Slave_ilist_iterator it(const_cast(m_slaves)); Slave *slave; uint fds_index= 0; FD_ZERO(&m_init_fds); + m_max_fd= -1; + + /* First put in the signal socket */ + FD_SET(local_read_signal, &m_init_fds); + fds_index++; + set_if_bigger(m_max_fd, local_read_signal); +#ifndef _WIN32 + if (local_read_signal > FD_SETSIZE) + { + int socket_id= local_read_signal; + sql_print_error("Semisync slave socket fd is %u. " + "select() cannot handle if the socket fd is " + "greater than %u (FD_SETSIZE).", socket_id, FD_SETSIZE); + return -1; + } +#endif + while ((slave= it++)) { my_socket socket_id= slave->sock_fd(); - m_max_fd= (socket_id > m_max_fd ? socket_id : m_max_fd); + set_if_bigger(m_max_fd, socket_id); #ifndef _WIN32 if (socket_id > FD_SETSIZE) { sql_print_error("Semisync slave socket fd is %u. " "select() cannot handle if the socket fd is " "greater than %u (FD_SETSIZE).", socket_id, FD_SETSIZE); - return 0; + it.remove(); + continue; } #endif //_WIN32 FD_SET(socket_id, &m_init_fds); fds_index++; + slave->active= 1; } return fds_index; } my_socket get_max_fd() { return m_max_fd; } - -private: - const Slave_ilist &m_slaves; - my_socket m_max_fd; - fd_set m_init_fds; - fd_set m_fds; }; #endif //HAVE_POLL diff --git a/sql/semisync_slave.cc b/sql/semisync_slave.cc index 3e7578b6a53..a56e22eab3e 100644 --- a/sql/semisync_slave.cc +++ b/sql/semisync_slave.cc @@ -20,20 +20,9 @@ Repl_semi_sync_slave repl_semisync_slave; -my_bool rpl_semi_sync_slave_enabled= 0; - +my_bool global_rpl_semi_sync_slave_enabled= 0; char rpl_semi_sync_slave_delay_master; -my_bool rpl_semi_sync_slave_status= 0; ulong rpl_semi_sync_slave_trace_level; - -/* - indicate whether or not the slave should send a reply to the master. - - This is set to true in repl_semi_slave_read_event if the current - event read is the last event of a transaction. And the value is - checked in repl_semi_slave_queue_event. -*/ -bool semi_sync_need_reply= false; unsigned int rpl_semi_sync_slave_kill_conn_timeout; unsigned long long rpl_semi_sync_slave_send_ack = 0; @@ -44,14 +33,26 @@ int Repl_semi_sync_slave::init_object() m_init_done = true; /* References to the parameter works after set_options(). */ - set_slave_enabled(rpl_semi_sync_slave_enabled); + set_slave_enabled(global_rpl_semi_sync_slave_enabled); set_trace_level(rpl_semi_sync_slave_trace_level); set_delay_master(rpl_semi_sync_slave_delay_master); set_kill_conn_timeout(rpl_semi_sync_slave_kill_conn_timeout); - return result; } +static bool local_semi_sync_enabled; + +int rpl_semi_sync_enabled(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *status_var, + enum_var_type scope) +{ + local_semi_sync_enabled= repl_semisync_slave.get_slave_enabled(); + var->type= SHOW_BOOL; + var->value= (char*) &local_semi_sync_enabled; + return 0; +} + + int Repl_semi_sync_slave::slave_read_sync_header(const uchar *header, unsigned long total_len, int *semi_flags, @@ -61,12 +62,12 @@ int Repl_semi_sync_slave::slave_read_sync_header(const uchar *header, int read_res = 0; DBUG_ENTER("Repl_semi_sync_slave::slave_read_sync_header"); - if (rpl_semi_sync_slave_status) + if (get_slave_enabled()) { if (DBUG_EVALUATE_IF("semislave_corrupt_log", 0, 1) && header[0] == k_packet_magic_num) { - semi_sync_need_reply = (header[1] & k_packet_flag_sync); + bool semi_sync_need_reply = (header[1] & k_packet_flag_sync); *payload_len = total_len - 2; *payload = header + 2; @@ -85,7 +86,9 @@ int Repl_semi_sync_slave::slave_read_sync_header(const uchar *header, "len: %lu", total_len); read_res = -1; } - } else { + } + else + { *payload= header; *payload_len= total_len; } @@ -93,9 +96,23 @@ int Repl_semi_sync_slave::slave_read_sync_header(const uchar *header, DBUG_RETURN(read_res); } -int Repl_semi_sync_slave::slave_start(Master_info *mi) +/* + Set default semisync variables and print some replication info to the log + + Note that the main setup is done in request_transmit() +*/ + +void Repl_semi_sync_slave::slave_start(Master_info *mi) { - bool semi_sync= get_slave_enabled(); + + /* + Set semi_sync_enabled at slave start. This is not changed until next + slave start or reconnect. + */ + bool semi_sync= global_rpl_semi_sync_slave_enabled; + + set_slave_enabled(semi_sync); + mi->semi_sync_reply_enabled= 0; sql_print_information("Slave I/O thread: Start %s replication to\ master '%s@%s:%d' in log '%s' at position %lu", @@ -104,30 +121,29 @@ int Repl_semi_sync_slave::slave_start(Master_info *mi) const_cast(mi->master_log_name), (unsigned long)(mi->master_log_pos)); - if (semi_sync && !rpl_semi_sync_slave_status) - rpl_semi_sync_slave_status= 1; - /*clear the counter*/ rpl_semi_sync_slave_send_ack= 0; - return 0; } -int Repl_semi_sync_slave::slave_stop(Master_info *mi) +void Repl_semi_sync_slave::slave_stop(Master_info *mi) { if (get_slave_enabled()) kill_connection(mi->mysql); - if (rpl_semi_sync_slave_status) - rpl_semi_sync_slave_status= 0; - - return 0; + set_slave_enabled(0); } -int Repl_semi_sync_slave::reset_slave(Master_info *mi) +void Repl_semi_sync_slave::slave_reconnect(Master_info *mi) { - return 0; + /* + Start semi-sync either if it globally enabled or if was enabled + before the reconnect. + */ + if (global_rpl_semi_sync_slave_enabled || get_slave_enabled()) + slave_start(mi); } + void Repl_semi_sync_slave::kill_connection(MYSQL *mysql) { if (!mysql) @@ -194,34 +210,44 @@ int Repl_semi_sync_slave::request_transmit(Master_info *mi) !(res= mysql_store_result(mysql))) { sql_print_error("Execution failed on master: %s, error :%s", query, mysql_error(mysql)); + set_slave_enabled(0); return 1; } row= mysql_fetch_row(res); if (DBUG_EVALUATE_IF("master_not_support_semisync", 1, 0) - || !row) + || (!row || ! row[1])) { /* Master does not support semi-sync */ - sql_print_warning("Master server does not support semi-sync, " - "fallback to asynchronous replication"); - rpl_semi_sync_slave_status= 0; + if (!row) + sql_print_warning("Master server does not support semi-sync, " + "fallback to asynchronous replication"); + set_slave_enabled(0); mysql_free_result(res); return 0; } + if (strcmp(row[1], "ON")) + sql_print_information("Slave has semi-sync enabled but master server does " + "not. Semi-sync will be activated when master " + "enables it"); mysql_free_result(res); /* Tell master dump thread that we want to do semi-sync - replication + replication. This is done by setting a thread local variable in + the master connection. */ query= "SET @rpl_semi_sync_slave= 1"; if (mysql_real_query(mysql, query, (ulong)strlen(query))) { - sql_print_error("Set 'rpl_semi_sync_slave=1' on master failed"); + sql_print_error("%s on master failed", query); + set_slave_enabled(0); return 1; } + mi->semi_sync_reply_enabled= 1; + /* Inform net_server that pkt_nr can come out of order */ + mi->mysql->net.pkt_nr_can_be_reset= 1; mysql_free_result(mysql_store_result(mysql)); - rpl_semi_sync_slave_status= 1; return 0; } @@ -231,46 +257,41 @@ int Repl_semi_sync_slave::slave_reply(Master_info *mi) MYSQL* mysql= mi->mysql; const char *binlog_filename= const_cast(mi->master_log_name); my_off_t binlog_filepos= mi->master_log_pos; - NET *net= &mysql->net; uchar reply_buffer[REPLY_MAGIC_NUM_LEN + REPLY_BINLOG_POS_LEN + REPLY_BINLOG_NAME_LEN]; int reply_res = 0; size_t name_len = strlen(binlog_filename); - DBUG_ENTER("Repl_semi_sync_slave::slave_reply"); + DBUG_ASSERT(get_slave_enabled() && mi->semi_sync_reply_enabled); - if (rpl_semi_sync_slave_status && semi_sync_need_reply) + /* Prepare the buffer of the reply. */ + reply_buffer[REPLY_MAGIC_NUM_OFFSET] = k_packet_magic_num; + int8store(reply_buffer + REPLY_BINLOG_POS_OFFSET, binlog_filepos); + memcpy(reply_buffer + REPLY_BINLOG_NAME_OFFSET, + binlog_filename, + name_len + 1 /* including trailing '\0' */); + + DBUG_PRINT("semisync", ("%s: reply (%s, %lu)", + "Repl_semi_sync_slave::slave_reply", + binlog_filename, (ulong)binlog_filepos)); + + /* + We have to do a net_clear() as with semi-sync the slave_reply's are + interleaved with data from the master and then the net->pkt_nr + cannot be kept in sync. Better to start pkt_nr from 0 again. + */ + net_clear(net, 0); + /* Send the reply. */ + reply_res = my_net_write(net, reply_buffer, + name_len + REPLY_BINLOG_NAME_OFFSET); + if (!reply_res) { - /* Prepare the buffer of the reply. */ - reply_buffer[REPLY_MAGIC_NUM_OFFSET] = k_packet_magic_num; - int8store(reply_buffer + REPLY_BINLOG_POS_OFFSET, binlog_filepos); - memcpy(reply_buffer + REPLY_BINLOG_NAME_OFFSET, - binlog_filename, - name_len + 1 /* including trailing '\0' */); - - DBUG_PRINT("semisync", ("%s: reply (%s, %lu)", - "Repl_semi_sync_slave::slave_reply", - binlog_filename, (ulong)binlog_filepos)); - - net_clear(net, 0); - /* Send the reply. */ - reply_res = my_net_write(net, reply_buffer, - name_len + REPLY_BINLOG_NAME_OFFSET); + reply_res= DBUG_EVALUATE_IF("semislave_failed_net_flush", 1, + net_flush(net)); if (!reply_res) - { - reply_res = DBUG_EVALUATE_IF("semislave_failed_net_flush", 1, net_flush(net)); - if (reply_res) - sql_print_error("Semi-sync slave net_flush() reply failed"); rpl_semi_sync_slave_send_ack++; - } - else - { - sql_print_error("Semi-sync slave send reply failed: %s (%d)", - net->last_error, net->last_errno); - } } - DBUG_RETURN(reply_res); } diff --git a/sql/semisync_slave.h b/sql/semisync_slave.h index a8229245ab1..6811584c9c8 100644 --- a/sql/semisync_slave.h +++ b/sql/semisync_slave.h @@ -33,7 +33,7 @@ class Master_info; class Repl_semi_sync_slave :public Repl_semi_sync_base { public: - Repl_semi_sync_slave() :m_slave_enabled(false) {} + Repl_semi_sync_slave() :m_slave_enabled(false) {} ~Repl_semi_sync_slave() = default; void set_trace_level(unsigned long trace_level) { @@ -45,7 +45,7 @@ public: */ int init_object(); - bool get_slave_enabled() { + inline bool get_slave_enabled() { return m_slave_enabled; } @@ -53,7 +53,7 @@ public: m_slave_enabled = enabled; } - bool is_delay_master(){ + inline bool is_delay_master(){ return m_delay_master; } @@ -88,24 +88,23 @@ public: * binlog position. */ int slave_reply(Master_info* mi); - int slave_start(Master_info *mi); - int slave_stop(Master_info *mi); - int request_transmit(Master_info*); + void slave_start(Master_info *mi); + void slave_stop(Master_info *mi); + void slave_reconnect(Master_info *mi); + int request_transmit(Master_info *mi); void kill_connection(MYSQL *mysql); - int reset_slave(Master_info *mi); private: /* True when init_object has been called */ bool m_init_done; - bool m_slave_enabled; /* semi-sycn is enabled on the slave */ + bool m_slave_enabled; /* semi-sync is enabled on the slave */ bool m_delay_master; unsigned int m_kill_conn_timeout; }; /* System and status variables for the slave component */ -extern my_bool rpl_semi_sync_slave_enabled; -extern my_bool rpl_semi_sync_slave_status; +extern my_bool global_rpl_semi_sync_slave_enabled; extern ulong rpl_semi_sync_slave_trace_level; extern Repl_semi_sync_slave repl_semisync_slave; @@ -113,4 +112,7 @@ extern char rpl_semi_sync_slave_delay_master; extern unsigned int rpl_semi_sync_slave_kill_conn_timeout; extern unsigned long long rpl_semi_sync_slave_send_ack; +extern int rpl_semi_sync_enabled(THD *thd, SHOW_VAR *var, void *buff, + system_status_var *status_var, + enum_var_type scope); #endif /* SEMISYNC_SLAVE_H */ diff --git a/sql/slave.cc b/sql/slave.cc index e745749d64d..3318c92b317 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -4659,6 +4659,7 @@ static int try_to_reconnect(THD *thd, MYSQL *mysql, Master_info *mi, sql_print_information("%s", messages[SLAVE_RECON_MSG_KILLED_AFTER]); return 1; } + repl_semisync_slave.slave_reconnect(mi); return 0; } @@ -4747,14 +4748,7 @@ pthread_handler_t handle_slave_io(void *arg) } thd->variables.wsrep_on= 0; - if (DBUG_EVALUATE_IF("failed_slave_start", 1, 0) - || repl_semisync_slave.slave_start(mi)) - { - mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, - ER_THD(thd, ER_SLAVE_FATAL_ERROR), - "Failed to run 'thread_start' hook"); - goto err; - } + repl_semisync_slave.slave_start(mi); if (!(mi->mysql = mysql = mysql_init(NULL))) { @@ -4848,6 +4842,7 @@ connected: if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings, reconnect_messages[SLAVE_RECON_ACT_REG])) goto err; + goto connected; } @@ -4911,6 +4906,15 @@ connected: we're in fact receiving nothing. */ THD_STAGE_INFO(thd, stage_waiting_for_master_to_send_event); + +#ifdef ENABLED_DEBUG_SYNC + DBUG_EXECUTE_IF("pause_before_io_read_event", + { + DBUG_ASSERT(!debug_sync_set_action( thd, STRING_WITH_LEN( + "now signal io_thread_at_read_event wait_for io_thread_continue_read_event"))); + DBUG_SET("-d,pause_before_io_read_event"); + };); +#endif event_len= read_event(mysql, mi, &suppress_warnings, &network_read_len); if (check_io_slave_killed(mi, NullS)) goto err; @@ -5010,17 +5014,36 @@ Stopping slave I/O thread due to out-of-memory error from master"); goto err; } - if (rpl_semi_sync_slave_status && (mi->semi_ack & SEMI_SYNC_NEED_ACK)) + if (repl_semisync_slave.get_slave_enabled() && + mi->semi_sync_reply_enabled && + (mi->semi_ack & SEMI_SYNC_NEED_ACK)) { - /* - We deliberately ignore the error in slave_reply, such error should - not cause the slave IO thread to stop, and the error messages are - already reported. - */ - DBUG_EXECUTE_IF("simulate_delay_semisync_slave_reply", my_sleep(800000);); - (void)repl_semisync_slave.slave_reply(mi); - } + DBUG_EXECUTE_IF("simulate_delay_semisync_slave_reply", + my_sleep(800000);); + if (repl_semisync_slave.slave_reply(mi)) + { + /* + Master is not responding (gone away?) or it has turned semi sync + off. Turning off semi-sync responses as there is no point in sending + data to the master if the master not receiving the messages. + This also stops the logs from getting filled with + "Semi-sync slave net_flush() reply failed" messages. + On reconnect semi sync will be turned on again, if the + master has semi-sync enabled. + We check mi->abort_slave to see if the io thread was + killed and in this case we do not need an error message as + we know what is going on. + */ + if (!mi->abort_slave) + sql_print_error("Master server does not read semi-sync messages " + "last_error: %s (%d). " + "Fallback to asynchronous replication", + mi->mysql->net.last_error, + mi->mysql->net.last_errno); + mi->semi_sync_reply_enabled= 0; + } + } if (mi->using_gtid == Master_info::USE_GTID_NO && /* If rpl_semi_sync_slave_delay_master is enabled, we will flush @@ -6879,7 +6902,7 @@ dbug_gtid_accept: */ mi->do_accept_own_server_id= (s_id == global_system_variables.server_id && - rpl_semi_sync_slave_enabled && opt_gtid_strict_mode && + repl_semisync_slave.get_slave_enabled() && opt_gtid_strict_mode && mi->using_gtid != Master_info::USE_GTID_NO && !mysql_bin_log.check_strict_gtid_sequence(event_gtid.domain_id, event_gtid.server_id, diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a03635bc868..fdf84ef8a99 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1876,14 +1876,6 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, */ } -#define SECONDS_TO_WAIT_FOR_KILL 2 -#if !defined(_WIN32) && defined(HAVE_SELECT) -/* my_sleep() can wait for sub second times */ -#define WAIT_FOR_KILL_TRY_TIMES 20 -#else -#define WAIT_FOR_KILL_TRY_TIMES 2 -#endif - /** Awake a thread. diff --git a/sql/sql_class.h b/sql/sql_class.h index 6bbac5647be..d61ee1545b6 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -652,6 +652,15 @@ enum killed_type KILL_TYPE_QUERY }; +#define SECONDS_TO_WAIT_FOR_KILL 2 +#define SECONDS_TO_WAIT_FOR_DUMP_THREAD_KILL 10 +#if !defined(_WIN32) && defined(HAVE_SELECT) +/* my_sleep() can wait for sub second times */ +#define WAIT_FOR_KILL_TRY_TIMES 20 +#else +#define WAIT_FOR_KILL_TRY_TIMES 2 +#endif + #include "sql_lex.h" /* Must be here */ class Delayed_insert; diff --git a/sql/sql_list.h b/sql/sql_list.h index a9ab5415d5a..909e6209c44 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -799,7 +799,9 @@ public: class base_ilist_iterator { base_ilist *list; - struct ilink **el,*current; + struct ilink **el; +protected: + struct ilink *current; public: base_ilist_iterator(base_ilist &list_par) :list(&list_par), el(&list_par.first),current(0) {} @@ -811,6 +813,13 @@ public: el= ¤t->next; return current; } + /* Unlink element returned by last next() call */ + inline void unlink(void) + { + struct ilink **tmp= current->prev; + current->unlink(); + el= tmp; + } }; @@ -840,6 +849,13 @@ template class I_List_iterator :public base_ilist_iterator public: I_List_iterator(I_List &a) : base_ilist_iterator(a) {} inline T* operator++(int) { return (T*) base_ilist_iterator::next(); } + /* Remove element returned by last next() call */ + inline void remove(void) + { + unlink(); + delete (T*) current; + current= 0; // Safety + } }; /** diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c09a59b3adc..c30c825ffb8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2126,7 +2126,6 @@ dispatch_command_return dispatch_command(enum enum_server_command command, THD * { ulong pos; ushort flags; - uint32 slave_server_id; status_var_increment(thd->status_var.com_other); @@ -2137,10 +2136,26 @@ dispatch_command_return dispatch_command(enum enum_server_command command, THD * /* TODO: The following has to be changed to an 8 byte integer */ pos = uint4korr(packet); flags = uint2korr(packet + 4); - thd->variables.server_id=0; /* avoid suicide */ - if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0 - kill_zombie_dump_threads(slave_server_id); - thd->variables.server_id = slave_server_id; + if ((thd->variables.server_id= uint4korr(packet+6))) + { + bool got_error; + + got_error= kill_zombie_dump_threads(thd, + thd->variables.server_id); + if (got_error || thd->killed) + { + if (!thd->killed) + my_printf_error(ER_MASTER_FATAL_ERROR_READING_BINLOG, + "Could not start dump thread for slave: %u as " + "it has already a running dump thread", + MYF(0), (uint) thd->variables.server_id); + else if (! thd->get_stmt_da()->is_set()) + thd->send_kill_message(); + error= TRUE; + thd->unregister_slave(); // todo: can be extraneous + break; + } + } const char *name= packet + 10; size_t nlen= strlen(name); @@ -2148,6 +2163,8 @@ dispatch_command_return dispatch_command(enum enum_server_command command, THD * general_log_print(thd, command, "Log: '%s' Pos: %lu", name, pos); if (nlen < FN_REFLEN) mysql_binlog_send(thd, thd->strmake(name, nlen), (my_off_t)pos, flags); + if (thd->killed && ! thd->get_stmt_da()->is_set()) + thd->send_kill_message(); thd->unregister_slave(); // todo: can be extraneous /* fake COM_QUIT -- if we get here, the thread needs to terminate */ error = TRUE; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 70b4b9aedf7..1ac6db00a15 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -2060,7 +2060,7 @@ send_event_to_slave(binlog_send_info *info, Log_event_type event_type, } if (need_sync && repl_semisync_master.flush_net(info->thd, - packet->c_ptr_safe())) + packet->c_ptr())) { info->error= ER_UNKNOWN_ERROR; return "Failed to run hook 'after_send_event'"; @@ -3011,8 +3011,13 @@ err: if (info->thd->killed == KILL_SLAVE_SAME_ID) { - info->errmsg= "A slave with the same server_uuid/server_id as this slave " - "has connected to the master"; + /* + Note that the text is limited to 64 characters in errmsg-utf8 in + ER_ABORTING_CONNECTION. + */ + info->errmsg= + "A slave with the same server_uuid/server_id is already " + "connected"; info->error= ER_SLAVE_SAME_ID; } @@ -3385,6 +3390,7 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report ) @retval 0 success @retval 1 error */ + int reset_slave(THD *thd, Master_info* mi) { MY_STAT stat_area; @@ -3472,8 +3478,6 @@ int reset_slave(THD *thd, Master_info* mi) else if (global_system_variables.log_warnings > 1) sql_print_information("Deleted Master_info file '%s'.", fname); - if (rpl_semi_sync_slave_enabled) - repl_semisync_slave.reset_slave(mi); err: mi->unlock_slave_threads(); if (unlikely(error)) @@ -3501,43 +3505,89 @@ err: struct kill_callback_arg { - kill_callback_arg(uint32 id): slave_server_id(id), thd(0) {} - uint32 slave_server_id; + kill_callback_arg(THD *thd_arg, uint32 id): + thd(thd_arg), slave_server_id(id), counter(0) {} THD *thd; + uint32 slave_server_id; + uint counter; }; -static my_bool kill_callback(THD *thd, kill_callback_arg *arg) + +/* + Collect all active dump threads +*/ + +static my_bool kill_callback_collect(THD *thd, kill_callback_arg *arg) { if (thd->get_command() == COM_BINLOG_DUMP && - thd->variables.server_id == arg->slave_server_id) + thd->variables.server_id == arg->slave_server_id && + thd != arg->thd) { - arg->thd= thd; + arg->counter++; mysql_mutex_lock(&thd->LOCK_thd_kill); // Lock from delete mysql_mutex_lock(&thd->LOCK_thd_data); - return 1; + thd->awake_no_mutex(KILL_SLAVE_SAME_ID); // Mark killed + /* + Remover the thread from ack_receiver to ensure it is not + sending acks to the master anymore. + */ + ack_receiver.remove_slave(thd); + + mysql_mutex_unlock(&thd->LOCK_thd_data); + mysql_mutex_unlock(&thd->LOCK_thd_kill); } return 0; } -void kill_zombie_dump_threads(uint32 slave_server_id) -{ - kill_callback_arg arg(slave_server_id); - server_threads.iterate(kill_callback, &arg); +/* + Check if there are any active dump threads +*/ - if (arg.thd) - { - /* - Here we do not call kill_one_thread() as - it will be slow because it will iterate through the list - again. We just to do kill the thread ourselves. - */ - arg.thd->awake_no_mutex(KILL_SLAVE_SAME_ID); - mysql_mutex_unlock(&arg.thd->LOCK_thd_kill); - mysql_mutex_unlock(&arg.thd->LOCK_thd_data); - } +static my_bool kill_callback_check(THD *thd, kill_callback_arg *arg) +{ + return (thd->get_command() == COM_BINLOG_DUMP && + thd->variables.server_id == arg->slave_server_id && + thd != arg->thd); } + +/** + Try to kill running dump threads on the master + + @result 0 ok + @result 1 old slave thread exists and does not want to die + + There should not be more than one dump thread with the same server id + this code has however in the past has several issues. To ensure that + things works in all cases (now and in the future), this code is collecting + all matching server id's and killing all of them. +*/ + +bool kill_zombie_dump_threads(THD *thd, uint32 slave_server_id) +{ + kill_callback_arg arg(thd, slave_server_id); + server_threads.iterate(kill_callback_collect, &arg); + + if (!arg.counter) + return 0; + + /* + Wait up to SECONDS_TO_WAIT_FOR_DUMP_THREAD_KILL for kill + of all dump thread, trying every 1/10 of second. + */ + for (uint i= 10 * SECONDS_TO_WAIT_FOR_DUMP_THREAD_KILL ; + --i > 0 && !thd->killed; + i++) + { + if (!server_threads.iterate(kill_callback_check, &arg)) + return 0; // All dump thread are killed + my_sleep(1000000L / 10); // Wait 1/10 of a second + } + return 1; +} + + /** Get value for a string parameter with error checking diff --git a/sql/sql_repl.h b/sql/sql_repl.h index 95916e31abf..3be1e18ca0d 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -43,7 +43,7 @@ void adjust_linfo_offsets(my_off_t purge_offset); void show_binlogs_get_fields(THD *thd, List *field_list); bool show_binlogs(THD* thd); extern int init_master_info(Master_info* mi); -void kill_zombie_dump_threads(uint32 slave_server_id); +bool kill_zombie_dump_threads(THD *thd, uint32 slave_server_id); int check_binlog_magic(IO_CACHE* log, const char** errmsg); int compare_log_name(const char *log_1, const char *log_2); diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index be8a66ff7f2..dea04bf3bc5 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3478,13 +3478,6 @@ static bool fix_rpl_semi_sync_master_wait_point(sys_var *self, THD *thd, return false; } -static bool fix_rpl_semi_sync_master_wait_no_slave(sys_var *self, THD *thd, - enum_var_type type) -{ - repl_semisync_master.check_and_switch(); - return false; -} - static Sys_var_on_access_global Sys_semisync_master_enabled( @@ -3511,12 +3504,11 @@ static Sys_var_on_access_global Sys_semisync_master_wait_no_slave( "rpl_semi_sync_master_wait_no_slave", - "Wait until timeout when no semi-synchronous replication slave " - "available (enabled by default).", + "Wait until timeout when no semi-synchronous replication slave is " + "available.", GLOBAL_VAR(rpl_semi_sync_master_wait_no_slave), CMD_LINE(OPT_ARG), DEFAULT(TRUE), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), - ON_UPDATE(fix_rpl_semi_sync_master_wait_no_slave)); + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0)); static Sys_var_on_access_global @@ -3543,13 +3535,6 @@ Sys_semisync_master_wait_point( NO_MUTEX_GUARD, NOT_IN_BINLOG,ON_CHECK(0), ON_UPDATE(fix_rpl_semi_sync_master_wait_point)); -static bool fix_rpl_semi_sync_slave_enabled(sys_var *self, THD *thd, - enum_var_type type) -{ - repl_semisync_slave.set_slave_enabled(rpl_semi_sync_slave_enabled != 0); - return false; -} - static bool fix_rpl_semi_sync_slave_trace_level(sys_var *self, THD *thd, enum_var_type type) { @@ -3577,10 +3562,9 @@ static Sys_var_on_access_global From 1ca813bf76b66e86af2bde918eb33ee98a4e522b Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 25 Dec 2023 15:30:03 +0200 Subject: [PATCH 26/61] Added socketpair.c as a replacement for 'pipe()' call for Windows. This was needed to get semisync to work on Windows. --- THIRDPARTY | 29 ++++++ sql/CMakeLists.txt | 1 + sql/semisync_master_ack_receiver.cc | 17 ++- sql/semisync_master_ack_receiver.h | 53 ++++++++-- sql/socketpair.c | 156 ++++++++++++++++++++++++++++ sql/socketpair.h | 21 ++++ 6 files changed, 263 insertions(+), 14 deletions(-) create mode 100644 sql/socketpair.c create mode 100644 sql/socketpair.h diff --git a/THIRDPARTY b/THIRDPARTY index 35bb238ed1e..b15d979ea4a 100644 --- a/THIRDPARTY +++ b/THIRDPARTY @@ -1690,3 +1690,32 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *************************************************************************** + +%%The following software may be included in this product: +socketpair.c + +Copyright 2007, 2010 by Nathan C. Myers +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + The name of the author must not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index f1c1c65310b..20283cdefc4 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -175,6 +175,7 @@ SET (SQL_SOURCE table_cache.cc encryption.cc temporary_tables.cc json_table.cc proxy_protocol.cc backup.cc xa.cc + socketpair.c socketpair.h ${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h ${CMAKE_CURRENT_BINARY_DIR}/lex_token.h ${GEN_SOURCES} diff --git a/sql/semisync_master_ack_receiver.cc b/sql/semisync_master_ack_receiver.cc index 6453b7ef32a..9320c7fc3e6 100644 --- a/sql/semisync_master_ack_receiver.cc +++ b/sql/semisync_master_ack_receiver.cc @@ -25,7 +25,7 @@ extern PSI_cond_key key_COND_ack_receiver; extern PSI_thread_key key_thread_ack_receiver; #endif -int global_ack_signal_fd= -1; +my_socket global_ack_signal_fd= -1; /* Callback function of ack receive thread */ pthread_handler_t ack_receive_handler(void *arg) @@ -242,6 +242,13 @@ void Ack_receiver::run() Select_socket_listener listener(m_slaves); #endif //HAVE_POLL + if (listener.got_error()) + { + sql_print_error("Got error %M starting ack receiver thread", + listener.got_error()); + return; + } + sql_print_information("Starting ack receiver thread"); thd->system_thread= SYSTEM_THREAD_SEMISYNC_MASTER_BACKGROUND; thd->thread_stack= (char*) &thd; @@ -258,7 +265,7 @@ void Ack_receiver::run() while (1) { - int ret, slave_count; + int ret, slave_count= 0; Slave *slave; mysql_mutex_lock(&m_mutex); @@ -315,7 +322,9 @@ void Ack_receiver::run() Slave_ilist_iterator it(m_slaves); while ((slave= it++)) { - if (slave->active) // Set in init_slave_sockets() + if (slave->active && + ((slave->vio.read_pos < slave->vio.read_end) || + listener.is_socket_active(slave))) { ulong len; @@ -341,6 +350,7 @@ void Ack_receiver::run() Delete it from listener */ it.remove(); + m_slaves_changed= true; } } else if (net.last_errno == ER_NET_READ_ERROR) @@ -351,6 +361,7 @@ void Ack_receiver::run() net.last_errno, ER_DEFAULT(net.last_errno), slave->server_id()); it.remove(); + m_slaves_changed= true; } } } diff --git a/sql/semisync_master_ack_receiver.h b/sql/semisync_master_ack_receiver.h index d3d9de27b89..eacb4b200c0 100644 --- a/sql/semisync_master_ack_receiver.h +++ b/sql/semisync_master_ack_receiver.h @@ -20,6 +20,7 @@ #include "my_pthread.h" #include "sql_class.h" #include "semisync.h" +#include "socketpair.h" #include struct Slave :public ilink @@ -127,32 +128,54 @@ private: }; -extern int global_ack_signal_fd; +extern my_socket global_ack_signal_fd; class Ack_listener { public: - int local_read_signal; + my_socket local_read_signal; const Slave_ilist &m_slaves; + int error; Ack_listener(const Slave_ilist &slaves) - :m_slaves(slaves) + :local_read_signal(-1), m_slaves(slaves), error(0) { - int pipes[2]; - pipe(pipes); - global_ack_signal_fd= pipes[1]; + my_socket pipes[2]; +#ifdef _WIN32 + error= create_socketpair(pipes); +#else + if (!pipe(pipes)) + { + fcntl(pipes[0], F_SETFL, O_NONBLOCK); + fcntl(pipes[1], F_SETFL, O_NONBLOCK); + } + else + { + pipes[0]= pipes[1]= -1; + } +#endif /* _WIN32 */ local_read_signal= pipes[0]; - fcntl(pipes[0], F_SETFL, O_NONBLOCK); - fcntl(pipes[1], F_SETFL, O_NONBLOCK); + global_ack_signal_fd= pipes[1]; } virtual ~Ack_listener() { - close(global_ack_signal_fd); - close(local_read_signal); - global_ack_signal_fd= -1; +#ifdef _WIN32 + my_socket pipes[2]; + pipes[0]= local_read_signal; + pipes[1]= global_ack_signal_fd; + close_socketpair(pipes); +#else + if (global_ack_signal_fd >= 0) + close(global_ack_signal_fd); + if (local_read_signal >= 0) + close(local_read_signal); +#endif /* _WIN32 */ + global_ack_signal_fd= local_read_signal= -1; } + int got_error() { return error; } + virtual bool has_signal_data()= 0; /* Clear data sent by signal_listener() to abort read */ @@ -162,14 +185,22 @@ public: { char buff[100]; /* Clear the signal message */ +#ifndef _WIN32 read(local_read_signal, buff, sizeof(buff)); +#else + recv(local_read_signal, buff, sizeof(buff), 0); +#endif /* _WIN32 */ } } }; static inline void signal_listener() { +#ifndef _WIN32 my_write(global_ack_signal_fd, (uchar*) "a", 1, MYF(0)); +#else + send(global_ack_signal_fd, "a", 1, 0); +#endif /* _WIN32 */ } #ifdef HAVE_POLL diff --git a/sql/socketpair.c b/sql/socketpair.c new file mode 100644 index 00000000000..ef89fa0446b --- /dev/null +++ b/sql/socketpair.c @@ -0,0 +1,156 @@ +/* socketpair.c +Copyright 2007, 2010 by Nathan C. Myers +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + The name of the author must not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Changes: + * 2023-12-25 Addopted for MariaDB usage + * 2014-02-12: merge David Woodhouse, Ger Hobbelt improvements + * git.infradead.org/users/dwmw2/openconnect.git/commitdiff/bdeefa54 + * github.com/GerHobbelt/selectable-socketpair + * always init the socks[] to -1/INVALID_SOCKET on error, both on Win32/64 + * and UNIX/other platforms + * 2013-07-18: Change to BSD 3-clause license + * 2010-03-31: + * set addr to 127.0.0.1 because win32 getsockname does not always set it. + * 2010-02-25: + * set SO_REUSEADDR option to avoid leaking some windows resource. + * Windows System Error 10049, "Event ID 4226 TCP/IP has reached + * the security limit imposed on the number of concurrent TCP connect + * attempts." Bleah. + * 2007-04-25: + * preserve value of WSAGetLastError() on all error returns. + * 2007-04-22: (Thanks to Matthew Gregan ) + * s/EINVAL/WSAEINVAL/ fix trivial compile failure + * s/socket/WSASocket/ enable creation of sockets suitable as stdin/stdout + * of a child process. + * add argument make_overlapped + */ + +#include +#ifdef _WIN32 +#include /* socklen_t, et al (MSVC20xx) */ +#include +#include +#include "socketpair.h" + +#define safe_errno (errno != 0) ? errno : -1 + +/** + create_socketpair() + + @param socks[2] Will be filled by 2 SOCKET entries (similar to pipe()) + socks[0] for reading + socks[1] for writing + + @return: 0 ok + # System error code. -1 if unknown + */ + +int create_socketpair(SOCKET socks[2]) +{ + union + { + struct sockaddr_in inaddr; + struct sockaddr addr; + } a; + SOCKET listener= -1; + int reuse = 1; + int last_error; + socklen_t addrlen = sizeof(a.inaddr); + + socks[0]= socks[1]= -1; + + if ((listener= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) + return safe_errno; + + memset(&a, 0, sizeof(a)); + a.inaddr.sin_family = AF_INET; + a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + a.inaddr.sin_port = 0; + + for (;;) /* Avoid using goto */ + { + if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, + (char*) &reuse, (socklen_t) sizeof(reuse)) == -1) + break; + if (bind(listener, &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR) + break; + + memset(&a, 0, sizeof(a)); + if (getsockname(listener, &a.addr, &addrlen) == SOCKET_ERROR) + break; + // win32 getsockname may only set the port number, p=0.0005. + // ( http://msdn.microsoft.com/library/ms738543.aspx ): + a.inaddr.sin_addr.s_addr= htonl(INADDR_LOOPBACK); + a.inaddr.sin_family= AF_INET; + + if (listen(listener, 1) == SOCKET_ERROR) + break; + + socks[1]= socket(AF_INET, SOCK_STREAM, 0); + if (socks[1] == -1) + break; + if (connect(socks[1], &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR) + break; + + socks[0]= accept(listener, NULL, NULL); + if (socks[0] == -1) + break; + + closesocket(listener); + + { + /* Make both sockets non blocking */ + ulong arg= 1; + ioctlsocket(socks[0], FIONBIO,(void*) &arg); + ioctlsocket(socks[1], FIONBIO,(void*) &arg); + } + return 0; + } + /* Error handling */ + last_error= WSAGetLastError(); + if (listener != -1) + closesocket(listener); + close_socketpair(socks); + WSASetLastError(last_error); + + return last_error; +} + +/* + Free socketpair +*/ + +void close_socketpair(SOCKET socks[2]) +{ + if (socks[0] != -1) + closesocket(socks[0]); + if (socks[1] != -1) + closesocket(socks[1]); + socks[0]= socks[1]= -1; +} + +#endif /*_WIN32 */ diff --git a/sql/socketpair.h b/sql/socketpair.h new file mode 100644 index 00000000000..d9f89c84ffa --- /dev/null +++ b/sql/socketpair.h @@ -0,0 +1,21 @@ +/* Copyright (c) 2023, MariaDB Plc + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifdef _WIN32 +C_MODE_START + int create_socketpair(SOCKET socks[2]); + void close_socketpair(SOCKET socks[2]); +C_MODE_END +#endif /* _WIN32 */ From 2fcb5d651b98f9e480a251639ec2ed169b8f9355 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 12 Dec 2023 15:26:04 +0200 Subject: [PATCH 27/61] Fixed possible mutex-wrong-order with KILL USER The old code collected a list of THD's, locked the THD's from getting deleted by locking two mutex and then later in a separate loop sent a kill signal to each THD. The problem with this approach is that, as THD's can be reused, the second time the THD is killed, the mutex can be taken in different order, which signals failures in safe_mutex. Fixed by sending the kill signal directly and not collect the THD's in a list to be signaled later. This is the same approach we are using in kill_zombie_dump_threads(). Other things: - Reset safe_mutex_t->locked_mutex when freed (Safety fix) --- mysys/thr_mutex.c | 1 + sql/sql_parse.cc | 52 ++++++++++++++--------------------------------- 2 files changed, 16 insertions(+), 37 deletions(-) diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c index dd3a5ce132f..24000685aef 100644 --- a/mysys/thr_mutex.c +++ b/mysys/thr_mutex.c @@ -665,6 +665,7 @@ void safe_mutex_free_deadlock_data(safe_mutex_t *mp) my_hash_free(mp->used_mutex); my_hash_free(mp->locked_mutex); my_free(mp->locked_mutex); + mp->locked_mutex= 0; mp->create_flags|= MYF_NO_DEADLOCK_DETECTION; } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c30c825ffb8..c17e24d9599 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -9371,11 +9371,13 @@ kill_one_thread(THD *thd, my_thread_id id, killed_state kill_signal, killed_type struct kill_threads_callback_arg { - kill_threads_callback_arg(THD *thd_arg, LEX_USER *user_arg): - thd(thd_arg), user(user_arg) {} + kill_threads_callback_arg(THD *thd_arg, LEX_USER *user_arg, + killed_state kill_signal_arg): + thd(thd_arg), user(user_arg), kill_signal(kill_signal_arg), counter(0) {} THD *thd; LEX_USER *user; - List threads_to_kill; + killed_state kill_signal; + uint counter; }; @@ -9398,11 +9400,12 @@ static my_bool kill_threads_callback(THD *thd, kill_threads_callback_arg *arg) { return MY_TEST(arg->thd->security_ctx->master_access & PROCESS_ACL); } - if (!arg->threads_to_kill.push_back(thd, arg->thd->mem_root)) - { - mysql_mutex_lock(&thd->LOCK_thd_kill); // Lock from delete - mysql_mutex_lock(&thd->LOCK_thd_data); - } + arg->counter++; + mysql_mutex_lock(&thd->LOCK_thd_kill); // Lock from delete + mysql_mutex_lock(&thd->LOCK_thd_data); + thd->awake_no_mutex(arg->kill_signal); + mysql_mutex_unlock(&thd->LOCK_thd_data); + mysql_mutex_unlock(&thd->LOCK_thd_kill); } } return 0; @@ -9412,42 +9415,17 @@ static my_bool kill_threads_callback(THD *thd, kill_threads_callback_arg *arg) static uint kill_threads_for_user(THD *thd, LEX_USER *user, killed_state kill_signal, ha_rows *rows) { - kill_threads_callback_arg arg(thd, user); + kill_threads_callback_arg arg(thd, user, kill_signal); DBUG_ENTER("kill_threads_for_user"); - - *rows= 0; - - if (unlikely(thd->is_fatal_error)) // If we run out of memory - DBUG_RETURN(ER_OUT_OF_RESOURCES); - DBUG_PRINT("enter", ("user: %s signal: %u", user->user.str, (uint) kill_signal)); + *rows= 0; + if (server_threads.iterate(kill_threads_callback, &arg)) DBUG_RETURN(ER_KILL_DENIED_ERROR); - if (!arg.threads_to_kill.is_empty()) - { - List_iterator_fast it2(arg.threads_to_kill); - THD *next_ptr; - THD *ptr= it2++; - do - { - ptr->awake_no_mutex(kill_signal); - /* - Careful here: The list nodes are allocated on the memroots of the - THDs to be awakened. - But those THDs may be terminated and deleted as soon as we release - LOCK_thd_kill, which will make the list nodes invalid. - Since the operation "it++" dereferences the "next" pointer of the - previous list node, we need to do this while holding LOCK_thd_kill. - */ - next_ptr= it2++; - mysql_mutex_unlock(&ptr->LOCK_thd_kill); - mysql_mutex_unlock(&ptr->LOCK_thd_data); - (*rows)++; - } while ((ptr= next_ptr)); - } + *rows= arg.counter; DBUG_RETURN(0); } From c49fd902632ad2c1547cfa63c1206ea26783ce3f Mon Sep 17 00:00:00 2001 From: Monty Date: Thu, 21 Dec 2023 18:25:39 +0200 Subject: [PATCH 28/61] Ensure keyread_tmp variable is assigned. In the case of calcuating cost for a ref access for which there exists a usable range, the variable keyread_tmp would always be 0. If there is also another index that could be used as a filter, the cost of that filter would be wrong. In many cases 'the worst_seeks optimzation' would disable the filter from getting used, which is why this bug has not been noticed before. The next commit, which allows one to disable worst_seeks, will have a test case for this bug. --- sql/sql_select.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f27126825ed..62c7f52748a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8219,6 +8219,9 @@ best_access_path(JOIN *join, trace_access_idx.add("used_range_estimates", true); tmp= adjust_quick_cost(table->opt_range[key].cost, table->opt_range[key].rows); + keyread_tmp= table->file->keyread_time(key, 1, + table->opt_range[key]. + rows); goto got_cost; } else From 6f65e08277a9e65c193367e18c5e7bf68f68e3d2 Mon Sep 17 00:00:00 2001 From: Monty Date: Fri, 22 Dec 2023 13:53:57 +0200 Subject: [PATCH 29/61] MDEV-33118 optimizer_adjust_secondary_key_costs variable optimizer-adjust_secondary_key_costs is added to provide 2 small adjustments to the 10.x optimizer cost model. This can be used in the case where the optimizer wrongly uses a secondary key instead of a clustered primary key. The reason behind this change is that MariaDB 10.x does not take into account that for engines like InnoDB, that scanning a primary key can be up to 7x faster than scanning a secondary key + read the row data trough the primary key. The different values for optimizer_adjust_secondary_key_costs are: optimizer_adjust_secondary_key_costs=0 - No changes to current model optimizer_adjust_secondary_key_costs=1 - Ensure that the cost of of secondary indexes has a cost of at least 5x times the cost of a clustered primary key (if one exists). This disables part of the worst_seek optimization described below. optimizer_adjust_secondary_key_costs=2 - Disable "worst_seek optimization" and adjust filter cost slightly (add cost of 1 if filter is used). The idea behind 'worst_seek optimization' is that we limit the cost for all non clustered ref access to the least of: - best-rows-by-range (or all rows in no range found) / 10 - scan-time-table (roughly number of file blocks to scan table) * 3 In addition we also do not try to use rowid_filter if number of rows estimated for 'ref' access is less than the worst_seek limitation. The idea is that worst_seek is trying to take into account that if we do a lot of accesses through a key, this is likely to be cached. However it only does this for secondary keys, and not for clustered keys or index only reads. The effect of the worst_seek are: - In some cases 'ref' will have a much lower cost than range or using a clustered key. - Some possible rowid filters for secondary keys will be ignored. When implementing optimizer_adjust_secondary_key_costs=2, I noticed that there is a slightly different costs for how ref+filter and range+filter are calculated. This caused a lot of range and range+filter to change to ref+filter, which is not good as range+filter provides the optimizer a better estimate of how many accepted rows there will be in the result set. Adding a extra small cost (1 seek) when using filter mitigated the above problems in almost all cases. This patch should not be applied to MariaDB 11.0 as worst_seeks is removed in 11.0 and the cost calculation for clustered keys, secondary keys, index scan and filter is more exact. Test case changes for --optimizer-adjust_secondary_key_costs=1 (Fix secondary key costs to be 5x of primary key): - stat_tables_innodb: - Complex change (probably ok as number of rows are really small) - ref over 1 row changed to range over 10 rows with join buffer - ref over 5 rows changed to eq_ref - secondary ref over 1 row changed to ref of primary key over 4 rows - Change of key to use longer key with index pushdown (a little bit worse but not significant). - Change to use secondary (1 row) -> primary (4 rows) - rowid_filter_innodb: - index_merge (2 rows) & ref (1) -> all (23 rows) -> primary eq_ref. Test case changes for --optimizer-adjust_secondary_key_costs=2 (remove of worst_seeks & adjust filter cost): - stat_tables_innodb: - Join order change (probably ok as number of rows are really small) - ref (5 rows) & ref(1 row) changed to range (10 rows & join buffer) & eq_ref. - selectivity_innodb: - ref -> ref|filter (ok) - rowid_filter_innodb: - ref -> ref|filter (ok) - range|filter (64 rows) changed to ref|filter (128 rows). ok as ref|filter outputs wrong number of rows in explain. - range, range_mrr_icp: -ref (500 rows -> ALL (1000 rows) (ok) - select_pkeycache, select, select_jcl6: - ref|filter (2 rows) -> ref (2 rows) (ok) - selectivity: - ref -> ref_filter (ok) - range: - Change of 'filtered' but no stat or plan change (ok) - selectivity: - ref -> ref+filter (ok) - Change of filtered but no plan change (ok) - join_nested_jcl6: - range -> ref|filter (ok as only 2 rows) - subselect3, subselect3_jcl6: - ref_or_null (4 rows) -> ALL (10 rows) (ok) - Index_subquery (4 rows) -> ALL (10 rows) (ok) - partition_mrr_myisam, partition_mrr_aria and partition_mrr_innodb: - Uses ALL instead of REF for a key value that is the same for > 50% of rows. (good) order_by_innodb: - range (200 rows) -> ref (20 rows)+filesort (ok) - subselect_sj2_mat: - One test changed. One ALL removed and replaced with eq_ref. Likely to be better. - join_cache: - Changed ref over 60% of the rows to use hash join (ok) - opt_tvc: - Changed to use eq_ref instead of ref with plan change (probably ok) - opt_trace: - No worst/max seeks clipping (good). - Almost double range_scan_time and index_scan_time (ok). - rowid_filter: - ref -> ref|filtered (ok) - range|filter (77 rows) changed to ref|filter (151 rows). Proably ok as ref|filter outputs wrong number of rows in explain. Reviewer: Sergei Petrunia --- mysql-test/main/mysqld--help.result | 8 ++ mysql-test/main/secondary_key_costs.result | 82 +++++++++++++++++++ mysql-test/main/secondary_key_costs.test | 53 ++++++++++++ .../sys_vars/r/sysvars_server_embedded.result | 10 +++ .../r/sysvars_server_notembedded.result | 10 +++ sql/sql_class.h | 3 +- sql/sql_select.cc | 48 +++++++++-- sql/sys_vars.cc | 13 +++ 8 files changed, 219 insertions(+), 8 deletions(-) create mode 100644 mysql-test/main/secondary_key_costs.result create mode 100644 mysql-test/main/secondary_key_costs.test diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index 219bad22528..d8a8fe449b6 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -712,6 +712,13 @@ The following specify which files/extra groups are read (specified before remain max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors (Automatically configured unless set explicitly) + --optimizer-adjust-secondary-key-costs=# + 0 = No changes. 1 = Update secondary key costs for ranges + to be at least 5x of clustered primary key costs. 2 = + Remove 'max_seek optimization' for secondary keys and + slight adjustment of filter cost. This option will be + deleted in MariaDB 11.0 as it is not needed with the new + 11.0 optimizer. --optimizer-max-sel-arg-weight=# The maximum weight of the SEL_ARG graph. Set to 0 for no limit @@ -1684,6 +1691,7 @@ old-alter-table DEFAULT old-mode UTF8_IS_UTF8MB3 old-passwords FALSE old-style-user-limits FALSE +optimizer-adjust-secondary-key-costs 0 optimizer-max-sel-arg-weight 32000 optimizer-max-sel-args 16000 optimizer-prune-level 1 diff --git a/mysql-test/main/secondary_key_costs.result b/mysql-test/main/secondary_key_costs.result new file mode 100644 index 00000000000..55c84705abf --- /dev/null +++ b/mysql-test/main/secondary_key_costs.result @@ -0,0 +1,82 @@ +create table t1 ( +pk int primary key auto_increment, +nm varchar(32), +fl1 tinyint default 0, +fl2 tinyint default 0, +index idx1(nm, fl1), +index idx2(fl2) +) engine=myisam; +create table name ( +pk int primary key auto_increment, +nm bigint +) engine=myisam; +create table flag2 ( +pk int primary key auto_increment, +fl2 tinyint +) engine=myisam; +insert into name(nm) select seq from seq_1_to_1000 order by rand(17); +insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19); +insert into t1(nm,fl2) +select nm, fl2 from name, flag2 where name.pk = flag2.pk; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +set optimizer_trace="enabled=on"; +set optimizer_switch='rowid_filter=on'; +set statement optimizer_adjust_secondary_key_costs=0 for +explain select * from t1 where nm like '500%' AND fl2 = 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where +set @trace=(select trace from information_schema.optimizer_trace); +select json_detailed(json_extract(@trace, '$**.considered_access_paths')); +json_detailed(json_extract(@trace, '$**.considered_access_paths')) +[ + [ + { + "access_type": "ref", + "index": "idx2", + "used_range_estimates": true, + "rowid_filter_skipped": "worst/max seeks clipping", + "rows": 492, + "cost": 492.3171406, + "chosen": true + }, + { + "access_type": "range", + "resulting_rows": 0.492, + "cost": 1.448699097, + "chosen": true + } + ] +] + +The following trace should have a different rowid_filter_key cost + +set statement optimizer_adjust_secondary_key_costs=2 for +explain select * from t1 where nm like '500%' AND fl2 = 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range idx1,idx2 idx1 35 NULL 1 Using index condition; Using where +set @trace=(select trace from information_schema.optimizer_trace); +select json_detailed(json_extract(@trace, '$**.considered_access_paths')); +json_detailed(json_extract(@trace, '$**.considered_access_paths')) +[ + [ + { + "access_type": "ref", + "index": "idx2", + "used_range_estimates": true, + "rowid_filter_key": "idx1", + "rows": 492, + "cost": 3.814364688, + "chosen": true + }, + { + "access_type": "range", + "resulting_rows": 0.492, + "cost": 1.448699097, + "chosen": true + } + ] +] +drop table t1, name, flag2; diff --git a/mysql-test/main/secondary_key_costs.test b/mysql-test/main/secondary_key_costs.test new file mode 100644 index 00000000000..d3db137653b --- /dev/null +++ b/mysql-test/main/secondary_key_costs.test @@ -0,0 +1,53 @@ +--source include/have_sequence.inc +--source include/not_embedded.inc + +# +# Show the costs for rowid filter +# + +create table t1 ( + pk int primary key auto_increment, + nm varchar(32), + fl1 tinyint default 0, + fl2 tinyint default 0, + index idx1(nm, fl1), + index idx2(fl2) +) engine=myisam; + +create table name ( + pk int primary key auto_increment, + nm bigint +) engine=myisam; + +create table flag2 ( + pk int primary key auto_increment, + fl2 tinyint +) engine=myisam; + +insert into name(nm) select seq from seq_1_to_1000 order by rand(17); +insert into flag2(fl2) select seq mod 2 from seq_1_to_1000 order by rand(19); + +insert into t1(nm,fl2) + select nm, fl2 from name, flag2 where name.pk = flag2.pk; + +analyze table t1 persistent for all; + +--disable_ps_protocol +set optimizer_trace="enabled=on"; +set optimizer_switch='rowid_filter=on'; +set statement optimizer_adjust_secondary_key_costs=0 for +explain select * from t1 where nm like '500%' AND fl2 = 0; +set @trace=(select trace from information_schema.optimizer_trace); +select json_detailed(json_extract(@trace, '$**.considered_access_paths')); + +--echo +--echo The following trace should have a different rowid_filter_key cost +--echo +set statement optimizer_adjust_secondary_key_costs=2 for +explain select * from t1 where nm like '500%' AND fl2 = 0; +set @trace=(select trace from information_schema.optimizer_trace); +select json_detailed(json_extract(@trace, '$**.considered_access_paths')); + +--enable_ps_protocol + +drop table t1, name, flag2; diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index 8e50d8e7268..aa88a8f74a8 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -2272,6 +2272,16 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_ADJUST_SECONDARY_KEY_COSTS +VARIABLE_SCOPE SESSION +VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_COMMENT 0 = No changes. 1 = Update secondary key costs for ranges to be at least 5x of clustered primary key costs. 2 = Remove 'max_seek optimization' for secondary keys and slight adjustment of filter cost. This option will be deleted in MariaDB 11.0 as it is not needed with the new 11.0 optimizer. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 2 +NUMERIC_BLOCK_SIZE 1 +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_MAX_SEL_ARGS VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 00c66ddf072..c07b7169608 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -2432,6 +2432,16 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME OPTIMIZER_ADJUST_SECONDARY_KEY_COSTS +VARIABLE_SCOPE SESSION +VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_COMMENT 0 = No changes. 1 = Update secondary key costs for ranges to be at least 5x of clustered primary key costs. 2 = Remove 'max_seek optimization' for secondary keys and slight adjustment of filter cost. This option will be deleted in MariaDB 11.0 as it is not needed with the new 11.0 optimizer. +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 2 +NUMERIC_BLOCK_SIZE 1 +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_MAX_SEL_ARGS VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED diff --git a/sql/sql_class.h b/sql/sql_class.h index d61ee1545b6..5175d440136 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -698,7 +698,6 @@ typedef struct system_variables ulonglong max_statement_time; ulonglong optimizer_switch; ulonglong optimizer_trace; - ulong optimizer_trace_max_mem_size; sql_mode_t sql_mode; ///< which non-standard SQL behaviour should be enabled sql_mode_t old_behavior; ///< which old SQL behaviour should be enabled ulonglong option_bits; ///< OPTION_xxx constants, e.g. OPTION_PROFILING @@ -761,6 +760,8 @@ typedef struct system_variables ulong optimizer_use_condition_selectivity; ulong optimizer_max_sel_arg_weight; ulong optimizer_max_sel_args; + ulong optimizer_trace_max_mem_size; + ulong optimizer_adjust_secondary_key_costs; ulong use_stat_tables; double sample_percentage; ulong histogram_size; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 62c7f52748a..b1779ebc24d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5895,11 +5895,15 @@ make_join_statistics(JOIN *join, List &tables_list, This is can't be to high as otherwise we are likely to use table scan. */ - s->worst_seeks= MY_MIN((double) s->found_records / 10, - (double) s->read_time*3); - if (s->worst_seeks < 2.0) // Fix for small tables - s->worst_seeks=2.0; - + /* Largest integer that can be stored in double (no compiler warning) */ + s->worst_seeks= (double) (1ULL << 53); + if (thd->variables.optimizer_adjust_secondary_key_costs != 2) + { + s->worst_seeks= MY_MIN((double) s->found_records / 10, + (double) s->read_time*3); + if (s->worst_seeks < 2.0) // Fix for small tables + s->worst_seeks=2.0; + } /* Add to stat->const_keys those indexes for which all group fields or all select distinct fields participate in one index. @@ -7817,8 +7821,27 @@ double cost_for_index_read(const THD *thd, const TABLE *table, uint key, if (table->covering_keys.is_set(key)) cost= file->keyread_time(key, 1, records); else + { cost= ((file->keyread_time(key, 0, records) + file->read_time(key, 1, MY_MIN(records, worst_seeks)))); + if (thd->variables.optimizer_adjust_secondary_key_costs == 1 && + file->is_clustering_key(0)) + { + /* + According to benchmarks done in 11.0 to calculate the new cost + model secondary key ranges are about 7x slower than primary + key ranges for big tables. Here we are a bit conservative and + only calculate with 5x. The reason for having it only 5x and + not for example 7x is is that choosing plans with more rows + that are read (ignored by the WHERE clause) causes the 10.x + optimizer to believe that there are more rows in the result + set, which can cause problems in finding the best join order. + Note: A clustering primary key is always key 0. + */ + double clustering_key_cost= file->read_time(0, 1, records); + cost= MY_MAX(cost, clustering_key_cost * 5); + } + } DBUG_PRINT("statistics", ("cost: %.3f", cost)); DBUG_RETURN(cost); @@ -7992,6 +8015,14 @@ best_access_path(JOIN *join, double keyread_tmp= 0; ha_rows rec; bool best_uses_jbuf= FALSE; + /* + if optimizer_use_condition_selectivity adjust filter cost to be slightly + higher to ensure that ref|filter is not less than range over same + number of rows + */ + double filter_setup_cost= (thd->variables. + optimizer_adjust_secondary_key_costs == 2 ? + 1.0 : 0.0); MY_BITMAP *eq_join_set= &s->table->eq_join_set; KEYUSE *hj_start_key= 0; SplM_plan_info *spl_plan= 0; @@ -8548,6 +8579,7 @@ best_access_path(JOIN *join, type == JT_EQ_REF ? 0.5 * tmp : MY_MIN(tmp, keyread_tmp); double access_cost_factor= MY_MIN((tmp - key_access_cost) / rows, 1.0); + if (!(records < s->worst_seeks && records <= thd->variables.max_seeks_for_key)) { @@ -8564,7 +8596,9 @@ best_access_path(JOIN *join, } if (filter) { - tmp-= filter->get_adjusted_gain(rows) - filter->get_cmp_gain(rows); + tmp-= (filter->get_adjusted_gain(rows) - + filter->get_cmp_gain(rows) - + filter_setup_cost); DBUG_ASSERT(tmp >= 0); trace_access_idx.add("rowid_filter_key", table->key_info[filter->key_no].name); @@ -8810,7 +8844,7 @@ best_access_path(JOIN *join, access_cost_factor); if (filter) { - tmp-= filter->get_adjusted_gain(rows); + tmp-= filter->get_adjusted_gain(rows) - filter_setup_cost; DBUG_ASSERT(tmp >= 0); } diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index dea04bf3bc5..61911d877e5 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -2817,6 +2817,19 @@ static Sys_var_ulong Sys_optimizer_trace_max_mem_size( SESSION_VAR(optimizer_trace_max_mem_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, ULONG_MAX), DEFAULT(1024 * 1024), BLOCK_SIZE(1)); +static Sys_var_ulong Sys_optimizer_adjust_secondary_key_costs( + "optimizer_adjust_secondary_key_costs", + "0 = No changes. " + "1 = Update secondary key costs for ranges to be at least 5x of clustered " + "primary key costs. " + "2 = Remove 'max_seek optimization' for secondary keys and slight " + "adjustment of filter cost. " + "This option will be deleted in MariaDB 11.0 as it is not needed with the " + "new 11.0 optimizer.", + SESSION_VAR(optimizer_adjust_secondary_key_costs), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 2), DEFAULT(0), BLOCK_SIZE(1)); + + static Sys_var_charptr_fscs Sys_pid_file( "pid_file", "Pid file used by safe_mysqld", READ_ONLY GLOBAL_VAR(pidfile_name_ptr), CMD_LINE(REQUIRED_ARG), From 3c63e2f89051457033d48920e6f7aebd082ddad3 Mon Sep 17 00:00:00 2001 From: Monty Date: Wed, 27 Dec 2023 19:58:59 +0200 Subject: [PATCH 30/61] Temporary table name used by multip-update has 'null' as part of the name Problem was that TMP_TABLE_PARAM was not properly initialized --- sql/sql_update.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 7fd5c864c06..980fa0fbddc 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -2431,7 +2431,8 @@ loop_end: group.direction= ORDER::ORDER_ASC; group.item= (Item**) temp_fields.head_ref(); - tmp_param->quick_group= 1; + tmp_param->init(); + tmp_param->tmp_name="update"; tmp_param->field_count= temp_fields.elements; tmp_param->func_count= temp_fields.elements - 1; calc_group_buffer(tmp_param, &group); From 740d3e7a7472d19fc8636d42bbcfbafa0a283f11 Mon Sep 17 00:00:00 2001 From: Monty Date: Fri, 5 Jan 2024 15:29:07 +0200 Subject: [PATCH 31/61] Trivial fixes: - Removed not used variable 'file' from MYSQL_BIN_LOG::open() - Assigned not initialized variable in connect/tabext.cpp --- sql/log.cc | 5 ----- storage/connect/tabext.cpp | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 3ca387d5ab9..401ce408c5f 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3694,7 +3694,6 @@ bool MYSQL_BIN_LOG::open(const char *log_name, bool null_created_arg, bool need_mutex) { - File file= -1; xid_count_per_binlog *new_xid_list_entry= NULL, *b; DBUG_ENTER("MYSQL_BIN_LOG::open"); @@ -4090,8 +4089,6 @@ err: sql_print_error(fatal_log_error, (name) ? name : log_name, tmp_errno); if (new_xid_list_entry) delete new_xid_list_entry; - if (file >= 0) - mysql_file_close(file, MYF(0)); close(LOG_CLOSE_INDEX); DBUG_RETURN(1); } @@ -5363,8 +5360,6 @@ int MYSQL_BIN_LOG::new_file_without_locking() /** Start writing to a new log file or reopen the old file. - @param need_lock Set to 1 if caller has not locked LOCK_log - @retval nonzero - error diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp index f558cb04f4d..e8b9da63c22 100644 --- a/storage/connect/tabext.cpp +++ b/storage/connect/tabext.cpp @@ -330,7 +330,7 @@ bool TDBEXT::MakeSrcdef(PGLOBAL g) char *catp = strstr(Srcdef, "%s"); if (catp) { - char *fil1 = 0, *fil2; + char *fil1 = 0, *fil2= 0; PCSZ ph = ((EXTDEF*)To_Def)->Phpos; if (!ph) From c777429cf90288c2fb6ac1ab1347826ed2125b7d Mon Sep 17 00:00:00 2001 From: Monty Date: Fri, 19 Jan 2024 12:01:28 +0200 Subject: [PATCH 32/61] MDEV-33279 Disable transparent huge pages after page buffers has been allocatedDisable transparent huge pages (THP) The reason for disabling transparent huge pages (THP) is that they do not work well with MariaDB (or other databases, see links in MDEV-33279). The effect of using THP are that MariaDB will use much more (10x) more memory and will no be able to release memory back to the system. Disabling THP is done after all storage engines are started, to allow buffer pools and keybuffers (big allocations) to be allocated as huge pages. --- sql/mysqld.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2766bc00e3a..b07b7a414af 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5451,6 +5451,15 @@ static int init_server_components() #else locked_in_memory= 0; #endif +#ifdef PR_SET_THP_DISABLE + /* + Engine page buffers are now allocated. + Disable transparent huge pages for all + future allocations as these causes memory + leaks. + */ + prctl(PR_SET_THP_DISABLE, 1, 0, 0, 0); +#endif ft_init_stopwords(); From d2c431bccbbd6ee74297a0dd9da44b2fe20c24d5 Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 20 Jan 2024 17:09:38 +0200 Subject: [PATCH 33/61] Disable main.gis from embedded Fails with: query 'select ST_AsWKT(GeometryCollection(Point(44, 6), @g))' failed: ER_ILLEGAL_VALUE_FOR_TYPE (1367): Illegal non geometric '@`g`' value found during parsing --- mysql-test/main/gis.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/main/gis.test b/mysql-test/main/gis.test index f160d8f1a10..b51080d2e1b 100644 --- a/mysql-test/main/gis.test +++ b/mysql-test/main/gis.test @@ -1,5 +1,5 @@ -- source include/have_geometry.inc - +-- source include/not_embedded.inc # # Spatial objects From 286d6f239a6f149208c30797ded3ad56af13fc18 Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 20 Jan 2024 17:41:33 +0200 Subject: [PATCH 34/61] Fixed main.strict test to work with icc compiler --- mysql-test/main/strict.result | 2 +- mysql-test/main/strict.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/strict.result b/mysql-test/main/strict.result index 3163059956c..d9d92402927 100644 --- a/mysql-test/main/strict.result +++ b/mysql-test/main/strict.result @@ -897,7 +897,7 @@ ERROR 22003: Out of range value for column 'col1' at row 1 INSERT INTO t1 (col2) VALUES ('-1.2E-3'); ERROR 22003: Out of range value for column 'col2' at row 1 UPDATE t1 SET col1 =col1 * 5000 WHERE col1 > 0; -ERROR 22003: DOUBLE value is out of range in '"test"."t1"."col1" * 5000' +Got one of the listed errors UPDATE t1 SET col2 =col2 / 0 WHERE col2 > 0; ERROR 22012: Division by 0 UPDATE t1 SET col2= MOD(col2,0) WHERE col2 > 0; diff --git a/mysql-test/main/strict.test b/mysql-test/main/strict.test index 830f051a5f6..1819f399041 100644 --- a/mysql-test/main/strict.test +++ b/mysql-test/main/strict.test @@ -824,7 +824,7 @@ INSERT INTO t1 (col2) VALUES (-1.1E-3); INSERT INTO t1 (col1) VALUES ('+1.8E+309'); --error 1264 INSERT INTO t1 (col2) VALUES ('-1.2E-3'); ---error ER_DATA_OUT_OF_RANGE +--error ER_DATA_OUT_OF_RANGE, ER_WARN_DATA_OUT_OF_RANGE UPDATE t1 SET col1 =col1 * 5000 WHERE col1 > 0; --error 1365 UPDATE t1 SET col2 =col2 / 0 WHERE col2 > 0; From 6085fb199a8a7da68c2ecc3c86452974c7b77dad Mon Sep 17 00:00:00 2001 From: Monty Date: Sun, 21 Jan 2024 16:52:19 +0200 Subject: [PATCH 35/61] Fixed compiler error/warning in backup_copy.cc --- extra/mariabackup/backup_copy.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc index f25570f32bb..04154be0538 100644 --- a/extra/mariabackup/backup_copy.cc +++ b/extra/mariabackup/backup_copy.cc @@ -2308,7 +2308,7 @@ ds_ctxt_t::make_hardlink(const char *from_path, const char *to_path) } else { - strncpy(to_path_full, to_path, sizeof(to_path_full)); + strncpy(to_path_full, to_path, sizeof(to_path_full)-1); } #ifdef _WIN32 return CreateHardLink(to_path_full, from_path, NULL); From 26c86c39fcf366aa14f8f948889c23e7a5be3702 Mon Sep 17 00:00:00 2001 From: Monty Date: Sun, 21 Jan 2024 19:10:37 +0200 Subject: [PATCH 36/61] Fixed some mtr tests that failed on windows Most things where wrong in the test suite. The one thing that was a bug was that table_map_id was in some places defined as ulong and in other places as ulonglong. On Linux 64 bit this is not a problem as ulong == ulonglong, but on windows this caused failures. Fixed by ensuring that all instances of table_map_id are ulonglong. --- extra/mariabackup/xtrabackup.cc | 2 +- libmysqld/libmysql.c | 6 +- mysql-test/suite/multi_source/mdev-9544.test | 1 + .../suite/rpl/r/rpl_row_big_table_id.result | 16 +- .../r/sysvars_server_notembedded,win.rdiff | 1465 +++++++++++++++++ mysql-test/suite/sys_vars/t/sysvars_star.test | 4 +- plugin/file_key_management/parser.cc | 2 +- sql/item_strfunc.cc | 2 +- sql/log.cc | 5 +- sql/log_event.cc | 7 +- sql/log_event.h | 24 +- sql/log_event_client.cc | 4 +- sql/log_event_old.cc | 29 +- sql/log_event_old.h | 12 +- sql/log_event_server.cc | 41 +- sql/sql_analyse.cc | 3 +- sql/sql_class.cc | 3 +- sql/table.cc | 18 +- sql/table.h | 10 +- storage/myisammrg/ha_myisammrg.h | 6 +- .../bugfix/t/mdev_32753_after_start.test | 1 + .../spider/include/clean_up_spider.inc | 1 + 22 files changed, 1576 insertions(+), 86 deletions(-) create mode 100644 mysql-test/suite/sys_vars/r/sysvars_server_notembedded,win.rdiff diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 74ea06e35ee..0dc2dda4705 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -2190,7 +2190,7 @@ static bool innodb_init_param() /* Check that values don't overflow on 32-bit systems. */ if (sizeof(ulint) == 4) { - if (xtrabackup_use_memory > UINT_MAX32) { + if (xtrabackup_use_memory > (longlong) UINT_MAX32) { msg("mariabackup: use-memory can't be over 4GB" " on 32-bit systems"); } diff --git a/libmysqld/libmysql.c b/libmysqld/libmysql.c index 7f55b0c2726..07926763c61 100644 --- a/libmysqld/libmysql.c +++ b/libmysqld/libmysql.c @@ -3229,7 +3229,8 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value, size_t { longlong data= my_strtoll10(value, &endptr, &err); *param->error= (IS_TRUNCATED(data, param->is_unsigned, - INT_MIN32, INT_MAX32, UINT_MAX32) || err > 0); + (longlong) INT_MIN32, (longlong) INT_MAX32, + (longlong) UINT_MAX32) || err > 0); longstore(buffer, (int32) data); break; } @@ -3346,7 +3347,8 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field, break; case MYSQL_TYPE_LONG: *param->error= IS_TRUNCATED(value, param->is_unsigned, - INT_MIN32, INT_MAX32, UINT_MAX32); + (longlong) INT_MIN32, (longlong) INT_MAX32, + (longlong) UINT_MAX32); longstore(buffer, (int32) value); break; case MYSQL_TYPE_LONGLONG: diff --git a/mysql-test/suite/multi_source/mdev-9544.test b/mysql-test/suite/multi_source/mdev-9544.test index f532a63a585..7b1169e7522 100644 --- a/mysql-test/suite/multi_source/mdev-9544.test +++ b/mysql-test/suite/multi_source/mdev-9544.test @@ -1,6 +1,7 @@ --source include/not_embedded.inc --source include/have_innodb.inc --source include/have_debug.inc +--source include/not_windows.inc --connect (server_1,127.0.0.1,root,,,$SERVER_MYPORT_1) --connect (server_2,127.0.0.1,root,,,$SERVER_MYPORT_2) diff --git a/mysql-test/suite/rpl/r/rpl_row_big_table_id.result b/mysql-test/suite/rpl/r/rpl_row_big_table_id.result index 694a6132244..0c51e58f5a7 100644 --- a/mysql-test/suite/rpl/r/rpl_row_big_table_id.result +++ b/mysql-test/suite/rpl/r/rpl_row_big_table_id.result @@ -21,23 +21,23 @@ master-bin.000001 # Gtid 1 # GTID #-#-# master-bin.000001 # Query 1 # use `test`; ALTER TABLE t comment '' master-bin.000001 # Gtid 1 # BEGIN GTID #-#-# master-bin.000001 # Annotate_rows 1 # INSERT INTO t SET a= 1 -master-bin.000001 # Table_map 1 # table_id: 4294967295 (test.t) -master-bin.000001 # Write_rows_v1 1 # table_id: 4294967295 flags: STMT_END_F -master-bin.000001 # Query 1 # COMMIT -master-bin.000001 # Gtid 1 # GTID #-#-# -master-bin.000001 # Query 1 # use `test`; ALTER TABLE t comment '' -master-bin.000001 # Gtid 1 # BEGIN GTID #-#-# -master-bin.000001 # Annotate_rows 1 # INSERT INTO t SET a= 2 master-bin.000001 # Table_map 1 # table_id: 4294967296 (test.t) master-bin.000001 # Write_rows_v1 1 # table_id: 4294967296 flags: STMT_END_F master-bin.000001 # Query 1 # COMMIT master-bin.000001 # Gtid 1 # GTID #-#-# master-bin.000001 # Query 1 # use `test`; ALTER TABLE t comment '' master-bin.000001 # Gtid 1 # BEGIN GTID #-#-# -master-bin.000001 # Annotate_rows 1 # INSERT INTO t SET a= 3 +master-bin.000001 # Annotate_rows 1 # INSERT INTO t SET a= 2 master-bin.000001 # Table_map 1 # table_id: 4294967297 (test.t) master-bin.000001 # Write_rows_v1 1 # table_id: 4294967297 flags: STMT_END_F master-bin.000001 # Query 1 # COMMIT +master-bin.000001 # Gtid 1 # GTID #-#-# +master-bin.000001 # Query 1 # use `test`; ALTER TABLE t comment '' +master-bin.000001 # Gtid 1 # BEGIN GTID #-#-# +master-bin.000001 # Annotate_rows 1 # INSERT INTO t SET a= 3 +master-bin.000001 # Table_map 1 # table_id: 4294967298 (test.t) +master-bin.000001 # Write_rows_v1 1 # table_id: 4294967298 flags: STMT_END_F +master-bin.000001 # Query 1 # COMMIT connection slave; connection master; SET debug_dbug=@old_debug_dbug; diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,win.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,win.rdiff new file mode 100644 index 00000000000..acee8a39b43 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,win.rdiff @@ -0,0 +1,1465 @@ +--- suite/sys_vars/r/sysvars_server_notembedded.result ++++ suite/sys_vars/r/sysvars_server_notembedded.reject +@@ -34,7 +34,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME ARIA_BLOCK_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Block size to be used for Aria index pages. + NUMERIC_MIN_VALUE 4096 + NUMERIC_MAX_VALUE 32768 +@@ -44,7 +44,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME ARIA_CHECKPOINT_INTERVAL + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Interval between tries to do an automatic checkpoints. In seconds; 0 means 'no automatic checkpoints' which makes sense only for testing. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -54,7 +54,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME ARIA_CHECKPOINT_LOG_ACTIVITY + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Number of bytes that the transaction log has to grow between checkpoints before a new checkpoint is written to the log. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -74,7 +74,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME ARIA_FORCE_START_AFTER_RECOVERY_FAILURES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Number of consecutive log recovery failures after which logs will be automatically deleted to cure the problem; 0 (the default) disables the feature. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 255 +@@ -94,7 +94,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME ARIA_GROUP_COMMIT_INTERVAL + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Interval between commits in microseconds (1/1000000 sec). 0 stands for no waiting for other threads to come and do a commit in "hard" mode and no sync()/commit at all in "soft" mode. Option has only an effect if aria_group_commit is used + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -114,7 +114,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME ARIA_LOG_FILE_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Limit for transaction log size + NUMERIC_MIN_VALUE 8388608 + NUMERIC_MAX_VALUE 4294967295 +@@ -144,10 +144,10 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME ARIA_PAGECACHE_AGE_THRESHOLD + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT This characterizes the number of hits a hot block has to be untouched until it is considered aged enough to be downgraded to a warm block. This specifies the percentage ratio of that number of hits to the total number of blocks in the page cache. + NUMERIC_MIN_VALUE 100 +-NUMERIC_MAX_VALUE 18446744073709551615 ++NUMERIC_MAX_VALUE 4294967295 + NUMERIC_BLOCK_SIZE 100 + ENUM_VALUE_LIST NULL + READ_ONLY NO +@@ -164,7 +164,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME ARIA_PAGECACHE_DIVISION_LIMIT + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The minimum percentage of warm blocks in key cache + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 100 +@@ -174,7 +174,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME ARIA_PAGECACHE_FILE_HASH_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Number of hash buckets for open and changed files. If you have a lot of Aria files open you should increase this for faster flush of changes. A good value is probably 1/10 of number of possible open Aria files. + NUMERIC_MIN_VALUE 128 + NUMERIC_MAX_VALUE 16384 +@@ -204,7 +204,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME ARIA_REPAIR_THREADS + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Number of threads to use when repairing Aria tables. The value of 1 disables parallel repair. + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 128 +@@ -274,7 +274,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME AUTO_INCREMENT_INCREMENT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Auto-increment columns are incremented by this + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 65535 +@@ -284,7 +284,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME AUTO_INCREMENT_OFFSET + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Offset added to Auto-increment columns. Used when auto-increment-increment != 1 + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 65535 +@@ -294,7 +294,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME BACK_LOG + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The number of outstanding connection requests MariaDB can have. This comes into play when the main MariaDB thread gets very many connection requests in a very short time + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 65535 +@@ -364,20 +364,20 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME BINLOG_COMMIT_WAIT_COUNT + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT If non-zero, binlog write will wait at most binlog_commit_wait_usec microseconds for at least this many commits to queue up for group commit to the binlog. This can reduce I/O on the binlog and provide increased opportunity for parallel apply on the slave, but too high a value will decrease commit throughput. + NUMERIC_MIN_VALUE 0 +-NUMERIC_MAX_VALUE 18446744073709551615 ++NUMERIC_MAX_VALUE 4294967295 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME BINLOG_COMMIT_WAIT_USEC + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum time, in microseconds, to wait for more commits to queue up for binlog group commit. Only takes effect if the value of binlog_commit_wait_count is non-zero. + NUMERIC_MIN_VALUE 0 +-NUMERIC_MAX_VALUE 18446744073709551615 ++NUMERIC_MAX_VALUE 4294967295 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO +@@ -394,7 +394,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME BINLOG_EXPIRE_LOGS_SECONDS + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT If non-zero, binary logs will be purged after binlog_expire_logs_seconds seconds; It and expire_logs_days are linked, such that changes in one are converted into the other. Possible purges happen at startup and at binary log rotation. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 8553600 +@@ -654,7 +654,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME CONNECT_TIMEOUT + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The number of seconds the mysqld server is waiting for a connect packet before responding with 'Bad handshake' + NUMERIC_MIN_VALUE 2 + NUMERIC_MAX_VALUE 31536000 +@@ -704,7 +704,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME DEADLOCK_SEARCH_DEPTH_LONG + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Long search depth for the two-step deadlock detection + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 33 +@@ -714,7 +714,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME DEADLOCK_SEARCH_DEPTH_SHORT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Short search depth for the two-step deadlock detection + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 32 +@@ -724,7 +724,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME DEADLOCK_TIMEOUT_LONG + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Long timeout for the two-step deadlock detection (in microseconds) + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -734,7 +734,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME DEADLOCK_TIMEOUT_SHORT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Short timeout for the two-step deadlock detection (in microseconds) + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -794,7 +794,7 @@ + COMMAND_LINE_ARGUMENT NULL + VARIABLE_NAME DEFAULT_WEEK_FORMAT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The default week format used by WEEK() functions + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 7 +@@ -804,7 +804,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME DELAYED_INSERT_LIMIT + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT After inserting delayed_insert_limit rows, the INSERT DELAYED handler will check if there are any SELECT statements pending. If so, it allows these to execute before continuing. + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 4294967295 +@@ -814,7 +814,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME DELAYED_INSERT_TIMEOUT + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT How long a INSERT DELAYED thread should wait for INSERT statements before terminating + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 31536000 +@@ -824,7 +824,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME DELAYED_QUEUE_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT What size queue (in rows) should be allocated for handling INSERT DELAYED. If the queue becomes full, any client that does INSERT DELAYED will wait until there is room in the queue again + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 4294967295 +@@ -854,7 +854,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME DIV_PRECISION_INCREMENT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Precision of the result of '/' operator will be increased on that value + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 38 +@@ -974,7 +974,7 @@ + COMMAND_LINE_ARGUMENT NULL + VARIABLE_NAME EXTRA_MAX_CONNECTIONS + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The number of connections on extra-port + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 100000 +@@ -1004,7 +1004,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME FLUSH_TIME + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT A dedicated thread is created to flush all tables at the given interval + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 31536000 +@@ -1034,7 +1034,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME FT_MAX_WORD_LEN + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The maximum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable + NUMERIC_MIN_VALUE 10 + NUMERIC_MAX_VALUE 84 +@@ -1044,7 +1044,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME FT_MIN_WORD_LEN + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The minimum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 84 +@@ -1054,7 +1054,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME FT_QUERY_EXPANSION_LIMIT + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Number of best matches to use for query expansion + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 1000 +@@ -1304,7 +1304,7 @@ + COMMAND_LINE_ARGUMENT NULL + VARIABLE_NAME HISTOGRAM_SIZE + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Number of bytes used for a histogram. If set to 0, no histograms are created by ANALYZE. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 255 +@@ -1334,7 +1334,7 @@ + COMMAND_LINE_ARGUMENT NULL + VARIABLE_NAME HOST_CACHE_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT How many host names should be cached to avoid resolving. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 65536 +@@ -1357,7 +1357,7 @@ + VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The number of seconds the server waits for read-only idle transaction + NUMERIC_MIN_VALUE 0 +-NUMERIC_MAX_VALUE 31536000 ++NUMERIC_MAX_VALUE 2147483 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO +@@ -1367,7 +1367,7 @@ + VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The number of seconds the server waits for idle transaction + NUMERIC_MIN_VALUE 0 +-NUMERIC_MAX_VALUE 31536000 ++NUMERIC_MAX_VALUE 2147483 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO +@@ -1377,7 +1377,7 @@ + VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The number of seconds the server waits for write idle transaction + NUMERIC_MIN_VALUE 0 +-NUMERIC_MAX_VALUE 31536000 ++NUMERIC_MAX_VALUE 2147483 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO +@@ -1444,7 +1444,7 @@ + COMMAND_LINE_ARGUMENT NULL + VARIABLE_NAME INTERACTIVE_TIMEOUT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The number of seconds the server waits for activity on an interactive connection before closing it + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 31536000 +@@ -1494,7 +1494,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME JOIN_CACHE_LEVEL + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Controls what join operations can be executed with join buffers. Odd numbers are used for plain join buffers while even numbers are used for linked buffers + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 8 +@@ -1672,19 +1672,9 @@ + ENUM_VALUE_LIST OFF,ON + READ_ONLY NO + COMMAND_LINE_ARGUMENT OPTIONAL +-VARIABLE_NAME LOCKED_IN_MEMORY +-VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BOOLEAN +-VARIABLE_COMMENT Whether mysqld was locked in memory with --memlock +-NUMERIC_MIN_VALUE NULL +-NUMERIC_MAX_VALUE NULL +-NUMERIC_BLOCK_SIZE NULL +-ENUM_VALUE_LIST OFF,ON +-READ_ONLY YES +-COMMAND_LINE_ARGUMENT NULL + VARIABLE_NAME LOCK_WAIT_TIMEOUT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Timeout in seconds to wait for a lock before returning an error. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 31536000 +@@ -1834,7 +1824,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME LOG_SLOW_MAX_WARNINGS + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Max numbers of warnings printed to slow query log per statement + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 1000 +@@ -1844,7 +1834,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME LOG_SLOW_RATE_LIMIT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Write to slow log every #th slow query. Set to 1 to log everything. Increase it to reduce the size of the slow or the performance impact of slow logging + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 4294967295 +@@ -1874,7 +1864,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME LOG_WARNINGS + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Log some non critical warnings to the error log.Value can be between 0 and 11. Higher values mean more verbosity + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -1934,7 +1924,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME MAX_ALLOWED_PACKET + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Max packet length to send to or receive from the server + NUMERIC_MIN_VALUE 1024 + NUMERIC_MAX_VALUE 1073741824 +@@ -1954,7 +1944,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MAX_BINLOG_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Binary log will be rotated automatically when the size exceeds this value. + NUMERIC_MIN_VALUE 4096 + NUMERIC_MAX_VALUE 1073741824 +@@ -1974,7 +1964,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MAX_CONNECTIONS + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The number of simultaneous clients allowed + NUMERIC_MIN_VALUE 10 + NUMERIC_MAX_VALUE 100000 +@@ -1984,7 +1974,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MAX_CONNECT_ERRORS + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT If there is more than this number of interrupted connections from a host this host will be blocked from further connections + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 4294967295 +@@ -1994,7 +1984,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MAX_DELAYED_THREADS + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Don't start more than this number of threads to handle INSERT DELAYED statements. If set to zero INSERT DELAYED will be not used + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 16384 +@@ -2014,7 +2004,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MAX_ERROR_COUNT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Max number of errors/warnings to store for a statement + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 65535 +@@ -2034,7 +2024,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MAX_INSERT_DELAYED_THREADS + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Don't start more than this number of threads to handle INSERT DELAYED statements. If set to zero INSERT DELAYED will be not used + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 16384 +@@ -2054,7 +2044,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MAX_LENGTH_FOR_SORT_DATA + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Max number of bytes in sorted records + NUMERIC_MIN_VALUE 4 + NUMERIC_MAX_VALUE 8388608 +@@ -2084,7 +2074,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MAX_RECURSIVE_ITERATIONS + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum number of iterations when executing recursive queries + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -2114,7 +2104,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MAX_SEEKS_FOR_KEY + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Limit assumed max number of seeks when looking up rows based on a key + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 4294967295 +@@ -2134,7 +2124,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MAX_SORT_LENGTH + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored) + NUMERIC_MIN_VALUE 64 + NUMERIC_MAX_VALUE 8388608 +@@ -2144,7 +2134,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MAX_SP_RECURSION_DEPTH + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum stored procedure recursion depth + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 255 +@@ -2164,7 +2154,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MAX_TMP_TABLES + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Unused, will be removed. + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 4294967295 +@@ -2184,7 +2174,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MAX_WRITE_LOCK_COUNT + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT After this many write locks, allow some read locks to run in between + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 4294967295 +@@ -2194,7 +2184,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME METADATA_LOCKS_CACHE_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Unused + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 1048576 +@@ -2204,7 +2194,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME METADATA_LOCKS_HASH_INSTANCES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Unused + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 1024 +@@ -2214,7 +2204,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MIN_EXAMINED_ROW_LIMIT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Don't write queries to slow log that examine fewer rows than that + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -2224,7 +2214,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MRR_BUFFER_SIZE + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Size of buffer to use when using MRR with range access + NUMERIC_MIN_VALUE 8192 + NUMERIC_MAX_VALUE 2147483647 +@@ -2234,7 +2224,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MYISAM_BLOCK_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Block size to be used for MyISAM index pages + NUMERIC_MIN_VALUE 1024 + NUMERIC_MAX_VALUE 16384 +@@ -2244,7 +2234,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME MYISAM_DATA_POINTER_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Default pointer size to be used for MyISAM tables + NUMERIC_MIN_VALUE 2 + NUMERIC_MAX_VALUE 7 +@@ -2284,10 +2274,10 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME MYISAM_REPAIR_THREADS + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT If larger than 1, when repairing a MyISAM table all indexes will be created in parallel, with one thread per index. The value of 1 disables parallel repair + NUMERIC_MIN_VALUE 1 +-NUMERIC_MAX_VALUE 18446744073709551615 ++NUMERIC_MAX_VALUE 4294967295 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO +@@ -2332,9 +2322,19 @@ + ENUM_VALUE_LIST OFF,ON + READ_ONLY NO + COMMAND_LINE_ARGUMENT OPTIONAL ++VARIABLE_NAME NAMED_PIPE ++VARIABLE_SCOPE GLOBAL ++VARIABLE_TYPE BOOLEAN ++VARIABLE_COMMENT Enable the named pipe (NT) ++NUMERIC_MIN_VALUE NULL ++NUMERIC_MAX_VALUE NULL ++NUMERIC_BLOCK_SIZE NULL ++ENUM_VALUE_LIST OFF,ON ++READ_ONLY YES ++COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME NET_BUFFER_LENGTH + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Buffer length for TCP/IP and socket communication + NUMERIC_MIN_VALUE 1024 + NUMERIC_MAX_VALUE 1048576 +@@ -2344,7 +2344,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME NET_READ_TIMEOUT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Number of seconds to wait for more data from a connection before aborting the read + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 31536000 +@@ -2354,7 +2354,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME NET_RETRY_COUNT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT If a read on a communication port is interrupted, retry this many times before giving up + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 4294967295 +@@ -2364,7 +2364,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME NET_WRITE_TIMEOUT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Number of seconds to wait for a block to be written to a connection before aborting the write + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 31536000 +@@ -2424,7 +2424,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME OPEN_FILES_LIMIT + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 or autoset then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -2434,7 +2434,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME OPTIMIZER_ADJUST_SECONDARY_KEY_COSTS + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT 0 = No changes. 1 = Update secondary key costs for ranges to be at least 5x of clustered primary key costs. 2 = Remove 'max_seek optimization' for secondary keys and slight adjustment of filter cost. This option will be deleted in MariaDB 11.0 as it is not needed with the new 11.0 optimizer. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 2 +@@ -2444,7 +2444,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME OPTIMIZER_MAX_SEL_ARGS + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The maximum number of SEL_ARG objects created when optimizing a range. If more objects would be needed, the range will not be used by the optimizer. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -2454,7 +2454,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME OPTIMIZER_MAX_SEL_ARG_WEIGHT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The maximum weight of the SEL_ARG graph. Set to 0 for no limit + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -2464,7 +2464,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME OPTIMIZER_PRUNE_LEVEL + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Controls the heuristic(s) applied during query optimization to prune less-promising partial plans from the optimizer search space. Meaning: 0 - do not apply any heuristic, thus perform exhaustive search; 1 - prune plans based on number of retrieved rows + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 1 +@@ -2474,7 +2474,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME OPTIMIZER_SEARCH_DEPTH + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 62 +@@ -2484,7 +2484,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME OPTIMIZER_SELECTIVITY_SAMPLING_LIMIT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Controls number of record samples to check condition selectivity + NUMERIC_MIN_VALUE 10 + NUMERIC_MAX_VALUE 4294967295 +@@ -2514,17 +2514,17 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME OPTIMIZER_TRACE_MAX_MEM_SIZE + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum allowed size of an optimizer trace + NUMERIC_MIN_VALUE 0 +-NUMERIC_MAX_VALUE 18446744073709551615 ++NUMERIC_MAX_VALUE 4294967295 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME OPTIMIZER_USE_CONDITION_SELECTIVITY + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Controls selectivity of which conditions the optimizer takes into account to calculate cardinality of a partial join when it searches for the best execution plan Meaning: 1 - use selectivity of index backed range conditions to calculate the cardinality of a partial join if the last joined table is accessed by full table scan or an index scan, 2 - use selectivity of index backed range conditions to calculate the cardinality of a partial join in any case, 3 - additionally always use selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join, 4 - use histograms to calculate selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join.5 - additionally use selectivity of certain non-range predicates calculated on record samples + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 5 +@@ -2544,7 +2544,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME PERFORMANCE_SCHEMA_ACCOUNTS_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of instrumented user@host accounts. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2554,7 +2554,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_DIGESTS_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Size of the statement digest. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2564,7 +2564,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STAGES_HISTORY_LONG_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Number of rows in EVENTS_STAGES_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2574,7 +2574,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STAGES_HISTORY_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Number of rows per thread in EVENTS_STAGES_HISTORY. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1024 +@@ -2584,7 +2584,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STATEMENTS_HISTORY_LONG_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Number of rows in EVENTS_STATEMENTS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2594,7 +2594,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STATEMENTS_HISTORY_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_HISTORY. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1024 +@@ -2604,7 +2604,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_TRANSACTIONS_HISTORY_LONG_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Number of rows in EVENTS_TRANSACTIONS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2614,7 +2614,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_TRANSACTIONS_HISTORY_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Number of rows per thread in EVENTS_TRANSACTIONS_HISTORY. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1024 +@@ -2624,7 +2624,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_WAITS_HISTORY_LONG_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Number of rows in EVENTS_WAITS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2634,7 +2634,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_WAITS_HISTORY_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Number of rows per thread in EVENTS_WAITS_HISTORY. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1024 +@@ -2644,7 +2644,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_HOSTS_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of instrumented hosts. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2654,7 +2654,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_COND_CLASSES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum number of condition instruments. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 256 +@@ -2664,7 +2664,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_COND_INSTANCES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of instrumented condition objects. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2674,7 +2674,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_DIGEST_LENGTH + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum length considered for digest text, when stored in performance_schema tables. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 1048576 +@@ -2684,7 +2684,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_CLASSES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum number of file instruments. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 256 +@@ -2694,7 +2694,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_HANDLES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum number of opened instrumented files. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 1048576 +@@ -2704,7 +2704,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_INSTANCES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of instrumented files. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2714,7 +2714,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_INDEX_STAT + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of index statistics for instrumented tables. Use 0 to disable, -1 for automated scaling. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2724,7 +2724,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MEMORY_CLASSES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum number of memory pool instruments. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 1024 +@@ -2734,7 +2734,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_METADATA_LOCKS + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of metadata locks. Use 0 to disable, -1 for automated scaling. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 104857600 +@@ -2744,7 +2744,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MUTEX_CLASSES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum number of mutex instruments. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 256 +@@ -2754,7 +2754,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MUTEX_INSTANCES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of instrumented MUTEX objects. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 104857600 +@@ -2764,7 +2764,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_PREPARED_STATEMENTS_INSTANCES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of instrumented prepared statements. Use 0 to disable, -1 for automated scaling. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2774,7 +2774,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_PROGRAM_INSTANCES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of instrumented programs. Use 0 to disable, -1 for automated scaling. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2784,7 +2784,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_RWLOCK_CLASSES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum number of rwlock instruments. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 256 +@@ -2794,7 +2794,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_RWLOCK_INSTANCES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of instrumented RWLOCK objects. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 104857600 +@@ -2804,7 +2804,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SOCKET_CLASSES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum number of socket instruments. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 256 +@@ -2814,7 +2814,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SOCKET_INSTANCES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of opened instrumented sockets. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2824,7 +2824,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SQL_TEXT_LENGTH + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum length of displayed sql text. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 1048576 +@@ -2834,7 +2834,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STAGE_CLASSES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum number of stage instruments. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 256 +@@ -2844,7 +2844,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_CLASSES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum number of statement instruments. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 256 +@@ -2854,7 +2854,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_STACK + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_CURRENT. + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 256 +@@ -2864,7 +2864,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_HANDLES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of opened instrumented tables. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2874,7 +2874,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_INSTANCES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of instrumented tables. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2884,7 +2884,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_LOCK_STAT + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of lock statistics for instrumented tables. Use 0 to disable, -1 for automated scaling. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2894,7 +2894,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_THREAD_CLASSES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum number of thread instruments. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 256 +@@ -2904,7 +2904,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_THREAD_INSTANCES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of instrumented threads. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2914,7 +2914,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_SESSION_CONNECT_ATTRS_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Size of session attribute string buffer per thread. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2924,7 +2924,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_SETUP_ACTORS_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of rows in SETUP_ACTORS. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1024 +@@ -2934,7 +2934,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_SETUP_OBJECTS_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of rows in SETUP_OBJECTS. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2944,7 +2944,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PERFORMANCE_SCHEMA_USERS_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT ++VARIABLE_TYPE INT + VARIABLE_COMMENT Maximum number of instrumented users. Use 0 to disable, -1 for automated sizing. + NUMERIC_MIN_VALUE -1 + NUMERIC_MAX_VALUE 1048576 +@@ -2994,7 +2994,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PRELOAD_BUFFER_SIZE + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The size of the buffer that is allocated when preloading indexes + NUMERIC_MIN_VALUE 1024 + NUMERIC_MAX_VALUE 1073741824 +@@ -3014,7 +3014,7 @@ + COMMAND_LINE_ARGUMENT NULL + VARIABLE_NAME PROFILING_HISTORY_SIZE + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Number of statements about which profiling information is maintained. If set to 0, no profiles are stored. See SHOW PROFILES. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 100 +@@ -3024,7 +3024,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME PROGRESS_REPORT_TIME + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Seconds between sending progress reports to the client for time-consuming statements. Set to 0 to disable progress reporting. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -3084,7 +3084,7 @@ + COMMAND_LINE_ARGUMENT NULL + VARIABLE_NAME QUERY_ALLOC_BLOCK_SIZE + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Allocation block size for query parsing and execution + NUMERIC_MIN_VALUE 1024 + NUMERIC_MAX_VALUE 4294967295 +@@ -3094,7 +3094,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME QUERY_CACHE_LIMIT + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Don't cache results that are bigger than this + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -3104,7 +3104,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME QUERY_CACHE_MIN_RES_UNIT + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The minimum size for blocks allocated by the query cache + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -3117,7 +3117,7 @@ + VARIABLE_TYPE BIGINT UNSIGNED + VARIABLE_COMMENT The memory allocated to store results from old queries + NUMERIC_MIN_VALUE 0 +-NUMERIC_MAX_VALUE 18446744073709551615 ++NUMERIC_MAX_VALUE 4294967295 + NUMERIC_BLOCK_SIZE 1024 + ENUM_VALUE_LIST NULL + READ_ONLY NO +@@ -3154,7 +3154,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME QUERY_PREALLOC_SIZE + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Persistent buffer for query parsing and execution + NUMERIC_MIN_VALUE 1024 + NUMERIC_MAX_VALUE 4294967295 +@@ -3167,7 +3167,7 @@ + VARIABLE_TYPE BIGINT UNSIGNED + VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes + NUMERIC_MIN_VALUE 0 +-NUMERIC_MAX_VALUE 18446744073709551615 ++NUMERIC_MAX_VALUE 4294967295 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO +@@ -3177,14 +3177,14 @@ + VARIABLE_TYPE BIGINT UNSIGNED + VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes + NUMERIC_MIN_VALUE 0 +-NUMERIC_MAX_VALUE 18446744073709551615 ++NUMERIC_MAX_VALUE 4294967295 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO + COMMAND_LINE_ARGUMENT NULL + VARIABLE_NAME RANGE_ALLOC_BLOCK_SIZE + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Allocation block size for storing ranges during optimization + NUMERIC_MIN_VALUE 4096 + NUMERIC_MAX_VALUE 4294967295 +@@ -3197,14 +3197,14 @@ + VARIABLE_TYPE BIGINT UNSIGNED + VARIABLE_COMMENT Maximum speed(KB/s) to read binlog from master (0 = no limit) + NUMERIC_MIN_VALUE 0 +-NUMERIC_MAX_VALUE 18446744073709551615 ++NUMERIC_MAX_VALUE 4294967295 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME READ_BUFFER_SIZE + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value + NUMERIC_MIN_VALUE 8192 + NUMERIC_MAX_VALUE 2147483647 +@@ -3224,7 +3224,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME READ_RND_BUFFER_SIZE + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 2147483647 +@@ -3434,10 +3434,10 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME ROWID_MERGE_BUFF_SIZE + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The size of the buffers used [NOT] IN evaluation via partial matching + NUMERIC_MIN_VALUE 0 +-NUMERIC_MAX_VALUE 9223372036854775807 ++NUMERIC_MAX_VALUE 2147483647 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO +@@ -3454,20 +3454,20 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME RPL_SEMI_SYNC_MASTER_TIMEOUT + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The timeout value (in ms) for semi-synchronous replication in the master + NUMERIC_MIN_VALUE 0 +-NUMERIC_MAX_VALUE 18446744073709551615 ++NUMERIC_MAX_VALUE 4294967295 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME RPL_SEMI_SYNC_MASTER_TRACE_LEVEL + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The tracing level for semi-sync replication. + NUMERIC_MIN_VALUE 0 +-NUMERIC_MAX_VALUE 18446744073709551615 ++NUMERIC_MAX_VALUE 4294967295 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO +@@ -3524,10 +3524,10 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME RPL_SEMI_SYNC_SLAVE_TRACE_LEVEL + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The tracing level for semi-sync replication. + NUMERIC_MIN_VALUE 0 +-NUMERIC_MAX_VALUE 18446744073709551615 ++NUMERIC_MAX_VALUE 4294967295 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO +@@ -3564,7 +3564,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME SERVER_ID + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Uniquely identifies the server instance in the community of replication partners + NUMERIC_MIN_VALUE 1 + NUMERIC_MAX_VALUE 4294967295 +@@ -3694,7 +3694,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME SLAVE_DOMAIN_PARALLEL_THREADS + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Maximum number of parallel threads to use on slave for events in a single replication domain. When using multiple domains, this can be used to limit a single domain from grabbing all threads and thus stalling other domains. The default of 0 means to allow a domain to grab as many threads as it wants, up to the value of slave_parallel_threads. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 16383 +@@ -3724,7 +3724,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME SLAVE_MAX_ALLOWED_PACKET + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The maximum packet length to sent successfully from the master to slave. + NUMERIC_MIN_VALUE 1024 + NUMERIC_MAX_VALUE 1073741824 +@@ -3744,7 +3744,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME SLAVE_PARALLEL_MAX_QUEUED + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Limit on how much memory SQL threads should use per parallel replication thread when reading ahead in the relay log looking for opportunities for parallel replication. Only used when --slave-parallel-threads > 0. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 2147483647 +@@ -3764,7 +3764,7 @@ + COMMAND_LINE_ARGUMENT NULL + VARIABLE_NAME SLAVE_PARALLEL_THREADS + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT If non-zero, number of threads to spawn to apply in parallel events on the slave that were group-committed on the master or were logged with GTID in different replication domains. Note that these threads are in addition to the IO and SQL threads, which are always created by a replication slave + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 16383 +@@ -3774,7 +3774,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME SLAVE_PARALLEL_WORKERS + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Alias for slave_parallel_threads + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 16383 +@@ -3814,7 +3814,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME SLAVE_TRANSACTION_RETRIES + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Number of times the slave SQL thread will retry a transaction in case it failed with a deadlock, elapsed lock wait timeout or listed in slave_transaction_retry_errors, before giving up and stopping + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 4294967295 +@@ -3834,7 +3834,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME SLAVE_TRANSACTION_RETRY_INTERVAL + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Interval of the slave SQL thread will retry a transaction in case it failed with a deadlock or elapsed lock wait timeout or listed in slave_transaction_retry_errors + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 3600 +@@ -3854,7 +3854,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME SLOW_LAUNCH_TIME + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 31536000 +@@ -4124,7 +4124,7 @@ + COMMAND_LINE_ARGUMENT NULL + VARIABLE_NAME STORED_PROGRAM_CACHE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The soft upper limit for number of cached stored routines for one connection. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 524288 +@@ -4224,7 +4224,7 @@ + COMMAND_LINE_ARGUMENT NULL + VARIABLE_NAME TABLE_DEFINITION_CACHE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The number of cached table definitions + NUMERIC_MIN_VALUE 400 + NUMERIC_MAX_VALUE 2097152 +@@ -4234,7 +4234,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME TABLE_OPEN_CACHE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The number of cached open tables + NUMERIC_MIN_VALUE 10 + NUMERIC_MAX_VALUE 1048576 +@@ -4294,7 +4294,7 @@ + COMMAND_LINE_ARGUMENT OPTIONAL + VARIABLE_NAME THREAD_CACHE_SIZE + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 16384 +@@ -4352,6 +4352,26 @@ + ENUM_VALUE_LIST NULL + READ_ONLY NO + COMMAND_LINE_ARGUMENT REQUIRED ++VARIABLE_NAME THREAD_POOL_MIN_THREADS ++VARIABLE_SCOPE GLOBAL ++VARIABLE_TYPE INT UNSIGNED ++VARIABLE_COMMENT Minimum number of threads in the thread pool. ++NUMERIC_MIN_VALUE 1 ++NUMERIC_MAX_VALUE 256 ++NUMERIC_BLOCK_SIZE 1 ++ENUM_VALUE_LIST NULL ++READ_ONLY NO ++COMMAND_LINE_ARGUMENT REQUIRED ++VARIABLE_NAME THREAD_POOL_MODE ++VARIABLE_SCOPE GLOBAL ++VARIABLE_TYPE ENUM ++VARIABLE_COMMENT Chose implementation of the threadpool ++NUMERIC_MIN_VALUE NULL ++NUMERIC_MAX_VALUE NULL ++NUMERIC_BLOCK_SIZE NULL ++ENUM_VALUE_LIST windows,generic ++READ_ONLY YES ++COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME THREAD_POOL_OVERSUBSCRIBE + VARIABLE_SCOPE GLOBAL + VARIABLE_TYPE INT UNSIGNED +@@ -4455,7 +4475,7 @@ + VARIABLE_NAME TMPDIR + VARIABLE_SCOPE GLOBAL + VARIABLE_TYPE VARCHAR +-VARIABLE_COMMENT Path for temporary files. Several paths may be specified, separated by a colon (:), in this case they are used in a round-robin fashion ++VARIABLE_COMMENT Path for temporary files. Several paths may be specified, separated by a semicolon (;), in this case they are used in a round-robin fashion + NUMERIC_MIN_VALUE NULL + NUMERIC_MAX_VALUE NULL + NUMERIC_BLOCK_SIZE NULL +@@ -4494,7 +4514,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME TRANSACTION_ALLOC_BLOCK_SIZE + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Allocation block size for transactions to be stored in binary log + NUMERIC_MIN_VALUE 1024 + NUMERIC_MAX_VALUE 134217728 +@@ -4504,7 +4524,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME TRANSACTION_PREALLOC_SIZE + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Persistent buffer for transactions to be stored in binary log + NUMERIC_MIN_VALUE 1024 + NUMERIC_MAX_VALUE 134217728 +@@ -4644,10 +4664,10 @@ + COMMAND_LINE_ARGUMENT NULL + VARIABLE_NAME WAIT_TIMEOUT + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT The number of seconds the server waits for activity on a connection before closing it + NUMERIC_MIN_VALUE 1 +-NUMERIC_MAX_VALUE 31536000 ++NUMERIC_MAX_VALUE 2147483 + NUMERIC_BLOCK_SIZE 1 + ENUM_VALUE_LIST NULL + READ_ONLY NO +@@ -4671,7 +4691,7 @@ + VARIABLE_NAME LOG_TC_SIZE + GLOBAL_VALUE_ORIGIN AUTO + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Size of transaction coordinator log. + ENUM_VALUE_LIST NULL + READ_ONLY YES diff --git a/mysql-test/suite/sys_vars/t/sysvars_star.test b/mysql-test/suite/sys_vars/t/sysvars_star.test index 8d0aefdc4c7..f1d1c137109 100644 --- a/mysql-test/suite/sys_vars/t/sysvars_star.test +++ b/mysql-test/suite/sys_vars/t/sysvars_star.test @@ -15,7 +15,7 @@ set global low_priority_updates=1; install soname 'sql_errlog'; vertical_results; -replace_regex /\/.*\//var\//; +replace_regex /(C:)?\/.*\//var\//; select * from information_schema.system_variables where variable_name in ( 'completion_type', #session!=global, origin=compile-time @@ -32,7 +32,7 @@ create user foo@localhost; connect foo,localhost,foo; select global_value_path from information_schema.system_variables where variable_name='plugin_maturity'; connection default; -replace_regex /\/.*\//var\//; +replace_regex /(C:)?\/.*\//var\//; select global_value_path from information_schema.system_variables where variable_name='plugin_maturity'; disconnect foo; drop user foo@localhost; diff --git a/plugin/file_key_management/parser.cc b/plugin/file_key_management/parser.cc index 57e0139a57d..a7b39f0ad16 100644 --- a/plugin/file_key_management/parser.cc +++ b/plugin/file_key_management/parser.cc @@ -260,7 +260,7 @@ int Parser::parse_line(char **line_ptr, keyentry *key) while (isdigit(*p)) { id = id * 10 + *p - '0'; - if (id > UINT_MAX32) + if (id > (longlong) UINT_MAX32) { report_error("Invalid key id", p - *line_ptr); return -1; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 3ce6f433999..ae855525060 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3224,7 +3224,7 @@ String *Item_func_binlog_gtid_pos::val_str(String *str) if (args[0]->null_value || args[1]->null_value) goto err; - if (pos < 0 || pos > UINT_MAX32) + if (pos < 0 || pos > (longlong) UINT_MAX32) goto err; if (gtid_state_from_binlog_pos(name->c_ptr_safe(), (uint32)pos, str)) diff --git a/sql/log.cc b/sql/log.cc index 401ce408c5f..a6342a15ddb 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -6129,12 +6129,13 @@ bool THD::binlog_write_table_map(TABLE *table, bool with_annotate) int error= 1; bool is_transactional= table->file->row_logging_has_trans; DBUG_ENTER("THD::binlog_write_table_map"); - DBUG_PRINT("enter", ("table: %p (%s: #%lu)", + DBUG_PRINT("enter", ("table: %p (%s: #%llu)", table, table->s->table_name.str, table->s->table_map_id)); /* Pre-conditions */ - DBUG_ASSERT(table->s->table_map_id != ULONG_MAX); + DBUG_ASSERT((table->s->table_map_id & MAX_TABLE_MAP_ID) != UINT32_MAX && + (table->s->table_map_id & MAX_TABLE_MAP_ID) != 0); /* Ensure that all events in a GTID group are in the same cache */ if (variables.option_bits & OPTION_GTID_BEGIN) diff --git a/sql/log_event.cc b/sql/log_event.cc index c5d58c04054..2acb77a2dc5 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3311,7 +3311,7 @@ Rows_log_event::Rows_log_event(const uchar *buf, uint event_len, } else { - m_table_id= (ulong) uint6korr(post_start); + m_table_id= (ulonglong) uint6korr(post_start); post_start+= RW_FLAGS_OFFSET; } @@ -3668,11 +3668,12 @@ Table_map_log_event::Table_map_log_event(const uchar *buf, uint event_len, else { DBUG_ASSERT(post_header_len == TABLE_MAP_HEADER_LEN); - m_table_id= (ulong) uint6korr(post_start); + m_table_id= (ulonglong) uint6korr(post_start); post_start+= TM_FLAGS_OFFSET; } - DBUG_ASSERT(m_table_id != ~0ULL); + DBUG_ASSERT((m_table_id & MAX_TABLE_MAP_ID) != UINT32_MAX && + (m_table_id & MAX_TABLE_MAP_ID) != 0); m_flags= uint2korr(post_start); diff --git a/sql/log_event.h b/sql/log_event.h index a85dcf9d782..8be46ed30cb 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -158,6 +158,12 @@ class String; #define NUM_LOAD_DELIM_STRS 5 +/* + The following is the max table_map_id. This is limited by that we + are using 6 bytes for it in replication +*/ +#define MAX_TABLE_MAP_ID ((1ULL << (6*8)) -1) + /***************************************************************************** MySQL Binary Log @@ -4796,7 +4802,8 @@ public: flag_set get_flags(flag_set flag) const { return m_flags & flag; } #ifdef MYSQL_SERVER - Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, bool is_transactional); + Table_map_log_event(THD *thd, TABLE *tbl, ulonglong tid, + bool is_transactional); #endif #ifdef HAVE_REPLICATION Table_map_log_event(const uchar *buf, uint event_len, @@ -5122,7 +5129,7 @@ protected: this class, not create instances of this class. */ #ifdef MYSQL_SERVER - Rows_log_event(THD*, TABLE*, ulong table_id, + Rows_log_event(THD*, TABLE*, ulonglong table_id, MY_BITMAP const *cols, bool is_transactional, Log_event_type event_type); #endif @@ -5356,7 +5363,7 @@ public: }; #if defined(MYSQL_SERVER) - Write_rows_log_event(THD*, TABLE*, ulong table_id, + Write_rows_log_event(THD*, TABLE*, ulonglong table_id, bool is_transactional); #endif #ifdef HAVE_REPLICATION @@ -5397,7 +5404,7 @@ class Write_rows_compressed_log_event : public Write_rows_log_event { public: #if defined(MYSQL_SERVER) - Write_rows_compressed_log_event(THD*, TABLE*, ulong table_id, + Write_rows_compressed_log_event(THD*, TABLE*, ulonglong table_id, bool is_transactional); virtual bool write(); #endif @@ -5433,7 +5440,7 @@ public: }; #ifdef MYSQL_SERVER - Update_rows_log_event(THD*, TABLE*, ulong table_id, + Update_rows_log_event(THD*, TABLE*, ulonglong table_id, bool is_transactional); void init(MY_BITMAP const *cols); @@ -5485,7 +5492,7 @@ class Update_rows_compressed_log_event : public Update_rows_log_event { public: #if defined(MYSQL_SERVER) - Update_rows_compressed_log_event(THD*, TABLE*, ulong table_id, + Update_rows_compressed_log_event(THD*, TABLE*, ulonglong table_id, bool is_transactional); virtual bool write(); #endif @@ -5529,7 +5536,7 @@ public: }; #ifdef MYSQL_SERVER - Delete_rows_log_event(THD*, TABLE*, ulong, bool is_transactional); + Delete_rows_log_event(THD*, TABLE*, ulonglong, bool is_transactional); #endif #ifdef HAVE_REPLICATION Delete_rows_log_event(const uchar *buf, uint event_len, @@ -5570,7 +5577,8 @@ class Delete_rows_compressed_log_event : public Delete_rows_log_event { public: #if defined(MYSQL_SERVER) - Delete_rows_compressed_log_event(THD*, TABLE*, ulong, bool is_transactional); + Delete_rows_compressed_log_event(THD*, TABLE*, ulonglong, + bool is_transactional); virtual bool write(); #endif #ifdef HAVE_REPLICATION diff --git a/sql/log_event_client.cc b/sql/log_event_client.cc index cbb593d0888..3b7df6e0f66 100644 --- a/sql/log_event_client.cc +++ b/sql/log_event_client.cc @@ -1502,8 +1502,8 @@ bool Rows_log_event::print_verbose(IO_CACHE *file, if (!(map= print_event_info->m_table_map.get_table(m_table_id)) || !(td= map->create_table_def())) { - return (my_b_printf(file, "### Row event for unknown table #%lu", - (ulong) m_table_id)); + return (my_b_printf(file, "### Row event for unknown table #%llu", + (ulonglong) m_table_id)); } /* If the write rows event contained no values for the AI */ diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 4e6b9e3f1c8..b7325225b0a 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -47,12 +47,12 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, rpl_group_info *rgi) const Relay_log_info *rli= rgi->rli; /* - If m_table_id == ~0UL, then we have a dummy event that does not + If m_table_id == UINT32_MAX, then we have a dummy event that does not contain any data. In that case, we just remove all tables in the tables_to_lock list, close the thread tables, and return with success. */ - if (ev->m_table_id == ~0UL) + if (ev->m_table_id == UINT32_MAX) { /* This one is supposed to be set: just an extra check so that @@ -1123,13 +1123,14 @@ int Update_rows_log_event_old::do_exec_row(TABLE *table) **************************************************************************/ #ifndef MYSQL_CLIENT -Old_rows_log_event::Old_rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid, +Old_rows_log_event::Old_rows_log_event(THD *thd_arg, TABLE *tbl_arg, + ulonglong table_id, MY_BITMAP const *cols, bool is_transactional) : Log_event(thd_arg, 0, is_transactional), m_row_count(0), m_table(tbl_arg), - m_table_id(tid), + m_table_id(table_id), m_width(tbl_arg ? tbl_arg->s->fields : 1), m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0) #ifdef HAVE_REPLICATION @@ -1142,12 +1143,12 @@ Old_rows_log_event::Old_rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid, /* We allow a special form of dummy event when the table, and cols - are null and the table id is ~0UL. This is a temporary + are null and the table id is UINT32_MAX. This is a temporary solution, to be able to terminate a started statement in the binary log: the extraneous events will be removed in the future. */ - DBUG_ASSERT((tbl_arg && tbl_arg->s && tid != ~0UL) || - (!tbl_arg && !cols && tid == ~0UL)); + DBUG_ASSERT((tbl_arg && tbl_arg->s && table_id != UINT32_MAX) || + (!tbl_arg && !cols && table_id == UINT32_MAX)); if (thd_arg->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS) set_flags(NO_FOREIGN_KEY_CHECKS_F); @@ -1209,7 +1210,7 @@ Old_rows_log_event::Old_rows_log_event(const uchar *buf, uint event_len, } else { - m_table_id= (ulong) uint6korr(post_start); + m_table_id= (ulonglong) uint6korr(post_start); post_start+= RW_FLAGS_OFFSET; } @@ -1364,12 +1365,12 @@ int Old_rows_log_event::do_apply_event(rpl_group_info *rgi) Relay_log_info const *rli= rgi->rli; /* - If m_table_id == ~0UL, then we have a dummy event that does not + If m_table_id == UINT32_MAX, then we have a dummy event that does not contain any data. In that case, we just remove all tables in the tables_to_lock list, close the thread tables, and return with success. */ - if (m_table_id == ~0UL) + if (m_table_id == UINT32_MAX) { /* This one is supposed to be set: just an extra check so that @@ -1786,7 +1787,7 @@ bool Old_rows_log_event::write_data_header() // This method should not be reached. assert(0); - DBUG_ASSERT(m_table_id != ~0UL); + DBUG_ASSERT(m_table_id != UINT32_MAX); DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", { int4store(buf + 0, m_table_id); @@ -2400,7 +2401,7 @@ int Old_rows_log_event::find_row(rpl_group_info *rgi) #if !defined(MYSQL_CLIENT) Write_rows_log_event_old::Write_rows_log_event_old(THD *thd_arg, TABLE *tbl_arg, - ulong tid_arg, + ulonglong tid_arg, MY_BITMAP const *cols, bool is_transactional) : Old_rows_log_event(thd_arg, tbl_arg, tid_arg, cols, is_transactional) @@ -2512,7 +2513,7 @@ bool Write_rows_log_event_old::print(FILE *file, #ifndef MYSQL_CLIENT Delete_rows_log_event_old::Delete_rows_log_event_old(THD *thd_arg, TABLE *tbl_arg, - ulong tid, + ulonglong tid, MY_BITMAP const *cols, bool is_transactional) : Old_rows_log_event(thd_arg, tbl_arg, tid, cols, is_transactional), @@ -2620,7 +2621,7 @@ bool Delete_rows_log_event_old::print(FILE *file, #if !defined(MYSQL_CLIENT) Update_rows_log_event_old::Update_rows_log_event_old(THD *thd_arg, TABLE *tbl_arg, - ulong tid, + ulonglong tid, MY_BITMAP const *cols, bool is_transactional) : Old_rows_log_event(thd_arg, tbl_arg, tid, cols, is_transactional), diff --git a/sql/log_event_old.h b/sql/log_event_old.h index e5aaacec209..1afe9aba60c 100644 --- a/sql/log_event_old.h +++ b/sql/log_event_old.h @@ -131,7 +131,7 @@ public: MY_BITMAP const *get_cols() const { return &m_cols; } size_t get_width() const { return m_width; } - ulong get_table_id() const { return m_table_id; } + ulonglong get_table_id() const { return m_table_id; } #ifndef MYSQL_CLIENT virtual bool write_data_header(); @@ -158,7 +158,7 @@ protected: this class, not create instances of this class. */ #ifndef MYSQL_CLIENT - Old_rows_log_event(THD*, TABLE*, ulong table_id, + Old_rows_log_event(THD*, TABLE*, ulonglong table_id, MY_BITMAP const *cols, bool is_transactional); #endif Old_rows_log_event(const uchar *row_data, uint event_len, @@ -176,7 +176,7 @@ protected: #ifndef MYSQL_CLIENT TABLE *m_table; /* The table the rows belong to */ #endif - ulong m_table_id; /* Table ID */ + ulonglong m_table_id; /* Table ID */ MY_BITMAP m_cols; /* Bitmap denoting columns available */ ulong m_width; /* The width of the columns bitmap */ @@ -359,7 +359,7 @@ class Write_rows_log_event_old : public Old_rows_log_event /********** BEGIN CUT & PASTE FROM Write_rows_log_event **********/ public: #if !defined(MYSQL_CLIENT) - Write_rows_log_event_old(THD*, TABLE*, ulong table_id, + Write_rows_log_event_old(THD*, TABLE*, ulonglong table_id, MY_BITMAP const *cols, bool is_transactional); #endif #ifdef HAVE_REPLICATION @@ -430,7 +430,7 @@ class Update_rows_log_event_old : public Old_rows_log_event /********** BEGIN CUT & PASTE FROM Update_rows_log_event **********/ public: #ifndef MYSQL_CLIENT - Update_rows_log_event_old(THD*, TABLE*, ulong table_id, + Update_rows_log_event_old(THD*, TABLE*, ulonglong table_id, MY_BITMAP const *cols, bool is_transactional); #endif @@ -507,7 +507,7 @@ class Delete_rows_log_event_old : public Old_rows_log_event /********** BEGIN CUT & PASTE FROM Update_rows_log_event **********/ public: #ifndef MYSQL_CLIENT - Delete_rows_log_event_old(THD*, TABLE*, ulong, + Delete_rows_log_event_old(THD*, TABLE*, ulonglong, MY_BITMAP const *cols, bool is_transactional); #endif #ifdef HAVE_REPLICATION diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index 976a657b635..3e7fcc9df85 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -5254,13 +5254,14 @@ bool sql_ex_info::write_data(Log_event_writer *writer) Rows_log_event member functions **************************************************************************/ -Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid, +Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, + ulonglong table_id, MY_BITMAP const *cols, bool is_transactional, Log_event_type event_type) : Log_event(thd_arg, 0, is_transactional), m_row_count(0), m_table(tbl_arg), - m_table_id(tid), + m_table_id(table_id), m_width(tbl_arg ? tbl_arg->s->fields : 1), m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0), m_type(event_type), m_extra_row_data(0) @@ -5272,12 +5273,13 @@ Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid, { /* We allow a special form of dummy event when the table, and cols - are null and the table id is ~0UL. This is a temporary + are null and the table id is UINT32_MAX. This is a temporary solution, to be able to terminate a started statement in the binary log: the extraneous events will be removed in the future. */ - DBUG_ASSERT((tbl_arg && tbl_arg->s && tid != ~0UL) || - (!tbl_arg && !cols && tid == ~0UL)); + DBUG_ASSERT((tbl_arg && tbl_arg->s && + (table_id & MAX_TABLE_MAP_ID) != UINT32_MAX) || + (!tbl_arg && !cols && (table_id & MAX_TABLE_MAP_ID) == UINT32_MAX)); if (thd_arg->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS) set_flags(NO_FOREIGN_KEY_CHECKS_F); @@ -5425,12 +5427,12 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) LEX *lex= thd->lex; uint8 new_trg_event_map= get_trg_event_map(); /* - If m_table_id == ~0ULL, then we have a dummy event that does not + If m_table_id == UINT32_MAX, then we have a dummy event that does not contain any data. In that case, we just remove all tables in the tables_to_lock list, close the thread tables, and return with success. */ - if (m_table_id == ~0ULL) + if (m_table_id == UINT32_MAX) { /* This one is supposed to be set: just an extra check so that @@ -6069,7 +6071,7 @@ Rows_log_event::do_update_pos(rpl_group_info *rgi) bool Rows_log_event::write_data_header() { uchar buf[ROWS_HEADER_LEN_V2]; // No need to init the buffer - DBUG_ASSERT(m_table_id != ~0ULL); + DBUG_ASSERT(m_table_id != UINT32_MAX); DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", { int4store(buf + 0, m_table_id); @@ -6277,7 +6279,7 @@ int Table_map_log_event::save_field_metadata() Mats says tbl->s lives longer than this event so it's ok to copy pointers (tbl->s->db etc) and not pointer content. */ -Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, +Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulonglong tid, bool is_transactional) : Log_event(thd, 0, is_transactional), m_table(tbl), @@ -6300,7 +6302,7 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, uchar cbuf[MAX_INT_WIDTH]; uchar *cbuf_end; DBUG_ENTER("Table_map_log_event::Table_map_log_event(TABLE)"); - DBUG_ASSERT(m_table_id != ~0ULL); + DBUG_ASSERT(m_table_id != UINT32_MAX); /* In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in table.cc / alloc_table_share(): @@ -6627,7 +6629,7 @@ int Table_map_log_event::do_update_pos(rpl_group_info *rgi) bool Table_map_log_event::write_data_header() { - DBUG_ASSERT(m_table_id != ~0ULL); + DBUG_ASSERT(m_table_id != UINT32_MAX); uchar buf[TABLE_MAP_HEADER_LEN]; DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", { @@ -7082,7 +7084,7 @@ void Table_map_log_event::pack_info(Protocol *protocol) Constructor used to build an event for writing to the binary log. */ Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg, - ulong tid_arg, + ulonglong tid_arg, bool is_transactional) :Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->rpl_write_set, is_transactional, WRITE_ROWS_EVENT_V1) @@ -7092,7 +7094,7 @@ Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg, Write_rows_compressed_log_event::Write_rows_compressed_log_event( THD *thd_arg, TABLE *tbl_arg, - ulong tid_arg, + ulonglong tid_arg, bool is_transactional) : Write_rows_log_event(thd_arg, tbl_arg, tid_arg, is_transactional) { @@ -8216,7 +8218,8 @@ end: */ Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg, - ulong tid, bool is_transactional) + ulonglong tid, + bool is_transactional) : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional, DELETE_ROWS_EVENT_V1) { @@ -8224,7 +8227,7 @@ Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg, Delete_rows_compressed_log_event::Delete_rows_compressed_log_event( THD *thd_arg, TABLE *tbl_arg, - ulong tid_arg, + ulonglong tid_arg, bool is_transactional) : Delete_rows_log_event(thd_arg, tbl_arg, tid_arg, is_transactional) { @@ -8365,7 +8368,7 @@ uint8 Delete_rows_log_event::get_trg_event_map() Constructor used to build an event for writing to the binary log. */ Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg, - ulong tid, + ulonglong tid, bool is_transactional) : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional, UPDATE_ROWS_EVENT_V1) @@ -8373,9 +8376,9 @@ Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg, init(tbl_arg->rpl_write_set); } -Update_rows_compressed_log_event::Update_rows_compressed_log_event(THD *thd_arg, TABLE *tbl_arg, - ulong tid, - bool is_transactional) +Update_rows_compressed_log_event:: +Update_rows_compressed_log_event(THD *thd_arg, TABLE *tbl_arg, + ulonglong tid, bool is_transactional) : Update_rows_log_event(thd_arg, tbl_arg, tid, is_transactional) { m_type = UPDATE_ROWS_COMPRESSED_EVENT_V1; diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 4c853689504..93b0dbb3ac7 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -953,7 +953,8 @@ void field_longlong::get_opt_type(String *answer, UINT_MAX24 : INT_MAX24)) snprintf(buff, sizeof(buff), "MEDIUMINT(%d)", (int) max_length); else if (min_arg >= INT_MIN32 && max_arg <= (min_arg >= 0 ? - UINT_MAX32 : INT_MAX32)) + (longlong) UINT_MAX32 : + (longlong) INT_MAX32)) snprintf(buff, sizeof(buff), "INT(%d)", (int) max_length); else snprintf(buff, sizeof(buff), "BIGINT(%d)", (int) max_length); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index fdf84ef8a99..da98be9bf2f 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -7005,7 +7005,8 @@ THD::binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id, { DBUG_ENTER("binlog_prepare_pending_rows_event"); /* Pre-conditions */ - DBUG_ASSERT(table->s->table_map_id != ~0UL); + DBUG_ASSERT((table->s->table_map_id & MAX_TABLE_MAP_ID) != UINT32_MAX && + (table->s->table_map_id & MAX_TABLE_MAP_ID) != 0); /* Fetch the type code for the RowsEventT template parameter */ int const general_type_code= RowsEventT::TYPE_CODE; diff --git a/sql/table.cc b/sql/table.cc index 836495992c3..0d4404008ea 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -48,6 +48,7 @@ #ifdef WITH_WSREP #include "wsrep_schema.h" #endif +#include "log_event.h" // MAX_TABLE_MAP_ID /* For MySQL 5.7 virtual fields */ #define MYSQL57_GENERATED_FIELD 128 @@ -107,7 +108,7 @@ LEX_CSTRING MYSQL_PROC_NAME= {STRING_WITH_LEN("proc")}; */ static LEX_CSTRING parse_vcol_keyword= { STRING_WITH_LEN("PARSE_VCOL_EXPR ") }; -static std::atomic last_table_id; +static std::atomic last_table_id; /* Functions defined in this file */ @@ -383,17 +384,20 @@ TABLE_SHARE *alloc_table_share(const char *db, const char *table_name, DBUG_EXECUTE_IF("simulate_big_table_id", if (last_table_id < UINT_MAX32) - last_table_id= UINT_MAX32 - 1;); + last_table_id= UINT_MAX32-1;); /* - There is one reserved number that cannot be used. Remember to - change this when 6-byte global table id's are introduced. + Replication is using 6 bytes as table_map_id. Ensure that + the 6 lowest bytes are not 0. + We also have to ensure that we do not use the special value + UINT_MAX32 as this is used to mark a dummy event row event. See + comments in Rows_log_event::Rows_log_event(). */ do { share->table_map_id= last_table_id.fetch_add(1, std::memory_order_relaxed); - } while (unlikely(share->table_map_id == ~0UL || - share->table_map_id == 0)); + } while (unlikely((share->table_map_id & MAX_TABLE_MAP_ID) == 0) || + unlikely((share->table_map_id & MAX_TABLE_MAP_ID) == UINT_MAX32)); } DBUG_RETURN(share); } @@ -456,7 +460,7 @@ void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key, table_map_id is also used for MERGE tables to suppress repeated compatibility checks. */ - share->table_map_id= (ulong) thd->query_id; + share->table_map_id= (ulonglong) thd->query_id; DBUG_VOID_RETURN; } diff --git a/sql/table.h b/sql/table.h index fb2b1167833..e061d1eb669 100644 --- a/sql/table.h +++ b/sql/table.h @@ -851,7 +851,7 @@ struct TABLE_SHARE /* 1 if frm version cannot be updated as part of upgrade */ bool keep_original_mysql_version; - ulong table_map_id; /* for row-based replication */ + ulonglong table_map_id; /* for row-based replication */ /* Things that are incompatible between the stored version and the @@ -1006,7 +1006,7 @@ struct TABLE_SHARE return (table_category == TABLE_CATEGORY_LOG); } - inline ulong get_table_def_version() + inline ulonglong get_table_def_version() { return table_map_id; } @@ -1085,7 +1085,7 @@ struct TABLE_SHARE @sa TABLE_LIST::is_the_same_definition() */ - ulong get_table_ref_version() const + ulonglong get_table_ref_version() const { return (tmp_table == SYSTEM_TMP_TABLE) ? 0 : table_map_id; } @@ -2774,7 +2774,7 @@ struct TABLE_LIST { set_table_ref_id(s->get_table_ref_type(), s->get_table_ref_version()); } inline void set_table_ref_id(enum_table_ref_type table_ref_type_arg, - ulong table_ref_version_arg) + ulonglong table_ref_version_arg) { m_table_ref_type= table_ref_type_arg; m_table_ref_version= table_ref_version_arg; @@ -2929,7 +2929,7 @@ private: /** See comments for set_table_ref_id() */ enum enum_table_ref_type m_table_ref_type; /** See comments for set_table_ref_id() */ - ulong m_table_ref_version; + ulonglong m_table_ref_version; }; class Item; diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h index 6da327ec84b..9964add9201 100644 --- a/storage/myisammrg/ha_myisammrg.h +++ b/storage/myisammrg/ha_myisammrg.h @@ -34,7 +34,7 @@ class Mrg_child_def: public Sql_alloc { /* Remembered MERGE child def version. See top comment in ha_myisammrg.cc */ enum_table_ref_type m_child_table_ref_type; - ulong m_child_def_version; + ulonglong m_child_def_version; public: LEX_STRING db; LEX_STRING name; @@ -44,12 +44,12 @@ public: { return m_child_table_ref_type; } - inline ulong get_child_def_version() + inline ulonglong get_child_def_version() { return m_child_def_version; } inline void set_child_def_version(enum_table_ref_type child_table_ref_type, - ulong version) + ulonglong version) { m_child_table_ref_type= child_table_ref_type; m_child_def_version= version; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_32753_after_start.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_32753_after_start.test index 281d2adce64..de2ab789a28 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_32753_after_start.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_32753_after_start.test @@ -4,6 +4,7 @@ # This test tests spider init after startup under global ORACLE mode install soname 'ha_spider'; +--replace_regex /\.dll/.so/ select * from mysql.plugin; create table t (c int) Engine=SPIDER; drop table t; 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..1c977bfb66f 100644 --- a/storage/spider/mysql-test/spider/include/clean_up_spider.inc +++ b/storage/spider/mysql-test/spider/include/clean_up_spider.inc @@ -3,6 +3,7 @@ DROP FUNCTION spider_copy_tables; DROP FUNCTION spider_ping_table; DROP FUNCTION spider_bg_direct_sql; DROP FUNCTION spider_direct_sql; +--replace_regex /\.dll/.so/ UNINSTALL SONAME IF EXISTS 'ha_spider'; DROP TABLE IF EXISTS mysql.spider_xa; DROP TABLE IF EXISTS mysql.spider_xa_member; From 27459b413deb1e21c2e9686e36ab44788a132b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Tue, 23 Jan 2024 16:24:27 +0200 Subject: [PATCH 37/61] MDEV-14448: Ctrl-C should not exit client Undo any Windows behaviour changes. --- client/mysql.cc | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index befa0e9b113..fe086f29dac 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -89,7 +89,6 @@ extern "C" { #undef bcmp // Fix problem with new readline #if defined(__WIN__) #include -#include #else # ifdef __APPLE__ # include @@ -1079,29 +1078,6 @@ static sig_handler window_resize(int sig); static void end_in_sig_handler(int sig); static bool kill_query(const char *reason); -#ifdef _WIN32 -static BOOL WINAPI ctrl_handler_windows(DWORD fdwCtrlType) -{ - switch (fdwCtrlType) - { - // Handle the CTRL-C signal. - case CTRL_C_EVENT: - case CTRL_BREAK_EVENT: - handle_sigint(SIGINT); - return TRUE; // this means that the signal is handled - case CTRL_CLOSE_EVENT: - case CTRL_LOGOFF_EVENT: - case CTRL_SHUTDOWN_EVENT: - kill_query("Terminate"); - end_in_sig_handler(SIGINT + 1); - aborted= 1; - } - // This means to pass the signal to the next handler. This allows - // my_cgets and the internal ReadConsole call to exit and gracefully - // abort the program. - return FALSE; -} -#endif const char DELIMITER_NAME[]= "delimiter"; const uint DELIMITER_NAME_LEN= sizeof(DELIMITER_NAME) - 1; inline bool is_delimiter_command(char *name, ulong len) @@ -1234,12 +1210,11 @@ int main(int argc,char *argv[]) if (!status.batch) ignore_errors=1; // Don't abort monitor -#ifndef _WIN32 - signal(SIGINT, handle_sigint); // Catch SIGINT to clean up + if (opt_sigint_ignore) + signal(SIGINT, SIG_IGN); + else + signal(SIGINT, handle_sigint); // Catch SIGINT to clean up signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up -#else - SetConsoleCtrlHandler(ctrl_handler_windows, TRUE); -#endif #if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL) /* Readline will call this if it installs a handler */ @@ -1471,9 +1446,6 @@ bool kill_query(const char *reason) */ sig_handler handle_sigint(int sig) { - if (opt_sigint_ignore) - return; - /* On Unix only, if no query is being executed just clear the prompt, don't exit. On Windows we exit. From 2bc940f7c940d792ef71058ed0c44660820bed8c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 20 Jan 2024 11:01:46 +0100 Subject: [PATCH 38/61] disable perfschema in mtr bootstrap should fix numerous failures of main.bootstrap tets --- mysql-test/mysql-test-run.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 789d97278fc..f75f0fe64df 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3076,6 +3076,7 @@ sub mysql_install_db { mtr_add_arg($args, "--core-file"); mtr_add_arg($args, "--console"); mtr_add_arg($args, "--character-set-server=latin1"); + mtr_add_arg($args, "--disable-performance-schema"); if ( $opt_debug ) { From db9fad1562b37b8d362bb48a35ac8d0bd9d00b4c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 21 Jan 2024 23:20:07 +0100 Subject: [PATCH 39/61] cleanup: main.log_tables test --- mysql-test/main/log_tables.result | 97 ++++++++++------ mysql-test/main/log_tables.test | 183 +++++++++++------------------- 2 files changed, 129 insertions(+), 151 deletions(-) diff --git a/mysql-test/main/log_tables.result b/mysql-test/main/log_tables.result index 553b4929bb5..e77de1b13ee 100644 --- a/mysql-test/main/log_tables.result +++ b/mysql-test/main/log_tables.result @@ -1,14 +1,9 @@ SET SQL_MODE=""; -SET @old_general_log_state = @@global.general_log; SET @old_log_output= @@global.log_output; SET @old_slow_query_log= @@global.slow_query_log; SET @old_general_log= @@global.general_log; SET @old_long_query_time= @@session.long_query_time; use mysql; -SET @saved_long_query_time = @@long_query_time; -SET @saved_log_output = @@log_output; -SET @saved_general_log = @@GLOBAL.general_log; -SET @saved_slow_query_log = @@GLOBAL.slow_query_log; truncate table general_log; select * from general_log; event_time user_host thread_id server_id command_type argument @@ -120,6 +115,9 @@ show open tables; Database Table In_use Name_locked SET GLOBAL GENERAL_LOG=ON; SET GLOBAL SLOW_QUERY_LOG=ON; +# +# Bug#23924 general_log truncates queries with character set introducers. +# truncate table mysql.general_log; set names binary; select _koi8r'ÔÅÓÔ' as test; @@ -131,6 +129,9 @@ TIMESTAMP USER_HOST THREAD_ID 1 Query set names binary TIMESTAMP USER_HOST THREAD_ID 1 Query select _koi8r'\xD4\xC5\xD3\xD4' as test TIMESTAMP USER_HOST THREAD_ID 1 Query select * from mysql.general_log set names utf8; +# +# Bug #16905 Log tables: unicode statements are logged incorrectly +# truncate table mysql.general_log; set names utf8; create table bug16905 (s char(15) character set utf8 default 'пуÑто'); @@ -142,6 +143,9 @@ TIMESTAMP USER_HOST THREAD_ID 1 Query create table bug16905 (s char(15) characte TIMESTAMP USER_HOST THREAD_ID 1 Query insert into bug16905 values ('новое') TIMESTAMP USER_HOST THREAD_ID 1 Query select * from mysql.general_log drop table bug16905; +# +# Bug #17600: Invalid data logged into mysql.slow_log +# truncate table mysql.slow_log; set session long_query_time=1; select sleep(2); @@ -150,7 +154,11 @@ sleep(2) select * from mysql.slow_log; start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text thread_id rows_affected TIMESTAMP USER_HOST QUERY_TIME 00:00:00.000000 1 0 mysql 0 0 1 select sleep(2) THREAD_ID 0 -set @@session.long_query_time = @saved_long_query_time; +set @@session.long_query_time = @old_long_query_time; +# +# Bug #18559 log tables cannot change engine, and gets deadlocked when +# dropping w/ log on +# alter table mysql.general_log engine=myisam; ERROR HY000: You cannot 'ALTER' a log table if logging is enabled alter table mysql.slow_log engine=myisam; @@ -232,7 +240,7 @@ TIMESTAMP USER_HOST THREAD_ID 1 Query truncate table mysql.slow_log TIMESTAMP USER_HOST THREAD_ID 1 Query set session long_query_time=1 TIMESTAMP USER_HOST THREAD_ID 1 Query select sleep(2) TIMESTAMP USER_HOST THREAD_ID 1 Query select * from mysql.slow_log -TIMESTAMP USER_HOST THREAD_ID 1 Query set @@session.long_query_time = @saved_long_query_time +TIMESTAMP USER_HOST THREAD_ID 1 Query set @@session.long_query_time = @old_long_query_time TIMESTAMP USER_HOST THREAD_ID 1 Query alter table mysql.general_log engine=myisam TIMESTAMP USER_HOST THREAD_ID 1 Query alter table mysql.slow_log engine=myisam TIMESTAMP USER_HOST THREAD_ID 1 Query drop table mysql.general_log @@ -300,17 +308,20 @@ ON UPDATE CURRENT_TIMESTAMP, set global general_log='ON'; set global slow_query_log='ON'; use test; +# +# Bug #20139 Infinite loop after "FLUSH" and "LOCK tabX, general_log" +# flush tables with read lock; unlock tables; use mysql; lock tables general_log read local, help_category read local; ERROR HY000: You can't use locks with log tables unlock tables; +# +# Bug #17544 Cannot do atomic log rotate and +# Bug #21785 Server crashes after rename of the log table +# SET SESSION long_query_time = 1000; -drop table if exists mysql.renamed_general_log; -drop table if exists mysql.renamed_slow_log; -drop table if exists mysql.general_log_new; -drop table if exists mysql.slow_log_new; use mysql; RENAME TABLE general_log TO renamed_general_log; ERROR HY000: Cannot rename 'general_log'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to 'general_log' @@ -356,13 +367,16 @@ set global slow_query_log='ON'; ERROR 42S02: Table 'mysql.slow_log' doesn't exist RENAME TABLE general_log2 TO general_log; RENAME TABLE slow_log2 TO slow_log; -SET SESSION long_query_time = @saved_long_query_time; +SET SESSION long_query_time = @old_long_query_time; set global general_log='ON'; set global slow_query_log='ON'; flush logs; flush logs; drop table renamed_general_log, renamed_slow_log; use test; +# +# Bug #21966 Strange warnings on repair of the log tables +# use mysql; repair table general_log; Table Op Msg_type Msg_text @@ -380,6 +394,10 @@ slow_log slow_log_new drop table slow_log_new, general_log_new; use test; +# +# Bug#69953 / MDEV-4851 +# Log tables should be modifable on LOG_OUTPUT != TABLE +# SET GLOBAL LOG_OUTPUT = 'FILE'; SET GLOBAL slow_query_log = 1; SET GLOBAL general_log = 1; @@ -388,6 +406,10 @@ ALTER TABLE mysql.general_log ADD COLUMN comment_text TEXT NOT NULL; SET GLOBAL LOG_OUTPUT = 'NONE'; ALTER TABLE mysql.slow_log DROP COLUMN comment_text; ALTER TABLE mysql.general_log DROP COLUMN comment_text; +# +# Bug#27857 (Log tables supplies the wrong value for generating +# AUTO_INCREMENT numbers) +# SET GLOBAL LOG_OUTPUT = 'TABLE'; SET GLOBAL general_log = 0; FLUSH LOGS; @@ -451,16 +473,15 @@ START_TIME USER_HOST QUERY_TIME 00:00:00.000000 1 0 test 0 0 1 SELECT "My own sl START_TIME USER_HOST QUERY_TIME 00:00:00.000000 1 0 test 0 0 1 SELECT "My own slow query", sleep(2) THREAD_ID 0 3 START_TIME USER_HOST QUERY_TIME 00:00:00.000000 1 0 test 0 0 1 SELECT "My own slow query", sleep(2) THREAD_ID 0 4 SET GLOBAL slow_query_log = 0; -SET SESSION long_query_time =@saved_long_query_time; +SET SESSION long_query_time =@old_long_query_time; FLUSH LOGS; ALTER TABLE mysql.slow_log DROP COLUMN seq; ALTER TABLE mysql.slow_log ENGINE = CSV; SET GLOBAL general_log = @old_general_log; SET GLOBAL slow_query_log = @old_slow_query_log; -drop procedure if exists proc25422_truncate_slow; -drop procedure if exists proc25422_truncate_general; -drop procedure if exists proc25422_alter_slow; -drop procedure if exists proc25422_alter_general; +# +# Bug#25422 (Hang with log tables) +# use test// create procedure proc25422_truncate_slow (loops int) begin @@ -485,26 +506,26 @@ end// create procedure proc25422_alter_slow (loops int) begin declare v1 int default 0; +declare old_log_state int default @@global.slow_query_log; declare ER_BAD_LOG_STATEMENT condition for 1575; declare continue handler for ER_BAD_LOG_STATEMENT begin end; while v1 < loops do -set @old_log_state = @@global.slow_query_log; set global slow_query_log = 'OFF'; alter table mysql.slow_log engine = CSV; -set global slow_query_log = @old_log_state; +set global slow_query_log = old_log_state; set v1 = v1 + 1; end while; end// create procedure proc25422_alter_general (loops int) begin declare v1 int default 0; +declare old_log_state int default @@global.general_log; declare ER_BAD_LOG_STATEMENT condition for 1575; declare continue handler for ER_BAD_LOG_STATEMENT begin end; while v1 < loops do -set @old_log_state = @@global.general_log; set global general_log = 'OFF'; alter table mysql.general_log engine = CSV; -set global general_log = @old_log_state; +set global general_log = old_log_state; set v1 = v1 + 1; end while; end// @@ -563,17 +584,19 @@ drop procedure proc25422_truncate_slow; drop procedure proc25422_truncate_general; drop procedure proc25422_alter_slow; drop procedure proc25422_alter_general; +# +# Bug#23044 (Warnings on flush of a log table) +# FLUSH TABLE mysql.general_log; show warnings; Level Code Message FLUSH TABLE mysql.slow_log; show warnings; Level Code Message -DROP TABLE IF EXISTS `db_17876.slow_log_data`; -DROP TABLE IF EXISTS `db_17876.general_log_data`; -DROP PROCEDURE IF EXISTS `db_17876.archiveSlowLog`; -DROP PROCEDURE IF EXISTS `db_17876.archiveGeneralLog`; -DROP DATABASE IF EXISTS `db_17876`; +# +# Bug#17876 (Truncating mysql.slow_log in a SP after using cursor locks the +# thread) +# CREATE DATABASE db_17876; CREATE TABLE `db_17876.slow_log_data` ( `start_time` timestamp(6) default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, @@ -686,6 +709,9 @@ DROP PROCEDURE IF EXISTS `db_17876.archiveGeneralLog`; DROP DATABASE IF EXISTS `db_17876`; SET GLOBAL general_log = @old_general_log; SET GLOBAL slow_query_log = @old_slow_query_log; +# +# Bug#21557 entries in the general query log truncated at 1000 characters. +# select CONNECTION_ID() into @thread_id; truncate table mysql.general_log; set global general_log = on; @@ -902,9 +928,9 @@ Execute select '000 001 002 003 004 005 006 007 008 009010 011 012 013 014 015 0 Query set global general_log = off deallocate prepare long_query; set global general_log = @old_general_log; -DROP TABLE IF EXISTS log_count; -DROP TABLE IF EXISTS slow_log_copy; -DROP TABLE IF EXISTS general_log_copy; +# +# Bug#34306: Can't make copy of log tables when server binary log is enabled +# CREATE TABLE log_count (count BIGINT(21)); SET GLOBAL general_log = ON; SET GLOBAL slow_query_log = ON; @@ -926,9 +952,12 @@ CREATE TABLE general_log_copy SELECT * FROM mysql.general_log; INSERT INTO general_log_copy SELECT * FROM mysql.general_log; INSERT INTO log_count (count) VALUES ((SELECT count(*) FROM mysql.general_log)); DROP TABLE general_log_copy; -SET GLOBAL general_log = @saved_general_log; -SET GLOBAL slow_query_log = @saved_slow_query_log; +SET GLOBAL general_log = @old_general_log; +SET GLOBAL slow_query_log = @old_slow_query_log; DROP TABLE log_count; +# +# Bug #31700: thd->examined_row_count not incremented for 'const' type queries +# SET SESSION long_query_time = 0; SET GLOBAL slow_query_log = ON; FLUSH LOGS; @@ -954,9 +983,10 @@ TIMESTAMP 1 1 SELECT SQL_NO_CACHE 'Bug#31700 - KEY', f1,f2,f3,SLEEP(1.1) FROM t1 TIMESTAMP 1 1 SELECT SQL_NO_CACHE 'Bug#31700 - PK', f1,f2,f3,SLEEP(1.1) FROM t1 WHERE f1=2 DROP TABLE t1; TRUNCATE TABLE mysql.slow_log; +# +# Bug #47924 main.log_tables times out sporadically +# use mysql; -drop table if exists renamed_general_log; -drop table if exists renamed_slow_log; RENAME TABLE general_log TO renamed_general_log; ERROR HY000: Cannot rename 'general_log'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to 'general_log' RENAME TABLE slow_log TO renamed_slow_log; @@ -964,7 +994,6 @@ ERROR HY000: Cannot rename 'slow_log'. When logging enabled, rename to/from log use test; flush tables with read lock; unlock tables; -SET @@session.long_query_time= @old_long_query_time; SET @@global.log_output= @old_log_output; SET @@global.slow_query_log= @old_slow_query_log; SET @@global.general_log= @old_general_log; diff --git a/mysql-test/main/log_tables.test b/mysql-test/main/log_tables.test index 9d964b8090b..b54b154cf05 100644 --- a/mysql-test/main/log_tables.test +++ b/mysql-test/main/log_tables.test @@ -1,13 +1,9 @@ # this test needs multithreaded mysqltest -- source include/not_embedded.inc -# -# Basic log tables test -# -# check that CSV engine was compiled in + --source include/have_csv.inc SET SQL_MODE=""; -SET @old_general_log_state = @@global.general_log; SET @old_log_output= @@global.log_output; SET @old_slow_query_log= @@global.slow_query_log; SET @old_general_log= @@global.general_log; @@ -16,16 +12,9 @@ SET @old_long_query_time= @@session.long_query_time; --disable_ps_protocol use mysql; -# Capture initial settings of system variables -# so that we can revert to old state after manipulation for testing -# NOTE: PLEASE USE THESE VALUES TO 'RESET' SYSTEM VARIABLES -# Capturing old values within the tests results in loss of values -# due to people not paying attention to previous tests' changes, captures -# or improper cleanup -SET @saved_long_query_time = @@long_query_time; -SET @saved_log_output = @@log_output; -SET @saved_general_log = @@GLOBAL.general_log; -SET @saved_slow_query_log = @@GLOBAL.slow_query_log; +# +# Basic log tables test +# # # Check that log tables work and we can do basic selects. This also @@ -147,9 +136,9 @@ show open tables; SET GLOBAL GENERAL_LOG=ON; SET GLOBAL SLOW_QUERY_LOG=ON; -# -# Bug#23924 general_log truncates queries with character set introducers. -# +--echo # +--echo # Bug#23924 general_log truncates queries with character set introducers. +--echo # truncate table mysql.general_log; set names binary; select _koi8r'ÔÅÓÔ' as test; @@ -157,9 +146,9 @@ select _koi8r' select * from mysql.general_log; set names utf8; -# -# Bug #16905 Log tables: unicode statements are logged incorrectly -# +--echo # +--echo # Bug #16905 Log tables: unicode statements are logged incorrectly +--echo # truncate table mysql.general_log; set names utf8; @@ -169,21 +158,21 @@ insert into bug16905 values ('новое'); select * from mysql.general_log; drop table bug16905; -# -# Bug #17600: Invalid data logged into mysql.slow_log -# +--echo # +--echo # Bug #17600: Invalid data logged into mysql.slow_log +--echo # truncate table mysql.slow_log; set session long_query_time=1; select sleep(2); --replace_column 1 TIMESTAMP 2 USER_HOST 3 QUERY_TIME 12 THREAD_ID select * from mysql.slow_log; -set @@session.long_query_time = @saved_long_query_time; +set @@session.long_query_time = @old_long_query_time; -# -# Bug #18559 log tables cannot change engine, and gets deadlocked when -# dropping w/ log on -# +--echo # +--echo # Bug #18559 log tables cannot change engine, and gets deadlocked when +--echo # dropping w/ log on +--echo # # check that appropriate error messages are given when one attempts to alter # or drop a log tables, while corresponding logs are enabled @@ -322,9 +311,9 @@ set global general_log='ON'; set global slow_query_log='ON'; use test; -# -# Bug #20139 Infinite loop after "FLUSH" and "LOCK tabX, general_log" -# +--echo # +--echo # Bug #20139 Infinite loop after "FLUSH" and "LOCK tabX, general_log" +--echo # flush tables with read lock; unlock tables; @@ -333,18 +322,12 @@ use mysql; lock tables general_log read local, help_category read local; unlock tables; -# -# Bug #17544 Cannot do atomic log rotate and -# Bug #21785 Server crashes after rename of the log table -# +--echo # +--echo # Bug #17544 Cannot do atomic log rotate and +--echo # Bug #21785 Server crashes after rename of the log table +--echo # SET SESSION long_query_time = 1000; ---disable_warnings -drop table if exists mysql.renamed_general_log; -drop table if exists mysql.renamed_slow_log; -drop table if exists mysql.general_log_new; -drop table if exists mysql.slow_log_new; ---enable_warnings use mysql; # Should result in error @@ -399,7 +382,7 @@ set global slow_query_log='ON'; RENAME TABLE general_log2 TO general_log; RENAME TABLE slow_log2 TO slow_log; -SET SESSION long_query_time = @saved_long_query_time; +SET SESSION long_query_time = @old_long_query_time; # this should work set global general_log='ON'; @@ -427,13 +410,6 @@ use test; # TODO: improve filtering of expected errors in master.err in # mysql-test-run.pl (based on the test name ?), and uncomment this test. -# --disable_warnings -# drop table if exists mysql.bad_general_log; -# drop table if exists mysql.bad_slow_log; -# drop table if exists mysql.general_log_hide; -# drop table if exists mysql.slow_log_hide; -# --enable_warnings -# # create table mysql.bad_general_log (a int) engine= CSV; # create table mysql.bad_slow_log (a int) engine= CSV; # @@ -459,9 +435,9 @@ use test; # drop table mysql.bad_general_log; # drop table mysql.bad_slow_log; -# -# Bug #21966 Strange warnings on repair of the log tables -# +--echo # +--echo # Bug #21966 Strange warnings on repair of the log tables +--echo # use mysql; # check that no warning occurs on repair of the log tables @@ -474,11 +450,10 @@ show tables like "%log%"; drop table slow_log_new, general_log_new; use test; -# -# Bug#69953 / MDEV-4851 -# Log tables should be modifable on LOG_OUTPUT != TABLE -# -# +--echo # +--echo # Bug#69953 / MDEV-4851 +--echo # Log tables should be modifable on LOG_OUTPUT != TABLE +--echo # SET GLOBAL LOG_OUTPUT = 'FILE'; SET GLOBAL slow_query_log = 1; @@ -492,10 +467,10 @@ ALTER TABLE mysql.slow_log DROP COLUMN comment_text; ALTER TABLE mysql.general_log DROP COLUMN comment_text; -# -# Bug#27857 (Log tables supplies the wrong value for generating -# AUTO_INCREMENT numbers) -# +--echo # +--echo # Bug#27857 (Log tables supplies the wrong value for generating +--echo # AUTO_INCREMENT numbers) +--echo # SET GLOBAL LOG_OUTPUT = 'TABLE'; @@ -554,7 +529,7 @@ SELECT "My own slow query", sleep(2); SELECT * FROM mysql.slow_log WHERE seq >= 2 LIMIT 3; SET GLOBAL slow_query_log = 0; -SET SESSION long_query_time =@saved_long_query_time; +SET SESSION long_query_time =@old_long_query_time; FLUSH LOGS; ALTER TABLE mysql.slow_log DROP COLUMN seq; @@ -563,16 +538,9 @@ ALTER TABLE mysql.slow_log ENGINE = CSV; SET GLOBAL general_log = @old_general_log; SET GLOBAL slow_query_log = @old_slow_query_log; -# -# Bug#25422 (Hang with log tables) -# - ---disable_warnings -drop procedure if exists proc25422_truncate_slow; -drop procedure if exists proc25422_truncate_general; -drop procedure if exists proc25422_alter_slow; -drop procedure if exists proc25422_alter_general; ---enable_warnings +--echo # +--echo # Bug#25422 (Hang with log tables) +--echo # delimiter //; @@ -602,14 +570,14 @@ end// create procedure proc25422_alter_slow (loops int) begin declare v1 int default 0; + declare old_log_state int default @@global.slow_query_log; declare ER_BAD_LOG_STATEMENT condition for 1575; declare continue handler for ER_BAD_LOG_STATEMENT begin end; while v1 < loops do - set @old_log_state = @@global.slow_query_log; set global slow_query_log = 'OFF'; alter table mysql.slow_log engine = CSV; - set global slow_query_log = @old_log_state; + set global slow_query_log = old_log_state; set v1 = v1 + 1; end while; end// @@ -617,14 +585,14 @@ end// create procedure proc25422_alter_general (loops int) begin declare v1 int default 0; + declare old_log_state int default @@global.general_log; declare ER_BAD_LOG_STATEMENT condition for 1575; declare continue handler for ER_BAD_LOG_STATEMENT begin end; while v1 < loops do - set @old_log_state = @@global.general_log; set global general_log = 'OFF'; alter table mysql.general_log engine = CSV; - set global general_log = @old_log_state; + set global general_log = old_log_state; set v1 = v1 + 1; end while; end// @@ -713,9 +681,9 @@ drop procedure proc25422_alter_general; --enable_ps_protocol -# -# Bug#23044 (Warnings on flush of a log table) -# +--echo # +--echo # Bug#23044 (Warnings on flush of a log table) +--echo # FLUSH TABLE mysql.general_log; show warnings; @@ -723,18 +691,10 @@ show warnings; FLUSH TABLE mysql.slow_log; show warnings; -# -# Bug#17876 (Truncating mysql.slow_log in a SP after using cursor locks the -# thread) -# - ---disable_warnings -DROP TABLE IF EXISTS `db_17876.slow_log_data`; -DROP TABLE IF EXISTS `db_17876.general_log_data`; -DROP PROCEDURE IF EXISTS `db_17876.archiveSlowLog`; -DROP PROCEDURE IF EXISTS `db_17876.archiveGeneralLog`; -DROP DATABASE IF EXISTS `db_17876`; ---enable_warnings +--echo # +--echo # Bug#17876 (Truncating mysql.slow_log in a SP after using cursor locks the +--echo # thread) +--echo # CREATE DATABASE db_17876; @@ -872,9 +832,9 @@ DROP DATABASE IF EXISTS `db_17876`; SET GLOBAL general_log = @old_general_log; SET GLOBAL slow_query_log = @old_slow_query_log; -# -# Bug#21557 entries in the general query log truncated at 1000 characters. -# +--echo # +--echo # Bug#21557 entries in the general query log truncated at 1000 characters. +--echo # select CONNECTION_ID() into @thread_id; --disable_ps_protocol @@ -992,15 +952,9 @@ select command_type, argument from mysql.general_log where thread_id = @thread_i deallocate prepare long_query; set global general_log = @old_general_log; -# -# Bug#34306: Can't make copy of log tables when server binary log is enabled -# - ---disable_warnings -DROP TABLE IF EXISTS log_count; -DROP TABLE IF EXISTS slow_log_copy; -DROP TABLE IF EXISTS general_log_copy; ---enable_warnings +--echo # +--echo # Bug#34306: Can't make copy of log tables when server binary log is enabled +--echo # CREATE TABLE log_count (count BIGINT(21)); @@ -1030,14 +984,14 @@ INSERT INTO general_log_copy SELECT * FROM mysql.general_log; INSERT INTO log_count (count) VALUES ((SELECT count(*) FROM mysql.general_log)); DROP TABLE general_log_copy; -SET GLOBAL general_log = @saved_general_log; -SET GLOBAL slow_query_log = @saved_slow_query_log; +SET GLOBAL general_log = @old_general_log; +SET GLOBAL slow_query_log = @old_slow_query_log; DROP TABLE log_count; -# -# Bug #31700: thd->examined_row_count not incremented for 'const' type queries -# +--echo # +--echo # Bug #31700: thd->examined_row_count not incremented for 'const' type queries +--echo # SET SESSION long_query_time = 0; SET GLOBAL slow_query_log = ON; @@ -1064,16 +1018,12 @@ DROP TABLE t1; TRUNCATE TABLE mysql.slow_log; -# -# Bug #47924 main.log_tables times out sporadically -# +--echo # +--echo # Bug #47924 main.log_tables times out sporadically +--echo # use mysql; # Should result in error ---disable_warnings -drop table if exists renamed_general_log; -drop table if exists renamed_slow_log; ---enable_warnings --error ER_CANT_RENAME_LOG_TABLE RENAME TABLE general_log TO renamed_general_log; --error ER_CANT_RENAME_LOG_TABLE @@ -1083,7 +1033,6 @@ use test; flush tables with read lock; unlock tables; -SET @@session.long_query_time= @old_long_query_time; SET @@global.log_output= @old_log_output; SET @@global.slow_query_log= @old_slow_query_log; From dcb814c44ec28e8cf011047407cc7304e93e466a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 21 Jan 2024 23:28:54 +0100 Subject: [PATCH 40/61] MDEV-11628 mysql.slow_log reports incorrect start time use thd->start_time for the "start_time" column of the slow_log table. "current_time" here refers to the current_time() function return value not to the actual *current* time. also fixes MDEV-33267 User with minimal permissions can intentionally corrupt mysql.slow_log table --- mysql-test/main/log_tables.result | 28 ++++++++++++++++++++++++++++ mysql-test/main/log_tables.test | 18 ++++++++++++++++++ sql/log.cc | 2 +- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/log_tables.result b/mysql-test/main/log_tables.result index e77de1b13ee..5c628458e7a 100644 --- a/mysql-test/main/log_tables.result +++ b/mysql-test/main/log_tables.result @@ -994,6 +994,34 @@ ERROR HY000: Cannot rename 'slow_log'. When logging enabled, rename to/from log use test; flush tables with read lock; unlock tables; +# +# MDEV-33267 User with minimal permissions can intentionally corrupt mysql.slow_log table +# +truncate mysql.slow_log; +set global log_output= 'TABLE'; +create user u@localhost; +set slow_query_log=on, long_query_time=0.1; +select 'before evil-doing', sleep(0.2); +before evil-doing sleep(0.2) +before evil-doing 0 +connect con1,localhost,u,,; +set @@timestamp= 2147483647; +set slow_query_log=on, long_query_time=0.1; +select 'evil-doing', sleep(1.1); +evil-doing sleep(1.1) +evil-doing 0 +disconnect con1; +connection default; +select 'after evil-doing', sleep(0.2); +after evil-doing sleep(0.2) +after evil-doing 0 +select distinct sql_text from mysql.slow_log where sql_text like '%evil%'; +sql_text +select 'before evil-doing', sleep(0.2) +select 'evil-doing', sleep(1.1) +select 'after evil-doing', sleep(0.2) +set global log_output=default; +drop user u@localhost; SET @@global.log_output= @old_log_output; SET @@global.slow_query_log= @old_slow_query_log; SET @@global.general_log= @old_general_log; diff --git a/mysql-test/main/log_tables.test b/mysql-test/main/log_tables.test index b54b154cf05..1169f2b094c 100644 --- a/mysql-test/main/log_tables.test +++ b/mysql-test/main/log_tables.test @@ -1033,6 +1033,24 @@ use test; flush tables with read lock; unlock tables; +--echo # +--echo # MDEV-33267 User with minimal permissions can intentionally corrupt mysql.slow_log table +--echo # +truncate mysql.slow_log; +set global log_output= 'TABLE'; +create user u@localhost; +set slow_query_log=on, long_query_time=0.1; +select 'before evil-doing', sleep(0.2); +--connect (con1,localhost,u,,) +set @@timestamp= 2147483647; +set slow_query_log=on, long_query_time=0.1; +select 'evil-doing', sleep(1.1); +--disconnect con1 +--connection default +select 'after evil-doing', sleep(0.2); +select distinct sql_text from mysql.slow_log where sql_text like '%evil%'; +set global log_output=default; +drop user u@localhost; SET @@global.log_output= @old_log_output; SET @@global.slow_query_log= @old_slow_query_log; diff --git a/sql/log.cc b/sql/log.cc index 75199000b85..32c8ad46321 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1334,7 +1334,7 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, size_t query_length, query_utime= (current_utime - thd->start_utime); lock_utime= (thd->utime_after_lock - thd->start_utime); my_hrtime_t current_time= { hrtime_from_time(thd->start_time) + - thd->start_time_sec_part + query_utime }; + thd->start_time_sec_part }; if (!query || thd->get_command() == COM_STMT_PREPARE) { From 8bb464899f1658522cc9740fdb73120d7190dca0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 22 Jan 2024 18:01:37 +0100 Subject: [PATCH 41/61] cleanup: unused and undefined methods --- sql/field.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/sql/field.h b/sql/field.h index 836de2d1bd6..4a95a6e0556 100644 --- a/sql/field.h +++ b/sql/field.h @@ -4060,9 +4060,6 @@ public: bool compatible_field_size(uint field_metadata, const Relay_log_info *rli, uint16 mflags, int *order_var) const override; uint row_pack_length() const override { return field_length; } - int pack_cmp(const uchar *a,const uchar *b,uint key_length, - bool insert_or_update); - int pack_cmp(const uchar *b,uint key_length,bool insert_or_update); uint packed_col_length(const uchar *to, uint length) override; uint max_packed_col_length(uint max_length) override; uint size_of() const override { return sizeof *this; } From 14d00fdb15b47c7f06768f39d5d8473ed47bdd18 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 22 Jan 2024 18:17:05 +0100 Subject: [PATCH 42/61] cleanup: MY_STRNNCOLLSP_NCHARS_EMULATE_TRIMMED_TRAILING_SPACES no need to use it when both arguments have the same length --- sql/field.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/field.cc b/sql/field.cc index 53dc5f2e15a..9e1e0931ef1 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7562,7 +7562,7 @@ int Field_string::cmp(const uchar *a_ptr, const uchar *b_ptr) const a_ptr, field_length, b_ptr, field_length, Field_string::char_length(), - MY_STRNNCOLLSP_NCHARS_EMULATE_TRIMMED_TRAILING_SPACES); + 0); } From a7ee3bc58bc23ad7ac5ced54dc745d0e65bee524 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 22 Jan 2024 18:02:11 +0100 Subject: [PATCH 43/61] MDEV-29954 Unique hash key on column prefix is computed incorrectly use the original, not the truncated, field in the long unique prefix, that is, in the hash(left(field, length)) expression. because MyISAM CHECK/REPAIR in compute_vcols() moves table->field but not prefix fields from keyparts. Also, implement Field_string::cmp_prefix() for prefix comparison of CHAR columns to work. --- mysql-test/main/long_unique_bugs.result | 9 +++++++++ mysql-test/main/long_unique_bugs.test | 8 ++++++++ sql/field.cc | 13 +++++++++++++ sql/field.h | 2 ++ sql/key.cc | 2 +- sql/table.cc | 5 ++--- 6 files changed, 35 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index e5c14afd9c4..30ba3d0af9a 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -651,5 +651,14 @@ f1 f2 f3 f4 f5 f6 f7 4 00004 0001009089999 netstes psit e drop table t1; # +# MDEV-29954 Unique hash key on column prefix is computed incorrectly +# +create table t1 (c char(10),unique key a using hash (c(1))); +insert into t1 values (0); +check table t1 extended; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; +# # End of 10.5 tests # diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index 5fed7c72d9a..12367b1deb8 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -634,6 +634,14 @@ replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netst select * from t1; drop table t1; +--echo # +--echo # MDEV-29954 Unique hash key on column prefix is computed incorrectly +--echo # +create table t1 (c char(10),unique key a using hash (c(1))); +insert into t1 values (0); +check table t1 extended; +drop table t1; + --echo # --echo # End of 10.5 tests --echo # diff --git a/sql/field.cc b/sql/field.cc index 9e1e0931ef1..fc828dcc86c 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7566,6 +7566,19 @@ int Field_string::cmp(const uchar *a_ptr, const uchar *b_ptr) const } +int Field_string::cmp_prefix(const uchar *a_ptr, const uchar *b_ptr, + size_t prefix_char_len) const +{ + size_t field_len= table->field[field_index]->field_length; + + return field_charset()->coll->strnncollsp_nchars(field_charset(), + a_ptr, field_len, + b_ptr, field_len, + prefix_char_len, + 0); +} + + void Field_string::sort_string(uchar *to,uint length) { #ifdef DBUG_ASSERT_EXISTS diff --git a/sql/field.h b/sql/field.h index 4a95a6e0556..aeb2ae0d20a 100644 --- a/sql/field.h +++ b/sql/field.h @@ -4038,6 +4038,8 @@ public: String *val_str(String *, String *) override; my_decimal *val_decimal(my_decimal *) override; int cmp(const uchar *,const uchar *) const override; + int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_char_len) const + override; void sort_string(uchar *buff,uint length) override; void update_data_type_statistics(Data_type_statistics *st) const override { diff --git a/sql/key.cc b/sql/key.cc index d801bcc982b..2fa7d7066a4 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -605,7 +605,7 @@ int key_rec_cmp(void *key_p, uchar *first_rec, uchar *second_rec) } /* No null values in the fields - We use the virtual method cmp_max with a max length parameter. + We use the virtual method cmp_prefix with a max length parameter. For most field types this translates into a cmp without max length. The exceptions are the BLOB and VARCHAR field types that take the max length into account. diff --git a/sql/table.cc b/sql/table.cc index a5e33052d3f..f3d186f4d9d 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1272,12 +1272,11 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, if (keypart->key_part_flag & HA_PART_KEY_SEG) { int length= keypart->length/keypart->field->charset()->mbmaxlen; + Field *kpf= table->field[keypart->field->field_index]; list_item= new (mem_root) Item_func_left(thd, - new (mem_root) Item_field(thd, keypart->field), + new (mem_root) Item_field(thd, kpf), new (mem_root) Item_int(thd, length)); list_item->fix_fields(thd, NULL); - keypart->field->vcol_info= - table->field[keypart->field->field_index]->vcol_info; } else list_item= new (mem_root) Item_field(thd, keypart->field); From 011d666ada0514875717a15171b93b139a701219 Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Tue, 23 Jan 2024 20:53:52 +0530 Subject: [PATCH 44/61] reorder the log columns for MDEV-27087 --- .../plugins/r/sql_error_log_withdbinfo.result | 8 +++---- .../plugins/t/sql_error_log_withdbinfo.test | 2 +- plugin/sql_errlog/sql_errlog.c | 22 +++++++++---------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/mysql-test/suite/plugins/r/sql_error_log_withdbinfo.result b/mysql-test/suite/plugins/r/sql_error_log_withdbinfo.result index 649d91269b6..4d869da5fd8 100644 --- a/mysql-test/suite/plugins/r/sql_error_log_withdbinfo.result +++ b/mysql-test/suite/plugins/r/sql_error_log_withdbinfo.result @@ -28,10 +28,10 @@ CREATE DATABASE `NULL`; USE `NULL`; DROP DATABASE db; ERROR HY000: Can't drop database 'db'; database doesn't exist -THREAD_ID `test` TIME HOSTNAME ERROR 1238: Variable 'sql_error_log_with_db_and_thread_info' is a read only variable : SET sql_error_log_with_db_and_thread_info=OFF -THREAD_ID `test` TIME HOSTNAME ERROR 1008: Can't drop database 'db'; database doesn't exist : DROP DATABASE db -THREAD_ID NULL TIME HOSTNAME ERROR 1008: Can't drop database 'db'; database doesn't exist : DROP DATABASE db -THREAD_ID `NULL` TIME HOSTNAME ERROR 1008: Can't drop database 'db'; database doesn't exist : DROP DATABASE db +TIME THREAD_ID HOSTNAME `test` ERROR 1238: Variable 'sql_error_log_with_db_and_thread_info' is a read only variable : SET sql_error_log_with_db_and_thread_info=OFF +TIME THREAD_ID HOSTNAME `test` ERROR 1008: Can't drop database 'db'; database doesn't exist : DROP DATABASE db +TIME THREAD_ID HOSTNAME NULL ERROR 1008: Can't drop database 'db'; database doesn't exist : DROP DATABASE db +TIME THREAD_ID HOSTNAME `NULL` ERROR 1008: Can't drop database 'db'; database doesn't exist : DROP DATABASE db DROP DATABASE `NULL`; # Reset CREATE DATABASE test; diff --git a/mysql-test/suite/plugins/t/sql_error_log_withdbinfo.test b/mysql-test/suite/plugins/t/sql_error_log_withdbinfo.test index bddcc14e275..c28fe793805 100644 --- a/mysql-test/suite/plugins/t/sql_error_log_withdbinfo.test +++ b/mysql-test/suite/plugins/t/sql_error_log_withdbinfo.test @@ -40,7 +40,7 @@ DROP DATABASE db; --let SEARCH_FILE= $MYSQLD_DATADIR/sql_errors.log --let LINES_TO_READ=4 ---replace_regex /[1-9]* `NULL` [1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [^E]*/THREAD_ID `NULL` TIME HOSTNAME / /[1-9]* `test` [1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [^E]*/THREAD_ID `test` TIME HOSTNAME / /[1-9]* NULL [1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [^E]*/THREAD_ID NULL TIME HOSTNAME / +--replace_regex /[1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]* .* @ .* `test` /TIME THREAD_ID HOSTNAME `test` //[1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]* .* @ .* NULL /TIME THREAD_ID HOSTNAME NULL //[1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]* .* @ .* `NULL` /TIME THREAD_ID HOSTNAME `NULL` / --source include/read_head.inc DROP DATABASE `NULL`; diff --git a/plugin/sql_errlog/sql_errlog.c b/plugin/sql_errlog/sql_errlog.c index a3f36fc966e..d668ed8779b 100644 --- a/plugin/sql_errlog/sql_errlog.c +++ b/plugin/sql_errlog/sql_errlog.c @@ -107,21 +107,19 @@ static void log_sql_errors(MYSQL_THD thd __attribute__((unused)), { if (event->database.str) { - logger_printf(logfile, "%llu %`s %04d-%02d-%02d %2d:%02d:%02d " - "%s ERROR %d: %s : %s \n", - event->general_thread_id, event->database.str, t.tm_year + 1900, - t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, - t.tm_sec, event->general_user, event->general_error_code, - event->general_command, event->general_query); + logger_printf(logfile, "%04d-%02d-%02d %2d:%02d:%02d %llu " + "%s %`s ERROR %d: %s : %s \n", + t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, + t.tm_sec, event->general_thread_id, event->general_user, event->database.str, + event->general_error_code, event->general_command, event->general_query); } else { - logger_printf(logfile, "%llu %s %04d-%02d-%02d %2d:%02d:%02d " - "%s ERROR %d: %s : %s \n", - event->general_thread_id, "NULL", t.tm_year + 1900, - t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, - t.tm_sec, event->general_user, event->general_error_code, - event->general_command, event->general_query); + logger_printf(logfile, "%04d-%02d-%02d %2d:%02d:%02d %llu " + "%s %s ERROR %d: %s : %s \n", + t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, + t.tm_sec, event->general_thread_id, event->general_user, "NULL", + event->general_error_code, event->general_command, event->general_query); } } else From 7c2f0822223a342d1ec4d8ec12c64291d7379492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Tue, 23 Jan 2024 18:38:22 +0200 Subject: [PATCH 45/61] Improve READLINE_V5 detection More in depth check to cover all used readline functions. --- cmake/readline.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/readline.cmake b/cmake/readline.cmake index 9c35d8c7d22..55a2867d2a3 100644 --- a/cmake/readline.cmake +++ b/cmake/readline.cmake @@ -114,6 +114,9 @@ MACRO (MYSQL_FIND_SYSTEM_READLINE) { rl_completion_func_t *func1= (rl_completion_func_t*)0; rl_compentry_func_t *func2= (rl_compentry_func_t*)0; + rl_on_new_line(); + rl_replace_line(\"\", 0); + rl_redisplay(); }" NEW_READLINE_INTERFACE) From 3699a7e1a90e17cfc016518fc4922b94d2dbe6be Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 11 Jan 2024 15:01:00 +1100 Subject: [PATCH 46/61] macos: Fix CMAKE_OSX_ARCHITECTURES when not set When CMAKE_OSX_ARCHITECTURES isn't set we end up with "Packaging as: mariadb-10.4.33-osx10.19-x86_64" on arm64 builders. Instead of implying 64bit is x86, use CMAKE_SYSTEM_PROCESSOR to form the filename. --- cmake/package_name.cmake | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cmake/package_name.cmake b/cmake/package_name.cmake index ce13a446fe6..ab0c1d44de8 100644 --- a/cmake/package_name.cmake +++ b/cmake/package_name.cmake @@ -99,11 +99,7 @@ IF(NOT VERSION) SET(DEFAULT_MACHINE "${CMAKE_OSX_ARCHITECTURES}") ENDIF() ELSE() - IF(64BIT) - SET(DEFAULT_MACHINE "x86_64") - ELSE() - SET(DEFAULT_MACHINE "i386") - ENDIF() + SET(DEFAULT_MACHINE ${CMAKE_SYSTEM_PROCESSOR}) ENDIF() IF(DEFAULT_MACHINE MATCHES "i386") From 9d88c5b8b40cce897b0a718584289f8ca331381e Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Tue, 23 Jan 2024 23:56:40 +0400 Subject: [PATCH 47/61] MDEV-31616 Problems with a stored function EMPTY() on upgrade to 10.6. The IDENT_sys doesn't include keywords, so the function with the keyword name can be created, but cannot be called. Moving keywords to new rules keyword_func_sp_var_and_label and keyword_func_sp_var_not_label so the functions with these names are allowed. --- mysql-test/main/parser.result | 16 +- mysql-test/main/sp.result | 73 ++++ mysql-test/main/sp.test | 38 ++ .../suite/compat/oracle/r/parser.result | 16 +- mysql-test/suite/funcs_1/r/storedproc.result | 150 ++++++-- mysql-test/suite/funcs_1/t/storedproc.test | 211 ++++++++++- .../suite/perfschema/r/digest_view.result | 50 +-- .../start_server_low_digest_sql_length.result | 4 +- sql/item_create.cc | 346 ++++++++++++++++++ sql/lex.h | 5 - sql/sql_yacc.yy | 243 ++++-------- 11 files changed, 897 insertions(+), 255 deletions(-) diff --git a/mysql-test/main/parser.result b/mysql-test/main/parser.result index 89732e20b40..bf9b8e4b137 100644 --- a/mysql-test/main/parser.result +++ b/mysql-test/main/parser.result @@ -1507,7 +1507,7 @@ BEGIN NOT ATOMIC DECLARE history INT; SET history=10; SELECT history; END SELECT history FROM t1 SELECT history 'alias' FROM t1 SELECT history() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.history does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT history.history() Error 1630 FUNCTION history.history does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT history DATE FROM t1 @@ -1530,7 +1530,7 @@ BEGIN NOT ATOMIC DECLARE next INT; SET next=10; SELECT next; END SELECT next FROM t1 SELECT next 'alias' FROM t1 SELECT next() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.next does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT next.next() Error 1630 FUNCTION next.next does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT next DATE FROM t1 @@ -1577,7 +1577,7 @@ BEGIN NOT ATOMIC DECLARE previous INT; SET previous=10; SELECT previous; END SELECT previous FROM t1 SELECT previous 'alias' FROM t1 SELECT previous() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.previous does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT previous.previous() Error 1630 FUNCTION previous.previous does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT previous DATE FROM t1 @@ -1601,7 +1601,7 @@ BEGIN NOT ATOMIC DECLARE system INT; SET system=10; SELECT system; END SELECT system FROM t1 SELECT system 'alias' FROM t1 SELECT system() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.system does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT system.system() Error 1630 FUNCTION system.system does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT system DATE FROM t1 @@ -1624,7 +1624,7 @@ BEGIN NOT ATOMIC DECLARE system_time INT; SET system_time=10; SELECT system_time SELECT system_time FROM t1 SELECT system_time 'alias' FROM t1 SELECT system_time() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.system_time does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT system_time.system_time() Error 1630 FUNCTION system_time.system_time does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT system_time DATE FROM t1 @@ -1695,7 +1695,7 @@ BEGIN NOT ATOMIC DECLARE transaction INT; SET transaction=10; SELECT transaction SELECT transaction FROM t1 SELECT transaction 'alias' FROM t1 SELECT transaction() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.transaction does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT transaction.transaction() Error 1630 FUNCTION transaction.transaction does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT transaction DATE FROM t1 @@ -1741,7 +1741,7 @@ BEGIN NOT ATOMIC DECLARE versioning INT; SET versioning=10; SELECT versioning; E SELECT versioning FROM t1 SELECT versioning 'alias' FROM t1 SELECT versioning() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.versioning does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT versioning.versioning() Error 1630 FUNCTION versioning.versioning does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT versioning DATE FROM t1 @@ -1764,7 +1764,7 @@ BEGIN NOT ATOMIC DECLARE without INT; SET without=10; SELECT without; END SELECT without FROM t1 SELECT without 'alias' FROM t1 SELECT without() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.without does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT without.without() Error 1630 FUNCTION without.without does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT without DATE FROM t1 diff --git a/mysql-test/main/sp.result b/mysql-test/main/sp.result index 4e93973782f..f33fbc84f30 100644 --- a/mysql-test/main/sp.result +++ b/mysql-test/main/sp.result @@ -9008,4 +9008,77 @@ BEGIN NOT ATOMIC DECLARE r ROW TYPE OF t1 DEFAULT (SELECT * FROM t1); SELECT r.a r.a 1 SET SESSION log_slow_verbosity= @tmp; +# +# MDEV-31616 Problems with a stored function EMPTY() on upgrade to 10.6. +# +CREATE OR REPLACE FUNCTION empty(a VARCHAR(128)) RETURNS int RETURN LENGTH(a)=0; +Warnings: +Note 1585 This function 'empty' has the same name as a native function +SELECT empty('1'); +empty('1') +0 +Warnings: +Note 1585 This function 'empty' has the same name as a native function +DROP FUNCTION empty; +CREATE OR REPLACE FUNCTION json_table(a VARCHAR(128)) RETURNS int RETURN LENGTH(a)=0; +Warnings: +Note 1585 This function 'json_table' has the same name as a native function +SELECT json_table('1'); +json_table('1') +0 +Warnings: +Note 1585 This function 'json_table' has the same name as a native function +DROP FUNCTION json_table; +CREATE OR REPLACE FUNCTION nested(a VARCHAR(128)) RETURNS int RETURN LENGTH(a)=0; +Warnings: +Note 1585 This function 'nested' has the same name as a native function +SELECT nested('1'); +nested('1') +0 +Warnings: +Note 1585 This function 'nested' has the same name as a native function +DROP FUNCTION nested; +CREATE OR REPLACE FUNCTION ordinality(a VARCHAR(128)) RETURNS int RETURN LENGTH(a)=0; +Warnings: +Note 1585 This function 'ordinality' has the same name as a native function +SELECT ordinality('1'); +ordinality('1') +0 +Warnings: +Note 1585 This function 'ordinality' has the same name as a native function +DROP FUNCTION ordinality; +CREATE OR REPLACE FUNCTION path(a VARCHAR(128)) RETURNS int RETURN LENGTH(a)=0; +Warnings: +Note 1585 This function 'path' has the same name as a native function +SELECT path('1'); +path('1') +0 +Warnings: +Note 1585 This function 'path' has the same name as a native function +DROP FUNCTION path; +CREATE OR REPLACE FUNCTION fast(a VARCHAR(128)) RETURNS int RETURN LENGTH(a)=0; +Warnings: +Note 1585 This function 'fast' has the same name as a native function +SELECT fast('1'); +fast('1') +0 +Warnings: +Note 1585 This function 'fast' has the same name as a native function +DROP FUNCTION fast; +CREATE OR REPLACE FUNCTION relay(a VARCHAR(128)) RETURNS int RETURN LENGTH(a)=0; +Warnings: +Note 1585 This function 'relay' has the same name as a native function +SELECT relay('1'); +relay('1') +0 +Warnings: +Note 1585 This function 'relay' has the same name as a native function +DROP FUNCTION relay; +CREATE OR REPLACE FUNCTION database() RETURNS int RETURN 333; +Warnings: +Note 1585 This function 'database' has the same name as a native function +SELECT database(); +database() +test +DROP FUNCTION database; DROP TABLE t1; diff --git a/mysql-test/main/sp.test b/mysql-test/main/sp.test index cc244a20014..5a794e46cd2 100644 --- a/mysql-test/main/sp.test +++ b/mysql-test/main/sp.test @@ -10618,6 +10618,44 @@ BEGIN NOT ATOMIC DECLARE r ROW TYPE OF t1 DEFAULT (SELECT * FROM t1); SELECT r.a --delimiter ; SET SESSION log_slow_verbosity= @tmp; + +--echo # +--echo # MDEV-31616 Problems with a stored function EMPTY() on upgrade to 10.6. +--echo # +CREATE OR REPLACE FUNCTION empty(a VARCHAR(128)) RETURNS int RETURN LENGTH(a)=0; +SELECT empty('1'); +DROP FUNCTION empty; + +CREATE OR REPLACE FUNCTION json_table(a VARCHAR(128)) RETURNS int RETURN LENGTH(a)=0; +SELECT json_table('1'); +DROP FUNCTION json_table; + +CREATE OR REPLACE FUNCTION nested(a VARCHAR(128)) RETURNS int RETURN LENGTH(a)=0; +SELECT nested('1'); +DROP FUNCTION nested; + +CREATE OR REPLACE FUNCTION ordinality(a VARCHAR(128)) RETURNS int RETURN LENGTH(a)=0; +SELECT ordinality('1'); +DROP FUNCTION ordinality; + +CREATE OR REPLACE FUNCTION path(a VARCHAR(128)) RETURNS int RETURN LENGTH(a)=0; +SELECT path('1'); +DROP FUNCTION path; + + +CREATE OR REPLACE FUNCTION fast(a VARCHAR(128)) RETURNS int RETURN LENGTH(a)=0; +SELECT fast('1'); +DROP FUNCTION fast; + +CREATE OR REPLACE FUNCTION relay(a VARCHAR(128)) RETURNS int RETURN LENGTH(a)=0; +SELECT relay('1'); +DROP FUNCTION relay; + +CREATE OR REPLACE FUNCTION database() RETURNS int RETURN 333; +SELECT database(); +DROP FUNCTION database; + + # Cleanup DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/parser.result b/mysql-test/suite/compat/oracle/r/parser.result index 32ea444ea25..0944b7f39bd 100644 --- a/mysql-test/suite/compat/oracle/r/parser.result +++ b/mysql-test/suite/compat/oracle/r/parser.result @@ -84,7 +84,7 @@ DECLARE history INT; BEGIN history:=10; SELECT history; END SELECT history FROM t1 SELECT history 'alias' FROM t1 SELECT history() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.history does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT history.history() Error 1630 FUNCTION history.history does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT history DATE FROM t1 @@ -106,7 +106,7 @@ DECLARE next INT; BEGIN next:=10; SELECT next; END SELECT next FROM t1 SELECT next 'alias' FROM t1 SELECT next() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.next does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT next.next() Error 1630 FUNCTION next.next does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT next DATE FROM t1 @@ -151,7 +151,7 @@ DECLARE previous INT; BEGIN previous:=10; SELECT previous; END SELECT previous FROM t1 SELECT previous 'alias' FROM t1 SELECT previous() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.previous does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT previous.previous() Error 1630 FUNCTION previous.previous does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT previous DATE FROM t1 @@ -174,7 +174,7 @@ DECLARE system INT; BEGIN system:=10; SELECT system; END SELECT system FROM t1 SELECT system 'alias' FROM t1 SELECT system() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.system does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT system.system() Error 1630 FUNCTION system.system does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT system DATE FROM t1 @@ -196,7 +196,7 @@ DECLARE system_time INT; BEGIN system_time:=10; SELECT system_time; END SELECT system_time FROM t1 SELECT system_time 'alias' FROM t1 SELECT system_time() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.system_time does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT system_time.system_time() Error 1630 FUNCTION system_time.system_time does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT system_time DATE FROM t1 @@ -264,7 +264,7 @@ DECLARE transaction INT; BEGIN transaction:=10; SELECT transaction; END SELECT transaction FROM t1 SELECT transaction 'alias' FROM t1 SELECT transaction() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.transaction does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT transaction.transaction() Error 1630 FUNCTION transaction.transaction does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT transaction DATE FROM t1 @@ -308,7 +308,7 @@ DECLARE versioning INT; BEGIN versioning:=10; SELECT versioning; END SELECT versioning FROM t1 SELECT versioning 'alias' FROM t1 SELECT versioning() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.versioning does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT versioning.versioning() Error 1630 FUNCTION versioning.versioning does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT versioning DATE FROM t1 @@ -330,7 +330,7 @@ DECLARE without INT; BEGIN without:=10; SELECT without; END SELECT without FROM t1 SELECT without 'alias' FROM t1 SELECT without() -Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +Error 1630 FUNCTION test.without does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT without.without() Error 1630 FUNCTION without.without does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual SELECT without DATE FROM t1 diff --git a/mysql-test/suite/funcs_1/r/storedproc.result b/mysql-test/suite/funcs_1/r/storedproc.result index c9f92d51210..3d33181c121 100644 --- a/mysql-test/suite/funcs_1/r/storedproc.result +++ b/mysql-test/suite/funcs_1/r/storedproc.result @@ -2088,9 +2088,11 @@ SELECT * from t1 where f2=f1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'cursor() SELECT * from t1 where f2=f1' at line 1 CREATE PROCEDURE database() -SELECT * from t1 where f2=f1; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'database() -SELECT * from t1 where f2=f1' at line 1 +SELECT 1; +CALL database(); +1 +1 +DROP PROCEDURE database; CREATE PROCEDURE databases() SELECT * from t1 where f2=f1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'databases() @@ -2350,6 +2352,12 @@ CREATE PROCEDURE join() SELECT * from t1 where f2=f1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'join() SELECT * from t1 where f2=f1' at line 1 +CREATE PROCEDURE json_table() +SELECT 1; +CALL json_table(); +1 +1 +DROP PROCEDURE json_table; CREATE PROCEDURE key() SELECT * from t1 where f2=f1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'key() @@ -2470,6 +2478,12 @@ CREATE PROCEDURE natural() SELECT * from t1 where f2=f1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'natural() SELECT * from t1 where f2=f1' at line 1 +CREATE PROCEDURE nested() +SELECT 1; +CALL nested(); +1 +1 +DROP PROCEDURE nested; CREATE PROCEDURE not() SELECT * from t1 where f2=f1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'not() @@ -2509,6 +2523,12 @@ CREATE PROCEDURE order() SELECT * from t1 where f2=f1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'order() SELECT * from t1 where f2=f1' at line 1 +CREATE PROCEDURE ordinality() +SELECT 1; +CALL ordinality; +1 +1 +DROP PROCEDURE ordinality; CREATE PROCEDURE out() SELECT * from t1 where f2=f1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'out() @@ -2521,6 +2541,12 @@ CREATE PROCEDURE outfile() SELECT * from t1 where f2=f1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'outfile() SELECT * from t1 where f2=f1' at line 1 +CREATE PROCEDURE path() +SELECT 1; +CALL path(); +1 +1 +DROP PROCEDURE path; CREATE PROCEDURE precision() SELECT * from t1 where f2=f1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'precision() @@ -2602,9 +2628,11 @@ SELECT * from t1 where f2=f1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'rlike() SELECT * from t1 where f2=f1' at line 1 CREATE PROCEDURE schema() -SELECT * from t1 where f2=f1; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'schema() -SELECT * from t1 where f2=f1' at line 1 +SELECT 1; +CALL schema(); +1 +1 +DROP PROCEDURE schema; CREATE PROCEDURE schemas() SELECT * from t1 where f2=f1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'schemas() @@ -4204,9 +4232,6 @@ CREATE PROCEDURE sp1() database:BEGIN SELECT @x; END// -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'database:BEGIN -SELECT @x; -END' at line 2 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1() databases:BEGIN @@ -4737,6 +4762,11 @@ SELECT @x; END' at line 2 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1() +json_table:BEGIN +SELECT @x; +END// +DROP PROCEDURE sp1; +CREATE PROCEDURE sp1() key:BEGIN SELECT @x; END// @@ -4977,6 +5007,11 @@ SELECT @x; END' at line 2 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1() +nested:BEGIN +SELECT @x; +END// +DROP PROCEDURE sp1; +CREATE PROCEDURE sp1() not:BEGIN SELECT @x; END// @@ -5057,6 +5092,11 @@ SELECT @x; END' at line 2 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1() +ordinality:BEGIN +SELECT @x; +END// +DROP PROCEDURE sp1; +CREATE PROCEDURE sp1() out:BEGIN SELECT @x; END// @@ -5081,6 +5121,11 @@ SELECT @x; END' at line 2 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1() +path:BEGIN +SELECT @x; +END// +DROP PROCEDURE sp1; +CREATE PROCEDURE sp1() precision:BEGIN SELECT @x; END// @@ -5253,9 +5298,6 @@ CREATE PROCEDURE sp1() schema:BEGIN SELECT @x; END// -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'schema:BEGIN -SELECT @x; -END' at line 2 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1() schemas:BEGIN @@ -7811,8 +7853,6 @@ CREATE PROCEDURE sp1() BEGIN declare database char; END// -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'database char; -END' at line 3 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1() BEGIN @@ -8278,6 +8318,11 @@ END' at line 3 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1() BEGIN +declare json_table char; +END// +DROP PROCEDURE sp1; +CREATE PROCEDURE sp1() +BEGIN declare key char; END// ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'key char; @@ -8488,6 +8533,11 @@ END' at line 3 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1() BEGIN +declare nested char; +END// +DROP PROCEDURE sp1; +CREATE PROCEDURE sp1() +BEGIN declare not char; END// ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'not char; @@ -8556,6 +8606,11 @@ END' at line 3 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1() BEGIN +declare ordinality char; +END// +DROP PROCEDURE sp1; +CREATE PROCEDURE sp1() +BEGIN declare out char; END// ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'out char; @@ -8577,6 +8632,11 @@ END' at line 3 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1() BEGIN +declare path char; +END// +DROP PROCEDURE sp1; +CREATE PROCEDURE sp1() +BEGIN declare precision char; END// ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'precision char; @@ -8745,11 +8805,7 @@ CREATE PROCEDURE sp1() BEGIN declare schema char; END// -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'schema char; -END' at line 3 DROP PROCEDURE IF EXISTS sp1; -Warnings: -Note 1305 PROCEDURE db_storedproc.sp1 does not exist CREATE PROCEDURE sp1() BEGIN declare schemas char; @@ -9704,11 +9760,7 @@ BEGIN declare database condition for sqlstate '02000'; declare exit handler for database set @var2 = 1; END// -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'database condition for sqlstate '02000'; -declare exit handler for database se...' at line 3 DROP PROCEDURE IF EXISTS sp1; -Warnings: -Note 1305 PROCEDURE db_storedproc.sp1 does not exist CREATE PROCEDURE sp1( ) BEGIN declare databases condition for sqlstate '02000'; @@ -10372,6 +10424,12 @@ Warnings: Note 1305 PROCEDURE db_storedproc.sp1 does not exist CREATE PROCEDURE sp1( ) BEGIN +declare json_table condition for sqlstate '02000'; +declare exit handler for json_table set @var2 = 1; +END// +DROP PROCEDURE sp1; +CREATE PROCEDURE sp1( ) +BEGIN declare key condition for sqlstate '02000'; declare exit handler for key set @var2 = 1; END// @@ -10672,6 +10730,12 @@ Warnings: Note 1305 PROCEDURE db_storedproc.sp1 does not exist CREATE PROCEDURE sp1( ) BEGIN +declare nested condition for sqlstate '02000'; +declare exit handler for nested set @var2 = 1; +END// +DROP PROCEDURE sp1; +CREATE PROCEDURE sp1( ) +BEGIN declare not condition for sqlstate '02000'; declare exit handler for not set @var2 = 1; END// @@ -10768,6 +10832,12 @@ Warnings: Note 1305 PROCEDURE db_storedproc.sp1 does not exist CREATE PROCEDURE sp1( ) BEGIN +declare ordinality condition for sqlstate '02000'; +declare exit handler for ordinality set @var2 = 1; +END// +DROP PROCEDURE sp1; +CREATE PROCEDURE sp1( ) +BEGIN declare out condition for sqlstate '02000'; declare exit handler for out set @var2 = 1; END// @@ -10798,6 +10868,12 @@ Warnings: Note 1305 PROCEDURE db_storedproc.sp1 does not exist CREATE PROCEDURE sp1( ) BEGIN +declare path condition for sqlstate '02000'; +declare exit handler for path set @var2 = 1; +END// +DROP PROCEDURE sp1; +CREATE PROCEDURE sp1( ) +BEGIN declare precision condition for sqlstate '02000'; declare exit handler for precision set @var2 = 1; END// @@ -11021,11 +11097,7 @@ BEGIN declare schema condition for sqlstate '02000'; declare exit handler for schema set @var2 = 1; END// -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'schema condition for sqlstate '02000'; -declare exit handler for schema set @v...' at line 3 DROP PROCEDURE IF EXISTS sp1; -Warnings: -Note 1305 PROCEDURE db_storedproc.sp1 does not exist CREATE PROCEDURE sp1( ) BEGIN declare schemas condition for sqlstate '02000'; @@ -11974,8 +12046,7 @@ CREATE PROCEDURE sp1( ) BEGIN declare database handler for sqlstate '02000' set @var2 = 1; END// -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'database handler for sqlstate '02000' set @var2 = 1; -END' at line 3 +ERROR HY000: Unknown data type: 'handler' DROP PROCEDURE IF EXISTS sp1; Warnings: Note 1305 PROCEDURE db_storedproc.sp1 does not exist @@ -12571,6 +12642,11 @@ Warnings: Note 1305 PROCEDURE db_storedproc.sp1 does not exist CREATE PROCEDURE sp1( ) BEGIN +declare json_table handler for sqlstate '02000' set @var2 = 1; +END// +ERROR HY000: Unknown data type: 'handler' +CREATE PROCEDURE sp1( ) +BEGIN declare key handler for sqlstate '02000' set @var2 = 1; END// ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'key handler for sqlstate '02000' set @var2 = 1; @@ -12841,6 +12917,11 @@ Warnings: Note 1305 PROCEDURE db_storedproc.sp1 does not exist CREATE PROCEDURE sp1( ) BEGIN +declare nested handler for sqlstate '02000' set @var2 = 1; +END// +ERROR HY000: Unknown data type: 'handler' +CREATE PROCEDURE sp1( ) +BEGIN declare not handler for sqlstate '02000' set @var2 = 1; END// ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'not handler for sqlstate '02000' set @var2 = 1; @@ -12930,6 +13011,11 @@ Warnings: Note 1305 PROCEDURE db_storedproc.sp1 does not exist CREATE PROCEDURE sp1( ) BEGIN +declare ordinality handler for sqlstate '02000' set @var2 = 1; +END// +ERROR HY000: Unknown data type: 'handler' +CREATE PROCEDURE sp1( ) +BEGIN declare out handler for sqlstate '02000' set @var2 = 1; END// ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'out handler for sqlstate '02000' set @var2 = 1; @@ -12957,6 +13043,11 @@ Warnings: Note 1305 PROCEDURE db_storedproc.sp1 does not exist CREATE PROCEDURE sp1( ) BEGIN +declare path handler for sqlstate '02000' set @var2 = 1; +END// +ERROR HY000: Unknown data type: 'handler' +CREATE PROCEDURE sp1( ) +BEGIN declare precision handler for sqlstate '02000' set @var2 = 1; END// ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'precision handler for sqlstate '02000' set @var2 = 1; @@ -13164,8 +13255,7 @@ CREATE PROCEDURE sp1( ) BEGIN declare schema handler for sqlstate '02000' set @var2 = 1; END// -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'schema handler for sqlstate '02000' set @var2 = 1; -END' at line 3 +ERROR HY000: Unknown data type: 'handler' DROP PROCEDURE IF EXISTS sp1; Warnings: Note 1305 PROCEDURE db_storedproc.sp1 does not exist diff --git a/mysql-test/suite/funcs_1/t/storedproc.test b/mysql-test/suite/funcs_1/t/storedproc.test index 8712919e430..e9c00742f01 100644 --- a/mysql-test/suite/funcs_1/t/storedproc.test +++ b/mysql-test/suite/funcs_1/t/storedproc.test @@ -1102,9 +1102,11 @@ CREATE PROCEDURE current_user() CREATE PROCEDURE cursor() SELECT * from t1 where f2=f1; ---error ER_PARSE_ERROR CREATE PROCEDURE database() - SELECT * from t1 where f2=f1; + SELECT 1; + +CALL database(); +DROP PROCEDURE database; --error ER_PARSE_ERROR CREATE PROCEDURE databases() @@ -1367,6 +1369,12 @@ CREATE PROCEDURE iterate() CREATE PROCEDURE join() SELECT * from t1 where f2=f1; +CREATE PROCEDURE json_table() + SELECT 1; + +CALL json_table(); +DROP PROCEDURE json_table; + --error ER_PARSE_ERROR CREATE PROCEDURE key() SELECT * from t1 where f2=f1; @@ -1487,6 +1495,13 @@ CREATE PROCEDURE modifies() CREATE PROCEDURE natural() SELECT * from t1 where f2=f1; +CREATE PROCEDURE nested() + SELECT 1; + +CALL nested(); + +DROP PROCEDURE nested; + --error ER_PARSE_ERROR CREATE PROCEDURE not() SELECT * from t1 where f2=f1; @@ -1527,6 +1542,13 @@ CREATE PROCEDURE or() CREATE PROCEDURE order() SELECT * from t1 where f2=f1; +CREATE PROCEDURE ordinality() + SELECT 1; + +CALL ordinality; + +DROP PROCEDURE ordinality; + --error ER_PARSE_ERROR CREATE PROCEDURE out() SELECT * from t1 where f2=f1; @@ -1539,6 +1561,13 @@ CREATE PROCEDURE outer() CREATE PROCEDURE outfile() SELECT * from t1 where f2=f1; +CREATE PROCEDURE path() + SELECT 1; + +CALL path(); + +DROP PROCEDURE path; + --error ER_PARSE_ERROR CREATE PROCEDURE precision() SELECT * from t1 where f2=f1; @@ -1619,9 +1648,11 @@ CREATE PROCEDURE right() CREATE PROCEDURE rlike() SELECT * from t1 where f2=f1; ---error ER_PARSE_ERROR CREATE PROCEDURE schema() - SELECT * from t1 where f2=f1; + SELECT 1; + +CALL schema(); +DROP PROCEDURE schema; --error ER_PARSE_ERROR CREATE PROCEDURE schemas() @@ -3481,7 +3512,7 @@ DROP PROCEDURE IF EXISTS sp1; --enable_warnings delimiter //; ---error ER_PARSE_ERROR + CREATE PROCEDURE sp1() database:BEGIN SELECT @x; @@ -4284,6 +4315,15 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; --enable_warnings +delimiter //; +CREATE PROCEDURE sp1() + json_table:BEGIN + SELECT @x; +END// +delimiter ;// + +DROP PROCEDURE sp1; + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1() @@ -4644,6 +4684,16 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; --enable_warnings +delimiter //; + +CREATE PROCEDURE sp1() + nested:BEGIN + SELECT @x; +END// +delimiter ;// + +DROP PROCEDURE sp1; + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1() @@ -4765,6 +4815,16 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; --enable_warnings +delimiter //; + +CREATE PROCEDURE sp1() + ordinality:BEGIN + SELECT @x; +END// +delimiter ;// + +DROP PROCEDURE sp1; + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1() @@ -4801,6 +4861,16 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; --enable_warnings +delimiter //; + +CREATE PROCEDURE sp1() + path:BEGIN + SELECT @x; +END// +delimiter ;// + +DROP PROCEDURE sp1; + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1() @@ -5066,7 +5136,7 @@ DROP PROCEDURE IF EXISTS sp1; --enable_warnings delimiter //; ---error ER_PARSE_ERROR + CREATE PROCEDURE sp1() schema:BEGIN SELECT @x; @@ -8938,7 +9008,7 @@ DROP PROCEDURE IF EXISTS sp1; --enable_warnings delimiter //; ---error ER_PARSE_ERROR + CREATE PROCEDURE sp1() BEGIN declare database char; @@ -9736,11 +9806,20 @@ BEGIN declare join char; END// delimiter ;// - --disable_warnings DROP PROCEDURE IF EXISTS sp1; --enable_warnings +delimiter //; + +CREATE PROCEDURE sp1() +BEGIN + declare json_table char; +END// +delimiter ;// + +DROP PROCEDURE sp1; + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1() @@ -10101,6 +10180,16 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; --enable_warnings +delimiter //; + +CREATE PROCEDURE sp1() +BEGIN + declare nested char; +END// +delimiter ;// + +DROP PROCEDURE sp1; + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1() @@ -10220,6 +10309,16 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; --enable_warnings +delimiter //; + +CREATE PROCEDURE sp1() +BEGIN + declare ordinality char; +END// +delimiter ;// + +DROP PROCEDURE sp1; + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1() @@ -10256,6 +10355,16 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; --enable_warnings +delimiter //; + +CREATE PROCEDURE sp1() +BEGIN + declare path char; +END// +delimiter ;// + +DROP PROCEDURE sp1; + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1() @@ -10506,7 +10615,7 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; delimiter //; ---error ER_PARSE_ERROR + CREATE PROCEDURE sp1() BEGIN declare schema char; @@ -11624,7 +11733,7 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; delimiter //; ---error ER_PARSE_ERROR + CREATE PROCEDURE sp1( ) BEGIN declare database condition for sqlstate '02000'; @@ -12360,6 +12469,17 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; +delimiter //; + +CREATE PROCEDURE sp1( ) +BEGIN + declare json_table condition for sqlstate '02000'; + declare exit handler for json_table set @var2 = 1; +END// +delimiter ;// + +DROP PROCEDURE sp1; + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1( ) @@ -12690,6 +12810,17 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; +delimiter //; + +CREATE PROCEDURE sp1( ) +BEGIN + declare nested condition for sqlstate '02000'; + declare exit handler for nested set @var2 = 1; +END// +delimiter ;// + +DROP PROCEDURE sp1; + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1( ) @@ -12799,6 +12930,17 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; +delimiter //; + +CREATE PROCEDURE sp1( ) +BEGIN + declare ordinality condition for sqlstate '02000'; + declare exit handler for ordinality set @var2 = 1; +END// +delimiter ;// + +DROP PROCEDURE sp1; + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1( ) @@ -12832,6 +12974,17 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; +delimiter //; + +CREATE PROCEDURE sp1( ) +BEGIN + declare path condition for sqlstate '02000'; + declare exit handler for path set @var2 = 1; +END// +delimiter ;// + +DROP PROCEDURE sp1; + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1( ) @@ -13075,7 +13228,7 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; delimiter //; ---error ER_PARSE_ERROR + CREATE PROCEDURE sp1( ) BEGIN declare schema condition for sqlstate '02000'; @@ -14181,7 +14334,7 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; delimiter //; ---error ER_PARSE_ERROR + CREATE PROCEDURE sp1( ) BEGIN declare database handler for sqlstate '02000' set @var2 = 1; @@ -14850,6 +15003,14 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; +delimiter //; +--error ER_UNKNOWN_DATA_TYPE +CREATE PROCEDURE sp1( ) +BEGIN + declare json_table handler for sqlstate '02000' set @var2 = 1; +END// +delimiter ;// + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1( ) @@ -15150,6 +15311,14 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; +delimiter //; +--error ER_UNKNOWN_DATA_TYPE +CREATE PROCEDURE sp1( ) +BEGIN + declare nested handler for sqlstate '02000' set @var2 = 1; +END// +delimiter ;// + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1( ) @@ -15250,6 +15419,14 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; +delimiter //; +--error ER_UNKNOWN_DATA_TYPE +CREATE PROCEDURE sp1( ) +BEGIN + declare ordinality handler for sqlstate '02000' set @var2 = 1; +END// +delimiter ;// + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1( ) @@ -15280,6 +15457,14 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; +delimiter //; +--error ER_UNKNOWN_DATA_TYPE +CREATE PROCEDURE sp1( ) +BEGIN + declare path handler for sqlstate '02000' set @var2 = 1; +END// +delimiter ;// + delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp1( ) @@ -15511,7 +15696,7 @@ delimiter ;// DROP PROCEDURE IF EXISTS sp1; delimiter //; ---error ER_PARSE_ERROR +--error ER_UNKNOWN_DATA_TYPE CREATE PROCEDURE sp1( ) BEGIN declare schema handler for sqlstate '02000' set @var2 = 1; diff --git a/mysql-test/suite/perfschema/r/digest_view.result b/mysql-test/suite/perfschema/r/digest_view.result index f3b5d9edcaa..cbaf9469829 100644 --- a/mysql-test/suite/perfschema/r/digest_view.result +++ b/mysql-test/suite/perfschema/r/digest_view.result @@ -191,17 +191,17 @@ SELECT SCHEMA_NAME, DIGEST, DIGEST_TEXT, COUNT_STAR FROM performance_schema.events_statements_summary_by_digest ORDER BY DIGEST_TEXT; SCHEMA_NAME DIGEST DIGEST_TEXT COUNT_STAR -test 6792f631a33c9aa30f74fc4a1ac00d0d EXPLAIN SELECT * FROM `test` . `v1` 1 -test 1a904f6e400d36fc3277347dc3dd7e3b EXPLAIN SELECT * FROM `test` . `v1` WHERE `a` = ? 1 -test 84b4a595b190b7b2be65930719a5f217 EXPLAIN SELECT * FROM `test` . `v1` WHERE `b` > ? 1 -test c2fbbef6771c0d94bc0bda68b083c2ee EXPLAIN SELECT `a` , `b` FROM `test` . `v1` 1 -test 89124df2148819b870c1d648f748b1ad EXPLAIN SELECT `b` , `a` FROM `test` . `v1` 1 -test 02270358998b539b9b11f709b372eda9 SELECT * FROM `test` . `v1` 1 -test e42e0a8f9dd70f815fd3b1323ae4d07d SELECT * FROM `test` . `v1` WHERE `a` = ? 1 -test f549d4607e65f96ae2bc4dc4f70965dd SELECT * FROM `test` . `v1` WHERE `b` > ? 1 -test d0ca89f87d46b19d6823e9c3d8fcc4f3 SELECT `a` , `b` FROM `test` . `v1` 1 -test 3599e7d908d651cd2b3410656f0a9a85 SELECT `b` , `a` FROM `test` . `v1` 1 -test 579dc8800f4005f131faf0202bfd383f TRUNCATE TABLE `performance_schema` . `events_statements_summary_by_digest` 1 +test 370e7bef18915f6611ac6d260774b983 EXPLAIN SELECT * FROM `test` . `v1` 1 +test 234d37a98244d9c8e7ddc95d8d615b67 EXPLAIN SELECT * FROM `test` . `v1` WHERE `a` = ? 1 +test 3dbb0324b7aa42191a45415438f0664b EXPLAIN SELECT * FROM `test` . `v1` WHERE `b` > ? 1 +test c4a754140ab2b645514868c727428aa0 EXPLAIN SELECT `a` , `b` FROM `test` . `v1` 1 +test 534e1e8b3fdd54ac7950a9c0c049d67b EXPLAIN SELECT `b` , `a` FROM `test` . `v1` 1 +test 6b928d386834bf77fb56d6917a66b3b3 SELECT * FROM `test` . `v1` 1 +test 914e5e0b02604c846266f1941ca5c99c SELECT * FROM `test` . `v1` WHERE `a` = ? 1 +test e037e9baeb863981ceed07178b82d85c SELECT * FROM `test` . `v1` WHERE `b` > ? 1 +test 1e4dbc9041d1c2c6ef0aee7bb10a9712 SELECT `a` , `b` FROM `test` . `v1` 1 +test ce9abb5b3de1de61ca0c7bed9bd8e268 SELECT `b` , `a` FROM `test` . `v1` 1 +test 8117308957580606865e284265d48615 TRUNCATE TABLE `performance_schema` . `events_statements_summary_by_digest` 1 DROP TABLE test.v1; CREATE VIEW test.v1 AS SELECT * FROM test.t1; EXPLAIN SELECT * from test.v1; @@ -248,19 +248,19 @@ SELECT SCHEMA_NAME, DIGEST, DIGEST_TEXT, COUNT_STAR FROM performance_schema.events_statements_summary_by_digest ORDER BY DIGEST_TEXT; SCHEMA_NAME DIGEST DIGEST_TEXT COUNT_STAR -test 1d9b60541940c07a0731da3a7e4b3710 CREATE VIEW `test` . `v1` AS SELECT * FROM `test` . `t1` 1 -test c3a18ebfa01b069ce0cbcf1d3c3a28fd DROP TABLE `test` . `v1` 1 -test 6792f631a33c9aa30f74fc4a1ac00d0d EXPLAIN SELECT * FROM `test` . `v1` 2 -test 1a904f6e400d36fc3277347dc3dd7e3b EXPLAIN SELECT * FROM `test` . `v1` WHERE `a` = ? 2 -test 84b4a595b190b7b2be65930719a5f217 EXPLAIN SELECT * FROM `test` . `v1` WHERE `b` > ? 2 -test c2fbbef6771c0d94bc0bda68b083c2ee EXPLAIN SELECT `a` , `b` FROM `test` . `v1` 2 -test 89124df2148819b870c1d648f748b1ad EXPLAIN SELECT `b` , `a` FROM `test` . `v1` 2 -test 02270358998b539b9b11f709b372eda9 SELECT * FROM `test` . `v1` 2 -test e42e0a8f9dd70f815fd3b1323ae4d07d SELECT * FROM `test` . `v1` WHERE `a` = ? 2 -test f549d4607e65f96ae2bc4dc4f70965dd SELECT * FROM `test` . `v1` WHERE `b` > ? 2 -test 279f05780dfbf44c1b9c444c4a3d7f81 SELECT SCHEMA_NAME , `DIGEST` , `DIGEST_TEXT` , `COUNT_STAR` FROM `performance_schema` . `events_statements_summary_by_digest` ORDER BY `DIGEST_TEXT` 1 -test d0ca89f87d46b19d6823e9c3d8fcc4f3 SELECT `a` , `b` FROM `test` . `v1` 2 -test 3599e7d908d651cd2b3410656f0a9a85 SELECT `b` , `a` FROM `test` . `v1` 2 -test 579dc8800f4005f131faf0202bfd383f TRUNCATE TABLE `performance_schema` . `events_statements_summary_by_digest` 1 +test aacd39adbd408fe1250208d032ce0bed CREATE VIEW `test` . `v1` AS SELECT * FROM `test` . `t1` 1 +test b7905ad078429428effa41db5d58c43e DROP TABLE `test` . `v1` 1 +test 370e7bef18915f6611ac6d260774b983 EXPLAIN SELECT * FROM `test` . `v1` 2 +test 234d37a98244d9c8e7ddc95d8d615b67 EXPLAIN SELECT * FROM `test` . `v1` WHERE `a` = ? 2 +test 3dbb0324b7aa42191a45415438f0664b EXPLAIN SELECT * FROM `test` . `v1` WHERE `b` > ? 2 +test c4a754140ab2b645514868c727428aa0 EXPLAIN SELECT `a` , `b` FROM `test` . `v1` 2 +test 534e1e8b3fdd54ac7950a9c0c049d67b EXPLAIN SELECT `b` , `a` FROM `test` . `v1` 2 +test 6b928d386834bf77fb56d6917a66b3b3 SELECT * FROM `test` . `v1` 2 +test 914e5e0b02604c846266f1941ca5c99c SELECT * FROM `test` . `v1` WHERE `a` = ? 2 +test e037e9baeb863981ceed07178b82d85c SELECT * FROM `test` . `v1` WHERE `b` > ? 2 +test ac0e7e062fb2eecae26f4e432cde3dd3 SELECT SCHEMA_NAME , `DIGEST` , `DIGEST_TEXT` , `COUNT_STAR` FROM `performance_schema` . `events_statements_summary_by_digest` ORDER BY `DIGEST_TEXT` 1 +test 1e4dbc9041d1c2c6ef0aee7bb10a9712 SELECT `a` , `b` FROM `test` . `v1` 2 +test ce9abb5b3de1de61ca0c7bed9bd8e268 SELECT `b` , `a` FROM `test` . `v1` 2 +test 8117308957580606865e284265d48615 TRUNCATE TABLE `performance_schema` . `events_statements_summary_by_digest` 1 DROP VIEW test.v1; DROP TABLE test.t1; diff --git a/mysql-test/suite/perfschema/r/start_server_low_digest_sql_length.result b/mysql-test/suite/perfschema/r/start_server_low_digest_sql_length.result index 3cca1764ec4..c2f2547ed49 100644 --- a/mysql-test/suite/perfschema/r/start_server_low_digest_sql_length.result +++ b/mysql-test/suite/perfschema/r/start_server_low_digest_sql_length.result @@ -8,5 +8,5 @@ SELECT 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 #################################### SELECT event_name, digest, digest_text, sql_text FROM events_statements_history_long; event_name digest digest_text sql_text -statement/sql/select bb82f2829bcdfd9ac1e53f7b27829d36 SELECT ? + ? + SELECT ... -statement/sql/truncate 86a7d96b41a68b8dfb6c94888bd3bb76 TRUNCATE TABLE truncat... +statement/sql/select 3ff8cd05d2991a9ac9b182801987d61e SELECT ? + ? + SELECT ... +statement/sql/truncate eddd22a5c210f96a5160acbb5d7563b3 TRUNCATE TABLE truncat... diff --git a/sql/item_create.cc b/sql/item_create.cc index 794e65a31a6..f15b343b127 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -127,6 +127,19 @@ protected: }; +class Create_func_addmonths : public Create_func_arg2 +{ +public: + virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2); + + static Create_func_addmonths s_singleton; + +protected: + Create_func_addmonths() = default; + virtual ~Create_func_addmonths() = default; +}; + + class Create_func_aes_encrypt : public Create_func_arg2 { public: @@ -258,6 +271,19 @@ protected: }; +class Create_func_collation : public Create_func_arg1 +{ +public: + virtual Item *create_1_arg(THD *thd, Item *arg1); + + static Create_func_collation s_singleton; + +protected: + Create_func_collation() = default; + virtual ~Create_func_collation() = default; +}; + + class Create_func_chr : public Create_func_arg1 { public: @@ -345,6 +371,20 @@ protected: }; +class Create_func_coalesce : public Create_native_func +{ +public: + virtual Item *create_native(THD *thd, const LEX_CSTRING *name, + List *item_list); + + static Create_func_coalesce s_singleton; + +protected: + Create_func_coalesce() = default; + virtual ~Create_func_coalesce() = default; +}; + + class Create_func_compress : public Create_func_arg1 { public: @@ -472,6 +512,19 @@ protected: }; +class Create_func_database : public Create_func_arg0 +{ +public: + virtual Item *create_builder(THD *thd); + + static Create_func_database s_singleton; + +protected: + Create_func_database() = default; + virtual ~Create_func_database() = default; +}; + + class Create_func_nvl2 : public Create_func_arg3 { public: @@ -563,6 +616,22 @@ protected: }; +class Create_func_date_format : public Create_native_func +{ +public: + virtual Item *create_native(THD *thd, const LEX_CSTRING *name, + List *item_list); + + static Create_func_date_format s_singleton; + +protected: + Create_func_date_format() = default; + virtual ~Create_func_date_format() = default; +}; + + + + class Create_func_dayname : public Create_func_arg1 { public: @@ -1382,6 +1451,31 @@ protected: virtual ~Create_func_octet_length() = default; }; +class Create_func_old_password : public Create_func_arg1 +{ +public: + virtual Item *create_1_arg(THD *thd, Item *arg1); + + static Create_func_old_password s_singleton; + +protected: + Create_func_old_password() = default; + virtual ~Create_func_old_password() = default; +}; + + +class Create_func_password : public Create_func_arg1 +{ +public: + virtual Item *create_1_arg(THD *thd, Item *arg1); + + static Create_func_password s_singleton; + +protected: + Create_func_password() = default; + virtual ~Create_func_password() = default; +}; + #ifndef DBUG_OFF class Create_func_like_range_min : public Create_func_arg2 @@ -1630,6 +1724,32 @@ protected: }; +class Create_func_microsecond : public Create_func_arg1 +{ +public: + virtual Item *create_1_arg(THD *thd, Item *arg1); + + static Create_func_microsecond s_singleton; + +protected: + Create_func_microsecond() = default; + virtual ~Create_func_microsecond() = default; +}; + + +class Create_func_mod : public Create_func_arg2 +{ +public: + virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2); + + static Create_func_mod s_singleton; + +protected: + Create_func_mod() = default; + virtual ~Create_func_mod() = default; +}; + + class Create_func_monthname : public Create_func_arg1 { public: @@ -1747,6 +1867,19 @@ protected: }; +class Create_func_quarter : public Create_func_arg1 +{ +public: + virtual Item *create_1_arg(THD *thd, Item *arg1); + + static Create_func_quarter s_singleton; + +protected: + Create_func_quarter() = default; + virtual ~Create_func_quarter() = default; +}; + + class Create_func_quote : public Create_func_arg1 { public: @@ -1888,6 +2021,19 @@ protected: }; +class Create_func_row_count : public Create_func_arg0 +{ +public: + virtual Item *create_builder(THD *thd); + + static Create_func_row_count s_singleton; + +protected: + Create_func_row_count() = default; + virtual ~Create_func_row_count() = default; +}; + + class Create_func_rpad : public Create_native_func { public: @@ -2349,6 +2495,20 @@ protected: }; +class Create_func_week : public Create_native_func +{ +public: + virtual Item *create_native(THD *thd, const LEX_CSTRING *name, + List *item_list); + + static Create_func_week s_singleton; + +protected: + Create_func_week() = default; + virtual ~Create_func_week() = default; +}; + + class Create_func_weekday : public Create_func_arg1 { public: @@ -2828,6 +2988,16 @@ Create_func_addtime::create_2_arg(THD *thd, Item *arg1, Item *arg2) } +Create_func_addmonths Create_func_addmonths::s_singleton; + +Item* +Create_func_addmonths::create_2_arg(THD *thd, Item *arg1, Item *arg2) +{ + return new (thd->mem_root) + Item_date_add_interval(thd, arg1, arg2, INTERVAL_MONTH, false); +} + + Create_func_aes_encrypt Create_func_aes_encrypt::s_singleton; Item* @@ -2957,6 +3127,15 @@ Create_func_ceiling::create_1_arg(THD *thd, Item *arg1) } +Create_func_collation Create_func_collation::s_singleton; + +Item* +Create_func_collation::create_1_arg(THD *thd, Item *arg1) +{ + return new (thd->mem_root) Item_func_collation(thd, arg1); +} + + Create_func_chr Create_func_chr::s_singleton; Item* @@ -3017,6 +3196,26 @@ Create_func_dyncol_json::create_1_arg(THD *thd, Item *arg1) return new (thd->mem_root) Item_func_dyncol_json(thd, arg1); } +Create_func_coalesce Create_func_coalesce::s_singleton; + +Item* +Create_func_coalesce::create_native(THD *thd, const LEX_CSTRING *name, + List *item_list) +{ + int arg_count= 0; + + if (item_list != NULL) + arg_count= item_list->elements; + + if (unlikely(arg_count < 1)) + { + my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); + return NULL; + } + + return new (thd->mem_root) Item_func_coalesce(thd, *item_list); +} + Create_func_concat Create_func_concat::s_singleton; Item* @@ -3111,6 +3310,16 @@ Create_func_connection_id::create_builder(THD *thd) } +Create_func_database Create_func_database::s_singleton; + +Item* +Create_func_database::create_builder(THD *thd) +{ + thd->lex->safe_to_cache_query= 0; + return new (thd->mem_root) Item_func_database(thd); +} + + Create_func_nvl2 Create_func_nvl2::s_singleton; Item* @@ -3175,6 +3384,37 @@ Create_func_datediff::create_2_arg(THD *thd, Item *arg1, Item *arg2) return new (thd->mem_root) Item_func_minus(thd, i1, i2); } +Create_func_date_format Create_func_date_format::s_singleton; + +Item* +Create_func_date_format::create_native(THD *thd, const LEX_CSTRING *name, + List *item_list) +{ + int arg_count= 0; + + if (item_list != NULL) + arg_count= item_list->elements; + + switch (arg_count) { + case 2: + { + Item *param_1= item_list->pop(); + Item *param_2= item_list->pop(); + return new (thd->mem_root) Item_func_date_format(thd, param_1, param_2); + } + case 3: + { + Item *param_1= item_list->pop(); + Item *param_2= item_list->pop(); + Item *param_3= item_list->pop(); + return new (thd->mem_root) Item_func_date_format(thd, + param_1, param_2, param_3); + } + } + my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); + return NULL; +} + Create_func_dayname Create_func_dayname::s_singleton; @@ -4289,6 +4529,23 @@ Create_func_length::create_1_arg(THD *thd, Item *arg1) return new (thd->mem_root) Item_func_octet_length(thd, arg1); } +Create_func_old_password Create_func_old_password::s_singleton; + +Item* +Create_func_old_password::create_1_arg(THD *thd, Item *arg1) +{ + return new (thd->mem_root) Item_func_password(thd, arg1, + Item_func_password::OLD); +} + +Create_func_password Create_func_password::s_singleton; + +Item* +Create_func_password::create_1_arg(THD *thd, Item *arg1) +{ + return new (thd->mem_root) Item_func_password(thd, arg1); +} + Create_func_octet_length Create_func_octet_length::s_singleton; Item* @@ -4657,6 +4914,24 @@ Create_func_md5::create_1_arg(THD *thd, Item *arg1) } +Create_func_microsecond Create_func_microsecond::s_singleton; + +Item* +Create_func_microsecond::create_1_arg(THD *thd, Item *arg1) +{ + return new (thd->mem_root) Item_func_microsecond(thd, arg1); +} + + +Create_func_mod Create_func_mod::s_singleton; + +Item* +Create_func_mod::create_2_arg(THD *thd, Item *arg1, Item *arg2) +{ + return new (thd->mem_root) Item_func_mod(thd, arg1, arg2); +} + + Create_func_monthname Create_func_monthname::s_singleton; Item* @@ -4759,6 +5034,15 @@ Create_func_pow::create_2_arg(THD *thd, Item *arg1, Item *arg2) } +Create_func_quarter Create_func_quarter::s_singleton; + +Item* +Create_func_quarter::create_1_arg(THD *thd, Item *arg1) +{ + return new (thd->mem_root) Item_func_quarter(thd, arg1); +} + + Create_func_quote Create_func_quote::s_singleton; Item* @@ -4934,6 +5218,17 @@ Create_func_round::create_native(THD *thd, const LEX_CSTRING *name, } +Create_func_row_count Create_func_row_count::s_singleton; + +Item* +Create_func_row_count::create_builder(THD *thd) +{ + thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); + thd->lex->safe_to_cache_query= 0; + return new (thd->mem_root) Item_func_row_count(thd); +} + + Create_func_rpad Create_func_rpad::s_singleton; Create_func_rpad_oracle Create_func_rpad_oracle::s_singleton; @@ -5391,6 +5686,43 @@ Create_func_version::create_builder(THD *thd) } +Create_func_week Create_func_week::s_singleton; + +Item* +Create_func_week::create_native(THD *thd, const LEX_CSTRING *name, + List *item_list) +{ + Item* func= NULL; + int arg_count= 0; + + if (item_list != NULL) + arg_count= item_list->elements; + + switch (arg_count) { + case 1: + { + Item *param_1= item_list->pop(); + func= new (thd->mem_root) Item_func_week(thd, param_1); + break; + } + case 2: + { + Item *param_1= item_list->pop(); + Item *param_2= item_list->pop(); + func= new (thd->mem_root) Item_func_week(thd, param_1, param_2); + break; + } + default: + { + my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); + break; + } + } + + return func; +} + + Create_func_weekday Create_func_weekday::s_singleton; Item* @@ -5541,6 +5873,7 @@ const Native_func_registry func_array[] = { { STRING_WITH_LEN("ABS") }, BUILDER(Create_func_abs)}, { { STRING_WITH_LEN("ACOS") }, BUILDER(Create_func_acos)}, { { STRING_WITH_LEN("ADDTIME") }, BUILDER(Create_func_addtime)}, + { { STRING_WITH_LEN("ADD_MONTHS") }, BUILDER(Create_func_addmonths)}, { { STRING_WITH_LEN("AES_DECRYPT") }, BUILDER(Create_func_aes_decrypt)}, { { STRING_WITH_LEN("AES_ENCRYPT") }, BUILDER(Create_func_aes_encrypt)}, { { STRING_WITH_LEN("ASIN") }, BUILDER(Create_func_asin)}, @@ -5556,7 +5889,9 @@ const Native_func_registry func_array[] = { { STRING_WITH_LEN("CHARACTER_LENGTH") }, BUILDER(Create_func_char_length)}, { { STRING_WITH_LEN("CHAR_LENGTH") }, BUILDER(Create_func_char_length)}, { { STRING_WITH_LEN("CHR") }, BUILDER(Create_func_chr)}, + { { STRING_WITH_LEN("COALESCE") }, BUILDER(Create_func_coalesce)}, { { STRING_WITH_LEN("COERCIBILITY") }, BUILDER(Create_func_coercibility)}, + { { STRING_WITH_LEN("COLLATION") }, BUILDER(Create_func_collation)}, { { STRING_WITH_LEN("COLUMN_CHECK") }, BUILDER(Create_func_dyncol_check)}, { { STRING_WITH_LEN("COLUMN_EXISTS") }, BUILDER(Create_func_dyncol_exists)}, { { STRING_WITH_LEN("COLUMN_LIST") }, BUILDER(Create_func_dyncol_list)}, @@ -5571,7 +5906,9 @@ const Native_func_registry func_array[] = { { STRING_WITH_LEN("COS") }, BUILDER(Create_func_cos)}, { { STRING_WITH_LEN("COT") }, BUILDER(Create_func_cot)}, { { STRING_WITH_LEN("CRC32") }, BUILDER(Create_func_crc32)}, + { { STRING_WITH_LEN("DATABASE") }, BUILDER(Create_func_database)}, { { STRING_WITH_LEN("DATEDIFF") }, BUILDER(Create_func_datediff)}, + { { STRING_WITH_LEN("DATE_FORMAT") }, BUILDER(Create_func_date_format)}, { { STRING_WITH_LEN("DAYNAME") }, BUILDER(Create_func_dayname)}, { { STRING_WITH_LEN("DAYOFMONTH") }, BUILDER(Create_func_dayofmonth)}, { { STRING_WITH_LEN("DAYOFWEEK") }, BUILDER(Create_func_dayofweek)}, @@ -5660,6 +5997,8 @@ const Native_func_registry func_array[] = { { STRING_WITH_LEN("MASTER_GTID_WAIT") }, BUILDER(Create_func_master_gtid_wait)}, { { STRING_WITH_LEN("MASTER_POS_WAIT") }, BUILDER(Create_func_master_pos_wait)}, { { STRING_WITH_LEN("MD5") }, BUILDER(Create_func_md5)}, + { { STRING_WITH_LEN("MICROSECOND") }, BUILDER(Create_func_microsecond)}, + { { STRING_WITH_LEN("MOD") }, BUILDER(Create_func_mod)}, { { STRING_WITH_LEN("MONTHNAME") }, BUILDER(Create_func_monthname)}, { { STRING_WITH_LEN("NAME_CONST") }, BUILDER(Create_func_name_const)}, { { STRING_WITH_LEN("NVL") }, BUILDER(Create_func_ifnull)}, @@ -5667,12 +6006,15 @@ const Native_func_registry func_array[] = { { STRING_WITH_LEN("NULLIF") }, BUILDER(Create_func_nullif)}, { { STRING_WITH_LEN("OCT") }, BUILDER(Create_func_oct)}, { { STRING_WITH_LEN("OCTET_LENGTH") }, BUILDER(Create_func_octet_length)}, + { { STRING_WITH_LEN("OLD_PASSWORD") }, BUILDER(Create_func_old_password)}, { { STRING_WITH_LEN("ORD") }, BUILDER(Create_func_ord)}, + { { STRING_WITH_LEN("PASSWORD") }, BUILDER(Create_func_password)}, { { STRING_WITH_LEN("PERIOD_ADD") }, BUILDER(Create_func_period_add)}, { { STRING_WITH_LEN("PERIOD_DIFF") }, BUILDER(Create_func_period_diff)}, { { STRING_WITH_LEN("PI") }, BUILDER(Create_func_pi)}, { { STRING_WITH_LEN("POW") }, BUILDER(Create_func_pow)}, { { STRING_WITH_LEN("POWER") }, BUILDER(Create_func_pow)}, + { { STRING_WITH_LEN("QUARTER") }, BUILDER(Create_func_quarter)}, { { STRING_WITH_LEN("QUOTE") }, BUILDER(Create_func_quote)}, { { STRING_WITH_LEN("REGEXP_INSTR") }, BUILDER(Create_func_regexp_instr)}, { { STRING_WITH_LEN("REGEXP_REPLACE") }, BUILDER(Create_func_regexp_replace)}, @@ -5686,11 +6028,14 @@ const Native_func_registry func_array[] = BUILDER(Create_func_replace_oracle)}, { { STRING_WITH_LEN("REVERSE") }, BUILDER(Create_func_reverse)}, { { STRING_WITH_LEN("ROUND") }, BUILDER(Create_func_round)}, + { { STRING_WITH_LEN("ROW_COUNT") }, BUILDER(Create_func_row_count)}, { { STRING_WITH_LEN("RPAD") }, BUILDER(Create_func_rpad)}, { { STRING_WITH_LEN("RPAD_ORACLE") }, BUILDER(Create_func_rpad_oracle)}, { { STRING_WITH_LEN("RTRIM") }, BUILDER(Create_func_rtrim)}, { { STRING_WITH_LEN("RTRIM_ORACLE") }, BUILDER(Create_func_rtrim_oracle)}, { { STRING_WITH_LEN("SEC_TO_TIME") }, BUILDER(Create_func_sec_to_time)}, + { { STRING_WITH_LEN("SCHEMA") }, BUILDER(Create_func_database)}, + { { STRING_WITH_LEN("SCHEMAS") }, BUILDER(Create_func_database)}, { { STRING_WITH_LEN("SHA") }, BUILDER(Create_func_sha)}, { { STRING_WITH_LEN("SHA1") }, BUILDER(Create_func_sha)}, { { STRING_WITH_LEN("SHA2") }, BUILDER(Create_func_sha2)}, @@ -5725,6 +6070,7 @@ const Native_func_registry func_array[] = { { STRING_WITH_LEN("UUID") }, BUILDER(Create_func_uuid)}, { { STRING_WITH_LEN("UUID_SHORT") }, BUILDER(Create_func_uuid_short)}, { { STRING_WITH_LEN("VERSION") }, BUILDER(Create_func_version)}, + { { STRING_WITH_LEN("WEEK") }, BUILDER(Create_func_week)}, { { STRING_WITH_LEN("WEEKDAY") }, BUILDER(Create_func_weekday)}, { { STRING_WITH_LEN("WEEKOFYEAR") }, BUILDER(Create_func_weekofyear)}, #ifdef WITH_WSREP diff --git a/sql/lex.h b/sql/lex.h index c2b83e67ded..d6241c50b6a 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -81,7 +81,6 @@ SYMBOL symbols[] = { { "AUTHORS", SYM(AUTHORS_SYM)}, { "AUTO_INCREMENT", SYM(AUTO_INC)}, { "AUTOEXTEND_SIZE", SYM(AUTOEXTEND_SIZE_SYM)}, - { "AUTO", SYM(AUTO_SYM)}, { "AVG", SYM(AVG_SYM)}, { "AVG_ROW_LENGTH", SYM(AVG_ROW_LENGTH)}, { "BACKUP", SYM(BACKUP_SYM)}, @@ -426,7 +425,6 @@ SYMBOL symbols[] = { { "NCHAR", SYM(NCHAR_SYM)}, { "NESTED", SYM(NESTED_SYM)}, { "NEVER", SYM(NEVER_SYM)}, - { "NEW", SYM(NEW_SYM)}, { "NEXT", SYM(NEXT_SYM)}, { "NEXTVAL", SYM(NEXTVAL_SYM)}, { "NO", SYM(NO_SYM)}, @@ -682,7 +680,6 @@ SYMBOL symbols[] = { { "TRUE", SYM(TRUE_SYM)}, { "TRUNCATE", SYM(TRUNCATE_SYM)}, { "TYPE", SYM(TYPE_SYM)}, - { "TYPES", SYM(TYPES_SYM)}, { "UNBOUNDED", SYM(UNBOUNDED_SYM)}, { "UNCOMMITTED", SYM(UNCOMMITTED_SYM)}, { "UNDEFINED", SYM(UNDEFINED_SYM)}, @@ -748,7 +745,6 @@ SYMBOL symbols[] = { SYMBOL sql_functions[] = { { "ADDDATE", SYM(ADDDATE_SYM)}, - { "ADD_MONTHS", SYM(ADD_MONTHS_SYM)}, { "BIT_AND", SYM(BIT_AND)}, { "BIT_OR", SYM(BIT_OR)}, { "BIT_XOR", SYM(BIT_XOR)}, @@ -759,7 +755,6 @@ SYMBOL sql_functions[] = { { "CURTIME", SYM(CURTIME)}, { "DATE_ADD", SYM(DATE_ADD_INTERVAL)}, { "DATE_SUB", SYM(DATE_SUB_INTERVAL)}, - { "DATE_FORMAT", SYM(DATE_FORMAT_SYM)}, { "DENSE_RANK", SYM(DENSE_RANK_SYM)}, { "EXTRACT", SYM(EXTRACT_SYM)}, { "FIRST_VALUE", SYM(FIRST_VALUE_SYM)}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 92fd102bc1a..a4e3a4c6531 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -737,7 +737,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token ACTION /* SQL-2003-N */ %token ADMIN_SYM /* SQL-2003-N */ %token ADDDATE_SYM /* MYSQL-FUNC */ -%token ADD_MONTHS_SYM /* Oracle FUNC*/ %token AFTER_SYM /* SQL-2003-N */ %token AGAINST %token AGGREGATE_SYM @@ -750,7 +749,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token AUTHORS_SYM %token AUTOEXTEND_SIZE_SYM %token AUTO_INC -%token AUTO_SYM %token AVG_ROW_LENGTH %token AVG_SYM /* SQL-2003-N */ %token BACKUP_SYM @@ -812,7 +810,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token DATAFILE_SYM %token DATA_SYM /* SQL-2003-N */ %token DATETIME -%token DATE_FORMAT_SYM /* MYSQL-FUNC */ %token DATE_SYM /* SQL-2003-R, Oracle-R, PLSQL-R */ %token DAY_SYM /* SQL-2003-R */ %token DEALLOCATE_SYM /* SQL-2003-R */ @@ -963,7 +960,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token NATIONAL_SYM /* SQL-2003-R */ %token NCHAR_SYM /* SQL-2003-R */ %token NEVER_SYM /* MySQL */ -%token NEW_SYM /* SQL-2003-R */ %token NEXT_SYM /* SQL-2003-N */ %token NEXTVAL_SYM /* PostgreSQL sequence function */ %token NOCACHE_SYM @@ -1126,7 +1122,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token TRIGGERS_SYM %token TRIM_ORACLE %token TRUNCATE_SYM -%token TYPES_SYM %token TYPE_SYM /* SQL-2003-N */ %token UDF_RETURNS_SYM %token UNBOUNDED_SYM /* SQL-2011-N */ @@ -1317,6 +1312,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type IDENT_sys + ident_func ident label_ident sp_decl_ident @@ -1341,6 +1337,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); IDENT_cli ident_cli ident_cli_set_usual_case + ident_cli_func %type ident_sys_alloc @@ -1355,6 +1352,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); keyword_sp_block_section keyword_sp_decl keyword_sp_head + keyword_func_sp_var_and_label + keyword_func_sp_var_not_label keyword_sp_var_and_label keyword_sp_var_not_label keyword_sysvar_name @@ -10411,14 +10410,7 @@ substring_operands_special: discouraged. */ function_call_nonkeyword: - ADD_MONTHS_SYM '(' expr ',' expr ')' - { - $$= new (thd->mem_root) Item_date_add_interval(thd, $3, $5, - INTERVAL_MONTH, 0); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } - | ADDDATE_SYM '(' expr ',' expr ')' + ADDDATE_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_date_add_interval(thd, $3, $5, INTERVAL_DAY, 0); @@ -10457,18 +10449,6 @@ function_call_nonkeyword: if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | DATE_FORMAT_SYM '(' expr ',' expr ')' - { - $$= new (thd->mem_root) Item_func_date_format(thd, $3, $5); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } - | DATE_FORMAT_SYM '(' expr ',' expr ',' expr ')' - { - $$= new (thd->mem_root) Item_func_date_format(thd, $3, $5, $7); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } | EXTRACT_SYM '(' interval FROM expr ')' { $$=new (thd->mem_root) Item_extract(thd, $3, $5); @@ -10593,13 +10573,6 @@ function_call_nonkeyword: if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | - COLUMN_CHECK_SYM '(' expr ')' - { - $$= new (thd->mem_root) Item_func_dyncol_check(thd, $3); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } | COLUMN_CREATE_SYM '(' dyncall_create_list ')' { @@ -10637,43 +10610,12 @@ function_call_conflict: if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | COALESCE '(' expr_list ')' - { - $$= new (thd->mem_root) Item_func_coalesce(thd, *$3); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } - | COLLATION_SYM '(' expr ')' - { - $$= new (thd->mem_root) Item_func_collation(thd, $3); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } - | DATABASE '(' ')' - { - $$= new (thd->mem_root) Item_func_database(thd); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - Lex->safe_to_cache_query=0; - } | IF_SYM '(' expr ',' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_if(thd, $3, $5, $7); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | FORMAT_SYM '(' expr ',' expr ')' - { - $$= new (thd->mem_root) Item_func_format(thd, $3, $5); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } - | FORMAT_SYM '(' expr ',' expr ',' expr ')' - { - $$= new (thd->mem_root) Item_func_format(thd, $3, $5, $7); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } /* LAST_VALUE here conflicts with the definition for window functions. We have these 2 separate rules to remove the shift/reduce conflict. */ @@ -10695,25 +10637,12 @@ function_call_conflict: if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | MICROSECOND_SYM '(' expr ')' - { - $$= new (thd->mem_root) Item_func_microsecond(thd, $3); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } | MOD_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_mod(thd, $3, $5); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | OLD_PASSWORD_SYM '(' expr ')' - { - $$= new (thd->mem_root) - Item_func_password(thd, $3, Item_func_password::OLD); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } | PASSWORD_SYM '(' expr ')' { Item* i1; @@ -10722,12 +10651,6 @@ function_call_conflict: MYSQL_YYABORT; $$= i1; } - | QUARTER_SYM '(' expr ')' - { - $$= new (thd->mem_root) Item_func_quarter(thd, $3); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } | REPEAT_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_repeat(thd, $3, $5); @@ -10740,38 +10663,12 @@ function_call_conflict: make_item_func_replace(thd, $3, $5, $7)))) MYSQL_YYABORT; } - | REVERSE_SYM '(' expr ')' - { - $$= new (thd->mem_root) Item_func_reverse(thd, $3); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } - | ROW_COUNT_SYM '(' ')' - { - $$= new (thd->mem_root) Item_func_row_count(thd); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); - Lex->safe_to_cache_query= 0; - } | TRUNCATE_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_round(thd, $3, $5, 1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | WEEK_SYM '(' expr ')' - { - $$= new (thd->mem_root) Item_func_week(thd, $3); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } - | WEEK_SYM '(' expr ',' expr ')' - { - $$= new (thd->mem_root) Item_func_week(thd, $3, $5); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } | WEIGHT_STRING_SYM '(' expr opt_ws_levels ')' { $$= new (thd->mem_root) Item_func_weight_string(thd, $3, 0, 0, $4); @@ -10817,7 +10714,7 @@ function_call_conflict: in sql/item_create.cc */ function_call_generic: - IDENT_sys '(' + ident_func '(' { #ifdef HAVE_DLOPEN udf_func *udf= 0; @@ -15673,6 +15570,22 @@ IDENT_sys: } ; +ident_cli_func: + IDENT + | IDENT_QUOTED + | keyword_func_sp_var_and_label { $$= $1; } + | keyword_func_sp_var_not_label { $$= $1; } + ; + +ident_func: + ident_cli_func + { + if (unlikely(thd->to_ident_sys_alloc(&$$, &$1))) + MYSQL_YYABORT; + } + ; + + TEXT_STRING_sys: TEXT_STRING { @@ -15896,7 +15809,8 @@ non_reserved_keyword_udt: TODO: check if some of them can migrate to keyword_sp_var_and_label. */ keyword_sp_var_not_label: - ASCII_SYM + keyword_func_sp_var_not_label + | ASCII_SYM | BACKUP_SYM | BINLOG_SYM | BYTE_SYM @@ -15904,7 +15818,6 @@ keyword_sp_var_not_label: | CHECKSUM_SYM | CHECKPOINT_SYM | COLUMN_ADD_SYM - | COLUMN_CHECK_SYM | COLUMN_CREATE_SYM | COLUMN_DELETE_SYM | COLUMN_GET_SYM @@ -15916,7 +15829,6 @@ keyword_sp_var_not_label: | EXECUTE_SYM | FLUSH_SYM | FOLLOWING_SYM - | FORMAT_SYM | GET_SYM | HELP_SYM | HOST_SYM @@ -16070,29 +15982,21 @@ keyword_cast_type: ; -/* - These keywords are fine for both SP variable names and SP labels. -*/ -keyword_sp_var_and_label: - ACTION +keyword_func_sp_var_and_label: + ACTION | ACCOUNT_SYM - | ADDDATE_SYM - | ADD_MONTHS_SYM | ADMIN_SYM | AFTER_SYM | AGAINST | AGGREGATE_SYM | ALGORITHM_SYM | ALWAYS_SYM - | ANY_SYM | AT_SYM | ATOMIC_SYM | AUTHORS_SYM | AUTO_INC | AUTOEXTEND_SIZE_SYM - | AUTO_SYM | AVG_ROW_LENGTH - | AVG_SYM | BLOCK_SYM | BODY_MARIADB_SYM | BTREE_SYM @@ -16104,7 +16008,6 @@ keyword_sp_var_and_label: | CLIENT_SYM | CLASS_ORIGIN_SYM | COALESCE - | CODE_SYM | COLLATION_SYM | COLUMN_NAME_SYM | COLUMNS @@ -16130,16 +16033,15 @@ keyword_sp_var_and_label: | CURSOR_NAME_SYM | CYCLE_SYM | DATA_SYM + | DATABASE | DATAFILE_SYM - | DATE_FORMAT_SYM - | DAY_SYM | DEFINER_SYM | DELAY_KEY_WRITE_SYM | DES_KEY_FILE | DIAGNOSTICS_SYM + | DISCARD | DIRECTORY_SYM | DISABLE_SYM - | DISCARD | DISK_SYM | DUMPFILE | DUPLICATE_SYM @@ -16147,6 +16049,11 @@ keyword_sp_var_and_label: | ELSEIF_ORACLE_SYM | ELSIF_MARIADB_SYM | EMPTY_SYM + | EXPIRE_SYM + | EXPORT_SYM + | EXTENDED_SYM + | EXTENT_SIZE_SYM + | ENABLE_SYM | ENDS_SYM | ENGINE_SYM | ENGINES_SYM @@ -16159,29 +16066,21 @@ keyword_sp_var_and_label: | EXCEPTION_MARIADB_SYM | EXCHANGE_SYM | EXPANSION_SYM - | EXPIRE_SYM - | EXPORT_SYM - | EXTENDED_SYM - | EXTENT_SIZE_SYM | FAULTS_SYM | FAST_SYM - | FOUND_SYM - | ENABLE_SYM | FEDERATED_SYM - | FULL | FILE_SYM | FIRST_SYM + | FOUND_SYM + | FULL | GENERAL | GENERATED_SYM - | GET_FORMAT | GRANTS | GOTO_MARIADB_SYM | HASH_SYM | HARD_SYM | HISTORY_SYM | HOSTS_SYM - | HOUR_SYM - | ID_SYM | IDENTIFIED_SYM | IGNORE_SERVER_IDS_SYM | INCREMENT_SYM @@ -16199,9 +16098,7 @@ keyword_sp_var_and_label: | INVISIBLE_SYM | JSON_TABLE_SYM | KEY_BLOCK_SIZE - | LAST_VALUE | LAST_SYM - | LASTVAL_SYM | LEAVES | LESS_SYM | LEVEL_SYM @@ -16243,7 +16140,6 @@ keyword_sp_var_and_label: | MESSAGE_TEXT_SYM | MICROSECOND_SYM | MIGRATE_SYM - | MINUTE_SYM %ifdef MARIADB | MINUS_ORACLE_SYM %endif @@ -16252,7 +16148,6 @@ keyword_sp_var_and_label: | MODIFY_SYM | MODE_SYM | MONITOR_SYM - | MONTH_SYM | MUTEX_SYM | MYSQL_SYM | MYSQL_ERRNO_SYM @@ -16260,8 +16155,6 @@ keyword_sp_var_and_label: | NESTED_SYM | NEVER_SYM | NEXT_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 - | NEXTVAL_SYM - | NEW_SYM | NOCACHE_SYM | NOCYCLE_SYM | NOMINVALUE_SYM @@ -16277,7 +16170,6 @@ keyword_sp_var_and_label: | ONLINE_SYM | ONLY_SYM | ORDINALITY_SYM - | OVERLAPS_SYM | PACKAGE_MARIADB_SYM | PACK_KEYS_SYM | PAGE_SYM @@ -16309,10 +16201,10 @@ keyword_sp_var_and_label: | REDOFILE_SYM | REDUNDANT_SYM | RELAY - | RELAYLOG_SYM | RELAY_LOG_FILE_SYM | RELAY_LOG_POS_SYM | RELAY_THREAD + | RELAYLOG_SYM | RELOAD | REORGANIZE_SYM | REPEATABLE_SYM @@ -16327,20 +16219,15 @@ keyword_sp_var_and_label: | REVERSE_SYM | ROLLUP_SYM | ROUTINE_SYM + | ROW_COUNT_SYM | ROWCOUNT_SYM | ROWTYPE_MARIADB_SYM - | ROW_COUNT_SYM | ROW_FORMAT_SYM -%ifdef MARIADB - | ROWNUM_SYM -%endif | RTREE_SYM | SCHEDULE_SYM | SCHEMA_NAME_SYM - | SECOND_SYM | SEQUENCE_SYM | SERIALIZABLE_SYM - | SETVAL_SYM | SIMPLE_SYM | SHARE_SYM | SKIP_SYM @@ -16348,7 +16235,6 @@ keyword_sp_var_and_label: | SLOW | SNAPSHOT_SYM | SOFT_SYM - | SOUNDS_SYM | SOURCE_SYM | SQL_CACHE_SYM | SQL_BUFFER_RESULT @@ -16361,7 +16247,6 @@ keyword_sp_var_and_label: | STORAGE_SYM | STRING_SYM | SUBCLASS_ORIGIN_SYM - | SUBDATE_SYM | SUBJECT_SYM | SUBPARTITION_SYM | SUBPARTITIONS_SYM @@ -16369,9 +16254,6 @@ keyword_sp_var_and_label: | SUSPEND_SYM | SWAPS_SYM | SWITCHES_SYM -%ifdef MARIADB - | SYSDATE -%endif | SYSTEM | SYSTEM_TIME_SYM | TABLE_NAME_SYM @@ -16385,10 +16267,6 @@ keyword_sp_var_and_label: | TRANSACTIONAL_SYM | THREADS_SYM | TRIGGERS_SYM - | TRIM_ORACLE - | TIMESTAMP_ADD - | TIMESTAMP_DIFF - | TYPES_SYM | TYPE_SYM | UDF_RETURNS_SYM | UNCOMMITTED_SYM @@ -16397,23 +16275,61 @@ keyword_sp_var_and_label: | UNDOFILE_SYM | UNKNOWN_SYM | UNTIL_SYM - | USER_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 | USE_FRM | VARIABLES | VERSIONING_SYM | VIEW_SYM | VIRTUAL_SYM | VISIBLE_SYM - | VALUE_SYM | WARNINGS | WAIT_SYM - | WEEK_SYM - | WEIGHT_STRING_SYM | WITHOUT | WORK_SYM | X509_SYM | XML_SYM | VIA_SYM + | WEEK_SYM + ; + +keyword_func_sp_var_not_label: + FORMAT_SYM + | COLUMN_CHECK_SYM + ; +/* + These keywords are fine for both SP variable names and SP labels. +*/ +keyword_sp_var_and_label: + keyword_func_sp_var_and_label + | ADDDATE_SYM + | ANY_SYM + | AVG_SYM + | CODE_SYM + | DAY_SYM + | GET_FORMAT + | HOUR_SYM + | ID_SYM + | LAST_VALUE + | LASTVAL_SYM + | MINUTE_SYM + | MONTH_SYM + | NEXTVAL_SYM + | OVERLAPS_SYM +%ifdef MARIADB + | ROWNUM_SYM +%endif + | SECOND_SYM + | SETVAL_SYM + | SOUNDS_SYM + | SUBDATE_SYM +%ifdef MARIADB + | SYSDATE +%endif + | TRIM_ORACLE + | TIMESTAMP_ADD + | TIMESTAMP_DIFF + | USER_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 + | VALUE_SYM + | WEIGHT_STRING_SYM ; @@ -16454,7 +16370,6 @@ reserved_keyword_udt_not_param_type: | CURRENT_USER | CURRENT_ROLE | CURTIME - | DATABASE | DATABASES | DATE_ADD_INTERVAL | DATE_SUB_INTERVAL From f738cc9876fee50909a9a5f5740617e95d46cf54 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 24 Nov 2023 13:23:56 +0400 Subject: [PATCH 48/61] MDEV-29095 REGEXP_REPLACE treats empty strings different than REPLACE in ORACLE mode Turning REGEXP_REPLACE into two schema-qualified functions: - mariadb_schema.regexp_replace() - oracle_schema.regexp_replace() Fixing oracle_schema.regexp_replace(subj,pattern,replacement) to treat NULL in "replacement" as an empty string. Adding new classes implementing oracle_schema.regexp_replace(): - Item_func_regexp_replace_oracle - Create_func_regexp_replace_oracle Adding helper methods: - String *Item::val_str_null_to_empty(String *to) - String *Item::val_str_null_to_empty(String *to, bool null_to_empty) and reusing these methods in both Item_func_replace and Item_func_regexp_replace. --- .../compat/oracle/r/func_qualified.result | 79 +++++++++++++++++++ .../oracle/r/func_regexp_replace.result | 34 ++++++++ .../suite/compat/oracle/t/func_qualified.test | 1 + .../compat/oracle/t/func_regexp_replace.test | 26 ++++++ sql/item.h | 13 +++ sql/item_create.cc | 38 ++++++--- sql/item_strfunc.cc | 34 +++----- sql/item_strfunc.h | 40 +++++++++- 8 files changed, 230 insertions(+), 35 deletions(-) create mode 100644 mysql-test/suite/compat/oracle/r/func_regexp_replace.result create mode 100644 mysql-test/suite/compat/oracle/t/func_regexp_replace.test diff --git a/mysql-test/suite/compat/oracle/r/func_qualified.result b/mysql-test/suite/compat/oracle/r/func_qualified.result index f8224b7ce81..4750a625ebd 100644 --- a/mysql-test/suite/compat/oracle/r/func_qualified.result +++ b/mysql-test/suite/compat/oracle/r/func_qualified.result @@ -1772,6 +1772,85 @@ Level Code Message Note 1003 select trim(both ' ' from 'a') AS "oracle_schema.TRIM(BOTH ' ' FROM 'a')" Warnings: Note 1003 select trim(both ' ' from 'a') AS "oracle_schema.TRIM(BOTH ' ' FROM 'a')" +CALL p3('REGEXP_REPLACE(''test'',''t'','''')'); +---------- +sql_mode='' qualifier='' +query +EXPLAIN EXTENDED SELECT REGEXP_REPLACE('test','t','') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select regexp_replace('test','t','') AS `REGEXP_REPLACE('test','t','')` +---------- +sql_mode='' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.REGEXP_REPLACE('test','t','') +errmsg +ERROR: FUNCTION unknown_schema.REGEXP_REPLACE does not exist +---------- +sql_mode='' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.REGEXP_REPLACE('test','t','') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select regexp_replace('test','t','') AS `mariadb_schema.REGEXP_REPLACE('test','t','')` +---------- +sql_mode='' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.REGEXP_REPLACE('test','t','') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select regexp_replace('test','t','') AS `maxdb_schema.REGEXP_REPLACE('test','t','')` +---------- +sql_mode='' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.REGEXP_REPLACE('test','t','') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select oracle_schema.regexp_replace('test','t','') AS `oracle_schema.REGEXP_REPLACE('test','t','')` +---------- +sql_mode='ORACLE' qualifier='' +query +EXPLAIN EXTENDED SELECT REGEXP_REPLACE('test','t','') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select regexp_replace('test','t','') AS "REGEXP_REPLACE('test','t','')" +---------- +sql_mode='ORACLE' qualifier='unknown_schema.' +query +EXPLAIN EXTENDED SELECT unknown_schema.REGEXP_REPLACE('test','t','') +errmsg +ERROR: FUNCTION unknown_schema.REGEXP_REPLACE does not exist +---------- +sql_mode='ORACLE' qualifier='mariadb_schema.' +query +EXPLAIN EXTENDED SELECT mariadb_schema.REGEXP_REPLACE('test','t','') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.regexp_replace('test','t','') AS "mariadb_schema.REGEXP_REPLACE('test','t','')" +---------- +sql_mode='ORACLE' qualifier='maxdb_schema.' +query +EXPLAIN EXTENDED SELECT maxdb_schema.REGEXP_REPLACE('test','t','') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select mariadb_schema.regexp_replace('test','t','') AS "maxdb_schema.REGEXP_REPLACE('test','t','')" +---------- +sql_mode='ORACLE' qualifier='oracle_schema.' +query +EXPLAIN EXTENDED SELECT oracle_schema.REGEXP_REPLACE('test','t','') +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select regexp_replace('test','t','') AS "oracle_schema.REGEXP_REPLACE('test','t','')" +Warnings: +Note 1003 select regexp_replace('test','t','') AS "oracle_schema.REGEXP_REPLACE('test','t','')" CALL p3('CONCAT_OPERATOR_ORACLE(''a'')'); ---------- sql_mode='' qualifier='' diff --git a/mysql-test/suite/compat/oracle/r/func_regexp_replace.result b/mysql-test/suite/compat/oracle/r/func_regexp_replace.result new file mode 100644 index 00000000000..7d0c5f79611 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/func_regexp_replace.result @@ -0,0 +1,34 @@ +SET sql_mode=ORACLE; +# +# MDEV-29095 REGEXP_REPLACE treats empty strings different than REPLACE in ORACLE mode +# +CREATE TABLE t1 (replacement VARCHAR(10)); +INSERT INTO t1 VALUES (NULL), (''); +SELECT replacement, REGEXP_REPLACE('abba','a',replacement) FROM t1 ORDER BY replacement; +replacement REGEXP_REPLACE('abba','a',replacement) +NULL bb + bb +DROP TABLE t1; +SELECT REGEXP_REPLACE('abba','a',null); +REGEXP_REPLACE('abba','a',null) +bb +EXPLAIN EXTENDED SELECT REPLACE('abba','a',null) ; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select replace('abba','a',NULL) AS "REPLACE('abba','a',null)" +CREATE VIEW v1 AS SELECT REPLACE('abba','a',null) ; +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select replace('abba','a',NULL) AS "REPLACE('abba','a',null)" latin1 latin1_swedish_ci +SELECT * FROM v1; +REPLACE('abba','a',null) +bb +SET sql_mode=DEFAULT; +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select oracle_schema.replace('abba','a',NULL) AS `REPLACE('abba','a',null)` latin1 latin1_swedish_ci +SELECT * FROM v1; +REPLACE('abba','a',null) +bb +DROP VIEW v1; diff --git a/mysql-test/suite/compat/oracle/t/func_qualified.test b/mysql-test/suite/compat/oracle/t/func_qualified.test index 842015dbbd6..f2c019ec063 100644 --- a/mysql-test/suite/compat/oracle/t/func_qualified.test +++ b/mysql-test/suite/compat/oracle/t/func_qualified.test @@ -165,6 +165,7 @@ CALL p3('TRIM(1,2)'); CALL p3('TRIM(''a'')'); CALL p3('TRIM(BOTH '' '' FROM ''a'')'); +CALL p3('REGEXP_REPLACE(''test'',''t'','''')'); # Deprecated compatibility XXX_ORACLE functions. # These functions are implemented as simple native functions diff --git a/mysql-test/suite/compat/oracle/t/func_regexp_replace.test b/mysql-test/suite/compat/oracle/t/func_regexp_replace.test new file mode 100644 index 00000000000..8841d524c4a --- /dev/null +++ b/mysql-test/suite/compat/oracle/t/func_regexp_replace.test @@ -0,0 +1,26 @@ +SET sql_mode=ORACLE; + +--echo # +--echo # MDEV-29095 REGEXP_REPLACE treats empty strings different than REPLACE in ORACLE mode +--echo # + +#SELECT REGEXP_REPLACE(null,'a','b') ; +#SELECT REGEXP_REPLACE('ab',null,'b') ; +#SELECT REGEXP_REPLACE('ab','a',null) ; +#SELECT REGEXP_REPLACE('ab',null,null) ; + +CREATE TABLE t1 (replacement VARCHAR(10)); +INSERT INTO t1 VALUES (NULL), (''); +SELECT replacement, REGEXP_REPLACE('abba','a',replacement) FROM t1 ORDER BY replacement; +DROP TABLE t1; + +SELECT REGEXP_REPLACE('abba','a',null); +EXPLAIN EXTENDED SELECT REPLACE('abba','a',null) ; + +CREATE VIEW v1 AS SELECT REPLACE('abba','a',null) ; +SHOW CREATE VIEW v1; +SELECT * FROM v1; +SET sql_mode=DEFAULT; +SHOW CREATE VIEW v1; +SELECT * FROM v1; +DROP VIEW v1; diff --git a/sql/item.h b/sql/item.h index 4e756f81c3f..3d971230413 100644 --- a/sql/item.h +++ b/sql/item.h @@ -904,6 +904,19 @@ public: expressions with subqueries in the ORDER/GROUP clauses. */ String *val_str() { return val_str(&str_value); } + String *val_str_null_to_empty(String *to) + { + String *res= val_str(to); + if (res) + return res; + to->set_charset(collation.collation); + to->length(0); + return to; + } + String *val_str_null_to_empty(String *to, bool null_to_empty) + { + return null_to_empty ? val_str_null_to_empty(to) : val_str(to); + } virtual Item_func *get_item_func() { return NULL; } const MY_LOCALE *locale_from_val_str(); diff --git a/sql/item_create.cc b/sql/item_create.cc index 43c869c05ef..12d7232f5f6 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -2666,7 +2666,10 @@ protected: class Create_func_regexp_replace : public Create_func_arg3 { public: - virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3); + Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3) override + { + return new (thd->mem_root) Item_func_regexp_replace(thd, arg1, arg2, arg3); + } static Create_func_regexp_replace s_singleton; @@ -2675,6 +2678,28 @@ protected: virtual ~Create_func_regexp_replace() = default; }; +Create_func_regexp_replace Create_func_regexp_replace::s_singleton; + + +class Create_func_regexp_replace_oracle : public Create_func_arg3 +{ +public: + Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3) override + { + return new (thd->mem_root) Item_func_regexp_replace_oracle(thd, arg1, + arg2, arg3); + } + + static Create_func_regexp_replace_oracle s_singleton; + +protected: + Create_func_regexp_replace_oracle() = default; + virtual ~Create_func_regexp_replace_oracle() = default; +}; + +Create_func_regexp_replace_oracle + Create_func_regexp_replace_oracle::s_singleton; + class Create_func_regexp_substr : public Create_func_arg2 { @@ -6464,15 +6489,6 @@ Create_func_regexp_instr::create_2_arg(THD *thd, Item *arg1, Item *arg2) } -Create_func_regexp_replace Create_func_regexp_replace::s_singleton; - -Item* -Create_func_regexp_replace::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3) -{ - return new (thd->mem_root) Item_func_regexp_replace(thd, arg1, arg2, arg3); -} - - Create_func_regexp_substr Create_func_regexp_substr::s_singleton; Item* @@ -7616,6 +7632,8 @@ const Native_func_registry func_array_oracle_overrides[] = { { STRING_WITH_LEN("LENGTH") }, BUILDER(Create_func_char_length)}, { { STRING_WITH_LEN("LPAD") }, BUILDER(Create_func_lpad_oracle)}, { { STRING_WITH_LEN("LTRIM") }, BUILDER(Create_func_ltrim_oracle)}, + { { STRING_WITH_LEN("REGEXP_REPLACE") }, + BUILDER(Create_func_regexp_replace_oracle)}, { { STRING_WITH_LEN("RPAD") }, BUILDER(Create_func_rpad_oracle)}, { { STRING_WITH_LEN("RTRIM") }, BUILDER(Create_func_rtrim_oracle)}, diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 0373d2a94a6..697d4fdf2ea 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1149,8 +1149,7 @@ bool Item_func_reverse::fix_length_and_dec() Fix that this works with binary strings when using USE_MB */ -String *Item_func_replace::val_str_internal(String *str, - String *empty_string_for_null) +String *Item_func_replace::val_str_internal(String *str, bool null_to_empty) { DBUG_ASSERT(fixed == 1); String *res,*res2,*res3; @@ -1168,13 +1167,8 @@ String *Item_func_replace::val_str_internal(String *str, res=args[0]->val_str(str); if (args[0]->null_value) goto null; - res2=args[1]->val_str(&tmp_value); - if (args[1]->null_value) - { - if (!empty_string_for_null) - goto null; - res2= empty_string_for_null; - } + if (!(res2= args[1]->val_str_null_to_empty(&tmp_value, null_to_empty))) + goto null; res->set_charset(collation.collation); #ifdef USE_MB @@ -1191,12 +1185,8 @@ String *Item_func_replace::val_str_internal(String *str, if (binary_cmp && (offset=res->strstr(*res2)) < 0) return res; #endif - if (!(res3=args[2]->val_str(&tmp_value2))) - { - if (!empty_string_for_null) - goto null; - res3= empty_string_for_null; - } + if (!(res3= args[2]->val_str_null_to_empty(&tmp_value2, null_to_empty))) + goto null; from_length= res2->length(); to_length= res3->length(); @@ -1279,7 +1269,7 @@ redo: } while ((offset=res->strstr(*res2,(uint) offset)) >= 0); } - if (empty_string_for_null && !res->length()) + if (null_to_empty && !res->length()) goto null; return res; @@ -1385,20 +1375,22 @@ bool Item_func_regexp_replace::append_replacement(String *str, } -String *Item_func_regexp_replace::val_str(String *str) +String *Item_func_regexp_replace::val_str_internal(String *str, + bool null_to_empty) { DBUG_ASSERT(fixed == 1); char buff0[MAX_FIELD_WIDTH]; char buff2[MAX_FIELD_WIDTH]; String tmp0(buff0,sizeof(buff0),&my_charset_bin); String tmp2(buff2,sizeof(buff2),&my_charset_bin); - String *source= args[0]->val_str(&tmp0); - String *replace= args[2]->val_str(&tmp2); + String *source, *replace; LEX_CSTRING src, rpl; int startoffset= 0; - if ((null_value= (args[0]->null_value || args[2]->null_value || - re.recompile(args[1])))) + if ((null_value= + (!(source= args[0]->val_str(&tmp0)) || + !(replace= args[2]->val_str_null_to_empty(&tmp2, null_to_empty)) || + re.recompile(args[1])))) return (String *) 0; if (!(source= re.convert_if_needed(source, &re.subject_converter)) || diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 826c7f784af..4fe7dd03d9c 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -353,12 +353,13 @@ public: class Item_func_replace :public Item_str_func { String tmp_value,tmp_value2; +protected: + String *val_str_internal(String *str, bool null_to_empty); public: Item_func_replace(THD *thd, Item *org, Item *find, Item *replace): Item_str_func(thd, org, find, replace) {} - String *val_str(String *to) { return val_str_internal(to, NULL); }; + String *val_str(String *to) { return val_str_internal(to, false); }; bool fix_length_and_dec(); - String *val_str_internal(String *str, String *empty_string_for_null); const Schema *schema() const { return &mariadb_schema; } void print(String *str, enum_query_type query_type) { @@ -377,7 +378,7 @@ class Item_func_replace_oracle :public Item_func_replace public: Item_func_replace_oracle(THD *thd, Item *org, Item *find, Item *replace): Item_func_replace(thd, org, find, replace) {} - String *val_str(String *to) { return val_str_internal(to, &tmp_emtpystr); }; + String *val_str(String *to) { return val_str_internal(to, true); }; const Schema *schema() const { return &oracle_schema_ref; } void print(String *str, enum_query_type query_type) { @@ -401,10 +402,18 @@ class Item_func_regexp_replace :public Item_str_func bool append_replacement(String *str, const LEX_CSTRING *source, const LEX_CSTRING *replace); +protected: + String *val_str_internal(String *str, bool null_to_empty); public: Item_func_regexp_replace(THD *thd, Item *a, Item *b, Item *c): Item_str_func(thd, a, b, c) {} + const Schema *schema() const { return &mariadb_schema; } + void print(String *str, enum_query_type query_type) + { + print_sql_mode_qualified_name(str, query_type); + print_args_parenthesized(str, query_type); + } void cleanup() { DBUG_ENTER("Item_func_regex::cleanup"); @@ -412,7 +421,10 @@ public: re.cleanup(); DBUG_VOID_RETURN; } - String *val_str(String *str); + String *val_str(String *str) + { + return val_str_internal(str, false); + } bool fix_fields(THD *thd, Item **ref); bool fix_length_and_dec(); const char *func_name() const { return "regexp_replace"; } @@ -420,6 +432,26 @@ public: }; +class Item_func_regexp_replace_oracle: public Item_func_regexp_replace +{ +public: + Item_func_regexp_replace_oracle(THD *thd, Item *a, Item *b, Item *c) + :Item_func_regexp_replace(thd, a, b, c) + {} + const Schema *schema() const { return &oracle_schema_ref; } + bool fix_length_and_dec() + { + bool rc= Item_func_regexp_replace::fix_length_and_dec(); + maybe_null= true; // Empty result is converted to NULL + return rc; + } + String *val_str(String *str) + { + return val_str_internal(str, true); + } +}; + + class Item_func_regexp_substr :public Item_str_func { Regexp_processor_pcre re; From 97fcafb9ece62cd813e2dfe05ba59787229ae04b Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 10 Jan 2024 15:35:25 +0400 Subject: [PATCH 49/61] MDEV-32837 long unique does not work like unique key when using replace write_record() when performing REPLACE has an optimization: - if the unique violation happened in the last unique key, then do UPDATE - otherwise, do DELETE+INSERT This patch changes the way of detecting if this optimization can be applied if the table has long (hash based) unique (i.e. UNIQUE..USING HASH) constraints. Problem: The old condition did not take into account that TABLE_SHARE and TABLE see long uniques differently: - TABLE_SHARE sees as HA_KEY_ALG_LONG_HASH and HA_NOSAME - TABLE sees as usual non-unique indexes So the old condition could erroneously decide that the UPDATE optimization is possible when there are still some unique hash constraints in the table. Fix: - If the current key is a long unique, it now works as follows: UPDATE can be done if the current long unique is the last long unique, and there are no in-engine (normal) uniques. - For in-engine uniques nothing changes, it still works as before: If the current key is an in-engine (normal) unique: UPDATE can be done if it is the last normal unique. --- mysql-test/main/long_unique_bugs.result | 15 +++ mysql-test/main/long_unique_bugs.test | 13 +++ .../long_unique_bugs_no_sp_protocol.result | 95 +++++++++++++++++++ .../main/long_unique_bugs_no_sp_protocol.test | 68 +++++++++++++ sql/sql_insert.cc | 25 ++++- 5 files changed, 213 insertions(+), 3 deletions(-) create mode 100644 mysql-test/main/long_unique_bugs_no_sp_protocol.result create mode 100644 mysql-test/main/long_unique_bugs_no_sp_protocol.test diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index 30ba3d0af9a..81482e68417 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -660,5 +660,20 @@ Table Op Msg_type Msg_text test.t1 check status OK drop table t1; # +# MDEV-32837 long unique does not work like unique key when using replace +# +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c INT, UNIQUE KEY `test` (b,c) USING HASH) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,1,1),(2,2,2); +REPLACE INTO t1 VALUES (3,1,1); +SELECT * FROM t1 ORDER BY a; +a b c +2 2 2 +3 1 1 +REPLACE INTO t1 VALUES (3,2,2); +SELECT * FROM t1; +a b c +3 2 2 +DROP TABLE t1; +# # End of 10.5 tests # diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index 12367b1deb8..2441dfa59e8 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -642,6 +642,19 @@ insert into t1 values (0); check table t1 extended; drop table t1; + +--echo # +--echo # MDEV-32837 long unique does not work like unique key when using replace +--echo # + +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c INT, UNIQUE KEY `test` (b,c) USING HASH) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,1,1),(2,2,2); +REPLACE INTO t1 VALUES (3,1,1); +SELECT * FROM t1 ORDER BY a; +REPLACE INTO t1 VALUES (3,2,2); +SELECT * FROM t1; +DROP TABLE t1; + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/long_unique_bugs_no_sp_protocol.result b/mysql-test/main/long_unique_bugs_no_sp_protocol.result new file mode 100644 index 00000000000..0776a130167 --- /dev/null +++ b/mysql-test/main/long_unique_bugs_no_sp_protocol.result @@ -0,0 +1,95 @@ +# +# Start of 10.5 tests +# +# +# MDEV-32837 long unique does not work like unique key when using replace +# +# +# Normal unique key + long unique key +# +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c INT, UNIQUE KEY `test` (b,c) USING HASH) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,1,1),(2,2,2); +FLUSH STATUS; +REPLACE INTO t1 VALUES (3,1,1); +SHOW STATUS WHERE Variable_name LIKE 'handler%' AND Value>0; +Variable_name Value +Handler_delete 1 +Handler_read_key 2 +Handler_read_rnd 1 +Handler_write 1 +SELECT * FROM t1 ORDER BY a; +a b c +2 2 2 +3 1 1 +FLUSH STATUS; +REPLACE INTO t1 VALUES (3,2,2); +SHOW STATUS WHERE Variable_name LIKE 'handler%' AND Value>0; +Variable_name Value +Handler_delete 1 +Handler_read_key 3 +Handler_read_rnd 2 +Handler_update 1 +Handler_write 1 +SELECT * FROM t1; +a b c +3 2 2 +DROP TABLE t1; +# +# Two long unique keys +# +CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE KEY a (a) USING HASH,UNIQUE KEY `test` (b,c) USING HASH) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,1,1),(2,2,2); +FLUSH STATUS; +REPLACE INTO t1 VALUES (3,1,1); +SHOW STATUS WHERE Variable_name LIKE 'handler%' AND Value>0; +Variable_name Value +Handler_read_key 3 +Handler_read_rnd 1 +Handler_update 1 +SELECT * FROM t1 ORDER BY a; +a b c +2 2 2 +3 1 1 +FLUSH STATUS; +REPLACE INTO t1 VALUES (3,2,2); +SHOW STATUS WHERE Variable_name LIKE 'handler%' AND Value>0; +Variable_name Value +Handler_delete 1 +Handler_read_key 4 +Handler_read_rnd 2 +Handler_update 1 +SELECT * FROM t1; +a b c +3 2 2 +DROP TABLE t1; +# +# One long unique key +# +CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE KEY `test` (b,c) USING HASH) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,1,1),(2,2,2); +FLUSH STATUS; +REPLACE INTO t1 VALUES (3,1,1); +SHOW STATUS WHERE Variable_name LIKE 'handler%' AND Value>0; +Variable_name Value +Handler_read_key 1 +Handler_read_rnd 1 +Handler_update 1 +SELECT * FROM t1 ORDER BY a; +a b c +2 2 2 +3 1 1 +FLUSH STATUS; +REPLACE INTO t1 VALUES (3,2,2); +SHOW STATUS WHERE Variable_name LIKE 'handler%' AND Value>0; +Variable_name Value +Handler_read_key 1 +Handler_read_rnd 1 +Handler_update 1 +SELECT * FROM t1; +a b c +3 1 1 +3 2 2 +DROP TABLE t1; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/long_unique_bugs_no_sp_protocol.test b/mysql-test/main/long_unique_bugs_no_sp_protocol.test new file mode 100644 index 00000000000..6bfa6182096 --- /dev/null +++ b/mysql-test/main/long_unique_bugs_no_sp_protocol.test @@ -0,0 +1,68 @@ +if (`SELECT $SP_PROTOCOL > 0`) +{ + --skip Test requires: sp-protocol disabled +} + + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-32837 long unique does not work like unique key when using replace +--echo # + +# This test produces different Handler commands in the SHOW STATUS output +# with --sp-protocol. So it's here, in this *.test file with --sp-protocol disabled. + +--echo # +--echo # Normal unique key + long unique key +--echo # + +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c INT, UNIQUE KEY `test` (b,c) USING HASH) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,1,1),(2,2,2); +FLUSH STATUS; +REPLACE INTO t1 VALUES (3,1,1); +SHOW STATUS WHERE Variable_name LIKE 'handler%' AND Value>0; +SELECT * FROM t1 ORDER BY a; +FLUSH STATUS; +REPLACE INTO t1 VALUES (3,2,2); +SHOW STATUS WHERE Variable_name LIKE 'handler%' AND Value>0; +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # Two long unique keys +--echo # + +CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE KEY a (a) USING HASH,UNIQUE KEY `test` (b,c) USING HASH) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,1,1),(2,2,2); +FLUSH STATUS; +REPLACE INTO t1 VALUES (3,1,1); +SHOW STATUS WHERE Variable_name LIKE 'handler%' AND Value>0; +SELECT * FROM t1 ORDER BY a; +FLUSH STATUS; +REPLACE INTO t1 VALUES (3,2,2); +SHOW STATUS WHERE Variable_name LIKE 'handler%' AND Value>0; +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # One long unique key +--echo # + +CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE KEY `test` (b,c) USING HASH) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,1,1),(2,2,2); +FLUSH STATUS; +REPLACE INTO t1 VALUES (3,1,1); +SHOW STATUS WHERE Variable_name LIKE 'handler%' AND Value>0; +SELECT * FROM t1 ORDER BY a; +FLUSH STATUS; +REPLACE INTO t1 VALUES (3,2,2); +SHOW STATUS WHERE Variable_name LIKE 'handler%' AND Value>0; +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index ec9e379768f..b3314e075f0 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1728,7 +1728,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, /* Check if there is more uniq keys after field */ -static int last_uniq_key(TABLE *table,uint keynr) +static int last_uniq_key(TABLE *table, const KEY *key, uint keynr) { /* When an underlying storage engine informs that the unique key @@ -1748,7 +1748,7 @@ static int last_uniq_key(TABLE *table,uint keynr) return 0; while (++keynr < table->s->keys) - if (table->key_info[keynr].flags & HA_NOSAME) + if (key[keynr].flags & HA_NOSAME) return 0; return 1; } @@ -2064,8 +2064,27 @@ int write_record(THD *thd, TABLE *table, COPY_INFO *info, select_result *sink) tables which have ON UPDATE but have no ON DELETE triggers, we just should not expose this fact to users by invoking ON UPDATE triggers. + + Note, TABLE_SHARE and TABLE see long uniques differently: + - TABLE_SHARE sees as HA_KEY_ALG_LONG_HASH and HA_NOSAME + - TABLE sees as usual non-unique indexes */ - if (last_uniq_key(table,key_nr) && + bool is_long_unique= table->s->key_info && + table->s->key_info[key_nr].algorithm == + HA_KEY_ALG_LONG_HASH; + if ((is_long_unique ? + /* + We have a long unique. Test that there are no in-engine + uniques and the current long unique is the last long unique. + */ + !(table->key_info[0].flags & HA_NOSAME) && + last_uniq_key(table, table->s->key_info, key_nr) : + /* + We have a normal key - not a long unique. + Test is the current normal key is unique and + it is the last normal unique. + */ + last_uniq_key(table, table->key_info, key_nr)) && !table->file->referenced_by_foreign_key() && (!table->triggers || !table->triggers->has_delete_triggers())) { From 1070575a890ad5fa52af01297b439073f63846a5 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Mon, 8 Jan 2024 17:50:19 +1100 Subject: [PATCH 50/61] MDEV-33191 spider: fix dbton_id when iterating over links There are two array fields in spider_share with similar names: share->use_sql_dbton_ids that maps from i to the i-th dbton used by share. Thus it should be used only when i iterates over all distinct dbtons used by share. share->sql_dbton_ids that maps from i to the dbton used by the i-th link of the share. Thus it should be used only when i iterates over all links of a share. We correct instances where share->sql_dbton_ids should be used instead of share->use_sql_dbton_ids. --- storage/spider/ha_spider.cc | 4 ++-- .../mysql-test/spider/bugfix/r/mdev_33191.result | 10 ++++++++++ .../spider/mysql-test/spider/bugfix/t/mdev_33191.test | 11 +++++++++++ storage/spider/spd_db_conn.cc | 2 +- storage/spider/spd_db_include.h | 6 ++++++ storage/spider/spd_include.h | 10 ++++++++++ 6 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_33191.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_33191.test diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 24ee6c5e902..89d86a9ca75 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -8392,7 +8392,7 @@ int ha_spider::ft_read_internal( } } else { #endif - uint dbton_id = share->use_sql_dbton_ids[roop_count]; + uint dbton_id = share->sql_dbton_ids[roop_count]; spider_db_handler *dbton_hdl = dbton_handler[dbton_id]; SPIDER_CONN *conn = conns[roop_count]; pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); @@ -13135,7 +13135,7 @@ int ha_spider::drop_tmp_tables() ) { if (spider_bit_is_set(result_list.tmp_table_created, roop_count)) { - uint dbton_id = share->use_sql_dbton_ids[roop_count]; + uint dbton_id = share->sql_dbton_ids[roop_count]; spider_db_handler *dbton_hdl = dbton_handler[dbton_id]; SPIDER_CONN *conn = conns[roop_count]; pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_33191.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_33191.result new file mode 100644 index 00000000000..7ab2e952213 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_33191.result @@ -0,0 +1,10 @@ +INSTALL SONAME 'ha_spider'; +set spider_same_server_link=on; +CREATE TABLE t2(c INT); +CREATE TABLE t1(c INT) ENGINE=Spider COMMENT='socket "$SOCKET", user "root", table "t2 t3"'; +ALTER TABLE t1 ENGINE=Spider; +TRUNCATE TABLE t1; +ERROR 42S02: Table 'test.t3' doesn't exist +drop table t1, t2; +Warnings: +Warning 1620 Plugin is busy and will be uninstalled on shutdown diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_33191.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_33191.test new file mode 100644 index 00000000000..90709127f46 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_33191.test @@ -0,0 +1,11 @@ +INSTALL SONAME 'ha_spider'; +set spider_same_server_link=on; +CREATE TABLE t2(c INT); +--let $SOCKET=`SELECT @@global.socket` +evalp CREATE TABLE t1(c INT) ENGINE=Spider COMMENT='socket "$SOCKET", user "root", table "t2 t3"'; +ALTER TABLE t1 ENGINE=Spider; +--error ER_NO_SUCH_TABLE +TRUNCATE TABLE t1; +drop table t1, t2; +--disable_query_log +--source ../../include/clean_up_spider.inc diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index 5b96bfec3cd..52fde02ad0c 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -8215,7 +8215,7 @@ int spider_db_delete_all_rows( spider->conn_link_idx, roop_count, share->link_count, SPIDER_LINK_STATUS_RECOVERY) ) { - uint dbton_id = share->use_sql_dbton_ids[roop_count]; + uint dbton_id = share->sql_dbton_ids[roop_count]; spider_db_handler *dbton_hdl = spider->dbton_handler[dbton_id]; conn = spider->conns[roop_count]; pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h index ee6202bf334..5add9fac3e4 100644 --- a/storage/spider/spd_db_include.h +++ b/storage/spider/spd_db_include.h @@ -1836,6 +1836,12 @@ enum spider_db_access_type SPIDER_DB_ACCESS_TYPE_NOSQL }; +/* + Type of singletons based on the type of the remote database. + + All such singletons are stored in the array `spider_dbton', see + `spider_db_init()'. +*/ typedef struct st_spider_dbton { uint dbton_id; diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h index f3df1ed8378..0e72ce26696 100644 --- a/storage/spider/spd_include.h +++ b/storage/spider/spd_include.h @@ -1358,6 +1358,7 @@ typedef struct st_spider_share uint *hs_read_conn_keys_lengths; uint *hs_write_conn_keys_lengths; #endif + /* The index in `spider_dbton' of each data node link. */ uint *sql_dbton_ids; #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) uint *hs_dbton_ids; @@ -1447,14 +1448,23 @@ typedef struct st_spider_share uchar dbton_bitmap[spider_bitmap_size(SPIDER_DBTON_SIZE)]; spider_db_share *dbton_share[SPIDER_DBTON_SIZE]; uint use_dbton_count; + /* Actual size is `use_dbton_count'. Values are the indices of item + in `spider_dbton'. */ uint use_dbton_ids[SPIDER_DBTON_SIZE]; + /* Inverse map of `use_dbton_ids'. */ uint dbton_id_to_seq[SPIDER_DBTON_SIZE]; uint use_sql_dbton_count; + /* Actual size is `use_sql_dbton_count'. Values are the indices of + item in `spider_dbton'. */ uint use_sql_dbton_ids[SPIDER_DBTON_SIZE]; + /* Inverse map of `use_sql_dbton_ids'. */ uint sql_dbton_id_to_seq[SPIDER_DBTON_SIZE]; #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) uint use_hs_dbton_count; + /* Actual size is `use_hs_dbton_count'. Values are the indices of + item in `spider_dbton'. */ uint use_hs_dbton_ids[SPIDER_DBTON_SIZE]; + /* Inverse map of `use_hs_dbton_ids'. */ uint hs_dbton_id_to_seq[SPIDER_DBTON_SIZE]; #endif From c9c4f15e99c38057b90b923f4a39ef0071cad79f Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 25 Jan 2024 14:44:42 +0100 Subject: [PATCH 51/61] Remove bogus "perl not found" on Windows. Testing exit code from popen(), comparing it with 1, and deciding that perl.exe is not there, is a) wrong conclusion, and b) uninteresting, because MTR always runs with perl, and with MTR_PERL set. Background: Recent change in 7af50e4df456761c433838f0e65e88b9117f298c introduced exit code 1 from perl snippet, that broke Windows CI. Do not want to debug this ever again. --- client/mysqltest.cc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index b839ae02606..545c2c9da1e 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -4648,15 +4648,11 @@ void do_perl(struct st_command *command) /* Check for error code that indicates perl could not be started */ int exstat= WEXITSTATUS(error); -#ifdef _WIN32 - if (exstat == 1) - /* Text must begin 'perl not found' as mtr looks for it */ - abort_not_supported_test("perl not found in path or did not start"); -#else +#ifndef _WIN32 if (exstat == 127) abort_not_supported_test("perl not found in path"); -#endif else +#endif handle_command_error(command, exstat, my_errno); } dynstr_free(&ds_delimiter); From 0f59810b9944929d2b3ffb64f6d197cf9a20e358 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 10 Sep 2021 02:20:16 +0200 Subject: [PATCH 52/61] MDEV-26579 Support minor MSI in Windows installer. With this patch, 4-component MSI version can be used, e.g by setting TINY_VERSION variable in CMake, or by adding a string, e.g MYSQL_VERSION_EXTRA=-2 which sets TINY_VERSION to 2, and also changes the package name. The 4-component MSI versions do not support MSI major upgrades, only minor ones, i.e do not reinstall components, just update existing ones based on versioning rules. To support these rules, add DefaultVersion for the files that won't otherwise be versioned - headers, static and import libraries, pdbs, text - xml, python and perl scripts Also silence WiX warning that MSI won't store hashes for those files anymore. --- cmake/mysql_version.cmake | 4 +++- win/packaging/create_msi.cmake | 10 +++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cmake/mysql_version.cmake b/cmake/mysql_version.cmake index cb12bf14b86..2924d6a0096 100644 --- a/cmake/mysql_version.cmake +++ b/cmake/mysql_version.cmake @@ -55,7 +55,9 @@ IF(NOT "${MAJOR_VERSION}" MATCHES "[0-9]+" OR NOT "${PATCH_VERSION}" MATCHES "[0-9]+") MESSAGE(FATAL_ERROR "VERSION file cannot be parsed.") ENDIF() - + IF((NOT TINY_VERSION) AND (EXTRA_VERSION MATCHES "[\\-][0-9]+")) + STRING(REPLACE "-" "" TINY_VERSION "${EXTRA_VERSION}") + ENDIF() SET(VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}${EXTRA_VERSION}") MESSAGE(STATUS "MariaDB ${VERSION}") SET(MYSQL_BASE_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}" CACHE INTERNAL "MySQL Base version") diff --git a/win/packaging/create_msi.cmake b/win/packaging/create_msi.cmake index f992915cd22..1b6f66d0f2c 100644 --- a/win/packaging/create_msi.cmake +++ b/win/packaging/create_msi.cmake @@ -248,6 +248,13 @@ FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) FILE(APPEND ${file} "\n") SET(NONEXEFILES) + FOREACH(v MAJOR_VERSION MINOR_VERSION PATCH_VERSION TINY_VERSION) + IF(NOT ${v}) + MESSAGE(FATAL_ERROR "${v} is not set") + ENDIF() + ENDFOREACH() + SET(default_version "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}.${TINY_VERSION}") + FOREACH(f ${all_files}) IF(NOT IS_DIRECTORY ${f}) FILE(RELATIVE_PATH rel ${topdir} ${f}) @@ -267,6 +274,7 @@ FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) FILE(APPEND ${file} " ${${id}.COMPONENT_CONDITION}\n") ENDIF() FILE(APPEND ${file} " \n${${id}.FILE_EXTRA}") ELSE() @@ -396,7 +404,7 @@ ENDIF() EXECUTE_PROCESS( COMMAND ${LIGHT_EXECUTABLE} -v -ext WixUIExtension -ext WixUtilExtension - -ext WixFirewallExtension -sice:ICE61 ${SILENCE_VCREDIST_MSM_WARNINGS} + -ext WixFirewallExtension -sice:ICE61 -sw1103 ${SILENCE_VCREDIST_MSM_WARNINGS} mysql_server.wixobj extra.wixobj -out ${CPACK_PACKAGE_FILE_NAME}.msi ${EXTRA_LIGHT_ARGS} ) From b62f25c6509c1b3c0a055316403850b0a8015179 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 10 Sep 2021 09:38:40 +0200 Subject: [PATCH 53/61] MDEV-26579 fixup --- cmake/mysql_version.cmake | 8 +++----- win/packaging/create_msi.cmake | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cmake/mysql_version.cmake b/cmake/mysql_version.cmake index 2924d6a0096..2d4ed95478f 100644 --- a/cmake/mysql_version.cmake +++ b/cmake/mysql_version.cmake @@ -50,13 +50,15 @@ MACRO(GET_MYSQL_VERSION) MYSQL_GET_CONFIG_VALUE("MYSQL_VERSION_EXTRA" EXTRA_VERSION) MYSQL_GET_CONFIG_VALUE("SERVER_MATURITY" SERVER_MATURITY) -IF(NOT "${MAJOR_VERSION}" MATCHES "[0-9]+" OR + IF(NOT "${MAJOR_VERSION}" MATCHES "[0-9]+" OR NOT "${MINOR_VERSION}" MATCHES "[0-9]+" OR NOT "${PATCH_VERSION}" MATCHES "[0-9]+") MESSAGE(FATAL_ERROR "VERSION file cannot be parsed.") ENDIF() IF((NOT TINY_VERSION) AND (EXTRA_VERSION MATCHES "[\\-][0-9]+")) STRING(REPLACE "-" "" TINY_VERSION "${EXTRA_VERSION}") + ELSE() + SET(TINY_VERSION "0") ENDIF() SET(VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}${EXTRA_VERSION}") MESSAGE(STATUS "MariaDB ${VERSION}") @@ -120,10 +122,6 @@ ENDIF() IF(MSVC) # Tiny version is used to identify the build, it can be set with cmake -DTINY_VERSION= # to bzr revno for example (in the CI builds) - IF(NOT TINY_VERSION) - SET(TINY_VERSION "0") - ENDIF() - GET_FILENAME_COMPONENT(MYSQL_CMAKE_SCRIPT_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) SET(FILETYPE VFT_APP) diff --git a/win/packaging/create_msi.cmake b/win/packaging/create_msi.cmake index 1b6f66d0f2c..83a8882f823 100644 --- a/win/packaging/create_msi.cmake +++ b/win/packaging/create_msi.cmake @@ -249,8 +249,8 @@ FUNCTION(TRAVERSE_FILES dir topdir file file_comp dir_root) SET(NONEXEFILES) FOREACH(v MAJOR_VERSION MINOR_VERSION PATCH_VERSION TINY_VERSION) - IF(NOT ${v}) - MESSAGE(FATAL_ERROR "${v} is not set") + IF(NOT DEFINED ${v}) + MESSAGE(FATAL_ERROR "${v} is not defined") ENDIF() ENDFOREACH() SET(default_version "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}.${TINY_VERSION}") From 220c0fb4054c57fe7f6992e0688af4fb97e13151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 26 Jan 2024 11:21:14 +0200 Subject: [PATCH 54/61] MDEV-33317 [Warning] InnoDB: Could not free any blocks in the buffer pool! Let us suppress this timing-sensitive warning globally. We added it in commit d34479dc664d4cbd4e9dad6b0f92d7c8e55595d1 (MDEV-33053) so that in case InnoDB hangs due to running out of buffer pool, there would be a warning about it. On a heavily loaded system that is running with a small buffer pool, these warnings may be occasionally issued while page writes are in progress. --- mysql-test/mariadb-test-run.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/mariadb-test-run.pl b/mysql-test/mariadb-test-run.pl index 2750e10ecf5..3253de4185f 100755 --- a/mysql-test/mariadb-test-run.pl +++ b/mysql-test/mariadb-test-run.pl @@ -4454,6 +4454,7 @@ sub extract_warning_lines ($$) { qr/InnoDB: Warning: a long semaphore wait:/, qr/InnoDB: Dumping buffer pool.*/, qr/InnoDB: Buffer pool.*/, + qr/InnoDB: Could not free any blocks in the buffer pool!/, qr/InnoDB: Warning: Writer thread is waiting this semaphore:/, qr/InnoDB: innodb_open_files .* should not be greater than/, qr/Slave: Unknown table 't1' .* 1051/, From e96a05948b98c4e034ad31eef55936d349d141e7 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 26 Jan 2024 10:48:54 +0100 Subject: [PATCH 55/61] update C/C --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index f1a72768d42..9155b19b462 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit f1a72768d4256416e5c0bf01b254c303f6135bd0 +Subproject commit 9155b19b462ac15fc69d0b58ae51370b7523ced5 From daca0c059b87d30ca067ab388983865fe238ac22 Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Fri, 26 Jan 2024 12:24:50 +0530 Subject: [PATCH 56/61] fix failing test on buildbot for MDEV-27087 --- plugin/sql_errlog/sql_errlog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/sql_errlog/sql_errlog.c b/plugin/sql_errlog/sql_errlog.c index d668ed8779b..83f80327640 100644 --- a/plugin/sql_errlog/sql_errlog.c +++ b/plugin/sql_errlog/sql_errlog.c @@ -107,7 +107,7 @@ static void log_sql_errors(MYSQL_THD thd __attribute__((unused)), { if (event->database.str) { - logger_printf(logfile, "%04d-%02d-%02d %2d:%02d:%02d %llu " + logger_printf(logfile, "%04d-%02d-%02d %2d:%02d:%02d %lu " "%s %`s ERROR %d: %s : %s \n", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, event->general_thread_id, event->general_user, event->database.str, @@ -115,7 +115,7 @@ static void log_sql_errors(MYSQL_THD thd __attribute__((unused)), } else { - logger_printf(logfile, "%04d-%02d-%02d %2d:%02d:%02d %llu " + logger_printf(logfile, "%04d-%02d-%02d %2d:%02d:%02d %lu " "%s %s ERROR %d: %s : %s \n", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, event->general_thread_id, event->general_user, "NULL", From 112eb14f7e0611371522f1555af2c74bd3eb3247 Mon Sep 17 00:00:00 2001 From: Brandon Nesterenko Date: Fri, 26 Jan 2024 10:34:40 -0700 Subject: [PATCH 57/61] MDEV-27850: rpl_seconds_behind_master_spike debug_sync fix A debug_sync signal could remain for the SQL thread that should have begun a wait_for upon seeing a GTID event, but would instead see the old signal and continue on without waiting. This broke an "idle" condition in SHOW SLAVE STATUS which should have automatically negated Seconds_Behind_Master. Instead, because the SQL thread had already processed the GTID event, it set sql_thread_caught_up to false, and thereby calculated the value of Seconds_behind_master, when the test expected 0. This patch fixes this by resetting the debug_sync state before creating a new transaction which sends a GTID event to the replica --- mysql-test/suite/rpl/t/rpl_seconds_behind_master_spike.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/rpl/t/rpl_seconds_behind_master_spike.test b/mysql-test/suite/rpl/t/rpl_seconds_behind_master_spike.test index d96863a14c2..9e73e6678a2 100644 --- a/mysql-test/suite/rpl/t/rpl_seconds_behind_master_spike.test +++ b/mysql-test/suite/rpl/t/rpl_seconds_behind_master_spike.test @@ -132,6 +132,7 @@ while (!$caught_up) } sleep 0.1; } +set debug_sync="RESET"; --enable_query_log --connection master From e20693c167911872afc531d5e86ca197dc05dd60 Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 27 Jan 2024 16:29:16 +0200 Subject: [PATCH 58/61] Fixed some wrong printf() usage after changing m_table_id to ulonglong This caused some crashes on 32 bit platforms. --- sql/log_event_client.cc | 5 +++-- sql/log_event_old.cc | 11 ++++++----- sql/log_event_server.cc | 8 ++++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/sql/log_event_client.cc b/sql/log_event_client.cc index 3b7df6e0f66..69f29cb09e7 100644 --- a/sql/log_event_client.cc +++ b/sql/log_event_client.cc @@ -1502,8 +1502,9 @@ bool Rows_log_event::print_verbose(IO_CACHE *file, if (!(map= print_event_info->m_table_map.get_table(m_table_id)) || !(td= map->create_table_def())) { - return (my_b_printf(file, "### Row event for unknown table #%llu", - (ulonglong) m_table_id)); + char llbuff[22]; + return (my_b_printf(file, "### Row event for unknown table #%s", + ullstr(m_table_id, llbuff))); } /* If the write rows event contained no values for the AI */ diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index b7325225b0a..dff4ca29f6f 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1251,7 +1251,7 @@ Old_rows_log_event::Old_rows_log_event(const uchar *buf, uint event_len, const uchar* const ptr_rows_data= (const uchar*) ptr_after_width; size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf); - DBUG_PRINT("info",("m_table_id: %lu m_flags: %d m_width: %lu data_size: %zu", + DBUG_PRINT("info",("m_table_id: %llu m_flags: %d m_width: %lu data_size: %zu", m_table_id, m_flags, m_width, data_size)); DBUG_DUMP("rows_data", (uchar*) ptr_rows_data, data_size); @@ -1790,7 +1790,7 @@ bool Old_rows_log_event::write_data_header() DBUG_ASSERT(m_table_id != UINT32_MAX); DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", { - int4store(buf + 0, m_table_id); + int4store(buf + 0, (ulong) m_table_id); int2store(buf + 4, m_flags); return write_data(buf, 6); }); @@ -1837,7 +1837,7 @@ void Old_rows_log_event::pack_info(Protocol *protocol) char const *const flagstr= get_flags(STMT_END_F) ? " flags: STMT_END_F" : ""; size_t bytes= my_snprintf(buf, sizeof(buf), - "table_id: %lu%s", m_table_id, flagstr); + "table_id: %llu%s", m_table_id, flagstr); protocol->store(buf, bytes, &my_charset_bin); } #endif @@ -1859,9 +1859,10 @@ bool Old_rows_log_event::print_helper(FILE *file, if (!print_event_info->short_form) { + char llbuff[22]; if (print_header(head, print_event_info, !do_print_encoded) || - my_b_printf(head, "\t%s: table id %lu%s\n", - name, m_table_id, + my_b_printf(head, "\t%s: table id %s%s\n", + name, ullstr(m_table_id, llbuff), do_print_encoded ? " flags: STMT_END_F" : "") || print_base64(body, print_event_info, do_print_encoded)) goto err; diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index 3e7fcc9df85..96e5866e0cc 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -6074,7 +6074,7 @@ bool Rows_log_event::write_data_header() DBUG_ASSERT(m_table_id != UINT32_MAX); DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", { - int4store(buf + 0, m_table_id); + int4store(buf + 0, (ulong) m_table_id); int2store(buf + 4, m_flags); return (write_data(buf, 6)); }); @@ -6588,7 +6588,7 @@ int Table_map_log_event::do_apply_event(rpl_group_info *rgi) char buf[256]; my_snprintf(buf, sizeof(buf), - "Found table map event mapping table id %u which " + "Found table map event mapping table id %llu which " "was already mapped but with different settings.", table_list->table_id); @@ -6633,7 +6633,7 @@ bool Table_map_log_event::write_data_header() uchar buf[TABLE_MAP_HEADER_LEN]; DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", { - int4store(buf + 0, m_table_id); + int4store(buf + 0, (ulong) m_table_id); int2store(buf + 4, m_flags); return (write_data(buf, 6)); }); @@ -7069,7 +7069,7 @@ void Table_map_log_event::pack_info(Protocol *protocol) { char buf[256]; size_t bytes= my_snprintf(buf, sizeof(buf), - "table_id: %llu (%s.%s)", + "table_id: %llu (%s.%s)", m_table_id, m_dbnam, m_tblnam); protocol->store(buf, bytes, &my_charset_bin); } From ed76a2e8ac265792f6ca4e49f4c8e04898fb7889 Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 27 Jan 2024 16:32:49 +0200 Subject: [PATCH 59/61] Updated some 32 bit result files in sys_vars --- .../r/sysvars_server_embedded,32bit.rdiff | 170 ++++++++--------- .../r/sysvars_server_notembedded,32bit.rdiff | 175 +++++++++--------- 2 files changed, 177 insertions(+), 168 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff index 4ebd48ad6bd..a8aa785fcd9 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff @@ -1,5 +1,5 @@ ---- sysvars_server_embedded.result -+++ sysvars_server_embedded.result +--- suite/sys_vars/r/sysvars_server_embedded.result ++++ suite/sys_vars/r/sysvars_server_embedded,32bit.reject @@ -34,7 +34,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME ARIA_BLOCK_SIZE @@ -290,16 +290,7 @@ VARIABLE_COMMENT Precision of the result of '/' operator will be increased on that value NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 38 -@@ -914,7 +914,7 @@ - COMMAND_LINE_ARGUMENT REQUIRED - VARIABLE_NAME EXPIRE_LOGS_DAYS - VARIABLE_SCOPE GLOBAL --VARIABLE_TYPE BIGINT UNSIGNED -+VARIABLE_TYPE INT UNSIGNED - VARIABLE_COMMENT If non-zero, binary logs will be purged after expire_logs_days days; possible purges happen at startup and at binary log rotation - NUMERIC_MIN_VALUE 0 - NUMERIC_MAX_VALUE 99 -@@ -944,7 +944,7 @@ +@@ -954,7 +954,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME EXTRA_MAX_CONNECTIONS VARIABLE_SCOPE GLOBAL @@ -723,6 +714,15 @@ NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 @@ -2274,7 +2274,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME OPTIMIZER_ADJUST_SECONDARY_KEY_COSTS + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT 0 = No changes. 1 = Update secondary key costs for ranges to be at least 5x of clustered primary key costs. 2 = Remove 'max_seek optimization' for secondary keys and slight adjustment of filter cost. This option will be deleted in MariaDB 11.0 as it is not needed with the new 11.0 optimizer. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 2 +@@ -2284,7 +2284,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_MAX_SEL_ARGS VARIABLE_SCOPE SESSION @@ -731,7 +731,7 @@ VARIABLE_COMMENT The maximum number of SEL_ARG objects created when optimizing a range. If more objects would be needed, the range will not be used by the optimizer. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2284,7 +2284,7 @@ +@@ -2294,7 +2294,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_MAX_SEL_ARG_WEIGHT VARIABLE_SCOPE SESSION @@ -740,7 +740,7 @@ VARIABLE_COMMENT The maximum weight of the SEL_ARG graph. Set to 0 for no limit NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2294,7 +2294,7 @@ +@@ -2304,7 +2304,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_PRUNE_LEVEL VARIABLE_SCOPE SESSION @@ -749,7 +749,7 @@ VARIABLE_COMMENT Controls the heuristic(s) applied during query optimization to prune less-promising partial plans from the optimizer search space. Meaning: 0 - do not apply any heuristic, thus perform exhaustive search; 1 - prune plans based on number of retrieved rows NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1 -@@ -2304,7 +2304,7 @@ +@@ -2314,7 +2314,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_SEARCH_DEPTH VARIABLE_SCOPE SESSION @@ -758,7 +758,7 @@ VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 62 -@@ -2314,7 +2314,7 @@ +@@ -2324,7 +2324,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_SELECTIVITY_SAMPLING_LIMIT VARIABLE_SCOPE SESSION @@ -767,7 +767,7 @@ VARIABLE_COMMENT Controls number of record samples to check condition selectivity NUMERIC_MIN_VALUE 10 NUMERIC_MAX_VALUE 4294967295 -@@ -2344,17 +2344,17 @@ +@@ -2354,17 +2354,17 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_TRACE_MAX_MEM_SIZE VARIABLE_SCOPE SESSION @@ -788,7 +788,7 @@ VARIABLE_COMMENT Controls selectivity of which conditions the optimizer takes into account to calculate cardinality of a partial join when it searches for the best execution plan Meaning: 1 - use selectivity of index backed range conditions to calculate the cardinality of a partial join if the last joined table is accessed by full table scan or an index scan, 2 - use selectivity of index backed range conditions to calculate the cardinality of a partial join in any case, 3 - additionally always use selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join, 4 - use histograms to calculate selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join.5 - additionally use selectivity of certain non-range predicates calculated on record samples NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 5 -@@ -2374,7 +2374,7 @@ +@@ -2384,7 +2384,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME PERFORMANCE_SCHEMA_ACCOUNTS_SIZE VARIABLE_SCOPE GLOBAL @@ -797,7 +797,7 @@ VARIABLE_COMMENT Maximum number of instrumented user@host accounts. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2384,7 +2384,7 @@ +@@ -2394,7 +2394,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_DIGESTS_SIZE VARIABLE_SCOPE GLOBAL @@ -806,7 +806,7 @@ VARIABLE_COMMENT Size of the statement digest. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2394,7 +2394,7 @@ +@@ -2404,7 +2404,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STAGES_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -815,7 +815,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_STAGES_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2404,7 +2404,7 @@ +@@ -2414,7 +2414,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STAGES_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -824,7 +824,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STAGES_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2414,7 +2414,7 @@ +@@ -2424,7 +2424,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STATEMENTS_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -833,7 +833,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_STATEMENTS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2424,7 +2424,7 @@ +@@ -2434,7 +2434,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STATEMENTS_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -842,7 +842,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2434,7 +2434,7 @@ +@@ -2444,7 +2444,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_TRANSACTIONS_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -851,7 +851,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_TRANSACTIONS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2444,7 +2444,7 @@ +@@ -2454,7 +2454,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_TRANSACTIONS_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -860,7 +860,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_TRANSACTIONS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2454,7 +2454,7 @@ +@@ -2464,7 +2464,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_WAITS_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -869,7 +869,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_WAITS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2464,7 +2464,7 @@ +@@ -2474,7 +2474,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_WAITS_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -878,7 +878,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_WAITS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2474,7 +2474,7 @@ +@@ -2484,7 +2484,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_HOSTS_SIZE VARIABLE_SCOPE GLOBAL @@ -887,7 +887,7 @@ VARIABLE_COMMENT Maximum number of instrumented hosts. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2484,7 +2484,7 @@ +@@ -2494,7 +2494,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_COND_CLASSES VARIABLE_SCOPE GLOBAL @@ -896,7 +896,7 @@ VARIABLE_COMMENT Maximum number of condition instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2494,7 +2494,7 @@ +@@ -2504,7 +2504,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_COND_INSTANCES VARIABLE_SCOPE GLOBAL @@ -905,7 +905,7 @@ VARIABLE_COMMENT Maximum number of instrumented condition objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2504,7 +2504,7 @@ +@@ -2514,7 +2514,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_DIGEST_LENGTH VARIABLE_SCOPE GLOBAL @@ -914,7 +914,7 @@ VARIABLE_COMMENT Maximum length considered for digest text, when stored in performance_schema tables. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2514,7 +2514,7 @@ +@@ -2524,7 +2524,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_CLASSES VARIABLE_SCOPE GLOBAL @@ -923,7 +923,7 @@ VARIABLE_COMMENT Maximum number of file instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2524,7 +2524,7 @@ +@@ -2534,7 +2534,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_HANDLES VARIABLE_SCOPE GLOBAL @@ -932,7 +932,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented files. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2534,7 +2534,7 @@ +@@ -2544,7 +2544,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_INSTANCES VARIABLE_SCOPE GLOBAL @@ -941,7 +941,7 @@ VARIABLE_COMMENT Maximum number of instrumented files. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2544,7 +2544,7 @@ +@@ -2554,7 +2554,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_INDEX_STAT VARIABLE_SCOPE GLOBAL @@ -950,7 +950,7 @@ VARIABLE_COMMENT Maximum number of index statistics for instrumented tables. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2554,7 +2554,7 @@ +@@ -2564,7 +2564,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MEMORY_CLASSES VARIABLE_SCOPE GLOBAL @@ -959,7 +959,7 @@ VARIABLE_COMMENT Maximum number of memory pool instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1024 -@@ -2564,7 +2564,7 @@ +@@ -2574,7 +2574,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_METADATA_LOCKS VARIABLE_SCOPE GLOBAL @@ -968,7 +968,7 @@ VARIABLE_COMMENT Maximum number of metadata locks. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2574,7 +2574,7 @@ +@@ -2584,7 +2584,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MUTEX_CLASSES VARIABLE_SCOPE GLOBAL @@ -977,7 +977,7 @@ VARIABLE_COMMENT Maximum number of mutex instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2584,7 +2584,7 @@ +@@ -2594,7 +2594,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MUTEX_INSTANCES VARIABLE_SCOPE GLOBAL @@ -986,7 +986,7 @@ VARIABLE_COMMENT Maximum number of instrumented MUTEX objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2594,7 +2594,7 @@ +@@ -2604,7 +2604,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_PREPARED_STATEMENTS_INSTANCES VARIABLE_SCOPE GLOBAL @@ -995,7 +995,7 @@ VARIABLE_COMMENT Maximum number of instrumented prepared statements. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2604,7 +2604,7 @@ +@@ -2614,7 +2614,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_PROGRAM_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1004,7 +1004,7 @@ VARIABLE_COMMENT Maximum number of instrumented programs. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2614,7 +2614,7 @@ +@@ -2624,7 +2624,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_RWLOCK_CLASSES VARIABLE_SCOPE GLOBAL @@ -1013,7 +1013,7 @@ VARIABLE_COMMENT Maximum number of rwlock instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2624,7 +2624,7 @@ +@@ -2634,7 +2634,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_RWLOCK_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1022,7 +1022,7 @@ VARIABLE_COMMENT Maximum number of instrumented RWLOCK objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2634,7 +2634,7 @@ +@@ -2644,7 +2644,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SOCKET_CLASSES VARIABLE_SCOPE GLOBAL @@ -1031,7 +1031,7 @@ VARIABLE_COMMENT Maximum number of socket instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2644,7 +2644,7 @@ +@@ -2654,7 +2654,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SOCKET_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1040,7 +1040,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented sockets. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2654,7 +2654,7 @@ +@@ -2664,7 +2664,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SQL_TEXT_LENGTH VARIABLE_SCOPE GLOBAL @@ -1049,7 +1049,7 @@ VARIABLE_COMMENT Maximum length of displayed sql text. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2664,7 +2664,7 @@ +@@ -2674,7 +2674,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STAGE_CLASSES VARIABLE_SCOPE GLOBAL @@ -1058,7 +1058,7 @@ VARIABLE_COMMENT Maximum number of stage instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2674,7 +2674,7 @@ +@@ -2684,7 +2684,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_CLASSES VARIABLE_SCOPE GLOBAL @@ -1067,7 +1067,7 @@ VARIABLE_COMMENT Maximum number of statement instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2684,7 +2684,7 @@ +@@ -2694,7 +2694,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_STACK VARIABLE_SCOPE GLOBAL @@ -1076,7 +1076,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_CURRENT. NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 256 -@@ -2694,7 +2694,7 @@ +@@ -2704,7 +2704,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_HANDLES VARIABLE_SCOPE GLOBAL @@ -1085,7 +1085,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented tables. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2704,7 +2704,7 @@ +@@ -2714,7 +2714,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1094,7 +1094,7 @@ VARIABLE_COMMENT Maximum number of instrumented tables. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2714,7 +2714,7 @@ +@@ -2724,7 +2724,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_LOCK_STAT VARIABLE_SCOPE GLOBAL @@ -1103,7 +1103,7 @@ VARIABLE_COMMENT Maximum number of lock statistics for instrumented tables. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2724,7 +2724,7 @@ +@@ -2734,7 +2734,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_THREAD_CLASSES VARIABLE_SCOPE GLOBAL @@ -1112,7 +1112,7 @@ VARIABLE_COMMENT Maximum number of thread instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2734,7 +2734,7 @@ +@@ -2744,7 +2744,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_THREAD_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1121,7 +1121,7 @@ VARIABLE_COMMENT Maximum number of instrumented threads. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2744,7 +2744,7 @@ +@@ -2754,7 +2754,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_SESSION_CONNECT_ATTRS_SIZE VARIABLE_SCOPE GLOBAL @@ -1130,7 +1130,7 @@ VARIABLE_COMMENT Size of session attribute string buffer per thread. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2754,7 +2754,7 @@ +@@ -2764,7 +2764,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_SETUP_ACTORS_SIZE VARIABLE_SCOPE GLOBAL @@ -1139,7 +1139,7 @@ VARIABLE_COMMENT Maximum number of rows in SETUP_ACTORS. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2764,7 +2764,7 @@ +@@ -2774,7 +2774,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_SETUP_OBJECTS_SIZE VARIABLE_SCOPE GLOBAL @@ -1148,7 +1148,7 @@ VARIABLE_COMMENT Maximum number of rows in SETUP_OBJECTS. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2774,7 +2774,7 @@ +@@ -2784,7 +2784,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_USERS_SIZE VARIABLE_SCOPE GLOBAL @@ -1157,7 +1157,7 @@ VARIABLE_COMMENT Maximum number of instrumented users. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2824,7 +2824,7 @@ +@@ -2834,7 +2834,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PRELOAD_BUFFER_SIZE VARIABLE_SCOPE SESSION @@ -1166,7 +1166,7 @@ VARIABLE_COMMENT The size of the buffer that is allocated when preloading indexes NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 1073741824 -@@ -2844,7 +2844,7 @@ +@@ -2854,7 +2854,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME PROFILING_HISTORY_SIZE VARIABLE_SCOPE SESSION @@ -1175,7 +1175,7 @@ VARIABLE_COMMENT Number of statements about which profiling information is maintained. If set to 0, no profiles are stored. See SHOW PROFILES. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 100 -@@ -2854,7 +2854,7 @@ +@@ -2864,7 +2864,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PROGRESS_REPORT_TIME VARIABLE_SCOPE SESSION @@ -1184,7 +1184,7 @@ VARIABLE_COMMENT Seconds between sending progress reports to the client for time-consuming statements. Set to 0 to disable progress reporting. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2914,7 +2914,7 @@ +@@ -2924,7 +2924,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME QUERY_ALLOC_BLOCK_SIZE VARIABLE_SCOPE SESSION @@ -1193,7 +1193,7 @@ VARIABLE_COMMENT Allocation block size for query parsing and execution NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 4294967295 -@@ -2924,7 +2924,7 @@ +@@ -2934,7 +2934,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME QUERY_CACHE_LIMIT VARIABLE_SCOPE GLOBAL @@ -1202,7 +1202,7 @@ VARIABLE_COMMENT Don't cache results that are bigger than this NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2934,7 +2934,7 @@ +@@ -2944,7 +2944,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME QUERY_CACHE_MIN_RES_UNIT VARIABLE_SCOPE GLOBAL @@ -1211,7 +1211,7 @@ VARIABLE_COMMENT The minimum size for blocks allocated by the query cache NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2947,7 +2947,7 @@ +@@ -2957,7 +2957,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The memory allocated to store results from old queries NUMERIC_MIN_VALUE 0 @@ -1220,7 +1220,7 @@ NUMERIC_BLOCK_SIZE 1024 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -2984,7 +2984,7 @@ +@@ -2994,7 +2994,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME QUERY_PREALLOC_SIZE VARIABLE_SCOPE SESSION @@ -1229,7 +1229,7 @@ VARIABLE_COMMENT Persistent buffer for query parsing and execution NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 4294967295 -@@ -2997,7 +2997,7 @@ +@@ -3007,7 +3007,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes NUMERIC_MIN_VALUE 0 @@ -1238,7 +1238,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3007,14 +3007,14 @@ +@@ -3017,14 +3017,14 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes NUMERIC_MIN_VALUE 0 @@ -1255,7 +1255,7 @@ VARIABLE_COMMENT Allocation block size for storing ranges during optimization NUMERIC_MIN_VALUE 4096 NUMERIC_MAX_VALUE 4294967295 -@@ -3024,7 +3024,7 @@ +@@ -3034,7 +3034,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME READ_BUFFER_SIZE VARIABLE_SCOPE SESSION @@ -1264,7 +1264,7 @@ VARIABLE_COMMENT Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value NUMERIC_MIN_VALUE 8192 NUMERIC_MAX_VALUE 2147483647 -@@ -3044,7 +3044,7 @@ +@@ -3054,7 +3054,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME READ_RND_BUFFER_SIZE VARIABLE_SCOPE SESSION @@ -1273,7 +1273,7 @@ VARIABLE_COMMENT When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 2147483647 -@@ -3064,10 +3064,10 @@ +@@ -3074,10 +3074,10 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME ROWID_MERGE_BUFF_SIZE VARIABLE_SCOPE SESSION @@ -1286,7 +1286,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3104,7 +3104,7 @@ +@@ -3114,7 +3114,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SERVER_ID VARIABLE_SCOPE SESSION @@ -1295,7 +1295,7 @@ VARIABLE_COMMENT Uniquely identifies the server instance in the community of replication partners NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 4294967295 -@@ -3174,7 +3174,7 @@ +@@ -3184,7 +3184,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME SLAVE_MAX_ALLOWED_PACKET VARIABLE_SCOPE GLOBAL @@ -1304,7 +1304,7 @@ VARIABLE_COMMENT The maximum packet length to sent successfully from the master to slave. NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 1073741824 -@@ -3184,7 +3184,7 @@ +@@ -3194,7 +3194,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLOW_LAUNCH_TIME VARIABLE_SCOPE GLOBAL @@ -1313,7 +1313,7 @@ VARIABLE_COMMENT If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 31536000 -@@ -3227,7 +3227,7 @@ +@@ -3237,7 +3237,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Each thread that needs to do a sort allocates a buffer of this size NUMERIC_MIN_VALUE 1024 @@ -1322,7 +1322,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3444,7 +3444,7 @@ +@@ -3454,7 +3454,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME STORED_PROGRAM_CACHE VARIABLE_SCOPE GLOBAL @@ -1331,7 +1331,7 @@ VARIABLE_COMMENT The soft upper limit for number of cached stored routines for one connection. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 524288 -@@ -3524,7 +3524,7 @@ +@@ -3534,7 +3534,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME TABLE_DEFINITION_CACHE VARIABLE_SCOPE GLOBAL @@ -1340,7 +1340,7 @@ VARIABLE_COMMENT The number of cached table definitions NUMERIC_MIN_VALUE 400 NUMERIC_MAX_VALUE 2097152 -@@ -3534,7 +3534,7 @@ +@@ -3544,7 +3544,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME TABLE_OPEN_CACHE VARIABLE_SCOPE GLOBAL @@ -1349,7 +1349,7 @@ VARIABLE_COMMENT The number of cached open tables NUMERIC_MIN_VALUE 10 NUMERIC_MAX_VALUE 1048576 -@@ -3594,7 +3594,7 @@ +@@ -3604,7 +3604,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME THREAD_CACHE_SIZE VARIABLE_SCOPE GLOBAL @@ -1358,7 +1358,7 @@ VARIABLE_COMMENT How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16384 -@@ -3677,7 +3677,7 @@ +@@ -3687,7 +3687,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Max size for data for an internal temporary on-disk MyISAM or Aria table. NUMERIC_MIN_VALUE 1024 @@ -1367,7 +1367,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3687,7 +3687,7 @@ +@@ -3697,7 +3697,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. Same as tmp_table_size. NUMERIC_MIN_VALUE 0 @@ -1376,7 +1376,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3697,14 +3697,14 @@ +@@ -3707,14 +3707,14 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Alias for tmp_memory_table_size. If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. NUMERIC_MIN_VALUE 0 @@ -1393,7 +1393,7 @@ VARIABLE_COMMENT Allocation block size for transactions to be stored in binary log NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 134217728 -@@ -3714,7 +3714,7 @@ +@@ -3724,7 +3724,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME TRANSACTION_PREALLOC_SIZE VARIABLE_SCOPE SESSION @@ -1402,7 +1402,7 @@ VARIABLE_COMMENT Persistent buffer for transactions to be stored in binary log NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 134217728 -@@ -3854,7 +3854,7 @@ +@@ -3864,7 +3864,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME WAIT_TIMEOUT VARIABLE_SCOPE SESSION @@ -1411,7 +1411,7 @@ VARIABLE_COMMENT The number of seconds the server waits for activity on a connection before closing it NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 31536000 -@@ -3881,7 +3881,7 @@ +@@ -3891,7 +3891,7 @@ VARIABLE_NAME LOG_TC_SIZE GLOBAL_VALUE_ORIGIN AUTO VARIABLE_SCOPE GLOBAL diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff index dfe7e0d829d..0fad61d69a7 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff @@ -1,5 +1,5 @@ ---- sysvars_server_notembedded.result -+++ sysvars_server_notembedded.result +--- suite/sys_vars/r/sysvars_server_notembedded.result ++++ suite/sys_vars/r/sysvars_server_notembedded,32bit.reject @@ -34,7 +34,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME ARIA_BLOCK_SIZE @@ -714,6 +714,15 @@ NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 @@ -2434,7 +2434,7 @@ + COMMAND_LINE_ARGUMENT REQUIRED + VARIABLE_NAME OPTIMIZER_ADJUST_SECONDARY_KEY_COSTS + VARIABLE_SCOPE SESSION +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT 0 = No changes. 1 = Update secondary key costs for ranges to be at least 5x of clustered primary key costs. 2 = Remove 'max_seek optimization' for secondary keys and slight adjustment of filter cost. This option will be deleted in MariaDB 11.0 as it is not needed with the new 11.0 optimizer. + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 2 +@@ -2444,7 +2444,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_MAX_SEL_ARGS VARIABLE_SCOPE SESSION @@ -722,7 +731,7 @@ VARIABLE_COMMENT The maximum number of SEL_ARG objects created when optimizing a range. If more objects would be needed, the range will not be used by the optimizer. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2444,7 +2444,7 @@ +@@ -2454,7 +2454,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_MAX_SEL_ARG_WEIGHT VARIABLE_SCOPE SESSION @@ -731,7 +740,7 @@ VARIABLE_COMMENT The maximum weight of the SEL_ARG graph. Set to 0 for no limit NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2454,7 +2454,7 @@ +@@ -2464,7 +2464,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_PRUNE_LEVEL VARIABLE_SCOPE SESSION @@ -740,7 +749,7 @@ VARIABLE_COMMENT Controls the heuristic(s) applied during query optimization to prune less-promising partial plans from the optimizer search space. Meaning: 0 - do not apply any heuristic, thus perform exhaustive search; 1 - prune plans based on number of retrieved rows NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1 -@@ -2464,7 +2464,7 @@ +@@ -2474,7 +2474,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_SEARCH_DEPTH VARIABLE_SCOPE SESSION @@ -749,7 +758,7 @@ VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 62 -@@ -2474,7 +2474,7 @@ +@@ -2484,7 +2484,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_SELECTIVITY_SAMPLING_LIMIT VARIABLE_SCOPE SESSION @@ -758,7 +767,7 @@ VARIABLE_COMMENT Controls number of record samples to check condition selectivity NUMERIC_MIN_VALUE 10 NUMERIC_MAX_VALUE 4294967295 -@@ -2504,17 +2504,17 @@ +@@ -2514,17 +2514,17 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OPTIMIZER_TRACE_MAX_MEM_SIZE VARIABLE_SCOPE SESSION @@ -779,7 +788,7 @@ VARIABLE_COMMENT Controls selectivity of which conditions the optimizer takes into account to calculate cardinality of a partial join when it searches for the best execution plan Meaning: 1 - use selectivity of index backed range conditions to calculate the cardinality of a partial join if the last joined table is accessed by full table scan or an index scan, 2 - use selectivity of index backed range conditions to calculate the cardinality of a partial join in any case, 3 - additionally always use selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join, 4 - use histograms to calculate selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join.5 - additionally use selectivity of certain non-range predicates calculated on record samples NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 5 -@@ -2534,7 +2534,7 @@ +@@ -2544,7 +2544,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME PERFORMANCE_SCHEMA_ACCOUNTS_SIZE VARIABLE_SCOPE GLOBAL @@ -788,7 +797,7 @@ VARIABLE_COMMENT Maximum number of instrumented user@host accounts. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2544,7 +2544,7 @@ +@@ -2554,7 +2554,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_DIGESTS_SIZE VARIABLE_SCOPE GLOBAL @@ -797,7 +806,7 @@ VARIABLE_COMMENT Size of the statement digest. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2554,7 +2554,7 @@ +@@ -2564,7 +2564,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STAGES_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -806,7 +815,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_STAGES_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2564,7 +2564,7 @@ +@@ -2574,7 +2574,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STAGES_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -815,7 +824,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STAGES_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2574,7 +2574,7 @@ +@@ -2584,7 +2584,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STATEMENTS_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -824,7 +833,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_STATEMENTS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2584,7 +2584,7 @@ +@@ -2594,7 +2594,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_STATEMENTS_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -833,7 +842,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2594,7 +2594,7 @@ +@@ -2604,7 +2604,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_TRANSACTIONS_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -842,7 +851,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_TRANSACTIONS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2604,7 +2604,7 @@ +@@ -2614,7 +2614,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_TRANSACTIONS_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -851,7 +860,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_TRANSACTIONS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2614,7 +2614,7 @@ +@@ -2624,7 +2624,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_WAITS_HISTORY_LONG_SIZE VARIABLE_SCOPE GLOBAL @@ -860,7 +869,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_WAITS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2624,7 +2624,7 @@ +@@ -2634,7 +2634,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_EVENTS_WAITS_HISTORY_SIZE VARIABLE_SCOPE GLOBAL @@ -869,7 +878,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_WAITS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2634,7 +2634,7 @@ +@@ -2644,7 +2644,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_HOSTS_SIZE VARIABLE_SCOPE GLOBAL @@ -878,7 +887,7 @@ VARIABLE_COMMENT Maximum number of instrumented hosts. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2644,7 +2644,7 @@ +@@ -2654,7 +2654,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_COND_CLASSES VARIABLE_SCOPE GLOBAL @@ -887,7 +896,7 @@ VARIABLE_COMMENT Maximum number of condition instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2654,7 +2654,7 @@ +@@ -2664,7 +2664,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_COND_INSTANCES VARIABLE_SCOPE GLOBAL @@ -896,7 +905,7 @@ VARIABLE_COMMENT Maximum number of instrumented condition objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2664,7 +2664,7 @@ +@@ -2674,7 +2674,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_DIGEST_LENGTH VARIABLE_SCOPE GLOBAL @@ -905,7 +914,7 @@ VARIABLE_COMMENT Maximum length considered for digest text, when stored in performance_schema tables. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2674,7 +2674,7 @@ +@@ -2684,7 +2684,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_CLASSES VARIABLE_SCOPE GLOBAL @@ -914,7 +923,7 @@ VARIABLE_COMMENT Maximum number of file instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2684,7 +2684,7 @@ +@@ -2694,7 +2694,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_HANDLES VARIABLE_SCOPE GLOBAL @@ -923,7 +932,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented files. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2694,7 +2694,7 @@ +@@ -2704,7 +2704,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_FILE_INSTANCES VARIABLE_SCOPE GLOBAL @@ -932,7 +941,7 @@ VARIABLE_COMMENT Maximum number of instrumented files. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2704,7 +2704,7 @@ +@@ -2714,7 +2714,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_INDEX_STAT VARIABLE_SCOPE GLOBAL @@ -941,7 +950,7 @@ VARIABLE_COMMENT Maximum number of index statistics for instrumented tables. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2714,7 +2714,7 @@ +@@ -2724,7 +2724,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MEMORY_CLASSES VARIABLE_SCOPE GLOBAL @@ -950,7 +959,7 @@ VARIABLE_COMMENT Maximum number of memory pool instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1024 -@@ -2724,7 +2724,7 @@ +@@ -2734,7 +2734,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_METADATA_LOCKS VARIABLE_SCOPE GLOBAL @@ -959,7 +968,7 @@ VARIABLE_COMMENT Maximum number of metadata locks. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2734,7 +2734,7 @@ +@@ -2744,7 +2744,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MUTEX_CLASSES VARIABLE_SCOPE GLOBAL @@ -968,7 +977,7 @@ VARIABLE_COMMENT Maximum number of mutex instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2744,7 +2744,7 @@ +@@ -2754,7 +2754,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_MUTEX_INSTANCES VARIABLE_SCOPE GLOBAL @@ -977,7 +986,7 @@ VARIABLE_COMMENT Maximum number of instrumented MUTEX objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2754,7 +2754,7 @@ +@@ -2764,7 +2764,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_PREPARED_STATEMENTS_INSTANCES VARIABLE_SCOPE GLOBAL @@ -986,7 +995,7 @@ VARIABLE_COMMENT Maximum number of instrumented prepared statements. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2764,7 +2764,7 @@ +@@ -2774,7 +2774,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_PROGRAM_INSTANCES VARIABLE_SCOPE GLOBAL @@ -995,7 +1004,7 @@ VARIABLE_COMMENT Maximum number of instrumented programs. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2774,7 +2774,7 @@ +@@ -2784,7 +2784,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_RWLOCK_CLASSES VARIABLE_SCOPE GLOBAL @@ -1004,7 +1013,7 @@ VARIABLE_COMMENT Maximum number of rwlock instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2784,7 +2784,7 @@ +@@ -2794,7 +2794,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_RWLOCK_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1013,7 +1022,7 @@ VARIABLE_COMMENT Maximum number of instrumented RWLOCK objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2794,7 +2794,7 @@ +@@ -2804,7 +2804,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SOCKET_CLASSES VARIABLE_SCOPE GLOBAL @@ -1022,7 +1031,7 @@ VARIABLE_COMMENT Maximum number of socket instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2804,7 +2804,7 @@ +@@ -2814,7 +2814,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SOCKET_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1031,7 +1040,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented sockets. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2814,7 +2814,7 @@ +@@ -2824,7 +2824,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_SQL_TEXT_LENGTH VARIABLE_SCOPE GLOBAL @@ -1040,7 +1049,7 @@ VARIABLE_COMMENT Maximum length of displayed sql text. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2824,7 +2824,7 @@ +@@ -2834,7 +2834,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STAGE_CLASSES VARIABLE_SCOPE GLOBAL @@ -1049,7 +1058,7 @@ VARIABLE_COMMENT Maximum number of stage instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2834,7 +2834,7 @@ +@@ -2844,7 +2844,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_CLASSES VARIABLE_SCOPE GLOBAL @@ -1058,7 +1067,7 @@ VARIABLE_COMMENT Maximum number of statement instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2844,7 +2844,7 @@ +@@ -2854,7 +2854,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_STACK VARIABLE_SCOPE GLOBAL @@ -1067,7 +1076,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_CURRENT. NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 256 -@@ -2854,7 +2854,7 @@ +@@ -2864,7 +2864,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_HANDLES VARIABLE_SCOPE GLOBAL @@ -1076,7 +1085,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented tables. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2864,7 +2864,7 @@ +@@ -2874,7 +2874,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1085,7 +1094,7 @@ VARIABLE_COMMENT Maximum number of instrumented tables. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2874,7 +2874,7 @@ +@@ -2884,7 +2884,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_TABLE_LOCK_STAT VARIABLE_SCOPE GLOBAL @@ -1094,7 +1103,7 @@ VARIABLE_COMMENT Maximum number of lock statistics for instrumented tables. Use 0 to disable, -1 for automated scaling. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2884,7 +2884,7 @@ +@@ -2894,7 +2894,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_THREAD_CLASSES VARIABLE_SCOPE GLOBAL @@ -1103,7 +1112,7 @@ VARIABLE_COMMENT Maximum number of thread instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2894,7 +2894,7 @@ +@@ -2904,7 +2904,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_THREAD_INSTANCES VARIABLE_SCOPE GLOBAL @@ -1112,7 +1121,7 @@ VARIABLE_COMMENT Maximum number of instrumented threads. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2904,7 +2904,7 @@ +@@ -2914,7 +2914,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_SESSION_CONNECT_ATTRS_SIZE VARIABLE_SCOPE GLOBAL @@ -1121,7 +1130,7 @@ VARIABLE_COMMENT Size of session attribute string buffer per thread. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2914,7 +2914,7 @@ +@@ -2924,7 +2924,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_SETUP_ACTORS_SIZE VARIABLE_SCOPE GLOBAL @@ -1130,7 +1139,7 @@ VARIABLE_COMMENT Maximum number of rows in SETUP_ACTORS. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2924,7 +2924,7 @@ +@@ -2934,7 +2934,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_SETUP_OBJECTS_SIZE VARIABLE_SCOPE GLOBAL @@ -1139,7 +1148,7 @@ VARIABLE_COMMENT Maximum number of rows in SETUP_OBJECTS. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2934,7 +2934,7 @@ +@@ -2944,7 +2944,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_USERS_SIZE VARIABLE_SCOPE GLOBAL @@ -1148,7 +1157,7 @@ VARIABLE_COMMENT Maximum number of instrumented users. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2984,7 +2984,7 @@ +@@ -2994,7 +2994,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PRELOAD_BUFFER_SIZE VARIABLE_SCOPE SESSION @@ -1157,7 +1166,7 @@ VARIABLE_COMMENT The size of the buffer that is allocated when preloading indexes NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 1073741824 -@@ -3004,7 +3004,7 @@ +@@ -3014,7 +3014,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME PROFILING_HISTORY_SIZE VARIABLE_SCOPE SESSION @@ -1166,7 +1175,7 @@ VARIABLE_COMMENT Number of statements about which profiling information is maintained. If set to 0, no profiles are stored. See SHOW PROFILES. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 100 -@@ -3014,7 +3014,7 @@ +@@ -3024,7 +3024,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PROGRESS_REPORT_TIME VARIABLE_SCOPE SESSION @@ -1175,7 +1184,7 @@ VARIABLE_COMMENT Seconds between sending progress reports to the client for time-consuming statements. Set to 0 to disable progress reporting. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3074,7 +3074,7 @@ +@@ -3084,7 +3084,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME QUERY_ALLOC_BLOCK_SIZE VARIABLE_SCOPE SESSION @@ -1184,7 +1193,7 @@ VARIABLE_COMMENT Allocation block size for query parsing and execution NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 4294967295 -@@ -3084,7 +3084,7 @@ +@@ -3094,7 +3094,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME QUERY_CACHE_LIMIT VARIABLE_SCOPE GLOBAL @@ -1193,7 +1202,7 @@ VARIABLE_COMMENT Don't cache results that are bigger than this NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3094,7 +3094,7 @@ +@@ -3104,7 +3104,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME QUERY_CACHE_MIN_RES_UNIT VARIABLE_SCOPE GLOBAL @@ -1202,7 +1211,7 @@ VARIABLE_COMMENT The minimum size for blocks allocated by the query cache NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3107,7 +3107,7 @@ +@@ -3117,7 +3117,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The memory allocated to store results from old queries NUMERIC_MIN_VALUE 0 @@ -1211,7 +1220,7 @@ NUMERIC_BLOCK_SIZE 1024 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3144,7 +3144,7 @@ +@@ -3154,7 +3154,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME QUERY_PREALLOC_SIZE VARIABLE_SCOPE SESSION @@ -1220,7 +1229,7 @@ VARIABLE_COMMENT Persistent buffer for query parsing and execution NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 4294967295 -@@ -3157,7 +3157,7 @@ +@@ -3167,7 +3167,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes NUMERIC_MIN_VALUE 0 @@ -1229,7 +1238,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3167,14 +3167,14 @@ +@@ -3177,14 +3177,14 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes NUMERIC_MIN_VALUE 0 @@ -1246,7 +1255,7 @@ VARIABLE_COMMENT Allocation block size for storing ranges during optimization NUMERIC_MIN_VALUE 4096 NUMERIC_MAX_VALUE 4294967295 -@@ -3187,14 +3187,14 @@ +@@ -3197,14 +3197,14 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Maximum speed(KB/s) to read binlog from master (0 = no limit) NUMERIC_MIN_VALUE 0 @@ -1263,7 +1272,7 @@ VARIABLE_COMMENT Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value NUMERIC_MIN_VALUE 8192 NUMERIC_MAX_VALUE 2147483647 -@@ -3214,7 +3214,7 @@ +@@ -3224,7 +3224,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME READ_RND_BUFFER_SIZE VARIABLE_SCOPE SESSION @@ -1272,7 +1281,7 @@ VARIABLE_COMMENT When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 2147483647 -@@ -3424,10 +3424,10 @@ +@@ -3434,10 +3434,10 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME ROWID_MERGE_BUFF_SIZE VARIABLE_SCOPE SESSION @@ -1285,7 +1294,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3444,20 +3444,20 @@ +@@ -3454,20 +3454,20 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME RPL_SEMI_SYNC_MASTER_TIMEOUT VARIABLE_SCOPE GLOBAL @@ -1310,7 +1319,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3514,10 +3514,10 @@ +@@ -3524,10 +3524,10 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME RPL_SEMI_SYNC_SLAVE_TRACE_LEVEL VARIABLE_SCOPE GLOBAL @@ -1323,7 +1332,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3554,7 +3554,7 @@ +@@ -3564,7 +3564,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SERVER_ID VARIABLE_SCOPE SESSION @@ -1332,7 +1341,7 @@ VARIABLE_COMMENT Uniquely identifies the server instance in the community of replication partners NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 4294967295 -@@ -3684,7 +3684,7 @@ +@@ -3694,7 +3694,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLAVE_DOMAIN_PARALLEL_THREADS VARIABLE_SCOPE GLOBAL @@ -1341,7 +1350,7 @@ VARIABLE_COMMENT Maximum number of parallel threads to use on slave for events in a single replication domain. When using multiple domains, this can be used to limit a single domain from grabbing all threads and thus stalling other domains. The default of 0 means to allow a domain to grab as many threads as it wants, up to the value of slave_parallel_threads. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16383 -@@ -3714,7 +3714,7 @@ +@@ -3724,7 +3724,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLAVE_MAX_ALLOWED_PACKET VARIABLE_SCOPE GLOBAL @@ -1350,7 +1359,7 @@ VARIABLE_COMMENT The maximum packet length to sent successfully from the master to slave. NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 1073741824 -@@ -3734,7 +3734,7 @@ +@@ -3744,7 +3744,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLAVE_PARALLEL_MAX_QUEUED VARIABLE_SCOPE GLOBAL @@ -1359,7 +1368,7 @@ VARIABLE_COMMENT Limit on how much memory SQL threads should use per parallel replication thread when reading ahead in the relay log looking for opportunities for parallel replication. Only used when --slave-parallel-threads > 0. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 2147483647 -@@ -3754,7 +3754,7 @@ +@@ -3764,7 +3764,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME SLAVE_PARALLEL_THREADS VARIABLE_SCOPE GLOBAL @@ -1368,7 +1377,7 @@ VARIABLE_COMMENT If non-zero, number of threads to spawn to apply in parallel events on the slave that were group-committed on the master or were logged with GTID in different replication domains. Note that these threads are in addition to the IO and SQL threads, which are always created by a replication slave NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16383 -@@ -3764,7 +3764,7 @@ +@@ -3774,7 +3774,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLAVE_PARALLEL_WORKERS VARIABLE_SCOPE GLOBAL @@ -1377,7 +1386,7 @@ VARIABLE_COMMENT Alias for slave_parallel_threads NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16383 -@@ -3804,7 +3804,7 @@ +@@ -3814,7 +3814,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME SLAVE_TRANSACTION_RETRIES VARIABLE_SCOPE GLOBAL @@ -1386,7 +1395,7 @@ VARIABLE_COMMENT Number of times the slave SQL thread will retry a transaction in case it failed with a deadlock, elapsed lock wait timeout or listed in slave_transaction_retry_errors, before giving up and stopping NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3824,7 +3824,7 @@ +@@ -3834,7 +3834,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLAVE_TRANSACTION_RETRY_INTERVAL VARIABLE_SCOPE GLOBAL @@ -1395,7 +1404,7 @@ VARIABLE_COMMENT Interval of the slave SQL thread will retry a transaction in case it failed with a deadlock or elapsed lock wait timeout or listed in slave_transaction_retry_errors NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 3600 -@@ -3844,7 +3844,7 @@ +@@ -3854,7 +3854,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLOW_LAUNCH_TIME VARIABLE_SCOPE GLOBAL @@ -1404,7 +1413,7 @@ VARIABLE_COMMENT If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 31536000 -@@ -3887,7 +3887,7 @@ +@@ -3897,7 +3897,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Each thread that needs to do a sort allocates a buffer of this size NUMERIC_MIN_VALUE 1024 @@ -1413,7 +1422,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -4114,7 +4114,7 @@ +@@ -4124,7 +4124,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME STORED_PROGRAM_CACHE VARIABLE_SCOPE GLOBAL @@ -1422,7 +1431,7 @@ VARIABLE_COMMENT The soft upper limit for number of cached stored routines for one connection. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 524288 -@@ -4214,7 +4214,7 @@ +@@ -4224,7 +4224,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME TABLE_DEFINITION_CACHE VARIABLE_SCOPE GLOBAL @@ -1431,7 +1440,7 @@ VARIABLE_COMMENT The number of cached table definitions NUMERIC_MIN_VALUE 400 NUMERIC_MAX_VALUE 2097152 -@@ -4224,7 +4224,7 @@ +@@ -4234,7 +4234,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME TABLE_OPEN_CACHE VARIABLE_SCOPE GLOBAL @@ -1440,7 +1449,7 @@ VARIABLE_COMMENT The number of cached open tables NUMERIC_MIN_VALUE 10 NUMERIC_MAX_VALUE 1048576 -@@ -4284,7 +4284,7 @@ +@@ -4294,7 +4294,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME THREAD_CACHE_SIZE VARIABLE_SCOPE GLOBAL @@ -1449,7 +1458,7 @@ VARIABLE_COMMENT How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16384 -@@ -4457,7 +4457,7 @@ +@@ -4467,7 +4467,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Max size for data for an internal temporary on-disk MyISAM or Aria table. NUMERIC_MIN_VALUE 1024 @@ -1458,7 +1467,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -4467,7 +4467,7 @@ +@@ -4477,7 +4477,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. Same as tmp_table_size. NUMERIC_MIN_VALUE 0 @@ -1467,7 +1476,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -4477,14 +4477,14 @@ +@@ -4487,14 +4487,14 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Alias for tmp_memory_table_size. If an internal in-memory temporary table exceeds this size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. NUMERIC_MIN_VALUE 0 @@ -1484,7 +1493,7 @@ VARIABLE_COMMENT Allocation block size for transactions to be stored in binary log NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 134217728 -@@ -4494,7 +4494,7 @@ +@@ -4504,7 +4504,7 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME TRANSACTION_PREALLOC_SIZE VARIABLE_SCOPE SESSION @@ -1493,7 +1502,7 @@ VARIABLE_COMMENT Persistent buffer for transactions to be stored in binary log NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 134217728 -@@ -4634,7 +4634,7 @@ +@@ -4644,7 +4644,7 @@ COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME WAIT_TIMEOUT VARIABLE_SCOPE SESSION @@ -1502,7 +1511,7 @@ VARIABLE_COMMENT The number of seconds the server waits for activity on a connection before closing it NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 31536000 -@@ -4661,7 +4661,7 @@ +@@ -4671,7 +4671,7 @@ VARIABLE_NAME LOG_TC_SIZE GLOBAL_VALUE_ORIGIN AUTO VARIABLE_SCOPE GLOBAL From 4dbf55bbfcdffb495ea25c6fcfe6c04b624b9654 Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 27 Jan 2024 16:47:00 +0200 Subject: [PATCH 60/61] Disable perfschema.misc_session_status for 32 bit 32bit uses less memory so the test for max_memory_usage does not work --- mysql-test/suite/perfschema/t/misc_session_status.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/suite/perfschema/t/misc_session_status.test b/mysql-test/suite/perfschema/t/misc_session_status.test index ea662ce6738..c9e7d066b0c 100644 --- a/mysql-test/suite/perfschema/t/misc_session_status.test +++ b/mysql-test/suite/perfschema/t/misc_session_status.test @@ -1,5 +1,7 @@ --source include/not_embedded.inc --source include/have_perfschema.inc +# This does not crash on 32 bit because of less memory used +--source include/have_64bit.inc --echo # --echo # MDEV-33150 double-locking of LOCK_thd_kill in performance_schema.session_status --echo # From c75905cacbd2e8429dc5abd00835e099227851b2 Mon Sep 17 00:00:00 2001 From: Brandon Nesterenko Date: Mon, 29 Jan 2024 15:17:57 -0700 Subject: [PATCH 61/61] MDEV-33327: rpl_seconds_behind_master_spike Sensitive to IO Thread Stop Position rpl.rpl_seconds_behind_master_spike uses the DEBUG_SYNC mechanism to count how many format descriptor events (FDEs) have been executed, to attempt to pause on a specific relay log FDE after executing transactions. However, depending on when the IO thread is stopped, it can send an extra FDE before sending the transactions, forcing the test to pause before executing any transactions, resulting in a table not existing, that is attempted to be read for COUNT. This patch fixes this by no longer counting FDEs, but rather by programmatically waiting until the SQL thread has executed the transaction and then automatically activating the DEBUG_SYNC point to trigger at the next relay log FDE. --- .../rpl/r/rpl_seconds_behind_master_spike.result | 8 ++------ .../rpl/t/rpl_seconds_behind_master_spike.test | 9 ++------- sql/slave.cc | 15 +++++++++++++-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_seconds_behind_master_spike.result b/mysql-test/suite/rpl/r/rpl_seconds_behind_master_spike.result index bb71f6c92b0..3234a512d86 100644 --- a/mysql-test/suite/rpl/r/rpl_seconds_behind_master_spike.result +++ b/mysql-test/suite/rpl/r/rpl_seconds_behind_master_spike.result @@ -3,7 +3,8 @@ include/master-slave.inc connection slave; include/stop_slave.inc SET @save_dbug= @@GLOBAL.debug_dbug; -SET @@global.debug_dbug="+d,pause_sql_thread_on_fde,negate_clock_diff_with_master"; +SET @@global.debug_dbug="+d,pause_sql_thread_on_relay_fde_after_trans"; +SET @@global.debug_dbug="+d,negate_clock_diff_with_master"; include/start_slave.inc # Future events must be logged at least 2 seconds after # the slave starts @@ -15,11 +16,6 @@ insert into t1 values (1); # event in its relay log flush logs; connection slave; -# Ignore FDEs that happen before the CREATE/INSERT commands -SET DEBUG_SYNC='now WAIT_FOR paused_on_fde'; -SET DEBUG_SYNC='now SIGNAL sql_thread_continue'; -SET DEBUG_SYNC='now WAIT_FOR paused_on_fde'; -SET DEBUG_SYNC='now SIGNAL sql_thread_continue'; # On the next FDE, the slave should have the master CREATE/INSERT events SET DEBUG_SYNC='now WAIT_FOR paused_on_fde'; select count(*)=1 from t1; diff --git a/mysql-test/suite/rpl/t/rpl_seconds_behind_master_spike.test b/mysql-test/suite/rpl/t/rpl_seconds_behind_master_spike.test index 9e73e6678a2..cd6311c5e19 100644 --- a/mysql-test/suite/rpl/t/rpl_seconds_behind_master_spike.test +++ b/mysql-test/suite/rpl/t/rpl_seconds_behind_master_spike.test @@ -27,7 +27,8 @@ --connection slave --source include/stop_slave.inc SET @save_dbug= @@GLOBAL.debug_dbug; -SET @@global.debug_dbug="+d,pause_sql_thread_on_fde,negate_clock_diff_with_master"; +SET @@global.debug_dbug="+d,pause_sql_thread_on_relay_fde_after_trans"; +SET @@global.debug_dbug="+d,negate_clock_diff_with_master"; --source include/start_slave.inc --let $sleep_time=2 @@ -46,12 +47,6 @@ insert into t1 values (1); flush logs; --connection slave ---echo # Ignore FDEs that happen before the CREATE/INSERT commands -SET DEBUG_SYNC='now WAIT_FOR paused_on_fde'; -SET DEBUG_SYNC='now SIGNAL sql_thread_continue'; -SET DEBUG_SYNC='now WAIT_FOR paused_on_fde'; -SET DEBUG_SYNC='now SIGNAL sql_thread_continue'; - --echo # On the next FDE, the slave should have the master CREATE/INSERT events SET DEBUG_SYNC='now WAIT_FOR paused_on_fde'; select count(*)=1 from t1; diff --git a/sql/slave.cc b/sql/slave.cc index f4d76e447cd..d37b00f2888 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -4301,6 +4301,15 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli, { Gtid_log_event *gev= static_cast(ev); +#ifdef ENABLED_DEBUG_SYNC + DBUG_EXECUTE_IF( + "pause_sql_thread_on_relay_fde_after_trans", + { + DBUG_SET("-d,pause_sql_thread_on_relay_fde_after_trans"); + DBUG_SET("+d,pause_sql_thread_on_next_relay_fde"); + }); +#endif + /* For GTID, allocate a new sub_id for the given domain_id. The sub_id must be allocated in increasing order of binlog order. @@ -4451,12 +4460,14 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli, #endif /* WITH_WSREP */ #ifdef ENABLED_DEBUG_SYNC DBUG_EXECUTE_IF( - "pause_sql_thread_on_fde", - if (ev && typ == FORMAT_DESCRIPTION_EVENT) { + "pause_sql_thread_on_next_relay_fde", + if (ev && typ == FORMAT_DESCRIPTION_EVENT && + ((Format_description_log_event *) ev)->is_relay_log_event()) { DBUG_ASSERT(!debug_sync_set_action( thd, STRING_WITH_LEN( "now SIGNAL paused_on_fde WAIT_FOR sql_thread_continue"))); + DBUG_SET("-d,pause_sql_thread_on_next_relay_fde"); }); #endif