mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with
concurrent I_S query There were two problem: 1) MYSQL_LOCK_IGNORE_FLUSH also ignored name locks 2) there was a race between abort_and_upgrade_locks and alter_close_tables (i.e. remove_table_from_cache and close_data_files_and_morph_locks) Which allowed the table to be opened with MYSQL_LOCK_IGNORE_FLUSH flag resulting in renaming a partition that was already in use, which could cause the table to be unusable. Solution was to not allow IGNORE_FLUSH to skip waiting for a named locked table. And to not release the LOCK_open mutex between the calls to remove_table_from_cache and close_data_files_and_morph_locks by merging the functions abort_and_upgrade_locks and alter_close_tables. mysql-test/suite/parts/r/partition_debug_sync_innodb.result: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Added test result mysql-test/suite/parts/t/partition_debug_sync_innodb-master.opt: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Added test option mysql-test/suite/parts/t/partition_debug_sync_innodb.test: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Added test file sql/authors.h: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Time to be acknowledged :) sql/ha_partition.cc: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Added DEBUG_SYNC for deterministic testing sql/mysql_priv.h: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Renamed function since merging alter_close_tables into abort_and_upgrade_lock. sql/sql_base.cc: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Changed MYSQL_LOCK_IGNORE_FLUSH to not ignore name locks (open_placeholder). Merged alter_close_tables into abort_and_upgrade_locks (and added _and_close_table to the name) to not release LOCK_open between remove_table_from_cache and close_data_files_and_morph_locks. Added DEBUG_SYNC for deterministic testing. sql/sql_partition.cc: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Removed alter_close_tables, (merged it into abort_and_upgrad_lock) so that LOCK_open never is released between remove_table_from_cache and close_data_files_and_morph_locks. sql/sql_show.cc: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Added DEBUG_SYNC for deterministic testing
This commit is contained in:
@@ -5955,32 +5955,6 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Unlock and close table before renaming and dropping partitions
|
||||
SYNOPSIS
|
||||
alter_close_tables()
|
||||
lpt Struct carrying parameters
|
||||
RETURN VALUES
|
||||
0
|
||||
*/
|
||||
|
||||
static int alter_close_tables(ALTER_PARTITION_PARAM_TYPE *lpt)
|
||||
{
|
||||
THD *thd= lpt->thd;
|
||||
const char *db= lpt->db;
|
||||
const char *table_name= lpt->table_name;
|
||||
DBUG_ENTER("alter_close_tables");
|
||||
/*
|
||||
We need to also unlock tables and close all handlers.
|
||||
We set lock to zero to ensure we don't do this twice
|
||||
and we set db_stat to zero to ensure we don't close twice.
|
||||
*/
|
||||
pthread_mutex_lock(&LOCK_open);
|
||||
close_data_files_and_morph_locks(thd, db, table_name);
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Handle errors for ALTER TABLE for partitioning
|
||||
@@ -6278,9 +6252,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
||||
write_log_drop_partition(lpt) ||
|
||||
ERROR_INJECT_CRASH("crash_drop_partition_3") ||
|
||||
(not_completed= FALSE) ||
|
||||
abort_and_upgrade_lock(lpt) || /* Always returns 0 */
|
||||
ERROR_INJECT_CRASH("crash_drop_partition_4") ||
|
||||
alter_close_tables(lpt) ||
|
||||
abort_and_upgrade_lock_and_close_table(lpt) ||
|
||||
ERROR_INJECT_CRASH("crash_drop_partition_5") ||
|
||||
((!thd->lex->no_write_to_binlog) &&
|
||||
(write_bin_log(thd, FALSE,
|
||||
@@ -6345,9 +6317,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
||||
ERROR_INJECT_CRASH("crash_add_partition_2") ||
|
||||
mysql_change_partitions(lpt) ||
|
||||
ERROR_INJECT_CRASH("crash_add_partition_3") ||
|
||||
abort_and_upgrade_lock(lpt) || /* Always returns 0 */
|
||||
ERROR_INJECT_CRASH("crash_add_partition_4") ||
|
||||
alter_close_tables(lpt) ||
|
||||
abort_and_upgrade_lock_and_close_table(lpt) ||
|
||||
ERROR_INJECT_CRASH("crash_add_partition_5") ||
|
||||
((!thd->lex->no_write_to_binlog) &&
|
||||
(write_bin_log(thd, FALSE,
|
||||
@@ -6435,9 +6405,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
||||
write_log_final_change_partition(lpt) ||
|
||||
ERROR_INJECT_CRASH("crash_change_partition_4") ||
|
||||
(not_completed= FALSE) ||
|
||||
abort_and_upgrade_lock(lpt) || /* Always returns 0 */
|
||||
ERROR_INJECT_CRASH("crash_change_partition_5") ||
|
||||
alter_close_tables(lpt) ||
|
||||
abort_and_upgrade_lock_and_close_table(lpt) ||
|
||||
ERROR_INJECT_CRASH("crash_change_partition_6") ||
|
||||
((!thd->lex->no_write_to_binlog) &&
|
||||
(write_bin_log(thd, FALSE,
|
||||
|
Reference in New Issue
Block a user