使用 bitpoke的mysql-operator 作为k8s的mysql服务,使用的版本v0.4.0,
github地址:https://github.com/bitpoke/mysql-operator
MysqlCluster operator主要支持如下功能
建立的mysql服务每隔一段时间就重启,事件的报错信息如下
为什么心跳不通过?
貌似心跳机制不通过,查看pod信息
心跳默认20秒不通过,就重启,看源码也没有心跳配置项,坑啊,不过这只是表象,到底是什么导致心跳不通过?
mysqlCluster启动时,会启动4个容器metrices-exporter, mysql, pt-heartbeat, sidecar。看这4个容器的cpu, 内存使用情况,发现mysql内存超过,如下:
看最后状态,OOMKilled,而且当前内存使用率3.9G 接近limit 4G的设置。 找到产生的问题原因了,是因为内存超了,被容器杀掉,导致心跳不通过报错重启
为什么内存使用这么高?
思考mysql使用内存高,可能跟mysql自身缓存有关系,查内存相关参数
看到 innodb_buffer_pool_size 设置得值特别大,这个参数设置只有主要缓存innodb表的索引,数据,插入数据时的缓冲,但默认是8M。
为什么 innodb_buffer_pool_size 设置变得这么大?
翻翻mysqlCluster源码,跟innodb_buffer_pool_size 有关代码
default.go
问题就在这里,为了保证资源独占,mysql设置时是request = limit,因为自动计算导致 innodb-buffer-pool-size过大,最终导致oom,需要手动设置innodb-buffer-pool-size,就手动设置2G吧
设置 innodb-buffer-pool-size 不生效?
设置后,pod不重启? 参数没有生效设置。设另一个512M就生效了。尝试加入引号,作为字符串处理,配置开始生效。难道跟类型有关系? 继续看相关源码
default.go
看这个类型定义cluster.Spec.MysqlConf
MysqlClusterSpec
intstr
如果设置成数字,则整数是int32位
看int32位的长度
int32 the set of all signed 32-bit integers (-2147483648 to 2147483647)
至此内存使用过大的问题,解决了,内存使用也降下来了
普通方式:(1)在Windows中打开“控制面板”窗口,在“控制面板”窗口中,双击“管理工具”打开“管理工具”窗口。(2)在“管理工具”窗口双击“服务”程序。(3)打开“服务”窗口,双击列表中的“MySQL”打开“MySQL的属性”对话框。(4)在“常规”选项卡下有服务状态选项,单击“停止”,即可关闭数据库。(5)关闭后若要重新打开数据库,单击“启动”即可。另外,可使用DOS命令方式:(1)在桌面“开始”搜索框内输入“cmd”,点击cmd.exe打开DOS命令窗口。(2)在命令窗口中输入netstopmysql后回车,即可关闭数据库。(3)关闭后若要重新打开数据库,在DOS命令窗口输入netstartmysql后回车,即可。MySQL 从库所在主机故障重启后,sql_thread 线程报错:
通过报错信息可知,worker 线程在回放事务 '471c2974-f9bb-11eb-afb1-52540010fb89:88313207' 时,由于要插入的记录主键冲突报错。
主机重启前,主从同步正常,主机重启后,主从同步由于主键冲突报错,对比了冲突主键所在行记
录在主从库是一致的,初步分析事务 '471c2974-f9bb-11eb-afb1-52540010fb89:88313207' 在主机故
障前已经在从库进行了回放,那为何事务会重复回放呢?
在开启gtid模式下,如果指定 master_auto_position=1,start slave 时,从库会把
Retrieved_Gtid_Set 和 Executed_Gtid_Set 的并集发送给主库,主库将收到的并集和自己的
gtid_executed 比较,把从库 gtid 集合里缺失的事务全都发送给从库。
主机重启后,事务重复回放,表明 Retrieved_Gtid_Set 和 Executed_Gtid_Set 的并集中有 GTID 事务
丢失,导致重复获取事务执行引发主键冲突错误。Retrieved_Gtid_Set 和 Executed_Gtid_Set 均为内存变
量,MySQL 重启后,Retrieved_Gtid_Set 初始化为空值,从而推断出 Executed_Gtid_Set 有 GTID 事务丢
失。
Executed_Gtid_Set 来源于 gtid_executed 变量,gtid_executed 变量持久化介质有
mysql.gtid_executed 表和 binlog ,其中 mysql.gtid_executed 表是 MySQL 5.7 后引入的,在 MySQL 5.6 中,从库要使用 GTID ,必须要先设置 log_bin=on,log_slave_updates=on ,因为从库执行过的 GTID 只保留在 binlog 中。
gtid_executed 变量值陈旧,推断出 binlog 未实时持久化,我们看一下参数 sync_binlog :
通过以上分析,此次故障来龙去脉就清楚了:
Worker 线程报 1062 主键冲突错误 -->gtid_executed 信息陈旧 -->binlog 未实时持久化
搭建一主一从测试环境,通过 sysbench 模拟主库并发插入,从库主机暴力关机后,故障复现:
既然错误原因是事务重复执行,那跳过错误就好了,有如下两种方式,根据需要选取其中一种方式执行:
如果最新 binglog 丢失的 GTID 较多,手工执行比较繁琐,需要不断试错。可写一个存储过程批量执行:
待主从同步正常后,再取消参数 slave_skip_errors 设置重启 MySQL 。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)