MySQL binlog_error_action分析

小编:啊南 295阅读 2020.11.21

MySQL生态中服务层的二进制日志有着非常重要的作用,有人问过MVCC机制不用的binlog,是否可以去掉,答案是否。binlog用于记录用户对数据库操作的SQL语句(除了数据查询语句),但同时用于保障高可用架构中的复制方式。

本文从一个日常不太关心的参数开始,了解一下mysql的binlog cache。

crash的截图内容:

2020-08-01T05:44:04.068924+08:00 674 
[ERROR] An error occurred during flush stage of the commit. 
'binlog_error_action' is set to 'IGNORE_ERROR'. 
Hence turning logging off for the whole duration of the MySQL server process. 
To turn it on again: fix the cause, shutdown the MySQL server and restart it.

从上述错误信息中了解到奥binlog flush无法进行下去,抛出binlog_error的异常,最终导致MySQL crash。

1)从上述错误中binlog_error_action

binlog_error_action:这个参数的意义在保证正确的写入binary log日志, ,默认值为 ABORT_SERVER,当出现错误的时候会使 MySQL 在写 binlog 遇到严重错误时直接退出( 即 Crash 动作)

当binlog_error_action设置为IGNORE_ERROR时,如果服务器遇到这样的错误,它将继续正在进行的事务,记录错误,然后停止日志记录,并继续执行更新。要恢复二进制日志记录,必须再次启用log_bin,这需要重新启动服务器。

2)从上述描述中可以推测到跟binlog写入有关。

mysql里binlog里参数有以下两个binlog_cache_size,max_binlog_cache_size,以下两个参数都是会话级别的。

binlog_cache_size: 在事务期间用于保存对二进制日志的更改的缓存的大小。二进制日志缓存分配给每个客户端服务器是否支持任何事务性存储引擎,如果服务器启用了二进制日志(——log-bin选项)。如果经常使用大型事务,可以增加缓存大小以获得更好的性能。

Binlog_cache_use和Binlog_cache_disk_use状态变量可以用于调优这个变量的大小

max_binlog_cache_size: 会话级别的参数,如果一个事务需要超过这么多字节的内存,服务器就会生成一个多语句事务,该事务需要超过’max_binlog_cache_size’字节的存储错误。最小值是4096。最大可能值为16EB (exabytes)。推荐最大值为4GB;这是因为MySQL目前无法处理大于4GB的二进制日志位置。 max_binlog_cache_size仅设置事务缓存的大小;语句缓存的上限由max_binlog_stmt_cache_size系统变量控制。

从以上理解来看 就是说binlog缓存大小无法超过4G的大小限制。

3)binlog_cache_size大小如何控制:

Binlog_cache_use:使用二进制日志缓存的事务数。 Binlog_cache_disk_use:使用临时二进制日志缓存但超过binlog_cache_size值并使用临时文件存储事务语句的事务数。 Binlog_stmt_cache_use:使用二进制日志语句缓存的非事务性语句的数量。 Binlog_stmt_cache_disk_use:使用二进制日志语句缓存但超过binlog_stmt_cache_size值并使用临时文件存储这些语句的非事务语句的数量。

4)从源码分析:

报错MYSQL_BIN_LOG::handle_binlog_flush_or_sync的时候触发的错误

分析1:无法创建io 缓存的时候出现问题Could not create IO cache 就是所谓的空间不足的情况

binlog cache 不够的时候使用tmp空间, No space left on device 即临时目录空间不足,在 同一个会话下 执行 commit 或者 再开启一个事务 就会立即触发 binlog_error_action,导致 MySQL 立即崩掉,且 errorlog 里会出现 binlog error 报错。

临时表需要设置一定的范围:

innodb_temp_data_file_path = ibtmp1:1G:autoextend:max:100G

分析2:MYSQL_BIN_LOG::ordered_commit

以下有两个阶段 flush 和sync阶段

  • flush stage:通知底层存储引擎日志刷盘
  • binlog fsync:落盘

这两个过程基本跟刷磁盘有关联,一般出现问题的情况是硬盘空间出现坏道,或则 刷盘过程中出现外部原因导致服务器突然crash。 如:停电

这时需要重新启动服务70%以上能自动检测恢复,如不行需要通过innodb_force_recovery进行启动,这样就比较麻烦,需要mysqldump导出,导入数据方式重新搭建。

总结

1.binlog_cache设置要合理化,默认是32k ,按照服务器资源情况,建议改成 1M~16M 2.尽量避免大事务,除非用到大事务也需要通过global status 状态进行合理设置 相关参数 3.建立监控报警体系是预防这类问题的最好方式。

关联标签: