说一说mvcc中的隐藏字段
- InnoDB存储引擎在每行数据的后面添加了三个隐藏字段:
- DB_TRX_ID(6字节):表示最近一次对本记录行作修改(insert | update)的事务ID。至于delete操作,InnoDB认为是一个update操作,不过会更新一个另外的删除位,将行表示为deleted。并非真正删除。
- DB_ROLL_PTR(7字节):回滚指针,指向当前记录行的undo log信息
- DB_ROW_ID(6字节):随着新行插入而单调递增的行ID。理解:当表没有主键或唯一非空索引时,innodb就会使用这个行ID自动产生聚簇索引。如果表有主键或唯一非空索引,聚簇索引就不会包含这个行ID了。这个DB_ROW_ID跟MVCC关系不大。
- 事务A先对该行加排它锁
- 然后把该行数据拷贝到undo log中,作为旧版本
- 拷贝完毕后,修改该行的数据,并且修改DB_TRX_ID为2(事务A的ID), 回滚指针指向拷贝到undo log的旧版本。(然后还会将修改后的最新数据写入redo log)
- 事务提交,释放排他锁
- ArrayList 底层基于动态数组,随机访问元素效率高,向集合尾部添加元素效率高,删除或者在其他位置添加元素效率低(需要移动数组)
- LinkedList 基于链表的动态数组,数据添加和删除效率高,只需要改变指针指向即可,但是访问数据的平均效率低,需要对链表进行遍历
- Undo log中存储的是老版本数据,当一个事务需要读取记录行时,如果当前记录行不可见,可以顺着undo log链找到满足其可见性条件的记录行版本。
- InnoDB里,undo log分为如下两类:
- insert undo log : 事务对insert新记录时产生的undo log, 只在事务回滚时需要, 并且在事务提交后就可以立即丢弃。
- update undo log : 事务对记录进行delete和update操作时产生的undo log,不仅在事务回滚时需要,快照读也需要,只有当数据库所使用的快照中不涉及该日志记录,对应的回滚日志才会被purge线程删除。
推荐阅读
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- linux笔记|linux 常用命令汇总(面向面试)
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 面试|我经历的IT公司面试及离职感受(转)
- android-面试|我经历的IT公司面试及离职感受
- Java|一个月内面了30家企业,不断对比薪资,我从18K变成了38K
- vue|Vue面试常用详细总结
- java人生|35K 入职华为Java开发那天,我哭了(这 5 个月做的一切都值了)
- Android|年后备战金三银四(Android面试吃透这一篇就没有拿不到的offer......)
- java|后悔没有早点遇到它 , 直接从 12K 涨到了 30K