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.
This commit is contained in:
parent
34045af03f
commit
4f42f0d1ea
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user