内容简介:公司之前在做东南亚社交项目,涉及到的各个端人员比较多,开发、运维、产品、测试20多个,当然,对大公司来说,20其实不算多,进入正题,我们数据库使用的是MySQL,运维搭建的主从,而正是由于这个所谓的主从,害苦了开发的兄弟们;缓存使用的是Redis,MySQL数据同步到Redis使用的是阿里开源的Canal,了解Canal的都知道,Canal是读取MySQL的二进制文件,进而得到数据的变更,然后同步到Redis。某天傍晚,后台开发兄弟们日常更新,由于产品要求用户的昵称支持输入表情,我们不得不修改MySQL的配
公司之前在做东南亚社交项目,涉及到的各个端人员比较多,开发、运维、产品、测试20多个,当然,对大公司来说,20其实不算多,进入正题,我们数据库使用的是MySQL,运维搭建的主从,而正是由于这个所谓的主从,害苦了开发的兄弟们;缓存使用的是Redis,MySQL数据同步到 Redis 使用的是阿里开源的Canal,了解Canal的都知道,Canal是读取 MySQL 的二进制文件,进而得到数据的变更,然后同步到Redis。
某天傍晚,后台开发兄弟们日常更新,由于产品要求用户的昵称支持输入表情,我们不得不修改MySQL的配置文件,使其支持表情,修改了Master配置文件,自然就需要修改Slave 的配置文件,将Master重启后,然后重启Slave,都重启后,发现master上的数据不能同步到slave了,我擦,不过由于项目刚刚起步,访问量不大,加上天色已晚,后台开发兄弟决定,不能同步就不能同步吧,明天找运维同事搞定。
第二天,运维同事了解情况后,连上服务器,一顿操作。下午三点左右, 产品正在演示APP,说APP首页没有数据了,我们说,呵呵,怎么可能,然后登上数据库后,我我我擦,master 用户表的数据被清空了,瞬间有点发毛,难道被攻击了,赶紧看下 slave,我*,比master上的数据都干净,而此时的master 里面的用户表 还有几条刚刚注册进来的几条数据,冷汗直流。缓存,对,看下缓存中,赶紧连上缓存服务器,疑问了,缓存里面 还有数据,master 用户表的数据没有了,而缓存又是读取的master里面的二进制文件,先不考虑这个问题,目前的紧急问题是赶紧恢复数据。由于开启了binlog,那就从这里恢复,一同事赶紧下载binlog,玛德,文件太大,拉下来 将近40分钟,这个方法暂缓。诶,缓存不是有数据嘛,那就把缓存里面的数据重新写到MySQL,赶紧写一个for循环,从 丢失的数据的 ID 往前读,然后一个个insert到数据库,当然,这种方法会导致数据有点旧,不过,和数据完全丢失比起来,那就毛毛雨了。终于,历经将近一小时,数据恢复。
数据恢复后,我们首要的目标就是查原因,原因无非就是两个,一是被攻击,二是内部人员所为。查看MySQL的二进制日志,数据丢失大约是在3点左右,而服务器是在曼谷,时间比北京时间晚一个小时,也就是服务器上的时间是2点左右,拉二进制文件找原因,呵,太慢了,几行命令搞定,
-- 查看某个时间段的二进制日志,并且输出到指定的文件 mysqlbinlog --no-defaults --start-datetime="2018-12-12 13:00:00" --stop-datetime="2018-12-12 14:40:00" mysql-bin.000085 -vv --base64-output=decode-rows | more >> target.txt -- 将@1、@2等一系列看不懂的符号转换为 SQL 语句 cat target.txt | sed -n '/###/p' | sed 's/### //g;s/\/\*.*/,/g;s/DELETE FROM/INSERT INTO/g;' | sed -r 's/(@4.*),/\1;/g' | sed 's/@[0-9]*\=//g' > test.sql 复制代码
然后将 test.sql 文件拉下来,查看,发现两处可疑点(即两条SQL),如下:
-- 创建一个像user一样的表,user_bak create table user_bak like user; -- 删除 user_bak drop table user_bak; 复制代码
但是,没有清空或者删除user 表的sql,奇了怪了。突然,技术总监过来问,有没有找到原因,我说还没有,只是找到了两条可疑的SQL,但是还没发现有清空user的SQL,因为一直在看master上的日志,因为是主从,看master 上的日志和看slave上的一样,然而,总监却说,slave上的日志也要查下,好吧,虽然觉得看了没什么用,谁让他是老大呢。登上slave服务器,却发现,为什么 slave 上也有二进制日志呢,先不管,看下日志,发现有如下SQL:
-- 删除 user drop table user; -- 创建user create table user( ...省略字段 ) COMMENT='用户表' COLLATE='utf8_general_ci' ENGINE=InnoDB AUTO_INCREMENT=4xxxxxx ; 复制代码
虽然打脸了,但是为什么slave上也会有二进制日志呢,赶紧找运维问下到底是不是主从,运维说是,算了,还是看下配置文件,呵呵,竟然是主主,不是说好的主从呢,怪不得在 slave上执行了 删除用户表,然后创建用户表,创建的下一个自增点还是丢失前的自增点,master上用户表的数据就不存在了,这样Redis中数据存在的原因也破解了,Redis 读取的是master中的二进制文件,正是由于从所谓的“从”删除然后重建user表后(记录到“从”的二进制日志),“主”上就有了user 表(记录到“主”的中继日志,并没有在这个“主”的二进制日志,所以 Canal根本没有读取到在“从”上的操作),原因是找到了,但是 是谁执行的呢??当我们正在讨论的时候,运维说他在做测试,测试昨天的主从有没有正常了,他在修复昨天不能主从复制的问题。
崩溃,修复就修复,执行删除干嘛,而说好的主从,咋还变成主主了,问题 原因找到了,意味着不用加班到天亮了。
这种问题一定要杜绝:
- 非特殊情况,禁止使用ROOT账户;
- 相关人员分配MySQL账户,制定权限;
- 禁止执行不带条件的DELETE、UPDATE,TRUNCATE,DROP
或者 扫描下方二维码:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Just My Type
Simon Garfield / Profile Books / 2010-10-21 / GBP 14.99
What's your type? Suddenly everyone's obsessed with fonts. Whether you're enraged by Ikea's Verdanagate, want to know what the Beach Boys have in common with easy Jet or why it's okay to like Comic Sa......一起来看看 《Just My Type》 这本书的介绍吧!