• Nikita Malyavin's avatar
    MDEV-33450 Assertion fails in main.alter_table_online_debug · c436b6a2
    Nikita Malyavin authored
    Assertion "from->s->online_alter_binlog == NULL" fails in
    copy_data_between_tables, signalizing that a table share is being reused
    (in another alter) after a lock upgrade to EXCLUSIVE fails.
    
    Commit 3059f274 relaxed the lock to be upgraded to MDL_SHARED_NO_WRITE, leaving
    it to happen later by a common path wait_while_table_is_used() call.
    
    However the error handling there is not enough for online alter case, where we
    require (for now) the table to be flushed, in order to clean up the memory
    properly.
    
    * Add another lock upgrade (to MDL_EXCLUSIVE) after the second replication stage
     in copy_data_between_tables.
    
    The error from this upgrade will be handled by the branch presented further in
    the function.
    
    MDEV-33450 Assertion fails in main.alter_table_online_debug
    
    `TABLE_SHARE` that is being online-altered has a shared `s->online_alter_binlog`
    member that all concurrent DMLs are writing to. Online alter thread deletes it
    under the MDL_EXCLUSIVE. If upgrading the lock to MDL_EXCLUSIVE fails, table as
    marked as `flushed` and it's freed automatically when its usage drops to zero.
    
    In commit 3059f274 the lock upgrade was relaxed to MDL_SHARED_NO_WRITE to allow
    concurrent SELECT threads during the final `online_alter_read_from_binlog()`
    pass. An attempt to upgrade the lock to MDL_EXCLUSIVE was still happening, but
    much later — after the code that marked the table `flushed`.
    
    That is, if the upgrade failed, the table was left with a stale
    `s->online_alter_binlog` triggering an assert in a future online alter.
    
    To fix this, upgrade the lock to MDL_EXCLUSIVE earlier, after the final
    `online_alter_read_from_binlog()`.
    c436b6a2
sql_table.cc 439 KB