快照读
普通读的执行方式是生成 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 保存了当前事务开启时所有活跃的事务列表
- trx_ids 系统当前正在活跃的事务ID集合。
- low_limit_id ,活跃事务的最大的事务 ID。
- up_limit_id 活跃的事务中最小的事务 ID。
- creator_trx_id,创建这个 ReadView 的事务ID。
查询数据过程
- 获取事务自己的版本号,即 事务ID
- 获取 Read View
- 查询得到的数据,然后 Read View 中的事务版本号进行比较。
- 如果不符合 ReadView 规则, 那么就需要 UndoLog 中历史快照;
- 最后返回符合规则的数据