Implementation of innodb isolation level principle

The difference between mysql database file
InnoDB and MyISAM
Innodb isolation level principle realizes
InnoDB master and backup replication

1. MVCC



    InnoDB is a multi-version storage engine: it keeps information about older versions of changed rows to support transactional features such as concurrency and rollback. MVCC can be thought of as a variant of row-level locking, but it is in many cases Locking operations are avoided, so the overhead is lower.



    innodb will add three fields to each row:
  • 6-byte ID field : Implicit primary key ID.
  • 6-byte DB_TRX_ID field : records the version of the transaction at the time of creation, and this version number increases continuously with the creation of the transaction.
  • 7-byte DB_ROLL_PTR field : records the pointer to the undo log record. The undo log is used for transaction rollback.
    MCVV only works under two isolation levels REPEATABLE READ and READ COMMITTED.

2. Transaction linked list

    Transactions in MySQL will be stored in a transaction linked list called trx_sys from the start to the submission process. This is a basic linked list structure:



    The new transaction (current transaction) and the committed transaction are not in the active transaction list.

3. undo log


    When transaction 1 changes the value of that row, it does the following:
  • lock the row with an exclusive lock
  • record redo log
  • Copy the value of the line before modification to the undo log, that is, the line below the above figure
  • Modify the value of the current row, fill in the transaction number, and make the rollback pointer point to the row before the modification in the undo log


Fourth, ReadView

    has the basis of the previous hidden column and transaction linked list, and then you can construct the key of MySQL to realize MVCC - ReadView.
    ReadView is a data structure that is created at the beginning of a transaction. This data structure contains 3 main members: ReadView{low_trx_id, up_trx_id, trx_ids}, in the case of concurrent, when a transaction starts, there are some uncommitted transactions in the trx_sys linked list, then which changes are to the current transaction Visible, which are invisible, this needs to be determined by ReadView. First, let's look at the meanings of the three members in ReadView:
  • low_trx_id indicates the largest transaction id number in the current transaction linked list when the transaction is started, that is, the largest transaction number created recently except itself;
  • up_trx_id indicates the smallest transaction id number in the current transaction linked list when the transaction starts, that is, the earliest but uncommitted transaction created in the current system;
  • trx_ids represents the id set of transactions in all transaction linked lists.

    The above three members form the main part of ReadView, and the simple diagram is as follows:




    The default isolation level of InnoDB is Repeatable Read (RR), which can be read repeatedly. InnoDB creates a global Read View before starting an RR read. Read Commited (RC) recreates the current read_view in the row_search_for_mysql function during each statement execution. Read View is used to determine the visibility of a record. Read View is defined in the read0read.h file.
The specific algorithm is as follows:

  1. Let the current transaction id of the row be trx_id, the earliest transaction id in the read view is up_trx_id, and the latest transaction id is low_trx_id.
  2. If trx_id < up_trx_id, it indicates that the transaction in which the row record is located has been committed before the new transaction is created, so the current value of the row record is visible. Skip to step 6.
  3. If trx_id>low_trx_id, it means that the transaction in which the row record belongs is opened after the new transaction is created, so the current value of the row record is not visible, and skip to step 5. Otherwise the current value of the row record is visible, skip to step 6.
  4. If up_trx_id<=trx_id<=low_trx_id, it indicates that the transaction in which the row record is located is active when the new transaction is created, traversing from up_trx_id to low_trx_id, if trx_id is equal to one of them, then no visible. Skip to step 5.
  5. Take the latest undo-log version number from the rollback segment pointed to by the DB_ROLL_PTR pointer recorded in this row, assign it the trx_id, and then skip to step 2.
  6. Returns the value of the visible row.



5. Transaction isolation level
  
    REPEATABLE READ (default isolation level)
    select : Before starting an RR read, a global Read View will be created. hallucinations
CREATE TABLE t (a INT NOT NULL, b INT) ENGINE = InnoDB;
INSERT INTO t VALUES (1,2),(2,3),(3,2),(4,3),(5,2);
UPDATE t SET b = 5 WHERE b = 3;

b field is an index: only records with b=3 will be locked
b field is not an index: all table records will be locked

x-lock(1,2); retain x-lock
x-lock(2,3); update(2,3) to (2,5); retain x-lock
x-lock(3,2); retain x-lock
x-lock(4,3); update(4,3) to (4,5); retain x-lock
x-lock(5,2); retain x-lock


    READ COMMITTED
    select : During each statement execution, a current read_view is recreated in the row_search_for_mysql function. Non-repeatable read
b field is an index: only records with b=3 will be locked.
b field is not an index: the entire table record will be locked first, and then the lock of the record with b!=3 will be released

x-lock(1,2); unlock(1,2)
x-lock(2,3); update(2,3) to (2,5); retain x-lock
x-lock(3,2); unlock(3,2)
x-lock(4,3); update(4,3) to (4,5); retain x-lock
x-lock(5,2); unlock(5,2)


    READ UNCOMMITTED
    select : Returns the latest record. Dirty read

    SERIALIZABLE
    select : InnoDB implicitly converts all normal SELECT statements to SELECT ... LOCK IN SHARE MODE. And through the gap locking (next-key locking) strategy to prevent the occurrence of phantom reads.

Guess you like

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