10.5.2 Optimizing InnoDB Transaction Management
MySQL 8.4 Reference Manual Including MySQL NDB Cluster 8.4
10.5.2 Optimizing InnoDB Transaction Management
To optimize InnoDB transaction processing,
find the ideal balance between the performance overhead of
transactional features and the workload of your server. 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.
- The default MySQL setting
AUTOCOMMIT=1can impose performance limitations on a busy database server. Where practical, wrap several related data change operations into a single transaction, by issuingSET AUTOCOMMIT=0or aSTART TRANSACTIONstatement, followed by aCOMMITstatement after making all the changes.
InnoDB must flush the log to disk at each
transaction commit if that transaction made modifications to
the database. 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.
- Alternatively, for transactions that consist only of a
single SELECT statement,
turning on AUTOCOMMIT helps
InnoDB to recognize read-only
transactions and optimize them. See
Section 10.5.3, “Optimizing InnoDB Read-Only Transactions” for
requirements.
- 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=allso that update and delete operations are buffered in addition to inserts. - Consider issuing
COMMITstatements periodically during the big data change operation, possibly breaking a single delete or update into multiple statements that operate on smaller numbers of rows.
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
innodb_force_recovery=3, as
explained in Section 17.18.2, “InnoDB Recovery”.
- 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 tries to flush the
log once per second anyway, although the flush is not
guaranteed.
- 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.
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.
