undolog 快照读 mvcc

338 阅读2分钟

快照读

普通读的执行方式是生成 ReadView,直接利用 MVCC 机制来进行读取,并不会对记录进行加锁。

普通读是通过 mvcc实现,具体是 undo log + readview 来实现的

MVCC解决的问题

1.读写不阻塞,提升并发能力 2.降低死锁概率,使用乐观锁,读不需要加锁 3.解决一致性读的问题,保证数据可见性,不存在幻读

undo log

在数据更改时,不但记录redo log,还记录了undo log,如果某些原因导致事物失败或者回滚,就可以借助undo log回滚

insert undo log: insert生成的undo log,回滚时为删除操作,只在事务回滚时需要,事务提交后就可以删除了

update undo log: update delete 时生成的undo log,delete也被视为更新

结构: 每行数据都包含隐藏字段, DB_TRX_ID,DB_ROLL_PTR

DB_TRX_ID:数据版本事务id DB_ROLL_PTR:数据回滚地址指针

生成过程: 1.排它锁锁定改行数据 , 记录binlog , redo log 2.把修改前的数据copy到 undo log 3.更新当前行数据隐藏的事物id 和 回滚数据指针

释放undo log:

undo log如果不删除,链表会越来越大,mysql通过purge线程清理 .

purge :会维护一个readview,用来删除比活跃事物还早的log.

insert undo log事务提交后可以删除.

Read View 读视图

RR:开启事务后第一个select生成readview RC:每次select生成readview

Read View 保存了当前事务开启时所有活跃的事务列表

  1. trx_ids 系统当前正在活跃的事务ID集合。
  2. low_limit_id ,活跃事务的最大的事务 ID。
  3. up_limit_id 活跃的事务中最小的事务 ID。
  4. creator_trx_id,创建这个 ReadView 的事务ID。

查询数据过程

  1. 获取事务自己的版本号,即 事务ID
  2. 获取 Read View
  3. 查询得到的数据,然后 Read View 中的事务版本号进行比较。
  4. 如果不符合 ReadView 规则, 那么就需要 UndoLog 中历史快照;
  5. 最后返回符合规则的数据