基于Binlog闪退恢复MySQL数据

0.闪退工具简介

  • 官方工具mysqlbinlog
    上手成本快,支持离线解析,但兼容性差。

  • 独立工具binlog2sql,通过伪装成slave拉取binlog来进行处理。
    兼容性好;安装和使用简单,但不支持离线解析,必须开启MySQL。

1.Binlog介绍

、binlog (二进制日志文件) 是记录所有数据库事件的逻辑日志,包括表结构变更的DDL语句、表数据修改的DML语句以及权限状态的DCL语句。

DML:insert  update  delete  
DCL: grant   revoke  lock 
DDL: create  drop    alter   truncate

binlog不会记录SELECT和SHOW这类操作,因为这类操作对数据本身并没有修改,但可以通过查询general_log来查看MySQL执行过的所有语句。
记录数据库发生的变化操作(DDL、DCL、DML)的(类似于sql语句记录)

2.Binlog作用

    数据恢复。
    主从复制。

3. Binlog配置方法

默认:未开启

vim /etc/my.cnf

server_id=66
binlog_format                  = ROW
log_bin                        = /data/3306/binlog/mysql-bin
log_bin_index                  = /data/3306/binlog/mysql-bin.index
# 强烈建议再开启GTID
gtid_mode=on                   # 开关
enforce_gtid_consistency=on    # 强制GTID一致性
log_slave_updates=ON           # 强制从库更新binlog

GTID (Global transaction identifiers)     全局事务ID
    全局唯一:对每个事务,进行单独编号。连续不断进行增长。 
    GTID具有幂等性
表示方式
    GTID 分两部分(uuid:trans_id)
mysql> select @@log_bin;
+-----------+
| @@log_bin |
+-----------+
|         1 |
+-----------+
1 row in set (0.00 sec)

mysql> select @@log_bin_basename;
+-----------------------------+
| @@log_bin_basename          |
+-----------------------------+
| /data/3306/binlog/mysql-bin |
+-----------------------------+
1 row in set (0.00 sec)

mysql> select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          66 |
+-------------+
1 row in set (0.00 sec)

mysql> select @@binlog_format;
+-----------------+
| @@binlog_format |
+-----------------+
| ROW             |
+-----------------+
1 row in set (0.00 sec)

4. DDL误操作恢复

处理思路:
登录数据库查找终点(删库);
查找起点(建库);
截取起点到终点之前的binlog日志;
恢复截取的binlog日志。

找终点(删库操作)----查看当前的binlog文件
show master status;
+------------------+----------+--------------+------------------+---------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                           |
+------------------+----------+--------------+------------------+---------------------------------------------+
| mysql-bin.000010 |      353 |              |                  | ffc6b8d8-402f-11eb-982a-00163e2ebbf7:1-1826 |
+------------------+----------+--------------+------------------+---------------------------------------------+

查看当前binlog文件确定终点的position号或者GTID号
show binlog events in 'mysql-bin.000010';
..............
| mysql-bin.000010 | 3427 | Xid            |        66 |        3458 | COMMIT /* xid=32988 */                                                                                                           |
| mysql-bin.000010 | 3458 | Gtid           |        66 |        3523 | SET @@SESSION.GTID_NEXT= 'ffc6b8d8-402f-11eb-982a-00163e2ebbf7:1824'                                                             |
| mysql-bin.000010 | 3523 | Query          |        66 |        3738 | GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED WITH 'mysql_native_password' AS '*13D630121C940C9189D36C6EB7E03304BB59A837' |
| mysql-bin.000010 | 3738 | Gtid           |        66 |        3803 | SET @@SESSION.GTID_NEXT= 'ffc6b8d8-402f-11eb-982a-00163e2ebbf7:1825'                                                             |
| mysql-bin.000010 | 3803 | Query          |        66 |        3897 | DROP DATABASE `test`  

刷新新的binlog文件:
flush logs;
找起点(建库操作)
mysql> pager grep  'create database test';
PAGER set to 'grep  'create database test''

经过查找确认在6号文件
mysql> show binlog events in 'mysql-bin.000006';
......
| mysql-bin.000006 | 12131489 | Query          |        66 |    12131583 | create database test xxxx
......
| mysql-bin.000006 | 16767492 | Query          |        66 |    16767616 | use `test`; /*!40000 ALTER TABLE `t_yq_from_to` ENABLE KEYS */                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| mysql-bin.000006 | 16767616 | Stop           |        66 |    16767639 |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+------------------+---------+----------------+-----------+-------------+----------------------------------------------------------------------+

15574 rows in set (0.02 sec)

目前,创建库的binlog是6号文件,DROP库是10号文件
方法1:根据GTID截取,全局事务编号唯一
方法2:根据position截取,逐个文件截取
当时用的第一种方式,效率高;现在用第二种。方式都是大同小异。

