Mysql之六-日志

binlog写入机制

  1. 过程:
    • 事务执行过程中, 先把日志写入binlog cache, 事务提交的时候, 再把binlog cache写到binlog文件中;
  2. 机制:
    • 系统给binlog cache分配了一片内存, 每个线程一个, 参数binlog_cache_size用于控制单个线程内binlog cache所占内存的大小, 如果超过就暂存硬盘;
    • 事务提交时, 执行器把binlog cache里的完整事务写入到binlog中, 并清空binlog cache;
  3. 写入磁盘时机:
    write 和 fsync 的时机,是由参数 sync_binlog 控制的:
    • sync_binlog=0 的时候,表示每次提交事务都只 write,不 fsync;
    • sync_binlog=1 的时候,表示每次提交事务都会执行 fsync;
    • sync_binlog=N(N>1) 的时候,表示每次提交事务都 write,但累积 N 个事务后才 fsync。
      (在出现 IO 瓶颈的场景里,将 sync_binlog 设置成一个比较大的值,可以提升性能。)
      (缺点是异常重启时, 会丢失最近N个事务的binlog日志)

redo log写入机制

  1. 机制:
    • 事务执行过程中, 生成的redo log是要先写入到redo log buffer的;
  2. 过程:
    • 存在 redo log buffer 中,物理上是在 MySQL 进程内存中;
    • 写到磁盘 (write),但是没有持久化(fsync),物理上是在文件系统的 page cache 里面;
    • 持久化到磁盘,对应的是 hard disk;
  3. 写入磁盘时机:
  • 日志写到 redo log buffer 是很快的,wirte 到 page cache 也差不多,但是持久化到磁盘的速度就慢多了。
  • 为了控制 redo log 的写入策略,InnoDB 提供了 innodb_flush_log_at_trx_commit 参数,它有三种可能取值:
    • 0:表示每次事务提交时都只是把 redo log 留在 redo log buffer 中 ;
    • 1:表示每次事务提交时都将 redo log 直接持久化到磁盘;
    • 2:表示每次事务提交时都只是把 redo log 写到 page cache。

binlog 组提交的两个参数

想提升 binlog 组提交的效果,可以通过设置 binlog_group_commit_sync_delay 和 binlog_group_commit_sync_no_delay_count 来实现。

  • binlog_group_commit_sync_delay 参数,表示延迟多少微秒后才调用 fsync;
  • binlog_group_commit_sync_no_delay_count 参数,表示累积多少次以后才调用 fsync。

这两个条件是或的关系,也就是说只要有一个满足条件就会调用 fsync。所以,当 binlog_group_commit_sync_delay 设置为 0 的时候,binlog_group_commit_sync_no_delay_count 也无效了。

WAL机制

WAL 机制是减少磁盘写,可是每次提交事务都要写 redo log 和 binlog,这磁盘读写次数也没变少呀?
现在你就能理解了,WAL 机制主要得益于两个方面:

  • redo log 和 binlog 都是顺序写,磁盘的顺序写比随机写速度要快;
  • 组提交机制,可以大幅度降低磁盘的 IOPS 消耗。
hyhcoder wechat
扫码关注我的个人订阅号