MySQL误操作数据后闪回恢复——Binlog2sql使用详解

Binlog2sql的用途

  1. 数据快速回滚(闪回)
  2. 主从切换后新master丢数据的修复
  3. 从binlog生成标准SQL,带来的衍生功能

Binlog2sql的安装步骤

首先,确保系统安装了git和pip。

安装binlog2sql。可以通过以下命令进行:

bash 复制代码
shell> git clone https://github.com/danfengcao/binlog2sql.git && cd binlog2sql
shell> pip install -r requirements.txt

使用要求

MySQL服务器必须设置以下参数:

bash 复制代码
[mysqld]
server_id = 1
log_bin = /var/log/mysql/mysql-bin.log
max_binlog_size = 1G
binlog_format = row
binlog_row_image = full

用户需要的最小权限:

bash 复制代码
select, super/replication client, replication slave

#建议授权
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 
权限说明
  • select:读取server端information_schema.COLUMNS表,获取表结构的元信息。
  • super/replication client:执行'SHOW MASTER STATUS', 获取server端的binlog列表。
  • replication slave:通过BINLOG_DUMP协议获取binlog内容的权限。

基本用法

解析出标准SQL

bash 复制代码
shell> python binlog2sql.py -h127.0.0.1 -P3306 -uadmin -padmin -dtest -t test3 test4 --start-file='mysql-bin.000002'

解析出回滚SQL

bash 复制代码
shell> python binlog2sql.py --flashback -h127.0.0.1 -P3306 -uadmin -p'admin' -dtest -ttest3 --start-file='mysql-bin.000002' --start-position=763 --stop-position=1147

Binlog2sql选项

1、mysql连接配置

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

2、解析模式

--stop-never 持续解析binlog。可选。默认False,同步至执行命令时最新的binlog位置。

-K, --no-primary-key 对INSERT语句去除主键。可选。默认False

-B, --flashback 生成回滚SQL,可解析大文件,不受内存限制。可选。默认False。与stop-never或no-primary-key不能同时添加。

--back-interval -B模式下,每打印一千行回滚SQL,加一句SLEEP多少秒,如不想加SLEEP,请设为0。可选。默认1.0。

3、解析范围控制

--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'。可选。默认不过滤。

4、对象过滤

-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。可选。默认为增删改都解析。用了此参数但没填任何类型,则三者都不解析。

应用案例

误删整张表数据,需要紧急回滚

例如,误删了test库的tbl表中的所有数据,需要紧急回滚。

  1. 登录mysql,查看目前的binlog文件
bash 复制代码
    mysql> show master status;
    +------------------+-----------+
    | Log_name         | File_size |
    +------------------+-----------+
    | mysql-bin.000051 |       967 |
    | mysql-bin.000052 |       965 |
    +------------------+-----------+
  1. 最新的binlog文件是mysql-bin.000052,我们再定位误操作SQL的binlog位置。误操作人只能知道大致的误操作时间,我们根据大致时间过滤数据。
bash 复制代码
 shell> python binlog2sql/binlog2sql.py -h127.0.0.1 -P3306 -uadmin -p'admin' -dtest -ttbl --start-file='mysql-bin.000052' --start-datetime='2016-12-13 20:25:00' --stop-datetime='2016-12-13 20:30:00'
    输出:
    INSERT INTO `test`.`tbl`(`addtime`, `id`, `name`) VALUES ('2016-12-13 20:26:00', 4, '小李'); #start 317 end 487 time 2016-12-13 20:26:26
    UPDATE `test`.`tbl` SET `addtime`='2016-12-12 00:00:00', `id`=4, `name`='小李' WHERE `addtime`='2016-12-13 20:26:00' AND `id`=4 AND `name`='小李' LIMIT 1; #start 514 end 701 time 2016-12-13 20:27:07
    DELETE FROM `test`.`tbl` WHERE `addtime`='2016-12-10 00:04:33' AND `id`=1 AND `name`='小赵' LIMIT 1; #start 728 end 938 time 2016-12-13 20:28:05
    DELETE FROM `test`.`tbl` WHERE `addtime`='2016-12-10 00:04:48' AND `id`=2 AND `name`='小钱' LIMIT 1; #start 728 end 938 time 2016-12-13 20:28:05
    DELETE FROM `test`.`tbl` WHERE `addtime`='2016-12-13 20:25:00' AND `id`=3 AND `name`='小孙' LIMIT 1; #start 728 end 938 time 2016-12-13 20:28:05
    DELETE FROM `test`.`tbl` WHERE `addtime`='2016-12-12 00:00:00' AND `id`=4 AND `name`='小李' LIMIT 1; #start 728 end 938 time 2016-12-13 20:28:05
  1. 我们得到了误操作sql的准确位置在728-938之间,再根据位置进一步过滤,使用flashback模式生成回滚sql,检查回滚sql是否正确(注:真实环境下,此步经常会进一步筛选出需要的sql。结合grep、编辑器等)
