Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  Optimizing InnoDB Transaction Management

10.5.2 InnoDB事务管理优化

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

  • 默认的 MySQL 设置 AUTOCOMMIT=1 可能会对繁忙的数据库服务器施加性能限制。在可能的情况下,将几个相关的数据更改操作包装到单个事务中,通过发出 SET AUTOCOMMIT=0START TRANSACTION 语句,后跟一个 COMMIT 语句,以便进行所有更改。

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

  • 另外,对于仅包含单个 SELECT 语句的事务,启用 AUTOCOMMIT 帮助 InnoDB 识别只读事务并对其进行优化。请参阅 第 10.5.3 节,“InnoDB 只读事务优化” 以获取要求。

  • 避免在插入、更新或删除大量行后执行回滚。如果一个大事务正在降低服务器性能,回滚可能会使问题变得更糟,可能需要比原始数据更改操作更长的时间来执行。杀死数据库进程也不会有帮助,因为回滚将在服务器启动时重新开始。

    为了最小化这种问题的发生:

    • 增加 缓冲池 的大小,以便所有数据更改都可以被缓存,而不是立即写入磁盘。

    • 设置 innodb_change_buffering=all,以便更新和删除操作也被缓存在插入操作中。

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

    要摆脱一次运行的回滚,增加缓冲池,以便回滚变得 CPU 绑定并快速运行,或者杀死服务器并使用 innodb_force_recovery=3 重新启动,如 第 17.18.2 节,“InnoDB 恢复” 中所述。

    这个问题在使用默认设置 innodb_change_buffering=all 时应该很少出现,该设置允许更新和删除操作被缓存在内存中,使它们变得更快,并且在需要时也更快地回滚。确保在处理长时间事务的服务器上使用这个参数设置,包括许多插入、更新或删除操作。

  • 如果您可以承担一些最新提交的事务在意外退出时的损失,可以将 innodb_flush_log_at_trx_commit 参数设置为 0。InnoDB 尝试每秒刷新日志一次,尽管不能保证刷新。

  • 当行被修改或删除时,相关的 撤销日志 不会立即被物理删除,甚至在事务提交后也不会。旧数据将被保留,直到早期或同时启动的事务完成,以便这些事务可以访问修改或删除行的先前状态。因此,长时间事务可能会阻止 InnoDB 清除由不同事务修改的数据。

  • 当行在长时间事务中被修改或删除时,使用 READ COMMITTEDREPEATABLE READ 隔离级别的其他事务需要更多工作来重建旧数据,如果它们读取了相同的行。

  • 当长时间运行的事务修改表时,从其他事务对该表的查询不会使用覆盖索引技术。通常可以从辅助索引中检索所有结果列的查询,反之会从表数据中查找适当的值。

    如果辅助索引页的PAGE_MAX_TRX_ID太新,或者辅助索引中的记录被删除标记,InnoDB可能需要使用聚簇索引来查找记录。