InnoDB如何实现多版本
作者:互联网
InnoDB是一个多版本的存储引擎
。它保留有关已更改行的旧版本的信息以支持事务功能,例如并发和回滚
。该信息以称为rollback segment
的数据结构存储在系统表空间或撤消表空间中。InnoDB 使用rollback segment
中的信息来执行事务回滚所需的撤消操作。它还使用这些信息来构建行的早期版本以实现一致读取。
在内部,InnoDB为存储在数据库中的每一行添加三个字段
:
一个 6 字节DB_TRX_ID字段
指示插入或更新行的最后一个事务的事务标识符。此外,删除在内部被视为更新,其中设置了行中的特殊位以将其标记为已删除。
DB_ROLL_PTR
称为roll pointer
的 7 字节字段。roll pointer指向写入回滚段的undo log record。如果该行被更新,undo log记录包含在更新前重建该行内容所需的信息。
一个 6 字节的DB_ROW_ID
字段包含一个行 ID,随着插入新行而单调增加。如果 InnoDB自动生成聚集索引,则该索引包含行 ID 值。否则,该 DB_ROW_ID列不会出现在任何索引中。
回滚段中的undo log
分为插入和更新undo log
。Insert undo log
仅在事务回滚时需要,并且可以在事务提交后立即丢弃。更新撤消日志也用于一致性读取,但只有在没有事务存在且为其InnoDB分配快照的情况下才能丢弃它们 ,在一致性读取中可能需要更新撤消日志中的信息来构建较早版本的数据库排。有关撤消日志的其他信息,请参阅第 14.6.7 节,“撤消日志”。
建议您定期提交事务,包括仅发出一致读取的事务。否则, InnoDB无法从更新撤消日志中丢弃数据,并且回滚段可能会变得过大,填满其所在的表空间。有关管理撤消表空间的信息,请参阅第 14.6.3.4 节,“撤消表空间”。
回滚段中撤消日志记录的物理大小通常小于相应的插入或更新行。您可以使用此信息来计算回滚段所需的空间。
在InnoDB多版本控制方案中,当您使用 SQL 语句删除某行时,不会立即从数据库中物理删除该行
。InnoDB只有在丢弃为删除而写入的更新撤消日志记录时,才物理删除相应的行及其索引记录。这种删除操作称为purge,它非常快,通常与执行删除操作的 SQL 语句花费的时间顺序相同。
如果您在表中以大致相同的速度以相同的速度以小批量插入和删除行,清除线程可能会开始滞后,并且由于所有“死”行,表会变得越来越大 ,从而使所有内容都受磁盘限制并且非常慢的。在这种情况下,通过调整innodb_max_purge_lag系统变量来限制新行操作,并为清除线程分配更多资源 。有关更多信息,请参阅 第 14.8.10 节,“清除配置”。
总结
- 在内部,
InnoDB为存储在数据库中的每一行添加三个字段
- InnoDB的删除其实并不会立刻删除,只是先标记一下
- InnoDB用rollback segment回滚获取历史版本数据
参考
MySQL :: MySQL 5.7 Reference Manual :: 14.3 InnoDB Multi-Versioning
标签:回滚,撤消,删除,更新,如何,InnoDB,版本,日志 来源: https://blog.csdn.net/u010711495/article/details/118650896