From c5e00fea102f0f8d614f60f39737b55dd09b4062 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 1 Nov 2019 19:18:47 +0400 Subject: [PATCH] MDEV-20867 - Perform careful review of "Server crashes with BACKUP STAGE and FLUSH TABLE table_name" Reverted original patch (c2e0a0b). For consistency with "LOCK TABLE READ" and "FLUSH TABLES WITH READ LOCK", which are forbidden under "BACKUP STAGE", forbid "FLUSH TABLE FOR EXPORT" and "FLUSH TABLE WITH READ LOCK" as well. It'd allow consistent fixes for problems like MDEV-18643. --- mysql-test/main/backup_interaction.result | 24 +++----------------- mysql-test/main/backup_interaction.test | 27 +++-------------------- sql/mdl.cc | 11 +++------ sql/sql_class.cc | 1 + sql/sql_reload.cc | 6 +++++ 5 files changed, 16 insertions(+), 53 deletions(-) diff --git a/mysql-test/main/backup_interaction.result b/mysql-test/main/backup_interaction.result index f1354f6778e..3c3071b8e70 100644 --- a/mysql-test/main/backup_interaction.result +++ b/mysql-test/main/backup_interaction.result @@ -521,26 +521,8 @@ BACKUP STAGE END; CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY, f INT); BACKUP STAGE START; FLUSH TABLE t1 FOR EXPORT; -UNLOCK TABLES; -BACKUP STAGE END; -DROP TABLE t1; -CREATE TABLE t1 (a INT); -BACKUP STAGE START; -FLUSH TABLE t1 FOR EXPORT; -UNLOCK TABLES; -connect con1,localhost,root,,test; -BACKUP STAGE START; -connection default; -BACKUP STAGE END; -connection con1; -BACKUP STAGE END; -disconnect con1; -connection default; -DROP TABLE t1; -CREATE TABLE t1 (a INT); -BACKUP STAGE START; -FLUSH TABLES t1 WITH READ LOCK; -UNLOCK TABLES; -BACKUP STAGE BLOCK_COMMIT; +ERROR HY000: Can't execute the command as you have a BACKUP STAGE active +FLUSH TABLE t1 WITH READ LOCK; +ERROR HY000: Can't execute the command as you have a BACKUP STAGE active BACKUP STAGE END; DROP TABLE t1; diff --git a/mysql-test/main/backup_interaction.test b/mysql-test/main/backup_interaction.test index 8ac905cc6ff..09ed769c898 100644 --- a/mysql-test/main/backup_interaction.test +++ b/mysql-test/main/backup_interaction.test @@ -509,30 +509,9 @@ BACKUP STAGE END; CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY, f INT); BACKUP STAGE START; +--error ER_BACKUP_LOCK_IS_ACTIVE FLUSH TABLE t1 FOR EXPORT; -UNLOCK TABLES; -BACKUP STAGE END; -DROP TABLE t1; - -CREATE TABLE t1 (a INT); -BACKUP STAGE START; -FLUSH TABLE t1 FOR EXPORT; -UNLOCK TABLES; ---connect (con1,localhost,root,,test) ---send BACKUP STAGE START ---connection default -BACKUP STAGE END; ---connection con1 -reap; -BACKUP STAGE END; ---disconnect con1 ---connection default -DROP TABLE t1; - -CREATE TABLE t1 (a INT); -BACKUP STAGE START; -FLUSH TABLES t1 WITH READ LOCK; -UNLOCK TABLES; -BACKUP STAGE BLOCK_COMMIT; +--error ER_BACKUP_LOCK_IS_ACTIVE +FLUSH TABLE t1 WITH READ LOCK; BACKUP STAGE END; DROP TABLE t1; diff --git a/sql/mdl.cc b/sql/mdl.cc index e7c0d699d76..591127dc1d8 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -3166,19 +3166,14 @@ void MDL_context::set_transaction_duration_for_all_locks() DBUG_ASSERT(m_tickets[MDL_STATEMENT].is_empty()); - /* Don't swap locks if this thread is running backup stages */ - if (current_thd->current_backup_stage == BACKUP_FINISHED) - m_tickets[MDL_TRANSACTION].swap(m_tickets[MDL_EXPLICIT]); + m_tickets[MDL_TRANSACTION].swap(m_tickets[MDL_EXPLICIT]); Ticket_iterator it_ticket(m_tickets[MDL_EXPLICIT]); while ((ticket= it_ticket++)) { - if (ticket->get_key()->mdl_namespace() != MDL_key::BACKUP) - { - m_tickets[MDL_EXPLICIT].remove(ticket); - m_tickets[MDL_TRANSACTION].push_front(ticket); - } + m_tickets[MDL_EXPLICIT].remove(ticket); + m_tickets[MDL_TRANSACTION].push_front(ticket); } #ifndef DBUG_OFF diff --git a/sql/sql_class.cc b/sql/sql_class.cc index d8d4b9a8d64..84e18e71a80 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5580,6 +5580,7 @@ void THD::leave_locked_tables_mode() { if (locked_tables_mode == LTM_LOCK_TABLES) { + DBUG_ASSERT(current_backup_stage == BACKUP_FINISHED); /* When leaving LOCK TABLES mode we have to change the duration of most of the metadata locks being held, except for HANDLER and GRL locks, diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 0e166b169aa..0898bea6d41 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -525,6 +525,12 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables) goto error; } + if (thd->current_backup_stage != BACKUP_FINISHED) + { + my_error(ER_BACKUP_LOCK_IS_ACTIVE, MYF(0)); + return true; + } + if (thd->lex->type & REFRESH_READ_LOCK) { /*