目录
-
1. 关于 binlog 日志文件
-
2. 从 trx_cache 读出来
-
2.1 只从内存 buffer 读取
-
2.2 从临时文件读取
-
3. 写入 binlog 日志文件
-
4. 总结
正文
1. 关于 binlog 日志文件
binlog 日志文件包含两部分:
- 内存 buffer,这是 MySQL 自己为 binlog 日志文件提供的内存缓冲区,称为
IO_CACHE
,和操作系统为文件提供的缓冲区(page cache
)不是同一个东西。 - 磁盘文件,这是磁盘上真正的 binlog 日志文件。
不考虑操作系统的 page cache,写入 binlog 日志到 binlog 日志文件的过程是这样的:
- 写入 binlog 日志到内存 buffer。
- 写满内存 buffer 之后,再把内存 buffer 中的全部内容一次性写入 binlog 日志文件。
- 清空内存 buffer,以供后续写入 binlog 日志复用。
和 trx_cache 的内存 buffer 一样,binlog 日志文件的内存 buffer 也有大小限制。
MySQL 打开新的 binlog 日志文件时,会初始化对应的内存 buffer,代码如下:
// 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(...) {
...
// 打开 binlog 日志文件
if ((file = mysql_file_open(...)) = 1),前面 N - 1 次都会读取 buffer_length
字节,每次都会填满内存 buffer。最后一次读取剩余的小于等于 32K 的全部 binlog 日志。
每次从临时文件读取 binlog 日志到内存 buffer 之后,都会把内存 buffer 中的 binlog 日志全部写入 binlog 日志文件。
循环往复,直到把临时文件中的所有 binlog 日志都写入 binlog 日志文件,这个过程就结束了。
3. 写入 binlog 日志文件
前面我们介绍了把 binlog 日志写入 binlog 日志文件的整体流程。
因为写入过程涉及 binlog 内存 buffer 和日志文件的协同配合,我们再来看看两者是怎么配合的。
以把 trx_cache 内存 buffer 中 32K 的 binlog 日志写入 binlog 日志文件为例,流程是这样的:
- 计算 binlog 日志文件的内存 buffer 剩余多少空闲空间(假设为 2K)。
- 判断 binlog 日志文件的内存 buffer 的剩余空闲空间,是否能够容纳从 trx_cache 内存 buffer 读取出来的 32K binlog 日志,显然容纳不下。
- 那么,先把读取出来的 32K binlog 日志中的前面 2K 写入 binlog 日志文件的内存 buffer,剩余未写入 binlog 日志文件的还有 30K。
- 判断剩余未写入 binlog 日志文件的 binlog 日志,是否大于等于 4096 字节(
IO_SIZE
)。 - 如果剩余 binlog 日志小于 4096 字节,把它们都写入 binlog 日志文件的内存 buffer。
- 如果剩余 binlog 日志大于等于 4096 字节,把剩余 binlog 日志前面的 N * 4096 字节直接写入 binlog 日志文件。
最后有可能还会剩下不足 4096 字节的 binlog 日志,写入 binlog 日志文件的内存 buffer。
4. 总结
binlog 日志文件包含两部分:内存 buffer、磁盘文件。内存 buffer 的大小固定为 8K。
二阶段提交的 flush 子阶段,会从 trx_cache 中读取 binlog 日志,写入 binlog 日志文件。
往期回顾