Commit 4f42f0d1 authored by Marko Mäkelä's avatar Marko Mäkelä

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.
parent 34045af0
......@@ -507,7 +507,8 @@ dict_table_try_drop_aborted(
ut_ad(table->id == table_id);
}
if (table && table->n_ref_count == ref_count && table->drop_aborted) {
if (table && table->n_ref_count == ref_count && table->drop_aborted
&& !UT_LIST_GET_FIRST(table->locks)) {
/* Silence a debug assertion in row_merge_drop_indexes(). */
ut_d(table->n_ref_count++);
row_merge_drop_indexes(trx, table, TRUE);
......
......@@ -2907,7 +2907,8 @@ row_merge_drop_indexes(
A concurrent purge will be prevented by dict_operation_lock. */
if (!locked && table->n_ref_count > 1) {
if (!locked && (table->n_ref_count > 1
|| UT_LIST_GET_FIRST(table->locks))) {
/* We will have to drop the indexes later, when the
table is guaranteed to be no longer in use. Mark the
indexes as incomplete and corrupted, so that other
......
......@@ -507,7 +507,8 @@ dict_table_try_drop_aborted(
ut_ad(table->id == table_id);
}
if (table && table->n_ref_count == ref_count && table->drop_aborted) {
if (table && table->n_ref_count == ref_count && table->drop_aborted
&& !UT_LIST_GET_FIRST(table->locks)) {
/* Silence a debug assertion in row_merge_drop_indexes(). */
ut_d(table->n_ref_count++);
row_merge_drop_indexes(trx, table, TRUE);
......
......@@ -2911,7 +2911,8 @@ row_merge_drop_indexes(
A concurrent purge will be prevented by dict_operation_lock. */
if (!locked && table->n_ref_count > 1) {
if (!locked && (table->n_ref_count > 1
|| UT_LIST_GET_FIRST(table->locks))) {
/* We will have to drop the indexes later, when the
table is guaranteed to be no longer in use. Mark the
indexes as incomplete and corrupted, so that other
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment