InnoDB多版本并发控制MVCC

前言

InnoDB维护旧版本数据来支持事务并发和回滚。旧版本信息会存储在系统表空间或者undo表空间里,以回滚段(rollback segment)的数据结构存储。当事务需要回滚的时候就会使用到这些回滚段来回滚,同时一致性读的时候也会用到这些回滚段。

注:
1、系统表空间:system tablespace,是InnoDB存储数据的空间,存储了doublewrite buffer、change buffer、undo logs,同时可能会存储表数据和索引数据。我们常见的ibdata1这种文件就存储在这个空间。
2、undo表空间:undo tablespaces,这个空间里存储了undo logs,能够节约其他表空间如system tablespace的使用,同时针对SSD存储该空间有做IO优化。

InnoDB架构图

实现原理

1、InnoDB向表里的每行增加三个字段

  • DB_TRX_ID,记录了上一次插入或者更新该行的事务id,删除操作也被视为更新操作
  • DB_ROLL_PTR,回滚指针,指向回滚段,如果一行被更新,那么更新之前undo log会记录这一行的信息。
  • DB_ROW_ID,如果是自增主键,这个值则包含自增主键,如果不是,那么该ID会给每个新增的行存储一个单调递增的ID。

2、Undo logs在回滚段里被划分为insert undo logs和update undo logs,前者事务提交之后就可以清除了;后者主要记录更新的版本数据,并且可以用于一致性读。

3、聚簇索引数据在原位置更新,且这些行的隐藏列会指向undo logs;辅助索引数据的更新则是先删除再插入,同时没有隐藏列,如果涉及事务一致性读或者回滚等操作则会找到该索引对应的聚簇索引,取出DB_TRX_ID,从undo log里取出正确版本信息。

InnoDB是如何利用一致性读(快照读)的

0、快照读和当前读

a、快照读简单理解为是事务里的select。快照读利用mvcc实现。
b、当前读简单理解为是事务里的update、delete。当前读加锁实现。

1、Repeatable Read可重复读隔离级别下
  • 同一事务里的所有快照读都读的是第一次读时创建的快照

If the transaction isolation level is REPEATABLE READ (the default level), all consistent reads within the same transaction read the snapshot established by the first such read in that transaction.

  • 此隔离级别下通过快照读和next-key lock(当前读)解决了幻读问题

a、快照读解决幻读就不解释了
b、当前读的时候会给读取到的行加上next-key lock,如果是范围读就给范围加锁,如果是读一些行就给行和行前的间隙加锁。这样当前读的时候就不会有新的数据插入或者被删除

2、Read Commited 读已提交隔离级别下
  • 同一事务里的所有快照读都自己创建快照,并读取这个快照
  • 可以看出此隔离级别下快照读无法解决幻读问题,因为每次读都创建快照,不保证多个读操作的一致性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值