From 14e1385691a4a6c19f26e0ecc9df006dd9196396 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 17 Dec 2019 23:00:23 +0400 Subject: [PATCH] Proper locking for mysql.gtid_slave_pos truncation Aim of this patch is to remove tdc_remove_table(TDC_RT_REMOVE_UNUSED), which was mistakenly introduced by 055a3334a. InnoDB allows only one open TABLE instance while performing table truncation. To fulfill this requirement: 1. MDL_EXCLUSIVE has to be acquired to block concurrent threads from accessing given table 2. cached TABLE instances have to be flushed 3. another InnoDB requirement is such that TABLE_SHARE and remaining TABLE instance have to be invalidated and re-opened after truncation This goes more or less inline with what regular TRUNCATE TABLE does. Alternative solution would be handler::ha_delete_all_rows(), but InnoDB doesn't implement it unfortunately. Part of MDEV-17882 - Cleanup refresh version --- sql/rpl_gtid.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc index 02f1cd616d3..be347cc5fad 100644 --- a/sql/rpl_gtid.cc +++ b/sql/rpl_gtid.cc @@ -425,11 +425,12 @@ rpl_slave_state::truncate_state_table(THD *thd) tlist.init_one_table(&MYSQL_SCHEMA_NAME, &rpl_gtid_slave_state_table_name, NULL, TL_WRITE); + tlist.mdl_request.set_type(MDL_EXCLUSIVE); if (!(err= open_and_lock_tables(thd, &tlist, FALSE, MYSQL_OPEN_IGNORE_LOGGING_FORMAT))) { DBUG_ASSERT(!tlist.table->file->row_logging); - tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, "mysql", + tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN, "mysql", rpl_gtid_slave_state_table_name.str); err= tlist.table->file->ha_truncate();