天天看点

redolog和binlog的写入机制

binlog的写入机制

**binlog 的写入逻辑**:事务执行过程中,先把日志写到 binlog cache,事务提交的时候,再把 binlog cache 写到 binlog 文件中

**binlog写入的三个阶段**:binlog cache  (write) 文件系统的page cache  (fsync) 磁盘

write 和 fsync 的时机,是由参数 sync_binlog 控制的:
- sync_binlog=0 的时候,表示每次提交事务都只 write,不 fsync;
- sync_binlog=1 的时候,表示每次提交事务都会执行 fsync;
- sync_binlog=N(N>1) 的时候,表示每次提交事务都 write,但累积 N 个事务后才 fsync。

**结论**:一般不建议将这个参数设成 0,比较常见的是将其设置为 100~1000 中的某个数值。如果设置成0,主动重启丢失的数据不可控制。设置成1,效率低下,设置成N(N>1),则主机重启,造成最多N个事务的binlog日志丢失,但是性能高,丢失数据量可控。
           

redolog写入机制

存储状态
  • 存在 redo log buffer 中,物理上是在 MySQL 进程内存中;
  • 写到磁盘 (write),但是没有持久化(fsync),物理上是在文件系统的 page cache 里面;
  • 持久化到磁盘,对应的是 hard disk。
redo log 的写入策略,InnoDB 提供了 innodb_flush_log_at_trx_commit 参数,它有三种可能取值:
  • 0:表示每次事务提交时都只是把 redo log 留在 redo log buffer 中;
  • 1:表示每次事务提交时都将 redo log 直接持久化到磁盘;
  • 2:表示每次事务提交时都只是把 redo log 写到 page cache。

InnoDB 有一个后台线程,每隔 1 秒,就会把 redo log buffer 中的日志,调用 write 写到文件系统的 page cache,然后调用 fsync 持久化到磁盘。

结论:一般建议设置成2。如果设置成0,则mysql进程重启时,会丢失数据,如果设置成1,则每次都刷磁盘,性能太差。设置成2,只会在主机重启才会丢失数据,安全系数比0要高,因为是写入数据到文件系统的page cache,所以性能也很高,和设置成0差不多。

redolog和binlog总的结论:

如果你的 MySQL 现在出现了性能瓶颈,而且瓶颈在 IO 上,可以通过哪些方法来提升性能呢?

  1. 设置 binlog_group_commit_sync_delay 和 binlog_group_commit_sync_no_delay_count 参数,减少 binlog 的写盘次数。这个方法是基于“额外的故意等待”来实现的,因此可能会增加语句的响应时间,但没有丢失数据的风险;
  2. 将 sync_binlog 设置为大于 1 的值(比较常见是 100~1000)。这样做的风险是,主机掉电时会丢 binlog 日志;
  3. 将 innodb_flush_log_at_trx_commit 设置为 2。这样做的风险是,主机掉电的时候会丢数据。

继续阅读