Skip to content

Commit 4f42f0d

Browse files
committed
MDEV-16119 InnoDB lock->index refers to a freed object after failed ADD INDEX
The problem is hard to repeat, and I failed to create a deterministic test case. Online index creation creates stubs for to-be-created indexes. If index creation fails, we could remove these stubs while locks exist in the indexes. (This would require that the index creation was completed, and a concurrent DML operation acquired a lock on a record in the uncommitted index. If a duplicate key error occurs in an uncommitted index, the error will be reported for the CREATE UNIQUE INDEX, not for the DML operation that tried to insert the duplicate.) dict_table_try_drop_aborted(), row_merge_drop_indexes(): If transactional locks exist on the table, keep the table->indexes intact.
1 parent 34045af commit 4f42f0d

File tree

4 files changed

+8
-4
lines changed

4 files changed

+8
-4
lines changed

storage/innobase/dict/dict0dict.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,8 @@ dict_table_try_drop_aborted(
507507
ut_ad(table->id == table_id);
508508
}
509509

510-
if (table && table->n_ref_count == ref_count && table->drop_aborted) {
510+
if (table && table->n_ref_count == ref_count && table->drop_aborted
511+
&& !UT_LIST_GET_FIRST(table->locks)) {
511512
/* Silence a debug assertion in row_merge_drop_indexes(). */
512513
ut_d(table->n_ref_count++);
513514
row_merge_drop_indexes(trx, table, TRUE);

storage/innobase/row/row0merge.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2907,7 +2907,8 @@ row_merge_drop_indexes(
29072907
29082908
A concurrent purge will be prevented by dict_operation_lock. */
29092909

2910-
if (!locked && table->n_ref_count > 1) {
2910+
if (!locked && (table->n_ref_count > 1
2911+
|| UT_LIST_GET_FIRST(table->locks))) {
29112912
/* We will have to drop the indexes later, when the
29122913
table is guaranteed to be no longer in use. Mark the
29132914
indexes as incomplete and corrupted, so that other

storage/xtradb/dict/dict0dict.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,8 @@ dict_table_try_drop_aborted(
507507
ut_ad(table->id == table_id);
508508
}
509509

510-
if (table && table->n_ref_count == ref_count && table->drop_aborted) {
510+
if (table && table->n_ref_count == ref_count && table->drop_aborted
511+
&& !UT_LIST_GET_FIRST(table->locks)) {
511512
/* Silence a debug assertion in row_merge_drop_indexes(). */
512513
ut_d(table->n_ref_count++);
513514
row_merge_drop_indexes(trx, table, TRUE);

storage/xtradb/row/row0merge.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2911,7 +2911,8 @@ row_merge_drop_indexes(
29112911
29122912
A concurrent purge will be prevented by dict_operation_lock. */
29132913

2914-
if (!locked && table->n_ref_count > 1) {
2914+
if (!locked && (table->n_ref_count > 1
2915+
|| UT_LIST_GET_FIRST(table->locks))) {
29152916
/* We will have to drop the indexes later, when the
29162917
table is guaranteed to be no longer in use. Mark the
29172918
indexes as incomplete and corrupted, so that other

0 commit comments

Comments
 (0)