查找7号文件的起点和终点
+------------------+---------+----------------+-----------+-------------+----------------------------------------------------------------------+
| Log_name         | Pos     | Event_type     | Server_id | End_log_pos | Info                                                                 |
+------------------+---------+----------------+-----------+-------------+----------------------------------------------------------------------+
| mysql-bin.000007 |        4 | Format_desc    |        66 |         123 | Server ver: 5.7.28-log, Binlog ver: 4                               |
| mysql-bin.000007 |      123 | Previous_gtids |        66 |         154 |                                                                     |
| mysql-bin.000007 |      154 | Anonymous_Gtid |        66 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'      
..............
| mysql-bin.000007 | 22230466 | Delete_rows    |        66 |    22230574 | table_id: 123 flags: STMT_END_F                                     |
| mysql-bin.000007 | 22230574 | Xid            |        66 |    22230605 | COMMIT /* xid=20521 */                                              |
| mysql-bin.000007 | 22230605 | Stop           |        66 |    22230628 |  
+------------------+---------+----------------+-----------+-------------+----------------------------------------------------------------------+

查找8号文件的起点和终点
+------------------+---------+----------------+-----------+-------------+----------------------------------------------------------------------+
| Log_name         | Pos     | Event_type     | Server_id | End_log_pos | Info                                                                 |
+------------------+---------+----------------+-----------+-------------+----------------------------------------------------------------------+
| mysql-bin.000008 |      4 | Format_desc    |        66 |         123 | Server ver: 5.7.28-log, Binlog ver: 4                                 |
| mysql-bin.000008 |    123 | Previous_gtids |        66 |         154 |                                                                       |
| mysql-bin.000008 |    154 | Gtid           |        66 |         219 | SET @@SESSION.GTID_NEXT= 'ffc6b8d8-402f-11eb-982a-00163e2ebbf7:1'     |
| mysql-bin.000008 |    219 | Query          |        66 |         302 | use `kodcloud`; FLUSH TABLES                                          |
.......
| mysql-bin.000008 | 394042 | Xid            |        66 |      394073 | COMMIT /* xid=2085 */                                                 |
| mysql-bin.000008 | 394073 | Stop           |        66 |      394096 |                                                                       |
+------------------+---------+----------------+-----------+-------------+----------------------------------------------------------------------+

查找9号文件的起点和终点
+------------------+---------+----------------+-----------+-------------+----------------------------------------------------------------------+
| Log_name         | Pos     | Event_type     | Server_id | End_log_pos | Info                                                                 |
+------------------+---------+----------------+-----------+-------------+----------------------------------------------------------------------+
| mysql-bin.000009 |       4 | Format_desc    |        66 |         123 | Server ver: 5.7.28-log, Binlog ver: 4                                |
| mysql-bin.000009 |     123 | Previous_gtids |        66 |         194 | ffc6b8d8-402f-11eb-982a-00163e2ebbf7:1-168                           |
| mysql-bin.000009 |     194 | Gtid           |        66 |         259 | SET @@SESSION.GTID_NEXT= 'ffc6b8d8-402f-11eb-982a-00163e2ebbf7:169'  |
| mysql-bin.000009 |     259 | Query          |        66 |         336 | BEGIN                                                                |
.........
| mysql-bin.000009 | 9760280 | Table_map      |        66 |     9760346 | table_id: 108 (wordpress.wp_options)                                 |
| mysql-bin.000009 | 9760346 | Delete_rows    |        66 |     9760454 | table_id: 108 flags: STMT_END_F                                      |
| mysql-bin.000009 | 9760454 | Xid            |        66 |     9760485 | COMMIT /* xid=32005 */                                               |
| mysql-bin.000009 | 9760485 | Rotate         |        66 |     9760532 | mysql-bin.000010;pos=4                                               |
+------------------+---------+----------------+-----------+-------------+----------------------------------------------------------------------+

截取test库下的日志(此时根据position号截取,需要跳过GTID幂等性检查)

mysqlbinlog -d test --skip-gtids --start-position=12131489  --stop-position=16767616   /data/3306/binlog/mysql-bin.000006 >/root/6.sql
mysqlbinlog -d test --skip-gtids --start-position=4 --stop-position=22230605    /data/3306/binlog/mysql-bin.000007  >/root/7.sql
mysqlbinlog -d test --skip-gtids --start-position=4 --stop-position=394073     /data/3306/binlog/mysql-bin.00000   >/root/8.sql
mysqlbinlog -d test --skip-gtids --start-position=4 --stop-position=9760485  /data/3306/binlog/mysql-bin.000009  >/root/9.sql
mysqlbinlog -d test --skip-gtids --start-position=4 --stop-position=3803    /data/3306/binlog/mysql-bin.000010  >/root/10.sql

恢复截取的binlog日志

mysql -uroot -p

set sql_log_bin=0;      临时关闭当前窗口的二进制日志
source /root/6.sql;
source /root/7.sql;
source /root/8.sql;
source /root/9.sql;
source /root/10.sql;
set sql_log_bin=1;

