InnoDB---implementation of repeatable read isolation level

Implementation of repeatable reading

    Repeatable read isolation level, referred to as RR , in Section 2.1.1 , we said:

    Repeatable Read : During the execution of a transaction, you can see the newly inserted records that have been submitted by other transactions (reading those that have been submitted is actually reading those that were earlier than the start of this transaction and have been submitted), but you cannot see them. Other transactions update existing records (that is, started later than this transaction), and this transaction is not required to be "serializable" with other transactions.

    The core of this sentence is "but you cannot see updates to existing records by other transactions." So how does the RR isolation level ensure this?

    If the database concurrency control engine is a simple blocking protocol mechanism, it should determine whether the data item has been updated by other transactions when reading data. However, InnoDB did not do this. Instead, it set a "consistent read view (i.e. snapshot)" for the transaction under the RR isolation level in the following way . Afterwards, the data is read based on this snapshot. In this way, it cannot be read. Updates to existing records by transactions later than this transaction (updates to generate new versions must not be within the scope of the old snapshot).

static my_bool snapshot_handlerton(THD *thd, plugin_ref plugin, void *arg)

{

    handlerton *hton= plugin_data<handlerton*>(plugin);

    if (hton->state == SHOW_OPTION_YES && hton-> start_consistent_snapshot ) // start_consistent_snapshot is assigned when the isolation level is RR

    {

        hton-> start_consistent_snapshot (hton, thd); // For InnoDB , actually execute the innobase_start_trx_and_assign_read_view() function

        *((bool *)arg)= false;

    }

    return FALSE;

}

    As shown in Figure 11-4 and the code analysis below, trans_begin() will call the snapshot_handlerton () function pointer at the beginning of the transaction, that is, use the innobase_start_trx_and_assign_read_view () function to create a snapshot under the repeatable read isolation level, and no snapshot will be created at other isolation levels. .

InnoDB---implementation of repeatable read isolation level-Nahailanlan-Nahailanlan's blog
 

Figure 11-4 snapshot_handlerton () function context call diagram

 

innobase_start_trx_and_assign_read_view (   // Create a snapshot under the repeatable read isolation level, and no snapshot will be created at other isolation levels

    handlerton*    hton,    /*!< in: InnoDB handlerton */

    THD*           thd)     /*!< in: MySQL thread handle of the user for whom the transaction should be committed */

{...

    if (trx->isolation_level == TRX_ISO_REPEATABLE_READ ) { // If it is the RR isolation level, assign a value to the read view , that is, build a consistency view

        trx_assign_read_view (trx);  // Assign a value to the read consistency view (snapshot). Note that in store_lock() , the isolation level should be less than RR before closing the snapshot.

    } else {

        push_warning_printf(thd, Sql_condition::SL_WARNING,

                    HA_ERR_UNSUPPORTED,

                    "InnoDB: WITH CONSISTENT SNAPSHOT"

                    " was ignored because this phrase"

                    " can only be used with"

                    " REPEATABLE READ isolation level.");

    }

...

}

    After that, when each SQL statement is executed, it is judged according to the isolation level whether to use a new snapshot. If it is repeatable reading, the new snapshot will not be used and the old snapshot will be used. This can ensure that all read operations can see The same data state is reached; it also ensures that the read operations of different statements in the transaction block under the read committed isolation level do not see the same data state.

ha_innobase::store_lock(...)

{...

    if (lock_type != TL_IGNORE && trx->n_mysql_tables_in_use == 0) {

        trx->isolation_level = innobase_map_isolation_level((enum_tx_isolation) thd_tx_isolation(thd));

        if (trx->isolation_level <= TRX_ISO_READ_COMMITTED  // The isolation level is less than or equal to Read Committed, close the old snapshot. Repeatable reading does not close the old snapshot, so it can be used

            && MVCC::is_view_active(trx->read_view)) {

            /* At low transaction isolation levels we let each consistent read set its own snapshot */

            mutex_enter(&trx_sys->mutex);

            trx_sys->mvcc-> view_close (trx-> read_view , true);   // The isolation level is small, close the snapshot, so that when the next SQL is executed, a new snapshot will be obtained

            mutex_exit(&trx_sys->mutex);

        }

    }

...

}

    As can be seen from the above analysis, the implementation of repeatable reading in InnoDB utilizes snapshot technology that implements MVCC technology. This is where MVCC and blockade-based technologies come together, two non-control technologies.

Guess you like

Origin blog.csdn.net/fly2nn/article/details/70239809