innodb的mvcc

innodb保存了修改过的版本记录,一是为了回滚,二是为了一致性读。

在innodb内部会自动增加三个列。一个6字节的DB_TRX_ID 代表此行数据的最后一次的insert或者update事务。删除也被当作update(有一个单独的bit来标志此行数据已被删除)。一个7字节的DB_ROLL_PTR指针指向回滚段中保存的undo日志地址,如果某行数据被提交修改了,undo日志会保存修改前的记录,以便可以恢复修改之前的数据。最后还有一个6字节的DB_ROW_ID ,当新数据插入的时候自增,如果innodb自动生成了聚簇索引,索引中都会包含这个字段,否则,该列不会出现在索引中。

回滚段中的undo日志分为insert和update两种。insert的undo日志只是为了回滚存在,提交之后就可以丢弃。update的undo日志是为了回滚和一致性读存在,所以只能在没有了可能需要通过该数据的undo日志来建立快照来保持一致性读的事务存在的时候才可以删除(英文版:Update undo logs are used also in consistent reads, but they can be discarded only after there is no transaction present for which InnoDB has assigned a snapshot that in a consistent read could need the information in the update undo log to build an earlier version of a database row),其实就是如果还有一致性读事务可能会需要该数据的早期版本的话,就不能丢弃它的undo日志。所以,周期性(如果可以的话,就尽早)提交事务,即使只是读事务。

回滚段中的撤消日志记录的物理大小通常小于相应的插入或更新行。你可以用它计算你的回滚段(rollback segment)所需空间。

当你执行删除记录的SQL的时候,innodb并不会立即物理移除(从磁盘删除)该数据,只有当它丢弃相应的update undo日志的时候才会物理移除(purge)。这个移除是非常快的。

如果你以近乎相同的速度小批量的删除和插入数据,清除线程(the purge thread)可能会滞后,然后你的表会越来越大。这种情况可以通过优化配置innodb_max_purge_lag系统变量来给清除线程更多的资源执行清除。

mvcc对待聚簇索引和二级索引是不一样的,聚簇索引中的记录会原地更新(updated in place),他们指向undo日志的隐藏系统列可以构建之前的版本;二级索引既没有隐藏系统列也不会原地更新。

当一个或者多个二级索引列被更新时,二级索引会被标记删除,新的记录被插入,最终会清除被删除的索引记录。当二级索引被标记删除或者被其他事务更新的时候,innodb通过聚簇索引查找数据(此时覆盖索引就不能用了),如果有事务在读事务开始之后更改了数据,聚簇索引会根据DB_TRX_ID 和undo日志来重建正确的版本。

看了看官网,自己翻译加理解了一下,后续会改的更简练和准确点。

如有错误,敬请指正,感谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值