-
Marko Mäkelä authored
Bug#14323614 Assert !dict_index_is_online_ddl(index) || dict_index_is_clust(index) || (flags & BTR_CREATE_FLAG) Race conditions are possible in online secondary index creation (WL#5526) when a successfully created index is removed by rollback_inplace_alter_table(), usually due to a lock wait timeout while waiting for the meta-data lock needed for commit_inplace_alter_table(commit=true). The non-DDL code (insert, update/delete, purge, rollback) was not prepared for the fact that index->online_status could be changed from ONLINE_INDEX_COMPLETE to ONLINE_INDEX_ABORTED or ONLINE_INDEX_ABORTED_DROPPED by rollback_inplace_alter_table(). Transaction rollback was accidentally race-free, because row_undo() holds dict_operation_lock S-latch, which conflicts with the X-latch acquired by rollback_inplace_alter_table(). But we fix the code anyway to avoid a regression if we later get rid of the S-latch in rollback. dict_index_online_trylog(): Replace with row_log_online_op_try(). Always check index->online_status while holding index->lock. dict_stats_should_ignore_index(): Fix a potential race condition between rollback_inplace_alter_table() and statistics collection. Do not try to collect statistics for any secondary indexes that are being or were created online, but have not been published yet. row_ins_sec_mtr_start_and_check_if_aborted(): Add the parameter search_mode to see if index->lock should be acquired in S or X mode. row_ins_sec_index_entry_low(): Invoke row_log_online_op() if needed. This replaces the dict_index_online_trylog() call in row_ins_sec_index_entry(). row_log_online_op(): Allow the caller to hold index->lock in S or X mode. row_purge_remove_sec_if_poss_tree(), row_purge_remove_sec_if_poss_leaf(): Check index->online_status after acquiring index->lock. These replace the check in row_purge_remove_sec_if_poss(). row_undo_ins_remove_sec_low(): Check index->online_status after acquiring index->lock. This replaces the check in row_undo_ins_remove_sec_rec(). row_undo_mod_del_mark_or_remove_sec_low(): Check index->online_status after acquiring index->lock. This replaces the check in row_undo_mod_del_mark_or_remove_sec(). row_undo_mod_del_unmark_sec_and_undo_update(): Check index->online_status after acquiring index->lock. row_upd_sec_index_entry(): Check index->online_status after acquiring index->lock, and log the change if needed. This fixes the reported assertion failure. row_upd_sec_online(): Remove. row_upd_sec_step(): Remove the checks for online index creation. They are now part of row_upd_sec_index_entry(). rb:1412 approved by Jimmy Yang
Marko Mäkelä authoredBug#14323614 Assert !dict_index_is_online_ddl(index) || dict_index_is_clust(index) || (flags & BTR_CREATE_FLAG) Race conditions are possible in online secondary index creation (WL#5526) when a successfully created index is removed by rollback_inplace_alter_table(), usually due to a lock wait timeout while waiting for the meta-data lock needed for commit_inplace_alter_table(commit=true). The non-DDL code (insert, update/delete, purge, rollback) was not prepared for the fact that index->online_status could be changed from ONLINE_INDEX_COMPLETE to ONLINE_INDEX_ABORTED or ONLINE_INDEX_ABORTED_DROPPED by rollback_inplace_alter_table(). Transaction rollback was accidentally race-free, because row_undo() holds dict_operation_lock S-latch, which conflicts with the X-latch acquired by rollback_inplace_alter_table(). But we fix the code anyway to avoid a regression if we later get rid of the S-latch in rollback. dict_index_online_trylog(): Replace with row_log_online_op_try(). Always check index->online_status while holding index->lock. dict_stats_should_ignore_index(): Fix a potential race condition between rollback_inplace_alter_table() and statistics collection. Do not try to collect statistics for any secondary indexes that are being or were created online, but have not been published yet. row_ins_sec_mtr_start_and_check_if_aborted(): Add the parameter search_mode to see if index->lock should be acquired in S or X mode. row_ins_sec_index_entry_low(): Invoke row_log_online_op() if needed. This replaces the dict_index_online_trylog() call in row_ins_sec_index_entry(). row_log_online_op(): Allow the caller to hold index->lock in S or X mode. row_purge_remove_sec_if_poss_tree(), row_purge_remove_sec_if_poss_leaf(): Check index->online_status after acquiring index->lock. These replace the check in row_purge_remove_sec_if_poss(). row_undo_ins_remove_sec_low(): Check index->online_status after acquiring index->lock. This replaces the check in row_undo_ins_remove_sec_rec(). row_undo_mod_del_mark_or_remove_sec_low(): Check index->online_status after acquiring index->lock. This replaces the check in row_undo_mod_del_mark_or_remove_sec(). row_undo_mod_del_unmark_sec_and_undo_update(): Check index->online_status after acquiring index->lock. row_upd_sec_index_entry(): Check index->online_status after acquiring index->lock, and log the change if needed. This fixes the reported assertion failure. row_upd_sec_online(): Remove. row_upd_sec_step(): Remove the checks for online index creation. They are now part of row_upd_sec_index_entry(). rb:1412 approved by Jimmy Yang
Loading