-
Annamalai Gurusami authored
Problem: Consider a clustered index page P1 holding a record r1. Let two sessions S1 and S2 operate on the page P1. Let S1 hold an exclusive lock on r1. Let S2 attempt to take an exclusive lock on r1. Now there will be two locks L1 and L2 on the record r1. Let L1 be the granted lock and L2 be the waiting lock. Let S1 initiate a page reorganize of P1. The locks will also be reorganized. During this reorganize if the lock is reorganized in the order L2, L1 then the assert in function lock_rec_add_to_queue() fails. if (!(type_mode & (LOCK_WAIT | LOCK_GAP))) { lock_mode mode = (type_mode & LOCK_MODE_MASK) == LOCK_S ? LOCK_X : LOCK_S; const lock_t* other_lock = lock_rec_other_has_expl_req( mode, block, false, heap_no, trx); ut_a(!other_lock); } Notice the 3rd argument to lock_rec_other_has_expl_req(). We have requested that wait locks are not to be considered. Even then the assert has failed. Solution: There seems to be problem in the if condition in function lock_rec_other_has_expl_req(). if (lock->trx != trx && !lock_rec_get_gap(lock) && (!wait || !lock_get_wait(lock)) && lock_mode_stronger_or_eq(lock_get_mode(lock), mode)) { return(lock); } The truth table of the relevant expression is given below: lock_get_wait wait (!wait || !lock_get_wait) 1 1 0 1 0 1 =====>> CHECK? 0 0 1 0 1 1 The correct one is as follows: lock_get_wait wait (wait || !lock_get_wait) 1 1 1 1 0 0 0 0 1 0 1 1 The solution is to use the expression "(wait || !lock_get_wait)". Additional Change: While reorganizing the page, we can process the granted locks before processing the waiting locks. rb#9289 approved by Marko.
Annamalai Gurusami authoredProblem: Consider a clustered index page P1 holding a record r1. Let two sessions S1 and S2 operate on the page P1. Let S1 hold an exclusive lock on r1. Let S2 attempt to take an exclusive lock on r1. Now there will be two locks L1 and L2 on the record r1. Let L1 be the granted lock and L2 be the waiting lock. Let S1 initiate a page reorganize of P1. The locks will also be reorganized. During this reorganize if the lock is reorganized in the order L2, L1 then the assert in function lock_rec_add_to_queue() fails. if (!(type_mode & (LOCK_WAIT | LOCK_GAP))) { lock_mode mode = (type_mode & LOCK_MODE_MASK) == LOCK_S ? LOCK_X : LOCK_S; const lock_t* other_lock = lock_rec_other_has_expl_req( mode, block, false, heap_no, trx); ut_a(!other_lock); } Notice the 3rd argument to lock_rec_other_has_expl_req(). We have requested that wait locks are not to be considered. Even then the assert has failed. Solution: There seems to be problem in the if condition in function lock_rec_other_has_expl_req(). if (lock->trx != trx && !lock_rec_get_gap(lock) && (!wait || !lock_get_wait(lock)) && lock_mode_stronger_or_eq(lock_get_mode(lock), mode)) { return(lock); } The truth table of the relevant expression is given below: lock_get_wait wait (!wait || !lock_get_wait) 1 1 0 1 0 1 =====>> CHECK? 0 0 1 0 1 1 The correct one is as follows: lock_get_wait wait (wait || !lock_get_wait) 1 1 1 1 0 0 0 0 1 0 1 1 The solution is to use the expression "(wait || !lock_get_wait)". Additional Change: While reorganizing the page, we can process the granted locks before processing the waiting locks. rb#9289 approved by Marko.
Loading