InnoDB Multi-Versioning

InnoDB 是一个数据多版本的存储引擎,它会保持它修改的数据的旧版本数据以此来支持事务特性,好比并发操做和事务的回滚。这些旧版本数据存储在一个叫作rollback segment的数据结构中(回滚段),当事务回滚的时候,Innodb会使用回滚段的数据来执行事务的撤销操做,也会使用这些老版本的数据来作旧版本的一致性读操做(可重复读的隔离级别下须要用到)。html

在Innodb内部会增长三个字段存储相关信息,6个字节的 DB_TRX_ID 字段标识插入或者更新该字段的最后一个事务的事务ID,删除操做在内部是视为更新操做,在行上标记为已删除,每一行包含一个7个字节的DB_ROLL_PTR字段,也叫着行指针,行指针指向undo log在回滚段(rollback segment)中的位置, 若是该行被更新了,undo log 包含了该行被更新前的必要的重建行的信息。6个字节的 DB_ROW_ID 字段,这个字段随着记录的插入而单调递增,若是Innodb自动生成一个聚簇索引(没有显示指定主键),那这个索引包含了db_row_id字段,不然,db_row_id 这个列不会出如今任何索引中。mysql

回滚段中的undo log 分红inser 和update 两类,insert undo log 只在事务回滚中被须要,而且能够在事务提交时丢弃这类日志。update undo log被用于一致性读,只有当没有未提交的事务时才能被丢弃,Innodb为事务分配了一个快照在一致性读时,它须要update undo log的信息来构建数据的旧的版本数据。sql

按期提交事务,也包含那些一致读的事务,不然innodb由于不能丢弃回滚段中的undo log会致使回滚段变得很大以至于占满表空间。数据库

回滚段中的undo log记录大小通常小于它相应行的大小,你能够基于这个来计算你须要的回滚段大小。数据结构

Innodb多版本模式下,当你使用SQL语句删除行时它不会马上从数据库物理删除数据,Innodb只会在丢弃相应的undo log时才会物理删除数据和索引数据,这个移除操做在Innodb中叫着purge,这个动做很是迅速,一般跟SQL的执行顺序一致。并发

若是插入和删除操做以差很少相同的速度进行,purge 线程会有延迟,表会变得愈来愈大由于表中的"dead" 行,这会致使性能被磁盘IO限制,在这种场景下,经过调整系统参数 innodb_max_purge_lag 来分配跟多的资源给purge线程。性能

多本版和二级索引线程

Innodb多版本并发控制对二级索引的处理不一样于聚簇索引(primary key),聚簇索引中的记录会被就地更新,他们指向undo log的隐藏系统列能够构建旧版本数据,不一样于聚簇索引,二级索引记录不包含隐藏系统列,不能被就地更新。翻译

当二级索引被更新的时候,老的记录被标记删除,插入一条新记录,标记删除的数据最终被移除,当二级索引记录标记删除或者二级索引的页被一个新事务更新,Innodb在聚簇索引中找到这些记录,在聚簇索引中,检查这些行的 DB_TRX_ID,若是这些行在当前事务启动以后被更新了,那么就从undo log中获取老版本的数据。 指针

当二级索引记录被标记删除或者二级索引的页被一个新事务更新,索引覆盖技术再也不适用,不一样于直接从索引返回数据,Innodb会从聚簇索引中寻找数据。

(翻译至MySQL官方文档)

相关文章
相关标签/搜索