• Marko Mäkelä's avatar
    Bug#17302896 DOUBLE PURGE ON ROLLBACK OF UPDATING A DELETE-MARKED RECORD · 31809607
    Marko Mäkelä authored
    There was a race condition in the rollback of TRX_UNDO_UPD_DEL_REC.
    
    Once row_undo_mod_clust() has rolled back the changes by the rolling-back
    transaction, it attempts to purge the delete-marked record, if possible, in a
    separate mini-transaction.
    
    However, row_undo_mod_remove_clust_low() fails to check if the DB_TRX_ID of
    the record that it found after repositioning the cursor, is still the same.
    If it is not, it means that the record was purged and another record was
    inserted in its place.
    
    So, the rollback would have performed an incorrect purge, breaking the
    locking rules and causing corruption.
    
    The problem was found by creating a table that contains a unique
    secondary index and a primary key, and two threads running REPLACE
    with only one value for the unique column, so that the uniqueness
    constraint would be violated all the time, leading to statement
    rollback.
    
    This bug exists in all InnoDB versions (I checked MySQL 3.23.53).
    It has become easier to repeat in 5.5 and 5.6 thanks to scalability
    improvements and a dedicated purge thread.
    
    rb#3085 approved by Jimmy Yang
    31809607
row0umod.c 18.7 KB