Databases 10 min read

How MySQL Writes Binlog Logs: Buffer Management and trx_cache Reading

This article explains MySQL 8.0.32's binlog log file structure, the 8 KB in‑memory buffer (IO_CACHE), how binlog entries are written from trx_cache to the binlog file, and the detailed steps and code involved in reading from memory or temporary files and flushing to disk.

Aikesheng Open Source Community
Aikesheng Open Source Community
Aikesheng Open Source Community
How MySQL Writes Binlog Logs: Buffer Management and trx_cache Reading

1. About the binlog log file

The binlog file consists of two parts: an in‑memory buffer provided by MySQL (called IO_CACHE ) and the actual disk file. The memory buffer is separate from the operating system's page cache.

When the OS cache is ignored, writing to the binlog proceeds as follows:

Write binlog data into the memory buffer.

When the buffer is full, flush its entire contents to the disk file.

Clear the buffer for reuse.

The buffer size is limited; MySQL initializes it when opening a new binlog file. The relevant source code is:

// sql/binlog.cc
class MYSQL_BIN_LOG::Binlog_ofile : public Basic_ostream {
  ...
  bool open(...){
    ...
    if (file_ostream->open(...)) return true;
    ...
  }
  ...
};

// sql/basic_ostream.cc
bool IO_CACHE_ostream::open(...){
  ...
  // open binlog file
  if ((file = mysql_file_open(...)) < 0)
    return true;
  // initialize memory buffer
  if (init_io_cache(..., IO_SIZE, ...)){
    ...
  }
  return false;
}

The cachesize argument passed to init_io_cache() is the constant IO_SIZE , defined as:

// include/my_io.h
// IO_SIZE = 4096 bytes
constexpr const size_t IO_SIZE{4096};

Because init_io_cache_ext() enforces a minimum of 2 * IO_SIZE , the actual in‑memory buffer size for the binlog file is 8192 bytes (8 KB).

2. Reading from trx_cache

trx_cache also contains two parts: an in‑memory buffer and a temporary file. During transaction execution, binlog entries are first written to trx_cache using the following steps:

Write into the memory buffer.

When the buffer is full, flush its contents to a temporary file.

Clear the buffer for further use.

During the second‑phase commit (flush sub‑stage), MySQL reads the binlog entries from trx_cache and writes them to the binlog file. Two situations exist:

Case 1: Only the memory buffer holds data (the buffer never filled). The entire content is read directly from memory.

Case 2: The buffer filled one or more times, leaving data in the temporary file. The data must be read from the temporary file.

In the flush stage, the buffer’s role changes from WRITE_CACHE to READ_CACHE so that it can be used for reading.

2.1 Reading only from the memory buffer

If all binlog entries remain in the memory buffer, they are simply read and written to the binlog file.

2.2 Reading from the temporary file

When the buffer has been flushed to a temporary file, MySQL may encounter two scenarios after the last flush:

Scenario 1: No further binlog entries are generated; the memory buffer is empty and all data resides in the temporary file.

Scenario 2: Additional binlog entries are generated but do not fill the buffer; most data is in the temporary file and a small remainder stays in memory.

Before the buffer switches to READ_CACHE , MySQL writes any remaining memory data to the temporary file to avoid loss, effectively reducing Scenario 2 to Scenario 1.

The default trx_cache buffer length is 32 KB. If the temporary file must be read N times (N ≥ 1), the first N‑1 reads each consume buffer_length bytes, filling the buffer, while the final read consumes the remaining ≤ 32 KB. After each read, the data is immediately flushed to the binlog file until the temporary file is exhausted.

3. Writing to the binlog file

The interaction between the trx_cache buffer and the binlog file buffer is illustrated with a 32 KB chunk from trx_cache and a binlog file buffer that has 2 KB of free space:

Calculate free space in the binlog file buffer (e.g., 2 KB).

Since 32 KB cannot fit, write the first 2 KB into the buffer, leaving 30 KB unwritten.

Check if the remaining 30 KB is ≥ IO_SIZE (4 KB). It is, so write as many full 4 KB blocks as possible directly to the file.

Any leftover (< 4 KB) is written back into the binlog file buffer.

4. Summary

The binlog log file consists of an 8 KB in‑memory buffer and the on‑disk file. During the second‑phase commit's flush sub‑stage, MySQL reads binlog entries from trx_cache (either from memory or a temporary file) and writes them to the binlog file following the buffer‑size rules described above.

MySQLBinlogDatabase InternalsBufferIO_CACHEtrx_cache
Aikesheng Open Source Community
Written by

Aikesheng Open Source Community

The Aikesheng Open Source Community provides stable, enterprise‑grade MySQL open‑source tools and services, releases a premium open‑source component each year (1024), and continuously operates and maintains them.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.