面试二十四、mysql之mvcc

1、mvcc:(multi-version concurrency control)多版本并发控制

  主要为了提高数据库并发性能

2、同一行数据在读写请求时会上锁阻塞住,mvcc实现了不需要加锁

  解决读写冲突的请求。

  注:这个读指的是快照读而不是当前读,当前读是一种加锁操作(悲观锁)

3、当前读:读取的数据记录都是当前最新版本,会对当前读取的行加锁防止事务修改。

  如下操作都是当前读:

    1)select * from db for update;

    2)update

    3)insert

    4)delete

4、快照读:基于mvcc实现,读到的数据记录有可能是历史版本。

  如:不加锁的select

5、数据库并发场景

  读-读:不需要并发控制

  读-写:有线程安全问题,可能造成事务隔离性问题(脏读、不可重复读、幻读)

  写-写:有线程安全问题,可能丢失更新记录

6、mvcc解决的问题

  1)解决了读操作不阻塞写操作,写操作不阻塞读操作

  2)解决了脏读、不可重复读、幻读的事务隔离性问题

7、mvcc原理

  通过版本链、undo日志、read view实现。mvcc会给每个事物分配一个单向

    增长的时间戳,每次数据修改都会记录一个版本,版本和时间戳关联。

  数据库隐藏字段:

    1)db_trx_id:最近修改此行数据事务id

    2)db_roll_pointer:回滚指针,指向上一个版本

    3)row_id:隐藏自增主键ID

  undolog:记录数据被修改过之前的旧数据,在表信息被修改前会将之前的数据拷贝进入undolog里,

    当事务回滚时可通过undolog数据还原

    1)结构:roll_pointer指针同样指向上个版本记录

  

 

    2)用途:

      保证事务进行回滚时的一致性和原子性,可通过undolog数据还原

      用于mvcc快照读的数据,通过undolog的历史版本数据可实现不同事务拥有自己的独立快照数据版本

    3)两种undolog

      insert undo log:insert时产生,只在事务回滚时需要,事务提交后丢弃

      update undo log:update时产生,事务回滚和快照读时都需要

  read view:在事务进行快照读时,会给当前数据系统生成一个快照版本

    1)属性

      trx_ids:记录当前系统活跃事务版本号集合

      low_limit_id:记录创建该读视图时最大的事务版本号+1

      up_limit_id:记录创建读视图时活跃事务中最小的版本号

      creator_trx_id:记录创建读视图的事务版本号

    2)可见性判断

      db_trx_id<up_limit_id || db_trx_id=creator_trx_id(可见)

        当前行数据记录的事务id小于创建读试图时的最小活跃事务id,即数据是在事务前就存在的

        当前行数据记录的事务id等于创建读视图的事务id,说明数据是自己修改的

      db_trx_id>=low_limit_id(不可见)

        当前行数据记录的事务id大于场景读视图时最大事务id,即数据是在事务后产生的

      db_trx_id是否在trx_ids中:

        不存在,说明事务已提交(可见)

        存在,说明我生成read view时,修改数据的事务未提交(不可见)

  rc和rr级别下快照读的区别:

    1)rc:每次快照读都会生成新的read view,所以会看到别的事务新提交的数据

    2)rr:只有在第一次快照读时会生成新的read view,并且记录下当时活跃的事务id列表,

        同一个事务在下一次快照读时直接读取之前生成的read view,所以看不到别的

        事务新提交的数据。

 

 

  

posted on 2021-09-02 10:47  Iversonstear  阅读(477)  评论(0编辑  收藏  举报

导航