今天开发在生产环境误删除了几条数据,作为DBA就得背锅了。二话不说,抓紧恢复
一开始选择使用binlog2sql工具,这是一款大众点评团队开发得工具。但介于生产环境使用的是操作系统是CentOS 6.6,系统默认安装的是Python 2.6。而binlog2sql是用Python开发的,而且现在从git拉下的包只支持 Python 2.7, 3.4+。而跟运维沟通,生产环境直接升级Python比较有风险。后来经过测试,2.6环境一直报语法问题,导致工具无法使用。
后来决定采用经美团开发的MyFlash(无需依赖Python)
- MyFlash是离线解析,速度也很快,非常方面
无需把binlog解析成文本,再进行转换
。提供原生的基于库、表、SQL类型、位置、时间等多种过滤方式
。- 支持MySQL多个版本(5.6与5.7)
- 对于数据库的代码重构不敏感,利于升级。
- 自主掌控binlog解析,提供尽可能灵活的方式。
一、限制
- binlog格式必须为row,且binlog_row_image=full
- 仅支持5.6与5.7
- 只能回滚DML(增、删、改)
二、安装
1、git clone https://github.com/Meituan-Dianping/MyFlash.git
2、安装依赖包
yum -y install libgnomeui-devel
3、动态编译连接
gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback
三、使用
鉴于MyFlash是离线解析,为了安全,如果binlog文件不太大,我建议先在测试环境进行恢复,研发进行数据校对,再进行线上恢复。
离线库上必须要创建需要恢复或者解析的库和表,不然解析会报错找不到表的错误。
注意对于update操作,离线恢复的时候记得把要恢复的表导入到离线库中,不然恢复回滚语句的时候会报找不到相应的记录。
1)查看误删除时正在使用的binlog,
show master status\G;
查看当前使用的binglog文件:mysql-bin.000020
2)flush logs;(切换日志,避免后续的更改日志影响,减少binlog文件的大小)
3)把生产环境的数据中的binlog文件:mysql-bin.000020 拖拽到本地测试机
4)、生成回滚文件(将该文件中的所有delete语句回滚)
#/home/tools/MyFlash/binary/flashback --binlogFileNames=/home/mysql-bin.000020 --start-datetime="2019-11-14 16:30:00" --stop-datetime="2019-11-14 17:15:00" --databaseNames=Tracker114 --tableNames=T1_AppointmentOrder --sqlTypes='DELETE'
默认将输出的结果打印到文件binlog_output_base.flashback,可以通过参数--outBinlogFileNameBase来指定
5)查看回滚sql
[root@master binary]# mysqlbinlog --no-defaults --base64-output=decode-rows -vv binlog_output_base.flashback
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#191107 6:01:04 server id 1223306 end_log_pos 123 CRC32 0x648b0507 Start: binlog v 4, server v 5.7.9-log created 191107 6:01:04
# at 123
#191114 16:53:16 server id 1223306 end_log_pos 266 CRC32 0x1c72e875 Table_map: `Tracker114`.`T1_AppointmentOrder` mapped to number 4750
# at 266
#191114 16:53:16 server id 1223306 end_log_pos 528 CRC32 0x97713f93 Write_rows: table id 4750 flags: STMT_END_F
### INSERT INTO `Tracker114`.`T1_AppointmentOrder`
### SET
### @1=1732109 /* INT meta=0 nullable=0 is_null=0 */
### @2='0bcc995235ae729016fb427f67bda481' /* VARSTRING(96) meta=96 nullable=0 is_null=0 */
### @3=1598817 /* INT meta=0 nullable=0 is_null=0 */
### @4=0 /* INT meta=0 nullable=0 is_null=0 */
### @5=1220344 /* INT meta=0 nullable=0 is_null=0 */
### @6=0 /* INT meta=0 nullable=0 is_null=0 */
### @7='2019-07-28' /* VARSTRING(30) meta=30 nullable=0 is_null=0 */
### @8=2 /* TINYINT meta=0 nullable=0 is_null=0 */
### @9=297 /* INT meta=0 nullable=0 is_null=0 */
### @10=1542 /* INT meta=0 nullable=0 is_null=0 */
### @11=3 /* INT meta=0 nullable=0 is_null=0 */
### @12=8024 /* INT meta=0 nullable=1 is_null=0 */
### @13=1 /* TINYINT meta=0 nullable=0 is_null=0 */
### @14=20000 /* INT meta=0 nullable=0 is_null=0 */
### @15='' /* VARSTRING(96) meta=96 nullable=0 is_null=0 */
### @16='230107199002071237' /* VARSTRING(96) meta=96 nullable=0 is_null=0 */
### @17='15210120322' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
### @18=1 /* INT meta=0 nullable=0 is_null=0 */
### @19=4 /* INT meta=0 nullable=0 is_null=0 */
### @20=28 /* INT meta=0 nullable=0 is_null=0 */
### @21=NULL /* VARSTRING(192) meta=192 nullable=1 is_null=1 */
### @22=1562763842 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
### @23=0 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
### @24=0 /* INT meta=0 nullable=1 is_null=0 */
### @25='支付前超时取消' /* VARSTRING(3072) meta=3072 nullable=1 is_null=0 */
### @26=0 /* INT meta=0 nullable=1 is_null=0 */
### @27='' /* VARSTRING(768) meta=768 nullable=1 is_null=0 */
### @28=NULL /* INT meta=0 nullable=1 is_null=1 */
### @29=NULL /* VARSTRING(3072) meta=3072 nullable=1 is_null=1 */
### @30=NULL /* VARSTRING(600) meta=600 nullable=1 is_null=1 */
### @31='' /* VARSTRING(600) meta=600 nullable=1 is_null=0 */
### @32=0 /* INT meta=0 nullable=1 is_null=0 */
### @33=0 /* TINYINT meta=0 nullable=1 is_null=0 */
### @34='svc_1562763842134609' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
### @35=1 /* INT meta=0 nullable=0 is_null=0 */
### @36=4 /* INT meta=0 nullable=0 is_null=0 */
### @37=0 /* INT meta=0 nullable=0 is_null=0 */
### @38=2 /* INT meta=0 nullable=0 is_null=0 */
### @39=1 /* TINYINT meta=0 nullable=0 is_null=0 */
### @40=NULL /* VARSTRING(150) meta=150 nullable=1 is_null=1 */
### @41=NULL /* VARSTRING(150) meta=150 nullable=1 is_null=1 */
# at 528
#191107 6:01:04 server id 1223306 end_log_pos 559 CRC32 0x4ec224e2 Xid = 97030048
COMMIT/*!*/;
# at 559
#191114 16:53:16 server id 1223306 end_log_pos 702 CRC32 0xca045513 Table_map: `Tracker114`.`T1_AppointmentOrder` mapped to number 4750
# at 702
#191114 16:53:16 server id 1223306 end_log_pos 956 CRC32 0x8d253998 Write_rows: table id 4750 flags: STMT_END_F
### INSERT INTO `Tracker114`.`T1_AppointmentOrder`
### SET
### @1=1732144 /* INT meta=0 nullable=0 is_null=0 */
### @2='221668e81f15830e8104d9d2e5c79004' /* VARSTRING(96) meta=96 nullable=0 is_null=0 */
### @3=1598818 /* INT meta=0 nullable=0 is_null=0 */
### @4=0 /* INT meta=0 nullable=0 is_null=0 */
### @5=1220344 /* INT meta=0 nullable=0 is_null=0 */
### @6=0 /* INT meta=0 nullable=0 is_null=0 */
### @7='2019-07-24' /* VARSTRING(30) meta=30 nullable=0 is_null=0 */
### @8=2 /* TINYINT meta=0 nullable=0 is_null=0 */
### @9=297 /* INT meta=0 nullable=0 is_null=0 */
### @10=1542 /* INT meta=0 nullable=0 is_null=0 */
### @11=3 /* INT meta=0 nullable=0 is_null=0 */
### @12=8024 /* INT meta=0 nullable=1 is_null=0 */
### @13=1 /* TINYINT meta=0 nullable=0 is_null=0 */
### @14=20000 /* INT meta=0 nullable=0 is_null=0 */
### @15='' /* VARSTRING(96) meta=96 nullable=0 is_null=0 */
### @16='230107199002071237' /* VARSTRING(96) meta=96 nullable=0 is_null=0 */
### @17='15210120322' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
### @18=1 /* INT meta=0 nullable=0 is_null=0 */
### @19=4 /* INT meta=0 nullable=0 is_null=0 */
### @20=28 /* INT meta=0 nullable=0 is_null=0 */
### @21=NULL /* VARSTRING(192) meta=192 nullable=1 is_null=1 */
### @22=1562773167 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
### @23=1562773470 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
### @24=0 /* INT meta=0 nullable=1 is_null=0 */
### @25='支付前取消' /* VARSTRING(3072) meta=3072 nullable=1 is_null=0 */
### @26=0 /* INT meta=0 nullable=1 is_null=0 */
### @27='' /* VARSTRING(768) meta=768 nullable=1 is_null=0 */
### @28=NULL /* INT meta=0 nullable=1 is_null=1 */
### @29=NULL /* VARSTRING(3072) meta=3072 nullable=1 is_null=1 */
### @30=NULL /* VARSTRING(600) meta=600 nullable=1 is_null=1 */
### @31=NULL /* VARSTRING(600) meta=600 nullable=1 is_null=1 */
### @32=0 /* INT meta=0 nullable=1 is_null=0 */
### @33=0 /* TINYINT meta=0 nullable=1 is_null=0 */
### @34='svc_1562773166842883' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
### @35=1 /* INT meta=0 nullable=0 is_null=0 */
### @36=4 /* INT meta=0 nullable=0 is_null=0 */
### @37=0 /* INT meta=0 nullable=0 is_null=0 */
### @38=2 /* INT meta=0 nullable=0 is_null=0 */
### @39=2 /* TINYINT meta=0 nullable=0 is_null=0 */
### @40=NULL /* VARSTRING(150) meta=150 nullable=1 is_null=1 */
### @41=NULL /* VARSTRING(150) meta=150 nullable=1 is_null=1 */
# at 956
#191107 6:01:04 server id 1223306 end_log_pos 987 CRC32 0x4ec224e2 Xid = 97030048
COMMIT/*!*/;
# at 987
#191114 16:53:15 server id 1223306 end_log_pos 1130 CRC32 0x0dda54db Table_map: `Tracker114`.`T1_AppointmentOrder` mapped to number 4750
# at 1130
#191114 16:53:15 server id 1223306 end_log_pos 1369 CRC32 0x7471682a Write_rows: table id 4750 flags: STMT_END_F
### INSERT INTO `Tracker114`.`T1_AppointmentOrder`
### SET
### @1=1733201 /* INT meta=0 nullable=0 is_null=0 */
### @2='424d02aef9e4cee8541d8dcf7e60d864' /* VARSTRING(96) meta=96 nullable=0 is_null=0 */
### @3=1604747 /* INT meta=0 nullable=0 is_null=0 */
### @4=0 /* INT meta=0 nullable=0 is_null=0 */
### @5=1220344 /* INT meta=0 nullable=0 is_null=0 */
### @6=0 /* INT meta=0 nullable=0 is_null=0 */
### @7='2019-07-15' /* VARSTRING(30) meta=30 nullable=0 is_null=0 */
### @8=2 /* TINYINT meta=0 nullable=0 is_null=0 */
### @9=245 /* INT meta=0 nullable=0 is_null=0 */
### @10=1053 /* INT meta=0 nullable=0 is_null=0 */
### @11=5 /* INT meta=0 nullable=0 is_null=0 */
### @12=7781 /* INT meta=0 nullable=1 is_null=0 */
### @13=1 /* TINYINT meta=0 nullable=0 is_null=0 */
### @14=50000 /* INT meta=0 nullable=0 is_null=0 */
### @15='' /* VARSTRING(96) meta=96 nullable=0 is_null=0 */
### @16='230107199002071237' /* VARSTRING(96) meta=96 nullable=0 is_null=0 */
### @17='15210120322' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
### @18=1 /* INT meta=0 nullable=0 is_null=0 */
### @19=2 /* INT meta=0 nullable=0 is_null=0 */
### @20=28 /* INT meta=0 nullable=0 is_null=0 */
### @21=NULL /* VARSTRING(192) meta=192 nullable=1 is_null=1 */
### @22=1562912822 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
### @23=1562912886 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
### @24=0 /* INT meta=0 nullable=1 is_null=0 */
### @25='' /* VARSTRING(3072) meta=3072 nullable=1 is_null=0 */
### @26=0 /* INT meta=0 nullable=1 is_null=0 */
### @27='' /* VARSTRING(768) meta=768 nullable=1 is_null=0 */
### @28=NULL /* INT meta=0 nullable=1 is_null=1 */
### @29=NULL /* VARSTRING(3072) meta=3072 nullable=1 is_null=1 */
### @30=NULL /* VARSTRING(600) meta=600 nullable=1 is_null=1 */
### @31=NULL /* VARSTRING(600) meta=600 nullable=1 is_null=1 */
### @32=0 /* INT meta=0 nullable=1 is_null=0 */
### @33=0 /* TINYINT meta=0 nullable=1 is_null=0 */
### @34='svc_1562912822662667' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
### @35=1 /* INT meta=0 nullable=0 is_null=0 */
### @36=4 /* INT meta=0 nullable=0 is_null=0 */
### @37=0 /* INT meta=0 nullable=0 is_null=0 */
### @38=1 /* INT meta=0 nullable=0 is_null=0 */
### @39=2 /* TINYINT meta=0 nullable=0 is_null=0 */
### @40=NULL /* VARSTRING(150) meta=150 nullable=1 is_null=1 */
### @41=NULL /* VARSTRING(150) meta=150 nullable=1 is_null=1 */
# at 1369
#191107 6:01:04 server id 1223306 end_log_pos 1400 CRC32 0x4ec224e2 Xid = 97030048
COMMIT/*!*/;
# at 1400
#191114 16:53:15 server id 1223306 end_log_pos 1543 CRC32 0xf1b1539b Table_map: `Tracker114`.`T1_AppointmentOrder` mapped to number 4750
# at 1543
#191114 16:53:15 server id 1223306 end_log_pos 1797 CRC32 0x8c38c8f9 Write_rows: table id 4750 flags: STMT_END_F
### INSERT INTO `Tracker114`.`T1_AppointmentOrder`
### SET
### @1=1780944 /* INT meta=0 nullable=0 is_null=0 */
### @2='4cf9f3129ddcc8a09cdac0b8ec07aa2f' /* VARSTRING(96) meta=96 nullable=0 is_null=0 */
### @3=1745989 /* INT meta=0 nullable=0 is_null=0 */
### @4=0 /* INT meta=0 nullable=0 is_null=0 */
### @5=1260270 /* INT meta=0 nullable=0 is_null=0 */
### @6=0 /* INT meta=0 nullable=0 is_null=0 */
### @7='2019-10-28' /* VARSTRING(30) meta=30 nullable=0 is_null=0 */
### @8=2 /* TINYINT meta=0 nullable=0 is_null=0 */
### @9=245 /* INT meta=0 nullable=0 is_null=0 */
### @10=1053 /* INT meta=0 nullable=0 is_null=0 */
### @11=5 /* INT meta=0 nullable=0 is_null=0 */
### @12=7781 /* INT meta=0 nullable=1 is_null=0 */
### @13=1 /* TINYINT meta=0 nullable=0 is_null=0 */
### @14=52000 /* INT meta=0 nullable=0 is_null=0 */
### @15='' /* VARSTRING(96) meta=96 nullable=0 is_null=0 */
### @16='513436200009246806' /* VARSTRING(96) meta=96 nullable=0 is_null=0 */
### @17='15210120322' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
### @18=1 /* INT meta=0 nullable=0 is_null=0 */
### @19=4 /* INT meta=0 nullable=0 is_null=0 */
### @20=28 /* INT meta=0 nullable=0 is_null=0 */
### @21=NULL /* VARSTRING(192) meta=192 nullable=1 is_null=1 */
### @22=1570698341 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
### @23=1570698361 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
### @24=0 /* INT meta=0 nullable=1 is_null=0 */
### @25='支付前取消' /* VARSTRING(3072) meta=3072 nullable=1 is_null=0 */
### @26=0 /* INT meta=0 nullable=1 is_null=0 */
### @27='' /* VARSTRING(768) meta=768 nullable=1 is_null=0 */
### @28=NULL /* INT meta=0 nullable=1 is_null=1 */
### @29=NULL /* VARSTRING(3072) meta=3072 nullable=1 is_null=1 */
### @30=NULL /* VARSTRING(600) meta=600 nullable=1 is_null=1 */
### @31=NULL /* VARSTRING(600) meta=600 nullable=1 is_null=1 */
### @32=0 /* INT meta=0 nullable=1 is_null=0 */
### @33=0 /* TINYINT meta=0 nullable=1 is_null=0 */
### @34='svc_1570698341883452' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
### @35=1 /* INT meta=0 nullable=0 is_null=0 */
### @36=4 /* INT meta=0 nullable=0 is_null=0 */
### @37=0 /* INT meta=0 nullable=0 is_null=0 */
### @38=1 /* INT meta=0 nullable=0 is_null=0 */
### @39=1 /* TINYINT meta=0 nullable=0 is_null=0 */
### @40=NULL /* VARSTRING(150) meta=150 nullable=1 is_null=1 */
### @41=NULL /* VARSTRING(150) meta=150 nullable=1 is_null=1 */
# at 1797
#191107 6:01:04 server id 1223306 end_log_pos 1828 CRC32 0x4ec224e2 Xid = 97030048
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
6)恢复(提前需要在离线测试环境创建其库和表)
#mysqlbinlog --skip-gtids binlog_output_base.flashback |mysql -uroot -p
7)验证:
mysql> SELECT * FROM T1_AppointmentOrder where Mobile='15210120322';
+---------+----------------------------------+--------------+---------+----------+--------------------+------------+----------+------------+--------------+---------------+----------+-----------------+---------------+----------------------+--------------------+-------------+--------------------+--------+----------------+------------------+---------------------+----------------------+---------------+-----------------------+-----------------+------------------+-------+--------+----------+----------+------------------+-----------------+----------------------+---------------+-----------+-----------------------+---------------------+--------+---------------------+-----------+
| Id | UniquenessCode | DutySourceId | AgentId | MemberId | MemberRegisteredId | DutyDate | DutyCode | HospitalId | DepartmentId | DoctorTitleId | DoctorId | ScheduledTarget | RegisteredFee | MemberRegisteredName | CardNumber | Mobile | HISIncrementNumber | Status | ChildChannelId | RegisteredUserId | CreateDate | CancelRegisteredDate | CancelAgentId | CancelReason | HospitalOfferId | MedicalInsurance | OldId | Remark | SubmitIp | CancelIp | RecommendChannel | WorkPlaceSource | ChannelOrderId | ServiceAreaId | ChannelId | ChannelSystemModuleId | SettlementChannelId | IsTest | ChannelDutySourceId | TpOrderId |
+---------+----------------------------------+--------------+---------+----------+--------------------+------------+----------+------------+--------------+---------------+----------+-----------------+---------------+----------------------+--------------------+-------------+--------------------+--------+----------------+------------------+---------------------+----------------------+---------------+-----------------------+-----------------+------------------+-------+--------+----------+----------+------------------+-----------------+----------------------+---------------+-----------+-----------------------+---------------------+--------+---------------------+-----------+
| 1732109 | 0bcc995235ae729016fb427f67bda481 | 1598817 | 0 | 1220344 | 0 | 2019-07-28 | 2 | 297 | 1542 | 3 | 8024 | 1 | 20000 | | 230107199002071237 | 15210120322 | 1 | 4 | 28 | NULL | 2019-07-10 21:04:02 | 0000-00-00 00:00:00 | 0 | 支付前超时取消 | 0 | | NULL | NULL | NULL | | 0 | 0 | svc_1562763842134609 | 1 | 4 | 0 | 2 | 1 | NULL | NULL |
| 1732144 | 221668e81f15830e8104d9d2e5c79004 | 1598818 | 0 | 1220344 | 0 | 2019-07-24 | 2 | 297 | 1542 | 3 | 8024 | 1 | 20000 | | 230107199002071237 | 15210120322 | 1 | 4 | 28 | NULL | 2019-07-10 23:39:27 | 2019-07-10 23:44:30 | 0 | 支付前取消 | 0 | | NULL | NULL | NULL | NULL | 0 | 0 | svc_1562773166842883 | 1 | 4 | 0 | 2 | 2 | NULL | NULL |
| 1733201 | 424d02aef9e4cee8541d8dcf7e60d864 | 1604747 | 0 | 1220344 | 0 | 2019-07-15 | 2 | 245 | 1053 | 5 | 7781 | 1 | 50000 | | 230107199002071237 | 15210120322 | 1 | 2 | 28 | NULL | 2019-07-12 14:27:02 | 2019-07-12 14:28:06 | 0 | | 0 | | NULL | NULL | NULL | NULL | 0 | 0 | svc_1562912822662667 | 1 | 4 | 0 | 1 | 2 | NULL | NULL |
| 1780944 | 4cf9f3129ddcc8a09cdac0b8ec07aa2f | 1745989 | 0 | 1260270 | 0 | 2019-10-28 | 2 | 245 | 1053 | 5 | 7781 | 1 | 52000 | | 513436200009246806 | 15210120322 | 1 | 4 | 28 | NULL | 2019-10-10 17:05:41 | 2019-10-10 17:06:01 | 0 | 支付前取消 | 0 | | NULL | NULL | NULL | NULL | 0 | 0 | svc_1570698341883452 | 1 | 4 | 0 | 1 | 1 | NULL | NULL |
参数:
--databaseNames
指定需要回滚的数据库名。多个数据库可以用“,”隔开。如果不指定该参数,相当于指定了所有数据库。
--tableNames
指定需要回滚的表名。多个表可以用“,”隔开。如果不指定该参数,相当于指定了所有表。
--start-datetime
指定回滚的开始时间。注意格式必须是 %Y-%m-%d %H:%M:%S。 如不指定,则不限定时间
--stop-datetime
指定回滚的结束时间。注意格式必须是 %Y-%m-%d %H:%M:%S。 如不指定,则不限定时间
--sqlTypes
指定需要回滚的sql类型。目前支持的过滤类型是INSERT, UPDATE ,DELETE。多个类型可以用“,”隔开。
--binlogFileNames
指定需要回滚的binlog文件,目前只支持单个文件,后续会增加多个文件支持。
--outBinlogFileNameBase
指定输出的binlog文件前缀,如不指定,则默认为binlog_output_base.flashback。