Apply flashback with DML
Project description
CooHSQL
介绍:
伪装 Slave 获取 MySQL binlog 从中解析到你想要的 SQL 语句,可以得到原始 SQL、回滚 SQL 语句。
用途:
- 数据库快速回滚(DML闪回)
- 配合其它备份工具恢复数据
- 可以自己定制 binlog 衍生功能
环境:
MySQL 数据库中设置相关参数:
[mysqld]
server_id = 1
log_bin = /var/log/mysql/mysql-bin.log
max_binlog_size = 1G
binlog_format = row
binlog_row_image = full
CooHSQL 需要安装的依赖环境
python 3.6+
MySQL 5.7+
PyMySQL >= 0.7.11
wheel >= 0.29.0
mysql-replication >= 0.13
演示:
测试一:测试环境数据库 School.Student 表设计如下:
desc Student;
Field | Type | Null | Key | Default | Extra |
---|---|---|---|---|---|
SId | varchar(10) | YES | NULL | ||
Sname | varchar(10) | YES | NULL | ||
Sage | datetime | YES | NULL | ||
Ssex | varchar(10) | YES | NULL |
select * from Student;
SId | Sname | Sage | Ssex |
---|---|---|---|
01 | 赵雷 | 1990-01-01 00:00:00 | 男 |
02 | 钱电 | 1990-12-21 00:00:00 | 男 |
03 | 孙风 | 1990-12-20 00:00:00 | 男 |
04 | 李云 | 1990-12-06 00:00:00 | 男 |
05 | 周梅 | 1991-12-01 00:00:00 | 女 |
06 | 吴兰 | 1992-01-01 00:00:00 | 女 |
-- update 语句忘记写条件, 导致整张表被修改
update Student set Ssex = '女';
-- 查看表数据, Sexx 已经全被修改
select * from Student;
SId | Sname | Sage | Ssex |
---|---|---|---|
01 | 赵雷 | 1990-01-01 00:00:00 | 女 |
02 | 钱电 | 1990-12-21 00:00:00 | 女 |
03 | 孙风 | 1990-12-20 00:00:00 | 女 |
04 | 李云 | 1990-12-06 00:00:00 | 女 |
05 | 周梅 | 1991-12-01 00:00:00 | 女 |
06 | 吴兰 | 1992-01-01 00:00:00 | 女 |
from CooHSQL.CooHSQL import CooHSQL
# mysql 连接参数
mysql_settings = {
'host': '127.0.01',
'port': 3306,
'user': 'root',
'password': 'coohsql'
}
CooHSQL = CooHSQL(mysql_settings, start_file='mysql-bin.000001', start_pos=143228)
CooHSQL.process_binlog() # 加工 binlog 输出回滚语句
UPDATE `school`.`Student` SET `SId`=04,`Sname`='李云',`Sage`='1990-12-06 00:00:00',`Ssex`='男' WHERE `SId`=04 and `Sname`='李云' and `Sage`='1990-12-06 00:00:00' and `Ssex`='女';
UPDATE `school`.`Student` SET `SId`=03,`Sname`='孙风',`Sage`='1990-12-20 00:00:00',`Ssex`='男' WHERE `SId`=03 and `Sname`='孙风' and `Sage`='1990-12-20 00:00:00' and `Ssex`='女';
UPDATE `school`.`Student` SET `SId`=02,`Sname`='钱电',`Sage`='1990-12-21 00:00:00',`Ssex`='男' WHERE `SId`=02 and `Sname`='钱电' and `Sage`='1990-12-21 00:00:00' and `Ssex`='女';
UPDATE `school`.`Student` SET `SId`=01,`Sname`='赵雷',`Sage`='1990-01-01 00:00:00',`Ssex`='男' WHERE `SId`=01 and `Sname`='赵雷' and `Sage`='1990-01-01 00:00:00' and `Ssex`='女';
SId | Sname | Sage | Ssex |
---|---|---|---|
1 | 赵雷 | 1990-01-01 00:00:00 | 男 |
2 | 钱电 | 1990-12-21 00:00:00 | 男 |
3 | 孙风 | 1990-12-20 00:00:00 | 男 |
4 | 李云 | 1990-12-06 00:00:00 | 男 |
05 | 周梅 | 1991-12-01 00:00:00 | 女 |
06 | 吴兰 | 1992-01-01 00:00:00 | 女 |
测试二:mode 参数两种用法
select * from Student;
SId | Sname | Sage | Ssex |
---|---|---|---|
1 | 赵雷 | 1990-01-01 00:00:00 | 男 |
2 | 钱电 | 1990-12-21 00:00:00 | 男 |
3 | 孙风 | 1990-12-20 00:00:00 | 男 |
4 | 李云 | 1990-12-06 00:00:00 | 男 |
05 | 周梅 | 1991-12-01 00:00:00 | 女 |
06 | 吴兰 | 1992-01-01 00:00:00 | 女 |
-- 插入 李华 信息
insert into Student value (07, '李华', '1992-01-01', '男');
mode = "flashback" 时生成的回滚语句,可以将李华的信息删除。
DELETE FROM `school`.`Student` WHERE `SId`=7 and `Sname`='李华' and `Sage`='1992-01-01 00:00:00' and `Ssex`='男';
mode = "dump" 时是直接从 binlog 中翻译出原 SQL 语句。
INSERT INTO `school`.`Student`(SId,Sname,Sage,Ssex) VALUE (07,'李华','1992-01-01 00:00:00','男');
参数:
-
mysql_settings:mysql 的连接信息 ip 地址、用户名、密码、端口格式如下:
mysql_settings = { 'host': '127.0.01', 'port': 3306, 'user': 'root', 'password': 'coohsql' }
-- 建议授权 GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO
-
max_filtration:语句中的 where 条件最长字符数量,这个比较难理解,先看一条 update 语句:
UPDATE `school`.`SC` SET `SId`=10,`CId`=4,`score`=100.0 WHERE `SId`=10 and `CId`=4 and `score`=99.0;
可以看到有 where 等式条件,如果这个等式特别大比如:digest=“此处省去1000字” 这样的等式无意义,虽然优化器也绝对不会使用,但是导出过程比较占用空间,所以在组成 where 条件等式时,会进行筛选,默认少于 20 字符,可以组成 where 条件等式。max_filtration 就是来避免使用大字段组成 where 条件等式 如果有特殊情况可以自行调整它。
-
start_file:与 start_pos 参数配合使用,需要解析的 binlog 日志文件,如果不指定会读取全部 binlog 如果数据量比较大,建议先确定一个范围,目前版本不支持多文件读取,未来 1.5 版本会添加多文件读取,敬请期待!
-- 查看正在使用的 binlog 文件和 log_pos show master logs;
Log_name File_size mysql-bin.000001 1461120 mysql-bin.000002 132332 如果 show master logs 可以查看当前使用的 binlog 文件,可以看到 mysql-bin.000001 已经弃用,如果解析的数据量比较小,那么直接指定 start_file 为 mysql-bin.000002 避免加载多余的数据。
-
start_pos:与 start_file 参数配合使用,binlog 日志中的 log_pos 起点,可以更加准确的定位到需要解析或者回滚到数据。默认不指定,建议先使用 show binlog events 确定大概范围,可以提升解析速度。
-
event_schemas:需要解析或者回滚的数据库,默认为 None 则解析全部数据库,如果指定数据库,则只加载相关的数据库。
-
event_tables:需要解析或回滚的数据表,配合 event_schemas 一起使用,可以定位到数据表。
-
mode:属于 process_binlog 中的参数,有两种 binlog 的解析方式 flashback 和 dump
- flashback:生成回滚 SQL 语句,默认。
- dump:翻译 binlog 生成 SQL 语句。
-
server_id:CooHSQL 伪装为 slave 所以需要 server_id 默认为 8023 如果重复请自行修改此参数。
-
start_time:开始时间,通过时间来过滤 binlog 日志生成某个时间段你需要的 SQL 格式为 1990-01-01 00:00:00。
-
stop_time:结束时间,通过时间来过滤 binlog 日志生成某个时间段你需要的 SQL 格式为 1990-01-01 00:00:00。
后记:
目前只能应用于 DML 语句回滚,不支持 DDL 语句。目前项目处于维护测试阶段,将不断完善,敬请期待!
已经 BUG
在空值和时间字典组成的 where 条件中可能会出现异常。将来未来 1.5 版本中修复。
联系:
如有任何问题,发送到我的邮箱:huabing8023@126.com
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.