To optimize 要优化InnoDB
transaction processing, find the ideal balance between the performance overhead of transactional features and the workload of your server. InnoDB
事务处理,请在事务功能的性能开销和服务器的工作负载之间找到理想的平衡。For example, an application might encounter performance issues if it commits thousands of times per second, and different performance issues if it commits only every 2-3 hours.例如,如果应用程序每秒提交数千次,则可能会遇到性能问题;如果应用程序仅每2-3小时提交一次,则可能会遇到不同的性能问题。
The default MySQL setting 默认的MySQL设置AUTOCOMMIT=1
can impose performance limitations on a busy database server. AUTOCOMMIT=1
会对繁忙的数据库服务器施加性能限制。Where practical, wrap several related data change operations into a single transaction, by issuing 在可行的情况下,通过发出SET AUTOCOMMIT=0
or a START TRANSACTION
statement, followed by a COMMIT
statement after making all the changes.SET AUTOCOMMIT=0
或START TRANSACTION
语句,在进行所有更改后,再发出COMMIT
语句,将几个相关的数据更改操作包装到一个事务中。
如果事务对数据库进行了修改,InnoDB
must flush the log to disk at each transaction commit if that transaction made modifications to the database. InnoDB
必须在每次事务提交时将日志刷新到磁盘。When each change is followed by a commit (as with the default autocommit setting), the I/O throughput of the storage device puts a cap on the number of potential operations per second.当每次更改之后都有一个提交(与默认的自动提交设置一样),存储设备的I/O吞吐量会限制每秒的潜在操作数。
Alternatively, for transactions that consist only of a single 或者,对于只包含单个SELECT
statement, turning on AUTOCOMMIT
helps InnoDB
to recognize read-only transactions and optimize them. SELECT
语句的事务,启用AUTOCOMMIT
可以帮助InnoDB
识别只读事务并对其进行优化。See Section 8.5.3, “Optimizing InnoDB Read-Only Transactions” for requirements.有关要求,请参阅第8.5.3节,“优化InnoDB
只读事务”。
Avoid performing rollbacks after inserting, updating, or deleting huge numbers of rows. 避免在插入、更新或删除大量行后执行回滚。If a big transaction is slowing down server performance, rolling it back can make the problem worse, potentially taking several times as long to perform as the original data change operations. 如果一个大型事务正在降低服务器性能,那么回滚它可能会使问题变得更糟,可能需要执行的时间是原始数据更改操作的几倍。Killing the database process does not help, because the rollback starts again on server startup.终止数据库进程没有帮助,因为回滚会在服务器启动时再次启动。
To minimize the chance of this issue occurring:为了最大限度地降低发生此问题的可能性,请执行以下操作:
Increase the size of the buffer pool so that all the data change changes can be cached rather than immediately written to disk.增加缓冲池的大小,以便可以缓存所有数据更改,而不是立即写入磁盘。
Set 设置innodb_change_buffering=all
so that update and delete operations are buffered in addition to inserts.innodb_change_buffering=all
,这样除了插入操作外,还可以缓冲更新和删除操作。
Consider issuing 考虑在大数据更改操作期间定期发布COMMIT
statements periodically during the big data change operation, possibly breaking a single delete or update into multiple statements that operate on smaller numbers of rows.COMMIT
语句,可能会将单个删除或更新分成多个语句,这些语句在较小行数上运行。
To get rid of a runaway rollback once it occurs, increase the buffer pool so that the rollback becomes CPU-bound and runs fast, or kill the server and restart with 要在发生失控回滚时消除它,请增加缓冲池,使回滚成为CPU受限并快速运行,或者关闭服务器,并使用innodb_force_recovery=3
, as explained in Section 15.18.2, “InnoDB Recovery”.innodb_force_recovery=3
重新启动,如第15.18.2节,“InnoDB
恢复”所述。
This issue is expected to be infrequent with the default setting 默认设置为innodb_change_buffering=all
, which allows update and delete operations to be cached in memory, making them faster to perform in the first place, and also faster to roll back if needed. innodb_change_buffering=all
时,这个问题预计不会经常出现。innodb_change_buffering=all
允许将更新和删除操作缓存在内存中,使它们在第一时间执行得更快,如果需要,还可以更快地回滚。Make sure to use this parameter setting on servers that process long-running transactions with many inserts, updates, or deletes.确保在处理包含许多插入、更新或删除的长期事务的服务器上使用此参数设置。
If you can afford the loss of some of the latest committed transactions if an unexpected exit occurs, you can set the 如果发生意外退出时,您可以承担一些最新提交的事务的丢失,那么可以将innodb_flush_log_at_trx_commit
parameter to 0. innodb_flush_log_at_trx_commit
参数设置为0。InnoDB
tries to flush the log once per second anyway, although the flush is not guaranteed.InnoDB
无论如何都会尝试每秒刷新一次日志,尽管刷新不能保证。
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.InnoDB
清除由其他事务更改的数据。
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.READ COMMITTED
和REPEATABLE READ
隔离级别的事务在读取相同的行时,必须做更多的工作来重建旧数据。
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.通常可以从二级索引中检索所有结果列的查询,而是从表数据中查找适当的值。
If secondary index pages are found to have a 如果发现辅助索引页的PAGE_MAX_TRX_ID
that is too new, or if records in the secondary index are delete-marked, InnoDB
may need to look up records using a clustered index.PAGE_MAX_TRX_ID
太新,或者如果辅助索引中的记录被标记为delete,InnoDB
可能需要使用聚集索引查找记录。