• Rinat Ibragimov's avatar
    MDEV-20946: Hard FTWRL deadlock under user level locks · fa5f6068
    Rinat Ibragimov authored
    It was possibile for a user to create an interlocked state which may go on
    for a significant period of time. There is a tight loop in the FTWRL code
    path that tries to repeatedly acquire a read lock. As the weight of FTWRL
    lock is the smallest among others, it's always selected by the deadlock
    detector, but can never be killed.
    
    Imaging the following sequence:
    
        connection_0                 connection_1
    
     GET_LOCK("l1", 0);
                                 LOCK TABLES t WRITE;
     FLUSH TABLES WITH READ LOCK;
                                 GET_LOCK("l1", 1000);
    
    The GET_LOCK statement in connection_1 triggers the deadlock detector,
    which tries to select the lock in FTWRL, since its weight is 0. However,
    since a loop in Global_read_lock::lock_global_read_lock() tries to always
    win, it tries to acquire lock again. Which invokes the deadlock detector,
    and that cycle continues until GET_LOCK in connection_1 times out.
    
    This patch resolves the live-locking by introducing a dynamic bonus to the
    deadlock weight associated with every lock. Each lock gets a bonus weight
    each time it's selected by the deadlock detector. In case of a live-lock
    situation, those locks that cannot be killed, get additional weight each
    iteration. Eventually their weight becomes so high that the deadlock
    detector shifts its attention to other lock, until it find the one that
    can be killed.
    fa5f6068
deadlock_ftwrl.result 527 Bytes