Documentation Home
MySQL 8.0 参考手册  / 第8章优化  / 8.5 优化 InnoDB 表  /  8.5.2 优化 InnoDB 事务管理

8.5.2 优化 InnoDB 事务管理

要优化InnoDB事务处理,请在事务功能的性能开销和服务器的工作负载之间找到理想的平衡点。例如,如果应用程序每秒提交数千次,则可能会遇到性能问题;如果它仅每 2-3 小时提交一次,则可能会遇到不同的性能问题。

  • 默认的 MySQL 设置AUTOCOMMIT=1 会对繁忙的数据库服务器施加性能限制。在可行的情况下,将几个相关的数据更改操作包装到一个事务中,方法是发布 SET AUTOCOMMIT=0START TRANSACTION声明,然后 COMMIT在进行所有更改后发布声明。

    InnoDB如果事务对数据库进行了修改,则必须在每次事务提交时将日志刷新到磁盘。当每次更改后都进行提交时(与默认的自动提交设置一样),存储设备的 I/O 吞吐量会限制每秒的潜在操作数。

  • 或者,对于仅包含单个SELECT语句的事务,打开AUTOCOMMIT有助于 InnoDB识别只读事务并优化它们。有关要求,请参阅 第 8.5.3 节,“优化 InnoDB 只读事务”

  • 避免在插入、更新或删除大量行后执行回滚。如果一个大事务正在降低服务器性能,将其回滚会使问题变得更糟,执行时间可能是原始数据更改操作的数倍。终止数据库进程没有帮助,因为回滚在服务器启动时再次开始。

    为了尽量减少发生此问题的可能性:

    • 增加 缓冲池的大小,这样所有的数据变化变化都可以缓存起来而不是立即写入磁盘。

    • 设置 innodb_change_buffering=all 以便除了插入之外还缓冲更新和删除操作。

    • 考虑COMMIT在大数据更改操作期间定期发布语句,可能会将单个删除或更新分解为多个对较少行数进行操作的语句。

    要在失控回滚发生后摆脱它,请增加缓冲池以使回滚受 CPU 限制并快速运行,或者终止服务器并重新启动 innodb_force_recovery=3,如第 14.19.2 节“InnoDB 恢复”中所述。

    默认设置下预计不会出现此问题,默认设置 innodb_change_buffering=all允许将更新和删除操作缓存在内存中,从而使它们首先执行得更快,并且在需要时回滚也更快。确保在处理具有大量插入、更新或删除的长时间运行的事务的服务器上使用此参数设置。

  • 如果您可以承受意外退出时丢失一些最新提交的事务,则可以将 innodb_flush_log_at_trx_commit 参数设置为 0。InnoDB尽管不能保证一定会刷新,但无论如何都会尝试每秒刷新一次日志。此外,将 的值设置 innodb_support_xa为 0,这样可以减少由于在磁盘数据和二进制日志上同步而导致的磁盘刷新次数。

    笔记

    innodb_support_xa已弃用;希望在未来的版本中将其删除。从 MySQL 5.7.10 开始,InnoDB始终启用 XA 事务中对两阶段提交的支持, innodb_support_xa不再允许禁用。

  • When rows are modified or deleted, the rows and associated undo logs are not physically removed immediately, or even immediately after the transaction commits. The old data is preserved until transactions that started earlier or concurrently are finished, so that those transactions can access the previous state of modified or deleted rows. Thus, a long-running transaction can prevent InnoDB from purging data that was changed by a different transaction.

  • When rows are modified or deleted within a long-running transaction, other transactions using the READ COMMITTED and REPEATABLE READ isolation levels have to do more work to reconstruct the older data if they read those same rows.

  • When a long-running transaction modifies a table, queries against that table from other transactions do not make use of the covering index technique. Queries that normally could retrieve all the result columns from a secondary index, instead look up the appropriate values from the table data.

    如果发现二级索引页有一个 PAGE_MAX_TRX_ID太新的,或者如果二级索引中的记录被删除标记, InnoDB可能需要使用聚集索引来查找记录。