• Dmitry Lenev's avatar
    Implementation of simple deadlock detection for metadata locks. · 236539b4
    Dmitry Lenev authored
    This change is supposed to reduce number of ER_LOCK_DEADLOCK
    errors which occur when multi-statement transaction encounters
    conflicting metadata lock in cases when waiting is possible.
    
    The idea is not to fail ER_LOCK_DEADLOCK error immediately when
    we encounter conflicting metadata lock. Instead we release all
    metadata locks acquired by current statement and start to wait
    until conflicting lock go away. To avoid deadlocks we use simple
    empiric which aborts waiting with ER_LOCK_DEADLOCK error if it
    turns out that somebody is waiting for metadata locks owned by
    this transaction.
    
    This patch also fixes bug #46273 "MySQL 5.4.4 new MDL: Bug#989
    is not fully fixed in case of ALTER".
    
    The bug was that concurrent execution of UPDATE or MULTI-UPDATE
    statement as a part of multi-statement transaction that already
    has used table being updated and ALTER TABLE statement might have
    resulted of loss of isolation between this transaction and ALTER
    TABLE statement, which manifested itself as changes performed by
    ALTER TABLE becoming visible in transaction and wrong binary log
    order as a consequence.
    
    This problem occurred when UPDATE or MULTI-UPDATE's wait in
    mysql_lock_tables() call was aborted due to metadata lock
    upgrade performed by concurrent ALTER TABLE. After such abort all
    metadata locks held by transaction were released but transaction
    silently continued to be executed as if nothing has happened.
    
    We solve this problem by changing our code not to release all
    locks in such case. Instead we release only locks which were
    acquired by current statement and then try to reacquire them
    by restarting open/lock tables process. We piggyback on simple
    deadlock detector implementation since this change has to be
    done anyway for it.
    236539b4
handler.inc 35 KB