binlog的写入机制
事务执行过程中,先把日志写到binlog cache,事务提交时,再把binlog cache写到binlog文件中,并清空binlog cache。
系统将binlog cache划分为一片内存,并为每个线程划分一块内存,通过参数binlog_cache_size控制单个线程内binlog cache所占用的大小,超过参数值时,就要暂存到磁盘。
每个线程有自己的binlog cache,但共用一份binlog文件。
图中的write,是将binlog cache的内容写入到文件系统的pagecache,并没有持久化到磁盘,这种速度较快。
图中的fsync才是将数据持久化到磁盘。
write和fsync的时机,由参数sync_binlog控制:
sync_binlog=0:每次事务提交只wirte,不fsync
sync_binlog=1:每次事务提交都会执行fsync
sync_binlog=N:每N次事务执行一次fsync
一般考虑到性能和日志丢失的可控性,往往N值设置为100~1000,这样最多丢失N个binlog日志。
redo log写入机制
先写入到redo log buffer,再持久化到磁盘。
组提交、搭便车。
解决MySQL在IO上的瓶颈
- 设置 binlog_group_commit_sync_delay 和 binlog_group_commit_sync_no_delay_count 参数,减少 binlog 的写盘次数。这个方法是基于“额外的故意等待”来实现的,因此可能会增加语句的响应时间,但没有丢失数据的风险。
- 将 sync_binlog 设置为大于 1 的值(比较常见是 100~1000)。这样做的风险是,主机掉电时会丢 binlog 日志。
- 将 innodb_flush_log_at_trx_commit 设置为 2。这样做的风险是,主机掉电的时候会丢数据。
