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
更多精彩内容,欢迎关注微信公众号