From 5d8684863c630d8a13793963ef8fbd95e65bfe1c Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Mon, 10 May 2021 11:33:29 -0400 Subject: [PATCH 1/4] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 182db29c53a..cf6ad8afb6e 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=10 +MYSQL_VERSION_PATCH=11 SERVER_MATURITY=stable From 621501f38bd8db1a334a6cd873db787a5a5070aa Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 10 May 2021 20:36:38 +0300 Subject: [PATCH 2/4] MDEV-25606: Concurrent CREATE TRIGGER statements mix up in binlog and break replication The bug is that we don't have a a lock on the trigger name, so it is possible for two threads to try to create the same trigger at the same time and both thinks that they have succeed. Same thing can happen with drop trigger or a combinations of create and drop trigger. Fixed by adding a mdl lock for the trigger name for the duration of the create/drop. Patch tested by Elena --- sql/sql_trigger.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 9417ec667ff..24bd7001eea 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -397,6 +397,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) String stmt_query; bool lock_upgrade_done= FALSE; MDL_ticket *mdl_ticket= NULL; + MDL_request mdl_request_for_trn; Query_tables_list backup; DBUG_ENTER("mysql_create_or_drop_trigger"); @@ -446,6 +447,16 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) DBUG_RETURN(TRUE); } + /* Protect against concurrent create/drop */ + MDL_REQUEST_INIT(&mdl_request_for_trn, MDL_key::TABLE, + create ? tables->db.str : thd->lex->spname->m_db.str, + thd->lex->spname->m_name.str, + MDL_EXCLUSIVE, MDL_EXPLICIT); + if (thd->mdl_context.acquire_lock(&mdl_request_for_trn, + thd->variables.lock_wait_timeout)) + goto end; + + if (!create) { bool if_exists= thd->lex->if_exists(); @@ -635,6 +646,9 @@ end: thd->lex->spname->m_name.str, static_cast(thd->lex->spname->m_name.length)); } + if (mdl_request_for_trn.ticket) + thd->mdl_context.release_lock(mdl_request_for_trn.ticket); + DBUG_RETURN(result); #ifdef WITH_WSREP wsrep_error_label: From 0df51e610bd88edbcda5da0234a8768cc2e219ef Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 11 May 2021 21:05:51 +0300 Subject: [PATCH 3/4] MDEV-25651 Server crash or assertion failure in THD::update_stats upon concurrent DROP TRIGGER The problem was that in a timeout event, thd->lex->restore_backup_query_tables_list() was called when it should not have been. Patch tested with the script in MDEV-25651 (not suitable for mtr) --- sql/sql_trigger.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 24bd7001eea..19379d3f77a 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -396,6 +396,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) bool result= TRUE; String stmt_query; bool lock_upgrade_done= FALSE; + bool backup_of_table_list_done= 0;; MDL_ticket *mdl_ticket= NULL; MDL_request mdl_request_for_trn; Query_tables_list backup; @@ -465,6 +466,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) Protect the query table list from the temporary and potentially destructive changes necessary to open the trigger's table. */ + backup_of_table_list_done= 1; thd->lex->reset_n_backup_query_tables_list(&backup); /* Restore Query_tables_list::sql_command, which was @@ -634,7 +636,7 @@ end: mdl_ticket->downgrade_lock(MDL_SHARED_NO_READ_WRITE); /* Restore the query table list. Used only for drop trigger. */ - if (!create) + if (backup_of_table_list_done) thd->lex->restore_backup_query_tables_list(&backup); if (!result) From 4d53a7585c532c2cfcea184259e3153f95b35683 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 11 May 2021 21:25:08 +0300 Subject: [PATCH 4/4] Updated tests in decimal.c that match current API and usage --- strings/decimal.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/strings/decimal.c b/strings/decimal.c index 16bc887814a..1f9a28c1ad5 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -2619,7 +2619,8 @@ void test_d2f(const char *s, int ex) void test_d2b2d(const char *str, int p, int s, const char *orig, int ex) { - char s1[100], buf[100], *end; + char s1[100], *end; + uchar buf[100]; int res, i, size=decimal_bin_size(p, s); sprintf(s1, "'%s'", str); @@ -2937,27 +2938,27 @@ int main() test_f2d(1234500009876.5, 0); printf("==== ulonglong2decimal ====\n"); - test_ull2d(ULL(12345), "12345", 0); - test_ull2d(ULL(0), "0", 0); - test_ull2d(ULL(18446744073709551615), "18446744073709551615", 0); + test_ull2d(12345ULL, "12345", 0); + test_ull2d(0ULL, "0", 0); + test_ull2d(18446744073709551615ULL, "18446744073709551615", 0); printf("==== decimal2ulonglong ====\n"); test_d2ull("12345", "12345", 0); test_d2ull("0", "0", 0); test_d2ull("18446744073709551615", "18446744073709551615", 0); - test_d2ull("18446744073709551616", "18446744073", 2); + test_d2ull("18446744073709551616", "18446744073709551615", 2); test_d2ull("-1", "0", 2); test_d2ull("1.23", "1", 1); - test_d2ull("9999999999999999999999999.000", "9999999999999999", 2); + test_d2ull("9999999999999999999999999.000", "18446744073709551615", 2); printf("==== longlong2decimal ====\n"); - test_ll2d(LL(-12345), "-12345", 0); - test_ll2d(LL(-1), "-1", 0); - test_ll2d(LL(-9223372036854775807), "-9223372036854775807", 0); - test_ll2d(ULL(9223372036854775808), "-9223372036854775808", 0); + test_ll2d(-12345LL, "-12345", 0); + test_ll2d(-1LL, "-1", 0); + test_ll2d(-9223372036854775807LL, "-9223372036854775807", 0); + test_ll2d(9223372036854775808ULL, "-9223372036854775808", 0); printf("==== decimal2longlong ====\n"); - test_d2ll("18446744073709551615", "18446744073", 2); + test_d2ll("18446744073709551615", "9223372036854775807", 2); test_d2ll("-1", "-1", 0); test_d2ll("-1.23", "-1", 1); test_d2ll("-9223372036854775807", "-9223372036854775807", 0); @@ -3131,12 +3132,12 @@ int main() printf("==== decimal2string ====\n"); test_pr("123.123", 0, 0, 0, "123.123", 0); - test_pr("123.123", 7, 3, '0', "123.123", 0); - test_pr("123.123", 9, 3, '0', "00123.123", 0); - test_pr("123.123", 9, 4, '0', "0123.1230", 0); - test_pr("123.123", 9, 5, '0', "123.12300", 0); - test_pr("123.123", 9, 2, '0', "000123.12", 1); - test_pr("123.123", 9, 6, '0', "23.123000", 2); + test_pr("123.123", 7, 3, '0', "0123.123", 0); + test_pr("123.123", 9, 3, '0', "000123.123", 0); + test_pr("123.123", 9, 4, '0', "00123.1230", 0); + test_pr("123.123", 9, 5, '0', "0123.12300", 0); + test_pr("123.123", 9, 2, '0', "0000123.12", 1); + test_pr("123.123", 8, 6, '0', "23.123000", 2); printf("==== decimal_shift ====\n"); test_sh("123.123", 1, "1231.23", 0);