起因:帐号同步服务访问网络存储异常,导致帐号数据文件只下载了一半就被截断了。而业务代码缺乏容错机制,直接把缺失的帐号给干掉了。
结果:自然是用户登录提示帐号不存在……
教训:
1、数据回滚流程不通畅,足足花了2个小时;
2、光有告警是不够的,异常保护机制很重要!超出阈值,就阻断。要把风险扼杀在摇篮里。
经验:从备份库取出一张表的数据,差异恢复到生产环境
1.1、切忌直接从备份库导出!
原因是:mysqldump -h 1.1.1.1 --single-transaction -u root xxdb xx_tbl > xx_tbl_1215.sql
vim xx_tbl_1215.sql 会发现语句:DROP TABLE IF EXISTS `xx_tbl`; CREATE TABLE `xx_tbl`(看起来 --add-drop-table参数是默认的)。
也就意味着,如果拿这个sql直接导入生产环境,则生成环境当前的数据会被drop掉。
正确的做法是创建个临时表:
在备份库上:CREATE TABLE xx_tbl_bak LIKE xx_tbl; insert xx_tbl_bak select * from xx_tbl;
mysqldump -h 1.1.1.1 --single-transaction -u root xxdb xx_tbl_bak > xx_tbl_bak_1215.sql
恢复到生产环境:CREATE TABLE xx_tbl_bak LIKE xx_tbl;
mysql -u root xxdb < xx_tbl_bak_1215.sql
1.2、找出xx_tbl和xx_tbl_bak的差异数据,合并处理
select * from xx_tbl_bak where not exists (select * from xx_tbl where Uin=xx_tbl_bak.Uin and Device=xx_tbl_bak.Device);
insert into xx_tbl select * from xx_tbl_bak where not exists (select * from xx_tbl where Uin=xx_tbl_bak.Uin and Device=xx_tbl_bak.Device);
反之,如果要查找两张表相同的数据:
select * from xx_tbl_bak where exists (select * from xx_tbl where Uin=xx_tbl_bak.Uin and Device=xx_tbl_bak.Device);