bash 复制代码
shell> python binlog2sql/binlog2sql.py -h127.0.0.1 -P3306 -uadmin -p'admin' -dtest -ttbl --start-file='mysql-bin.000052' --start-position=3346 --stop-position=3556 -B > rollback.sql | cat
    输出:
    INSERT INTO `test`.`tbl`(`addtime`, `id`, `name`) VALUES ('2016-12-12 00:00:00', 4, '小李'); #start 728 end 938 time 2016-12-13 20:28:05
    INSERT INTO `test`.`tbl`(`addtime`, `id`, `name`) VALUES ('2016-12-13 20:25:00', 3, '小孙'); #start 728 end 938 time 2016-12-13 20:28:05
    INSERT INTO `test`.`tbl`(`addtime`, `id`, `name`) VALUES ('2016-12-10 00:04:48', 2, '小钱'); #start 728 end 938 time 2016-12-13 20:28:05
    INSERT INTO `test`.`tbl`(`addtime`, `id`, `name`) VALUES ('2016-12-10 00:04:33', 1, '小赵'); #start 728 end 938 time 2016-12-13 20:28:05
  1. 确认回滚sql正确,执行回滚语句。
bash 复制代码
 shell> mysql -h127.0.0.1 -P3306 -uadmin -p'admin' < rollback.sql

5、登录mysql确认,数据回滚成功。

sql 复制代码
   mysql> select * from tbl;
    +----+--------+---------------------+
    | id | name   | addtime             |
    +----+--------+---------------------+
    |  1 | 小赵   | 2016-12-10 00:04:33 |
    |  2 | 小钱   | 2016-12-10 00:04:48 |
    |  3 | 小孙   | 2016-12-13 20:25:00 |
    |  4 | 小李   | 2016-12-12 00:00:00 |
    +----+--------+---------------------+

限制(对比mysqlbinlog)

  • MySQL服务器必须开启,离线模式下不能解析。
  • 参数binlog_row_image必须为FULL
  • 解析速度不如mysqlbinlog。

优点(对比mysqlbinlog)

  • 纯Python开发,安装与使用都很简单。
  • 自带flashback、no-primary-key解析模式。
  • 适合闪回实战。
  • 解析为标准SQL,方便理解、筛选。
  • 代码容易改造,可以支持更多个性化解析。

通过binlog2sql,MySQL数据库管理者可以有效地应对数据误操作的情况,快速恢复数据,减少潜在的损失。

相关推荐
苹果醋38 分钟前
2020重新出发,MySql基础,MySql表数据操作
java·运维·spring boot·mysql·nginx
小蜗牛慢慢爬行10 分钟前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
hanbarger13 分钟前
nosql,Redis,minio,elasticsearch
数据库·redis·nosql
微服务 spring cloud35 分钟前
配置PostgreSQL用于集成测试的步骤
数据库·postgresql·集成测试
先睡38 分钟前
MySQL的架构设计和设计模式
数据库·mysql·设计模式
弗罗里达老大爷39 分钟前
Redis
数据库·redis·缓存
仰望大佬0071 小时前
Avalonia实例实战五:Carousel自动轮播图
数据库·microsoft·c#
学不透java不改名1 小时前
sqlalchemy连接dm8 get_columns BIGINT VARCHAR字段不显示
数据库
一只路过的猫咪1 小时前
thinkphp6使用MongoDB多个数据,聚合查询的坑
数据库·mongodb