Repository navigation
[Proposal]: Binlog Commit Optimization For Large Transaction #77
Description
Pre-flight Checklist
- I have searched existing GitHub issues and did not find a duplicate proposal.
- I have removed or redacted sensitive information.
Primary Contact Name
Libing Song
Primary Contact Email
Company / Organization
Alibaba Cloud
Role
Software Engineer
Additional Authors / Contributors
No response
Component
Replication
Target Release (Optional)
No response
Roadmap Section
Performance & Observability
Related Issues / Pull Requests / References (Optional)
- Related Issues:
Support InnoDB-based binary log (transactional binlog stored within InnoDB) #24, Next-Generation MySQL Replication Performance and Scalability Improvements #46 these 2 issues may change the architecture of replication and related code. - References:
https://bugs.mysql.com/bug.php?id=118332
Executive Summary
For transactions whose binlog payload exceeds binlog_cache_size, MySQL
spills the binlog cache to a temporary file on disk. At commit time, this
temporary file is read back into memory and written out into the active
binary log file. For large transactions (multi-GB DDL, large bulk loads,
INSERT ... SELECT, etc.) this means the same data is written to disk twice
under the LOCK_log mutex, generating significant disk and page-cache
pressure and stalling all other writes for the duration of the copy.
Binlog Commit Optimization (BCO) replaces that read-then-write cycle with a
single rename(2). When the feature is enabled and a transaction's binlog
cache is larger than binlog_large_commit_threshold, the on-disk
binlog cache temporary file is converted in place into the next binary log
file:
- A small, adaptive space is reserved at the head of the temporary file
when the cache first spills to disk. This space will hold the binary
log magic, Format_description event, Previous_GTIDs event, GTID event,
plus a padding Empty event. - On commit the active binary log file is closed and the temporary file
is opened as the new binary log. The front events are written into the
reserved space and a padding Empty event fills any unused part of the
reserved region exactly. - The temporary file is fsynced, then renamed to a new binary log file
name, registered in the purge index and the binlog index. The server
then rotates to the next regular binary log file.
The result is one fsync of the (already-on-disk) cache file plus a file
rename, instead of streaming the entire cache through the LOCK_log critical
section. Throughput of large transactions improves substantially and small
concurrent transactions are no longer blocked behind multi-GB copies.
User / Developer Stories
- As a DBA loading large datasets with
LOAD DATA, bigINSERT ... SELECT
or batched DML, I want commit latency for those transactions to depend
only on fsync of the already-spilled cache file, not on rewriting it
through the binary log. - As a DBA running an OLTP workload alongside occasional large transactions,
I want short transactions to keep committing while a large transaction is
in its commit phase, instead of stalling behind tens of seconds of
LOCK_log-held binlog copying. - As an operator I want a single size threshold knob that gates the
optimization, so small transactions pay no overhead and I can opt out
entirely (by setting the threshold higher than any expected
transaction) without restarting the server. - As a developer reading the binary logs, I expect the resulting files to
be byte-for-byte valid binary logs thatmysqlbinlogand replicas
process normally (with one Ignorable padding event at the start of the
file that replicas already know to skip).
Proposed Scope
- New commit-time optimization for any binlog cache larger than a
configurable size threshold (default 64 MiB). - One new global system variable (
binlog_large_commit_threshold). - New error-log messages tagging entry into / failure of the optimization.
- Crash-safety of the new commit path (4 crash points are tested).
- Behaviour fallback when prerequisites are not satisfied (small cache,
encryption on, transaction modified mysql.gtid_executed, reserved space
underestimated by a stalem_reserved_size).
Out of Scope / Future Work
- The optimization is silently disabled when binary log encryption is on:
the binlog cache temporary file is encrypted with a per-cache password
that does not match the binary log file's encryption key, so the file
cannot simply be renamed in. - The optimization is disabled when the transaction has modified
mysql.gtid_executed(postfix change). This avoids a deadlock between
theattachable_trx_rwused to updatemysql.gtid_executedfrom the
prepared-state optimized-commit transaction. - The optimization is disabled when the trx cache has not spilled to disk
(nothing to rename) and when reserved space at the head of the cache
file turns out to be smaller than the actual front events (rare; the
server logs a warning and falls back). - Per-file checksum: binary log files produced by the optimization use
checksum algOFFbecause the original cache events were written
without the binary log's checksum stream.binlog_checksumis restored
on the next rotation.
References
https://mariadb.com/resources/blog/binlog-commit-optimization-for-large-transaction/
https://help.aliyun.com/en/rds/apsaradb-rds-for-mysql/binlog-cache-free-flush
Functional Requirements
No response
Non-functional Requirements
No response
Impact Areas
- SQL syntax or statements
- Configuration options or system variables
- Command-line options or utilities
- User-visible behavior
- Observability
- Security or privilege model
- Protocol or replication behavior
- Upgrade / downgrade compatibility
- Performance or resource usage
- Files, persistence, or metadata formats
- APIs or internal interfaces
- Testing or QA coverage needs
Summary of the Approach
No response
User Interface
No response
Configuration / Knobs
No response
Observability
No response
User Procedure
No response
Security Considerations
No response
Compatibility and Behavior Changes
No response
Block Diagram
No response
Interface Specification
No response
Proposed Implementation Plan
No response
QA Notes
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
jfg956 commentedon Jul 22, 2026
Thanks for quoting my bug report. I thought I would add two related blog post:
henrikingo-oracle commentedon Jul 28, 2026
Thank you SongLibing
It turns out there seems to be a duplicate proposal mysql/mysql-server#683
We decided to invite both to speak at the Aug 2026 summit and are especially interested to hear your experiences as you already have this in production?
SongLibing commentedon Jul 29, 2026
Fine Henrik Ingo. Yes, the feature has been online more than 3 years, it is used everyday by many instances.
SongLibing commentedon Aug 3, 2026
mysql_binlog_optimizations.pdf
github-actions commentedon Aug 20, 2026
💬 A discussion has been created in Performance & Observability:
#127
Please continue community discussion there while this issue remains the authoritative tracking item.
nacarvalho commentedon Sep 1, 2026
Hi Libing,
Thank you for contribution proposal.
There are two proposals for the same feature:
After analysis, being mysql/mysql-server#683 more complete, it will be the one moving forward.
Given you have detailed knowledge on the proposal, can you please review it? I known that you did already review a part of it.
Best regards,
Nuno Carvalho
SongLibing commentedon Sep 2, 2026
Hi Nuno,
Sure, I am glad to review it. I will try to finish the review in next week.