innodb的多版本控制

inndo也是通过跟oracle类似的回滚段来实现多版本,内部实现中,innodb会添加3个字段到数据库中的每个记录上,一个6byte的DB_TRX_ID表示最后插入或更新的行的事务标识符,删除在内部被表示成更新用一个标记为来标识这行被删除了。还有个7byte的DB_ROLL_PTR来执行undo log的记录,如果一行被更新了,那么undo log记录信息能重构被更新前的内容,一个6byte的DB_ROW_ID字段包含一个row id,如果innodb产生一个聚簇索引,索引包含row id的值,否则db_row_ID不会出现在任何索引中。
undo log被分成插入和更新,插入的undo log在事务回滚中使用,在事务提交后马上被删除,update的undo log被用于一致性读。
事务提交要正常,否则innodb不会丢弃日志中的数据,回滚段会增长的很大,撑满你的表空间。
innodb中,行不会在数据库中马上被物理删除,只会在丢弃了为了删除而生成的update的日志后才会删除相关记录和索引,这个删除过程叫做purge,执行的很快。
如果在一个表中以相同的速率小批量的插入和删除数据,purge的操作会开始落后,表可能会变得非常大,因为那些僵死的行,在这种情况下可以使用innodb_max_purge_lag变量分配更多的资源给purge线程。
innodb mvcc区别对待二级索引和聚集索引,聚集索引记录的更新发生在内部,隐藏列指向早期版本的undo记录,可以用来重建,二级索引不包含隐藏列也不在内部更新。二级索引更新的时候,老的记录被标记删除,新的记录被插入,被标记删除的记录最终被删除。
如果二级索引的记录被标记删除或二级索引页被新的事务更新,转换索引的技术不会被使用,innodb会在聚集索引中查找记录。然而index condition pushdown会开启。
mysql中的clustered index按照索引组织表的方式更好理解,不能认为它是索引结构,而是存储表的一种方式,这样在理解上就不会有混淆了,只不过是表的存储是有序存放的。

你可能感兴趣的:(innodb-mvc)