Skip to content

Commit e63c53e

Browse files
author
Vidhya Sree Rajuladevi
committed
Bug #36677952 - killing DDL on partitioned tables: Assertion failure: dict0dict.cc:1887:table->get_ref_count() == 0
SYMPTOM: - There is a crash that is occuring in a scenario where multiple connections are opened on mysql client with below operations are ran continuously: a) conn1 - create multiple tables b) conn2 - 'replace into' and 'delete from' the tables c) conn3 - 'alter table rebuild partition' d) conn4 - kill all the connections where alter table is running ROOT CAUSE: - When kill is called, alter table goes into cleanup which leads to removal of table from dict cache. table->get_ref_count() refers to number of handles the table is opened from. The problem occurs when the race condition is hit where server tries to remove table from dict cache but the table's n_ref_count is >0. - In dict_partitioned_table_remove_from_cache(), the if condition compares strings of name and prev_tabl-> name only until length of name. If name is t1 and prev_table is t123, it will recognize as true and tries to remove t123 from dict cache. SOLUTION: - The idea is to check if prev_table->name starts with the name with PART_SEPARATOR appended, so that it filters only those partitions or subpartitions of table with "name" and removes from dict cache. Change-Id: Ibd66dbca37fcbca52dc3b27c46d21bafe908b994
1 parent 8fb2245 commit e63c53e

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

sql/sql_table.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13608,6 +13608,8 @@ static bool mysql_inplace_alter_table(
1360813608
close_temporary_table(thd, altered_table, true, false);
1360913609
rollback_needs_dict_cache_reset = true;
1361013610

13611+
DEBUG_SYNC(thd, "alter_table_inplace_will_need_reset");
13612+
1361113613
/*
1361213614
Replace table definition in the data-dictionary.
1361313615

storage/innobase/dict/dict0dict.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1983,6 +1983,8 @@ void dict_partitioned_table_remove_from_cache(const char *name) {
19831983
ut_ad(dict_sys_mutex_own());
19841984

19851985
size_t name_len = strlen(name);
1986+
const auto name_with_separator =
1987+
std::string{name, name_len} + dict_name::PART_SEPARATOR;
19861988

19871989
for (uint32_t i = 0; i < hash_get_n_cells(dict_sys->table_id_hash); ++i) {
19881990
dict_table_t *table;
@@ -2000,8 +2002,10 @@ void dict_partitioned_table_remove_from_cache(const char *name) {
20002002
continue;
20012003
}
20022004

2003-
if ((strncmp(name, prev_table->name.m_name, name_len) == 0) &&
2004-
dict_table_is_partition(prev_table)) {
2005+
/* Find all the partitions or subpartitions of table with name */
2006+
if (!strncmp(name_with_separator.data(), prev_table->name.m_name,
2007+
name_with_separator.size())) {
2008+
ut_a(dict_table_is_partition(prev_table));
20052009
btr_drop_ahi_for_table(prev_table);
20062010
dict_table_remove_from_cache(prev_table);
20072011
}

0 commit comments

Comments
 (0)