MySQL semi-consistent reading principle analysis - analysis from the source code point of view

1. What is semi-consistent read

A type of read operation used for UPDATE statements, that is a combination of read committed and consistent read. When an UPDATE statement examines a row that is already locked, InnoDB returns the latest committed version to MySQL so that MySQL can determine whether the row matches the WHERE condition of the UPDATE. If the row matches (must be updated), MySQL reads the row again, and this time InnoDB either locks it or waits for a lock on it. This type of read operation can only happen when the transaction has the read committed isolation level, or when the innodb_locks_unsafe_for_binlog option is enabled.

It happens in the update statement. When the RC isolation level or innodb_locks_unsafe_for_binlog is set to true, during concurrent, if the update record has lock waiting, then return the prev version of the record (the lock waiting for the lock will be removed from trx before returning), to the mysql layer Where to judge whether the conditions are met. If the where condition is met, then enter the innodb layer again, and lock or wait for a lock to occur.

The advantages of this are: reduce lock conflicts and lock waiting for the same row of records; when there is no concurrency conflict, directly read the latest version and lock, when there is a conflict, do not lock, read the prev version without lock waiting.

Disadvantage: Non-conflicting serial conversation strategy, not safe for binlog. Can only happen under RC isolation level and innodb_lock_unsafe_for_binlog.

2. Principle
MySQL semi-consistent reading principle analysis - analysis from the source code point of view
3. Explanation

1) Semi-consistent read requires the use of the mysql layer and the innodb layer.

2) In the mysql_update function, try_semi_consistent_read will be called by default to add a semi-consistent read tag under RC or innodb_lock_unsafe_for_binlog: prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT. The actual execution of semi-consistent reads is determined by the innodb layer.

3) Conditions for semi-consistent read: the record has a lock wait; it must be a full table scan && the index is a secondary index

4) When reading semi-consistently, build the prev version, and then call the function lock_trx_handle_wait to remove the lock waiting from trx.

5) Before returning to prev rec, it will be set as a semi-consistent read tag: prebuilt->row_read_type = ROW_READ_DID_SEMI_CONSISTENT

6) Return to the mysql layer, where judgment will be made. If it matches, it will enter the innodb layer again. Since prebuilt->row_read_type == ROW_READ_DID_SEMI_CONSISTENT, the process of semi-consistent read judgment will not be taken at this time, and it will directly enter the lock or lock wait.

5) There is an optimization for update here: if the execution plan of the innodb layer is index pushdown, it will be judged in advance whether the where condition matches. If it does not match, call the function row_unlock_for_mysql in advance to release the lock on the clustered index

6) Another optimization: After returning to the mysql layer, if it is judged that the where does not match, the unlock_row function will be called to release the lock. Note: There is no lock conflict at the innodb layer for update here, and the lock is successfully added. i.e. no semi-consistent reads

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324654612&siteId=291194637