#作者:stackofumbrella
文章目录
- 一、前言
- 二、故障概述
-
- [2.1 基础信息](#2.1 基础信息)
- [2.2 故障现象描述](#2.2 故障现象描述)
- 三、故障诊断分析
-
- [3.1 排查过程](#3.1 排查过程)
- [3.2 问题根因](#3.2 问题根因)
- [四、故障解决方案 📊](#四、故障解决方案 📊)
-
- [4.1 解决方案 🛠️](#4.1 解决方案 🛠️)
- 五、总结
- 附件
一、前言
在磐基系统中大量使用MySQL作为后端的数据存储,支撑着各类关键业务的数据读写需求。为保障数据的高可用性与业务连续性,实现数据的冗余备份,普遍采用MySQL主从复制架构。但在使用过程中,较频繁的出现从库被写入数据的问题,导致主从数据不一致,影响业务的正常运行。因此,配置合理参数,防止从库被写入数据,显得尤为重要。
二、故障概述
2.1 基础信息
磐基版本:kem
涉及组件:MySQL 5.7.38
参考范围:所有使用MySQL的业务系统
2.2 故障现象描述
磐基租户在使用MySQL主从同步过程中从库同步异常,导致主从数据不一致。
三、故障诊断分析
3.1 排查过程
通过查看show slave status\G状态信息,从错误信息可以看出从库在同步mysql-bin.000010文件的偏移量位置为830237357的数据时候出现错误。从库具体报错信息如下:
Last_SQL_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 'ANONYMOUS' at master log mysql-bin.000010, end_log_pos 830237357. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
从错误信息中可以看出,查看performance_schema.replication_applier_status_by_worker表可以获取更详细的信息,因此在从库执行SQL语句select * from performance_schema.replication_applier_status_by_worker查询结果如下图所示:
在查询结果中看出,在更新某个库的某个表时发生了错误,找到这个表和主库进行对比,发现从库比主库的数据较新且数据量多于主库。
另外可以根据查询结果,到主库找到对应的mysql-bin.000010二进制文件,使用如下命令找到偏移量830237357前后的SQL语句,查看到底是哪些操作,在与从库数据对比并更正,跳过错误的事件或者删除某些数据:
# mysqlbinlog --no-defaults -v -v --base64 --output=decode-rows /var/lib/mysql/mysql-bin.000010 | grep -A 20 "830237357" --color
注意:此命令针对数据量不大的情况使用,对于大量差异数据,还是采用下面章节的方法。
3.2 问题根因
业务在连接数据库时,配置DNS域名地址,使得主从数据库被轮询访问,而从库中并未配置只读参数,这样就会导致从库中被写入了大量数据,从而进一步导致主从同步不一致。
四、故障解决方案 📊
4.1 解决方案 🛠️
注意:请提前备份好主从库数据,再执行SQL语句:
mysql> stop slave;
mysql> set global sql_slave_skip_counter=1; #跳过一个事务,可以执行多次
mysql> start slave;
mysql> show slave status\G;
或者执行:
mysql> stop slave;
mysql> reset slave; #重置同步
mysql> start slave;
mysql> show slave status\G;
以上方式只适用于同步过程中出现的较少错误,对于较多同步错误,需要为从库添加只读参数,修改部署mysql的deploy清单文件,添加arg参数:
arg:
- --read_only=1
- --super_read_only=1
- --slave-skip-errors=all
重启deploy后,主从恢复正常同步
五、总结
MySQL的read_only参数可以让整个MySQL实例普通权限用户处于只读状态,但并不能限制拥有super权限的用户。read_only参数一般是用于主从复制从库的配置,目的是为了规避从库误写数据,导致主从复制异常或者主从数据不一致的隐患。另外,为了避免从库被super权限用户误写数据,MySQL官方在MySQL5.7版本引入了super_read_only参数来限制super用户在从库的只读属性。
附件
官方参考地址:
https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_super_read_only