【mysql问题处理专栏】记一次通过binlog日志查询异常数据问题

周五的惊喜:一场数据大保健与周末拯救行动

一、问题简述

周五傍晚,当大脑已然启动“度假模式”,心儿早已飞向按摩浴缸与马杀鸡的怀抱,突然间,手机铃声如晴天霹雳般炸响。领导亲切的声音如同催命符,将我从美梦拉回现实。原来,线上数据出了大乱子——两家项目的数据玩起了“灵魂互换”,仿佛隔壁老王的媳妇半夜摸黑闯进了自家卧室,那叫一个尴尬又严重!领导拍板:周一上班前必须整得明明白白!
我一边应承着,心里暗喜:“小case嘛,查查日志不就得了?”然而,生活总是喜欢跟你开个小玩笑,让你知道什么叫“too young, too naive”。

二、解决问题大冒险

第一关:日志排查之锅甩前奏

策略:翻开系统日志,找找看是不是前端那帮家伙传参时手抖,把数据送错了门。
实况:登录系统,一顿猛搜,却发现日志里压根没记录入参数据。哎呀我去,这日志比“薛定谔的猫”还让人捉摸不透,关键时刻掉链子!看来这条路是堵死了,想把锅甩给前端的如意算盘落空。

第二关:数据库binlog探秘

策略:既然日志不给力,那就深入数据库的腹地,揪出那个捣蛋的binlog,看看它能否揭示数据串门的秘密。

(1)确认binlog开关

SHOW VARIABLES LIKE'log_bin';

在这里插入图片描述
看到“ON”,宛如见到救命稻草,内心狂喜:“还好,你丫没关!”

(2)定位binlog藏身之处

show VARIABLES like "log%';

在这里插入图片描述
哎呀,mysql住在docker容器里,这binlog的地址可是个“迷宫入口”。

(3)穿越迷宫找binlog

docker inspect mysql

在这里插入图片描述
终于发现,容器里的 /var/lib/mysql/mysql-bin 实际上映射到宿主机的 /opt/mysql/data。这就好比找到了神秘地下室的隐藏楼梯,离真相又近了一步。

(4)锁定嫌疑binlog

根据数据出生时间(17:54),锁定嫌疑犯——18:09收工的那家伙。
在这里插入图片描述
(5)翻译binlog密码本

借助 mysqlbinlog 工具,将嫌疑binlog翻译成人话。

mysqlbinlog --verbose mysql-bin.000108 --start-datetime="202X-XX-29 17:30:00" --stop-datetime="20XX-XX-29 18:20:00" | grep -E "XX表|insert|update|delete" > /var/lib/mysql/output.txt

这段命令是用来从MySQL的二进制日志(binlog)文件mysql-bin.000108中筛选出特定时间段内涉及特定表或特定操作类型(插入、更新、删除)的事件,并将筛选结果重定向输出到指定的文本文件/var/lib/mysql/output.txt。命令的具体组成部分及其含义如下:

mysqlbinlog: 这是MySQL提供的一个工具,用于读取和解析MySQL的二进制日志文件。它能将二进制格式的日志转换为可读的SQL语句或其他形式的文本输出。

–verbose: 启用详细模式。在输出中包含额外的信息,如事件头信息、服务器版本等,使得输出更易于理解和调试。

mysql-bin.000108: 指定要处理的二进制日志文件名。这是MySQL存储二进制日志的默认命名格式之一,表示具体的日志文件编号。

–start-datetime=“20XX-XX-29 17:30:00”: 设置开始时间过滤条件。命令将只处理在该指定日期和时间之后发生的事件。这里的日期和时间格式遵循MySQL的标准格式。

–stop-datetime=“20XX-XX-29 18:20:00”: 设置结束时间过滤条件。命令将只处理在该指定日期和时间之前发生的事件。结合–start-datetime参数,这定义了一个时间窗口,在该窗口内的日志事件才会被提取出来。

| grep -E “XX表|insert|update|delete”: 使用管道符号 (|) 将mysqlbinlog的输出传递给grep命令进行进一步筛选。grep使用扩展正则表达式(-E选项)来匹配以下模式:

XX表: 匹配包含特定表名(XX表)的事件,可能是指定表上的任何操作(插入、更新、删除)。

insert|update|delete: 匹配包含关键词“insert”、“update”或“delete”的事件,这些代表了对数据库表进行插入、更新或删除操作的SQL语句。

/var/lib/mysql/output.txt: 重定向操作符(>), 将上述命令组合产生的全部输出写入到指定的文件路径/var/lib/mysql/output.txt。如果该文件已存在,其内容将被覆盖;如果不存在,则创建该文件并写入输出。

遭遇时间差怪: 打开output.txt,却发现里面空空如也,连个鬼影都没有。难道binlog是个哑巴?调宽时间范围,依旧无果。直到发现容器与宿主机之间存在8小时的“时差”,恍然大悟,原来这家伙在倒时差呢!(实际时间12点了)
在这里插入图片描述
调整时间坐标: 将时间减去8小时,重新翻译。

mysqlbinlog --verbose mysql-bin.000108 --start-datetime="20XX-XX-29 7:30:00" --stop-datetime="20XX-XX-29 8:20:00" | grep -E "XX表|insert|update|delete" > /var/lib/mysql/output.txt

第三关:真相只有一个

解析binlog密文: 终于,output.txt里浮现出一段诡异的舞蹈:先是正常的插入,接着在另外的某同一时刻,数据被无情删掉,紧接着,一个错误关联的数据被强行塞进来。这剧情,比《名侦探柯南》还反转!
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

幕后黑手浮现: 顺藤摸瓜,发现前端代码里果然藏了个“定时炸弹”——在编辑数据时,偶尔会触发了数据大乱斗,传递不属于这个项目的参数。这下好了,罪魁祸首找到了,就是那个偶尔抽风的编辑功能。

终极解决方案: 给编辑功能戴上紧箍咒,严格校验数据,严禁删除非本业务的数据,严禁添加非本业务的数据。至此,数据界的“灵魂互换”闹剧宣告终结,世界恢复和平。

结语: 周末的大保健虽然泡汤,但成功拯救了一场数据危机,也算功德一件。生活告诉我们,即使遇到再奇葩的问题,只要保持冷静,步步为营,总能找到那只藏在深处的“bug狐狸”。至于大保健,改天再约也不迟,毕竟代码的世界里,每天都有新的“坑”等待填平,程序员的生活,就是如此多“滋”多彩!另外,上面只是解题的思路,遇到问题不要慌张,沿着问题一步步去摸索就行,再做一个警告,一定要做好日志处理,一定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值