cond1 = true - i.e. the the lock caused by foreign key check is not "insert intention lock";
cond2 = false - as our isolation level is READ COMMITTED, and the lock should not be inherited to avoid gap lock;
cond3 = true - because lock->trx->duplicates is 0 (as I understood correct, this means that the lock was not caused by "REPLACE" or "INSERT ... ON DUPLICATE KEY UPDATE ...") and the lock itself is LOCK_S.
The only thing which I don't fully understand is cond3. Here is the comment for the above code:
/* If srv_locks_unsafe_for_binlog is TRUE or session is using
READ COMMITTED isolation level, we do not want locks set
by an UPDATE or a DELETE to be inherited as gap type locks. But we
DO want S-locks/X-locks(taken for replace) set by a consistency
constraint to be inherited also then */
The first sentence corresponds to the (cond1 && cond2).
The second sentence corresponds to cond3.
This condition should be modified because it means that any S-lock, which is not caused by "REPLACE" or "INSERT ... ON DUPLICATE KEY UPDATE ..." statements, must be inherited despite on cond2(despite isolation level). I think this is not corresponds to the initial intention.
I think "REPLACE" or "INSERT ... ON DUPLICATE KEY UPDATE ..." case should be considered separately, as described in the code comments above, but this specific condition cond3 is wrong. To fix it we need to understand the initial intention about the S-LOCK in cond3.
The condition in comment 11 can be rewritten as:
!lock_ rec_get_ insert_ intention( lock) && srv_locks_ unsafe_ for_binlog || lock->trx- >isolation_ level <= TRX_ISO_ READ_COMMITTED) || get_mode( lock) == (lock-> trx->duplicates ? LOCK_X : LOCK_S))
(!(
lock_
It can be divided into three parts:
bool cond1 = !lock_rec_ get_insert_ intention( lock); unsafe_ for_binlog || lock->trx- >isolation_ level <= TRX_ISO_ READ_COMMITTED) ; trx->duplicates ? LOCK_X : LOCK_S);
bool cond2 = !(srv_locks_
bool cond3 = lock_get_mode(lock) == (lock->
So, it can be rewritten as:
cond1 && (cond2 || cond3)
If we consider our test case then:
cond1 = true - i.e. the the lock caused by foreign key check is not "insert intention lock";
cond2 = false - as our isolation level is READ COMMITTED, and the lock should not be inherited to avoid gap lock;
cond3 = true - because lock->trx- >duplicates is 0 (as I understood correct, this means that the lock was not caused by "REPLACE" or "INSERT ... ON DUPLICATE KEY UPDATE ...") and the lock itself is LOCK_S.
The only thing which I don't fully understand is cond3. Here is the comment for the above code:
/* If srv_locks_ unsafe_ for_binlog is TRUE or session is using X-locks( taken for replace) set by a consistency
READ COMMITTED isolation level, we do not want locks set
by an UPDATE or a DELETE to be inherited as gap type locks. But we
DO want S-locks/
constraint to be inherited also then */
The first sentence corresponds to the (cond1 && cond2).
The second sentence corresponds to cond3.
This condition should be modified because it means that any S-lock, which is not caused by "REPLACE" or "INSERT ... ON DUPLICATE KEY UPDATE ..." statements, must be inherited despite on cond2(despite isolation level). I think this is not corresponds to the initial intention.
I think "REPLACE" or "INSERT ... ON DUPLICATE KEY UPDATE ..." case should be considered separately, as described in the code comments above, but this specific condition cond3 is wrong. To fix it we need to understand the initial intention about the S-LOCK in cond3.