论双1的重要性

前言

双1是什么?

即:参数 innodb_flush_log_at_trx_commit 和sync_binlog均设置为1。

接下来,先看由该参数引起的一个案例。

案例

场景:

mysql 故障宕机,查看binlog的最后一个事务,如下:

'/*!*/;

### INSERT INTO `guolm`.`t1`

### SET

### @1=806527 /* INT meta=0 nullable=0 is_null=0 */

### @2='n806527' /* VARSTRING(80) meta=80 nullable=1 is_null=0 */

# at 6822647

#180425 18:00:49 server id 6451 end_log_pos 6822678 CRC32 0x05e6ff87 Xid = 1175295

COMMIT/*!*/;

在启动mysql之后,查看最后一个事务在表中不存在:

mysql> select * from guolm.t1 where id=806527;

Empty set (0.00 sec)

原因:

innodb_flush_log_at_trx_commit = 0

可能在mysql突然宕机时,脏页没有来得及刷新到磁盘,而因为该参数设置的不是及时将redo log刷新到磁盘,所以有一部分redo log没有保存到磁盘,

故在mysql启动时,由于丢失了部分redo log,并且脏页部分没有刷到磁盘,因此丢失了那些已经提交的事务。

思考

在遇到意外宕机时:

若 innodb_flush_log_at_trx_commit 设置的是0:

  • 将不能够及时的将redo log 刷新到磁盘。
  • 若意外宕机,redo log没有刷到盘里,在启动时,可能会造成部分事务丢失,提交的数据缺少。
  • 在线上使用中,即使担心刷盘频繁,也要最低是为2,不要设置为0

若 sync_binlog 设置的是0:

  • 将不能及时将binlog及时刷新到磁盘。
  • 在需要根据binlog找position/gtid/Xid的情况下,无法获取最后一个事务的position/gtid/Xid,因为可能部分binlog没有保存到文件中,所以丢失了一些binlog日志。

附录

innodb_flush_log_at_trx_commit  —— 将redo log同步到磁盘的策略

  • 0:当事务提交时,不刷新日志到磁盘,而是等待主线程每秒刷新重做日志。
  • 1:在commit时,将重做日志缓冲同步到磁盘中。
  • 2:在commit时,将重做日志缓冲异步到磁盘中,即重做日志会先同步到操作系统的文件系统缓存中,就提示提交完成,后来在异步写入磁盘。

sync_binlog  —— 将binlog同步到磁盘的策略

  • 0:当事务提交之后,MySQL不对binlog_cache做fsync同步磁盘,由操作系统决定什么时候刷到磁盘。
  • 1:在事务提交时,便将binlog刷到磁盘文件中。

猜你喜欢

转载自my.oschina.net/starglm/blog/1801153