惊险!记一次从删库到恢复的经历

栏目: 数据库 · 发布时间: 5年前

内容简介:公司之前在做东南亚社交项目,涉及到的各个端人员比较多,开发、运维、产品、测试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
欢迎关注我的公众号,第一时间接收最新文章~ 搜索公众号:码咖

或者 扫描下方二维码:

惊险!记一次从删库到恢复的经历

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

《Unity3D网络游戏实战(第2版)》

《Unity3D网络游戏实战(第2版)》

罗培羽 / 机械工业出版社 / 2019-1-1 / 89.00元

详解Socket编程,搭建稳健的网络框架;解决网游中常见的卡顿、频繁掉线等问题;探求适宜的实时同步算法。完整的多人对战游戏案例,揭秘登录注册、游戏大厅、战斗系统等模块的实现细节。 想要制作当今热门的网络游戏,特别是开发手机网络游戏,或者想要到游戏公司求职,都需要深入了解网络游戏的开发技术。本书分为三大部分,揭示网络游戏开发的细节。 第一部分“扎基础”(1-5章) 介绍TCP网络游......一起来看看 《《Unity3D网络游戏实战(第2版)》》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具