前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MGR修改max_binlog_cache_size参数导致异常

MGR修改max_binlog_cache_size参数导致异常

作者头像
老叶茶馆
发布2020-09-23 14:29:03
1K0
发布2020-09-23 14:29:03
举报
文章被收录于专栏:MySQL修行 | 老叶茶馆

作者:高鹏(网名八怪),《深入理解MySQL主从原理32讲》系列的作者。

一、问题来源

这是一位朋友的问题,因为前期朋友设置max_binlog_cache_size为8m,后面在线进行了修改了本参数,但是结果导致整个3节点的MGR集群除了primary节点其他两个second节点均掉线。大概的日志如下:

二、使用binlog cache的大概流程

这也是我以前写过的一个过程。

  • 开启读写事务。
  • 执行‘DML’语句,在‘DML’语句第一次执行的时候会分配内存空间给binlog cache缓冲区。
  • 执行‘DML’语句期间生成的Event不断写入到binlog cache缓冲区。
  • 如果binlog cache缓冲区已经写满了,则将binlog cache缓冲区的数据写入到binlog cache临时文件,同时清空binlog cache缓冲区,这个临时文件名以ML开头。
  • 事务提交,binlog cache缓冲区和binlog cache临时文件数据全部写入到binary log中进行固化,释放binlog cache缓冲区和binlog cache临时文件。但是注意此时binlog cache缓冲区的内存空间留用供下次事务使用,但是binlog cache临时文件被截断为0,保留文件描述符。其实也就是IO_CACHE结构保留,并且保留IO_CACHE中分配的内存空间和临时文件文件描述符。
  • 断开连接,这个过程会释放IO_CACHE同时释放其持有的binlog cache缓冲区内存以及持有的binlog cache临时文件。

三、max_binlog_cache_size参数的作用

这部分也是我以前记录过的。

max_binlog_cache_size:修改需要使用set global进行修改,定义了binlog cache临时文件的最大容量。如果某个事务的Event总量大于了(max_binlog_cache_size+binlog_cache_size)的大小那么将会报错,如下:

代码语言:javascript
复制
ERROR 1197 (HY000): Multi-statement transaction required more than
'max_binlog_cache_size' bytes of storage; increase this mysqld variable
and try again

我们在函数_my_b_write可以看到如下代码:

代码语言:javascript
复制
if (pos_in_file+info->buffer_length > info->end_of_file) //判断binlog cache临时文件的位置加上本次需要写盘的数据大于info->end_of_file的大小则抛错
  {
    errno=EFBIG;
    set_my_errno(EFBIG);
    return info->error = -1;
  }

其中info->end_of_file的大小正是来自于我们的参数max_binlog_cache_size。

四、分析问题

从second节点的报错来看,是applier线程应用的事务超过了max_binlog_cache_size设置的大小,但是朋友已经修改了其大小,并且主库并没有报这个错误。 我们知道MGR applier线程从启动MGR的那一刻开始就不会停止,类似的master-slave的sql线程也是一样,我们修改参数是通过set global修改的参数,但是实际上在对于MGR的applier线程并不会生效。 但是对于主库来讲,我们修改参数后只要重启应用重新连接那么参数就生效了,这个时候实际上primary session的max_binlog_cache_size和second applier的max_binlog_cache_size并不一致,一旦有主库做一个稍大的事务,如果这个事务的binlog大于以前设置的值,主库虽然能成功,但是备节点就会由于applier线程的max_binlog_cache_size过小而导致备节点脱离整个集群。 对于这一点我们可以通过debug MySQL的sql线程进行验证。

五、验证

这里我们使用master-slave来进行验证,我们对sql线程进行debug。如下,

  • 当前配置
  • sql线程
  • 修改参数
  • 主库执行一个事务,从库执行 我们可以查看sql线程binlog cache的IO CACHE的信息如下:

可以看到这个值还是老值。

  • 重启后sql线程后,主库再做一个事务观察

很明显我们刚才修改的值重启sql线程后才生效。 因此故障原因得到证明。

Enjoy MySQL :)

全文完。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老叶茶馆 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二、使用binlog cache的大概流程
  • 三、max_binlog_cache_size参数的作用
  • 四、分析问题
  • 五、验证
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档