Skip to content
  • Marko Mäkelä's avatar
    f2f7d43a
    Bug#14756963 Assert !dict_index_is_online_ddl(index)||(flags&BTR_CREATE_FLAG) · f2f7d43a
    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
    f2f7d43a
    Bug#14756963 Assert !dict_index_is_online_ddl(index)||(flags&BTR_CREATE_FLAG)
    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
Loading