文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  InnoDB 存储引擎  /  InnoDB 多版本控制

17.3 InnoDB 多版本控制

InnoDB 是一种多版本存储引擎。它保留有关已更改行的旧版本的信息,以支持并发和回滚等事务功能。此信息存储在撤消表空间中称为回滚段的数据结构中。请参阅 第 17.6.3.4 节“撤消表空间”InnoDB 使用回滚段中的信息来执行事务回滚所需的撤消操作。它还使用该信息为一致性读取构建行的早期版本。请参阅 第 17.7.2.3 节“一致性非锁定读取”

在内部,InnoDB 会向存储在数据库中的每一行添加三个字段

  • 一个 6 字节的 DB_TRX_ID 字段,指示插入或更新该行的最后一个事务的事务标识符。此外,删除在内部被视为更新,其中行中的一个特殊位被设置为将其标记为已删除。

  • 一个 7 字节的 DB_ROLL_PTR 字段,称为回滚指针。回滚指针指向写入回滚段的撤消日志记录。如果该行已更新,则撤消日志记录包含在更新之前重建行内容所需的信息。

  • 一个 6 字节的 DB_ROW_ID 字段,包含一个行 ID,该 ID 随着新行的插入而单调递增。如果 InnoDB 自动生成聚簇索引,则该索引包含行 ID 值。否则,DB_ROW_ID 列不会出现在任何索引中。

回滚段中的撤消日志分为插入撤消日志和更新撤消日志。插入撤消日志仅在事务回滚中需要,并且可以在事务提交后立即丢弃。更新撤消日志也用于一致性读取,但只有在没有事务需要 InnoDB 为其分配快照的情况下才能丢弃它们,这些快照在一致性读取中可能需要更新撤消日志中的信息来构建数据库行的早期版本。有关撤消日志的更多信息,请参阅 第 17.6.6 节“撤消日志”

建议您定期提交事务,包括仅发出一致性读取的事务。否则,InnoDB 无法从更新撤消日志中丢弃数据,并且回滚段可能会变得太大,从而填满它所在的撤消表空间。有关管理撤消表空间的信息,请参阅 第 17.6.3.4 节“撤消表空间”

回滚段中撤消日志记录的物理大小通常小于相应的插入或更新的行。您可以使用此信息来计算回滚段所需的空间。

InnoDB 多版本控制方案中,当您使用 SQL 语句删除一行时,该行不会立即从数据库中物理删除。 InnoDB 仅在丢弃为删除操作编写的更新撤消日志记录时才物理删除相应的行及其索引记录。此删除操作称为清除,并且速度非常快,通常与执行删除的 SQL 语句花费的时间相同。

如果您以大致相同的速率在表中小批量插入和删除行,则清除线程可能会开始滞后,并且由于所有“”行,表可能会越来越大,从而导致所有内容都受磁盘限制并且速度非常慢。在这种情况下,请限制新行操作,并通过调整 innodb_max_purge_lag 系统变量为清除线程分配更多资源。有关更多信息,请参阅 第 17.8.9 节“清除配置”

多版本控制和辅助索引

InnoDB 多版本并发控制 (MVCC) 处理辅助索引的方式与处理聚簇索引的方式不同。聚簇索引中的记录会就地更新,并且其隐藏的系统列指向可以从中重建早期版本记录的撤消日志条目。与聚簇索引记录不同,辅助索引记录不包含隐藏的系统列,也不会就地更新。

当二级索引列被更新时,旧的二级索引记录会被标记为删除,新的记录会被插入,并且标记为删除的记录最终会被清除。 当二级索引记录被标记为删除或二级索引页被更新的事务更新时,InnoDB 会在聚簇索引中查找数据库记录。 在聚簇索引中,会检查记录的 DB_TRX_ID,如果记录在读取事务启动后被修改,则从撤消日志中检索记录的正确版本。

如果二级索引记录被标记为删除或二级索引页被更新的事务更新,则不会使用覆盖索引技术。 InnoDB 不会从索引结构返回数据,而是在聚簇索引中查找记录。

但是,如果启用了索引条件下推 (ICP) 优化,并且 WHERE 条件的部分内容可以使用仅来自索引的字段进行评估,则 MySQL 服务器仍会将 WHERE 条件的这一部分下推到存储引擎,并在存储引擎中使用索引对其进行评估。 如果未找到匹配的记录,则避免进行聚簇索引查找。 如果找到了匹配的记录,即使在标记为删除的记录中,InnoDB 也会在聚簇索引中查找该记录。