mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Bug#53676: Unexpected errors and possible table
corruption on ADD PARTITION and LOCK TABLE Bug#53770: Server crash at handler.cc:2076 on LOAD DATA after timed out COALESCE PARTITION 5.5 fix for: Bug#51042: REORGANIZE PARTITION can leave table in an inconsistent state in case of crash Needs to be back-ported to 5.1 5.5 fix for: Bug#50418: DROP PARTITION does not interact with transactions Main problem was non-persistent operations done before meta-data lock was taken (53770+53676). And 53676 needed to keep the table/partitions opened and locked while copying the data to the new partitions. Also added thorough tests to spot some additional bugs in the ddl_log code, which could result in bad state between the .frm and partitions. Collapsed patch, includes all fixes required from the reviewers. mysql-test/r/partition_innodb.result: updated result with new test mysql-test/suite/parts/inc/partition_crash.inc: crash test include file mysql-test/suite/parts/inc/partition_crash_add.inc: test all states in fast_alter_partition_table ADD PARTITION branch mysql-test/suite/parts/inc/partition_crash_change.inc: test all states in fast_alter_partition_table CHANGE PARTITION branch mysql-test/suite/parts/inc/partition_crash_drop.inc: test all states in fast_alter_partition_table DROP PARTITION branch mysql-test/suite/parts/inc/partition_fail.inc: recovery test including injecting errors mysql-test/suite/parts/inc/partition_fail_add.inc: test all states in fast_alter_partition_table ADD PARTITION branch mysql-test/suite/parts/inc/partition_fail_change.inc: test all states in fast_alter_partition_table CHANGE PARTITION branch mysql-test/suite/parts/inc/partition_fail_drop.inc: test all states in fast_alter_partition_table DROP PARTITION branch mysql-test/suite/parts/inc/partition_mgm_crash.inc: include file that runs all crash and failure injection tests. mysql-test/suite/parts/r/partition_debug_innodb.result: new test result file mysql-test/suite/parts/r/partition_debug_myisam.result: new test result file mysql-test/suite/parts/r/partition_special_innodb.result: updated result mysql-test/suite/parts/r/partition_special_myisam.result: updated result mysql-test/suite/parts/t/partition_debug_innodb-master.opt: opt file for using with crashing tests of partitioned innodb mysql-test/suite/parts/t/partition_debug_innodb.test: partitioned innodb test that require debug builds mysql-test/suite/parts/t/partition_debug_myisam-master.opt: opt file for using with crashing tests of partitioned myisam mysql-test/suite/parts/t/partition_debug_myisam.test: partitioned myisam test that require debug builds mysql-test/suite/parts/t/partition_special_innodb-master.opt: added innodb-file-per-table to easier verify partition status on disk mysql-test/suite/parts/t/partition_special_innodb.test: added test case mysql-test/suite/parts/t/partition_special_myisam.test: added test case mysql-test/t/partition_innodb.test: added test case sql/sql_base.cc: Moved alter_close_tables to sql_partition.cc sql/sql_base.h: removed some non existing and duplicated functions. sql/sql_partition.cc: fast_alter_partition_table: Spletted abort_and_upgrad_lock_and_close_table to its parts (wait_while_table_is_used and alter_close_tables) and always have wait_while_table_is_used before any persistent operations (including logs, which will be executed on failure) and alter_close_tables after create/read/write operations and before drop operations. moved alter_close_tables here from sql_base.cc Added error injections for better test coverage. write_log_final_change_partition: fixed a log_entry linking bug (delete_frm was not linked to change/drop partition) and drop partition must be executed before change partition (change partition can rename a partition to an old name, like REORG p1 INTO (p1,p2). write_log_add_change_partition: need to use drop_frm first, and relinking that entry and reusing its execute entry. sql/sql_table.cc: added initialization of next_active_log_entry. sql/table.h: removed a duplicate declaration.
This commit is contained in:
@ -8889,87 +8889,6 @@ bool is_equal(const LEX_STRING *a, const LEX_STRING *b)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
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)
|
||||
{
|
||||
TABLE_SHARE *share= lpt->table->s;
|
||||
THD *thd= lpt->thd;
|
||||
TABLE *table;
|
||||
DBUG_ENTER("alter_close_tables");
|
||||
/*
|
||||
We must keep LOCK_open while manipulating with thd->open_tables.
|
||||
Another thread may be working on it.
|
||||
*/
|
||||
mysql_mutex_lock(&LOCK_open);
|
||||
/*
|
||||
We can safely remove locks for all tables with the same name:
|
||||
later they will all be closed anyway in
|
||||
alter_partition_lock_handling().
|
||||
*/
|
||||
for (table= thd->open_tables; table ; table= table->next)
|
||||
{
|
||||
if (!strcmp(table->s->table_name.str, share->table_name.str) &&
|
||||
!strcmp(table->s->db.str, share->db.str))
|
||||
{
|
||||
mysql_lock_remove(thd, thd->lock, table);
|
||||
table->file->close();
|
||||
table->db_stat= 0; // Mark file closed
|
||||
/*
|
||||
Ensure that we won't end up with a crippled table instance
|
||||
in the table cache if an error occurs before we reach
|
||||
alter_partition_lock_handling() and the table is closed
|
||||
by close_thread_tables() instead.
|
||||
*/
|
||||
tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,
|
||||
table->s->db.str,
|
||||
table->s->table_name.str);
|
||||
}
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_open);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
abort_and_upgrade_lock_and_close_table()
|
||||
lpt Parameter passing struct
|
||||
All parameters passed through the ALTER_PARTITION_PARAM_TYPE object
|
||||
RETURN VALUE
|
||||
0
|
||||
DESCRIPTION
|
||||
Remember old lock level (for possible downgrade later on), abort all
|
||||
waiting threads and ensure that all keeping locks currently are
|
||||
completed such that we own the lock exclusively and no other interaction
|
||||
is ongoing. Close the table and hold the name lock.
|
||||
|
||||
thd Thread object
|
||||
table Table object
|
||||
db Database name
|
||||
table_name Table name
|
||||
old_lock_level Old lock level
|
||||
*/
|
||||
|
||||
int abort_and_upgrade_lock_and_close_table(ALTER_PARTITION_PARAM_TYPE *lpt)
|
||||
{
|
||||
DBUG_ENTER("abort_and_upgrade_lock_and_close_table");
|
||||
|
||||
if (wait_while_table_is_used(lpt->thd, lpt->table, HA_EXTRA_FORCE_REOPEN))
|
||||
DBUG_RETURN(1);
|
||||
if (alter_close_tables(lpt))
|
||||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Tells if two (or more) tables have auto_increment columns and we want to
|
||||
lock those tables with a write lock.
|
||||
|
Reference in New Issue
Block a user