e.检验是否恢复成功
mysql> use test;
Database changed
mysql> show tables;
+-----------------------------------------+
| Tables_in_test                          |
+-----------------------------------------+
| con_info_xxxxx                          |
| con_xxxxxxxx_area                       |
| con_xxxxxxxxxxxxxxxxxxrea_ref           |
| xxxxxxxxxxxxxxxxxxxure_area_ref         |
| xxxxxxxxxxxxxxxxxxxe_log                |
| ........                                |
| water_cxxxxxxxxn_view                   |
+-----------------------------------------+
92 rows in set (0.02 sec)


抽查表中数据是否正确
mysql> select count(*) from test.t_yq_province_num;
+----------+
| count(*) |
+----------+
|      337 |
+----------+

5.DML误操作恢复

在日常工作中,也会碰到DML误操作的一些情况,比如update,delete批量误操作等的情况,可以利用binlog2sql快速回退。

binlog2sql是一个开源的Python开发的MySQL Binlog解析工具,能够将Binlog解析为原始的SQL,也支持将Binlog解析为回滚的SQL,以便做数据恢复。

安装binlog2sql

git clone https://github.com/danfengcao/binlog2sql.git && cd binlog2sql
yum install python3
cd binlog2sql-master
pip3 install -r requirements.txt
pip3 show pymysql
pip3 install --upgrade PyMySQL

解析日志事件SQL

a.参数选项
基础参数

-h host
-P port
-u user
-p password

解析模式

--stop-never      持续解析binlog。可选。默认False,同步至执行命令时最新的binlog位置。
-B                生成回滚SQL,可解析大文件,不受内存限制。可选。默认False。与stop-never或no-primary-key不能同时添加。
--back-interval   -B模式下,每打印一千行回滚SQL,加一句SLEEP多少秒,如不想加SLEEP,请设为0。可选。默认1.0。

解析范围控制

--start-file                     起始解析文件,只需文件名,无需全路径 。
--start-position/--start-pos     起始解析位置。可选。默认为start-file的起始位置。
--stop-file/--end-file           终止解析文件。可选。默认为start-file同一个文件。若解析模式为stop-never,此选项失效。
--stop-position/--end-pos        终止解析位置。可选。默认为stop-file的最末位置;若解析模式为stop-never,此选项失效。
--start-datetime                 起始解析时间,格式'%Y-%m-%d %H:%M:%S'。可选。默认不过滤。
--stop-datetime                  终止解析时间,格式'%Y-%m-%d %H:%M:%S'。可选。默认不过滤。

对象过滤

-d, --databases        只解析目标db的sql,多个库用空格隔开,如-d db1 db2。可选。默认为空。
-t, --tables           只解析目标table的sql,多张表用空格隔开,如-t tbl1 tbl2。可选。默认为空。
--only-dml             只解析dml,忽略ddl。可选。默认False。
--sql-type             只解析指定类型,支持INSERT, UPDATE, DELETE。多个类型用空格隔开,如--sql-type INSERT DELETE。

b. 单独过滤某张表的binlog

cd /root/binlog2sql/binlog2sql/
# python3 binlog2sql.py  -h 127.0.0.1 -P3306 -uroot -p123 -d test1 -t t1 --start-file='mysql-bin.000003'
INSERT INTO `test1`.`t1`(`id`) VALUES (1); #start 1647 end 1891 time 2020-09-18 08:46:53 gtid
INSERT INTO `test1`.`t1`(`id`) VALUES (2); #start 1922 end 2166 time 2020-09-18 08:46:54 gtid
INSERT INTO `test1`.`t1`(`id`) VALUES (3); #start 3125 end 3369 time 2020-09-18 08:47:50 gtid
INSERT INTO `test1`.`t1`(`id`) VALUES (4); #start 3400 end 3644 time 2020-09-18 08:47:53 gtid

c. 单独过滤某些类型的binlog

python3 binlog2sql.py  -h 127.0.0.1 -P3306 -uroot -p123 -d test1 -t t1 --sql-type=delete  --start-file='mysql-bin.000003'
DELETE FROM `test1`.`t1` WHERE `id`=3 LIMIT 1; #start 5172 end 5416 time 2020-09-18 09:17:48 gtid

python3 binlog2sql.py  -h 127.0.0.1 -P3306 -uroot -p123 -d test1 -t t1 --sql-type=update  --start-file='mysql-bin.000003'
UPDATE `test1`.`t1` SET `id`=10 WHERE `id`=1 LIMIT 1; #start 4882 end 5141 time 2020-09-18 09:17:35 gtid

d. 生成指定事件回滚语句

python3 binlog2sql.py  -h 127.0.0.1 -P3306 -uroot -p123 -d test -t t1  --start-file='mysql-bin.000003'   --sql-type=delete --start-position=932 --stop-position=1198 -B >/tmp/flashback.sql

mysql -uroot -p
source /tmp/flashback.sql

更多精彩内容,欢迎关注微信公众号
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45320660/article/details/115326297