MySQL Binlog 解析与数据恢复之 my2sql

一、核心功能

my2sql 是基于 Go 语言开发的 MySQL Binlog 解析工具,主要用于以下场景:

  1. 数据恢复
    • 通过解析 Binlog 生成可执行的 SQL 语句(如 INSERTUPDATEDELETE
    • 支持生成回滚语句(Rollback SQL)直接恢复误操作数据
  2. 数据审计
    • 按时间、表名、操作类型等条件过滤 Binlog
    • 支持输出为 SQL 文件或 JSON 格式
  3. 高效率处理
    • 原生 Go 实现,无需依赖 MySQL 客户端
    • 支持并行解析(Go 协程优化)
  4. 兼容性强
    • 支持 MySQL 5.6+ 和 MariaDB 10.0+
    • 兼容 Row/Statement/Mixed 格式的 Binlog

二、安装 Go 与 my2sql

1. 安装 Go 环境(以 Linux 为例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 下载 Go 安装包
wget https://golang.org/dl/go1.21.3.linux-amd64.tar.gz

# 解压并安装
sudo tar -C /usr/local -xzf go1.21.3.linux-amd64.tar.gz

# 配置环境变量(添加到 ~/.bashrc 或 /etc/profile)
export PATH=$PATH:/usr/local/go/bin
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin

# 生效配置
source ~/.bashrc

# 验证安装
go version

2. 编译 my2sql

1
2
3
4
5
6
7
8
9
# 下载源码
git clone https://github.com/shanbay/my2sql.git
cd my2sql

# 编译(需 Go 1.18+)
go build -o my2sql main.go

# 可执行文件路径
./my2sql --help

三、工具注意事项与核心参数

⚠️ 注意事项

  1. MySQL 配置要求

    • Binlog 格式必须为ROW(默认即可):

      1
      SET GLOBAL binlog_format = 'ROW';
    • 开启 Binlog 文件索引:

      1
      SET GLOBAL log_bin = ON;
    • 如需永久生效,需在 my.cnf/my.ini 中添加:

      1
      2
      3
      [mysqld]
      binlog_format = ROW
      log_bin = ON
  2. 权限要求

    • MySQL 用户需具备

      1
      REPLICATION SLAVE

      权限:

      1
      GRANT REPLICATION SLAVE ON *.* TO 'my2sql_user'@'%' IDENTIFIED BY 'password';
  3. 时间范围限制

    • Binlog 默认保留周期由 expire_logs_days 控制,需确保误操作时间在有效范围内。
  4. DDL 不可逆

    • 无法恢复 DROP TABLE 等操作,需依赖备份。

🔧 核心参数说明

参数名说明
--start-file起始 Binlog 文件名(如 mysql-bin.000001
--start-position起始位置(配合 --start-file 使用)
--stop-file结束 Binlog 文件名
--stop-position结束位置
--start-datetime起始时间(格式:YYYY-MM-DD HH:MM:SS
--stop-datetime结束时间
--database过滤指定数据库(支持通配符 *
--table过滤指定表(支持通配符 *
--output输出文件路径(默认输出到终端)
--rollback生成回滚语句(Rollback SQL)
--help查看完整参数列表

四、详细实战教程:误删数据恢复与统计分析

环境准备

  1. MySQL 配置
1
2
3
4
5
6
7
8
-- 确保 binlog 格式为 ROW 模式
SET GLOBAL binlog_format = 'ROW';
SET GLOBAL log_bin = ON;

-- 创建测试用户并授权
CREATE USER 'my2sql_user'@'%' IDENTIFIED BY 'your_password';
GRANT REPLICATION SLAVE ON *.* TO 'my2sql_user'@'%';
FLUSH PRIVILEGES;
  1. 创建测试数据库与数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-- 创建数据库和表
CREATE DATABASE test_db;
USE test_db;

CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
email VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 插入测试数据
INSERT INTO users (name, email) VALUES
('Alice', 'alice@example.com'),
('Bob', 'bob@example.com'),
('Charlie', 'charlie@example.com'),
('David', 'david@example.com'),
('Eve', 'eve@example.com');

-- 查看当前 binlog 文件
SHOW MASTER STATUS;
-- 假设当前 binlog 为 mysql-bin.000005

模拟误删操作

  1. 执行误删操作
1
2
-- 删除 id > 2 的记录
DELETE FROM users WHERE id > 2;
  1. 确认误删结果
1
2
SELECT * FROM users;
-- 当前数据只剩下 id=1 和 id=2

使用 my2sql 生成回滚 SQL

  1. 获取 Binlog 信息
1
2
3
-- 查询 binlog 文件和位置
SHOW BINARY LOGS;
-- 假设误删操作记录在 mysql-bin.000005 中
  1. 生成回滚 SQL
1
2
3
4
5
6
7
8
./my2sql \
--start-file="mysql-bin.000005" \
--start-datetime="2023-10-01 12:00:00" \ # 误删操作开始时间
--stop-datetime="2023-10-01 12:05:00" \ # 误删操作结束时间
--database="test_db" \
--table="users" \
--rollback \
--output="/tmp/rollback_users.sql"
  1. 检查生成的回滚 SQL
1
2
3
4
-- /tmp/rollback_users.sql 内容示例
INSERT INTO `test_db`.`users`(`id`, `name`, `email`, `created_at`) VALUES (3, 'Charlie', 'charlie@example.com', '2023-10-01 12:03:45');
INSERT INTO `test_db`.`users`(`id`, `name`, `email`, `created_at`) VALUES (4, 'David', 'david@example.com', '2023-10-01 12:03:46');
INSERT INTO `test_db`.`users`(`id`, `name`, `email`, `created_at`) VALUES (5, 'Eve', 'eve@example.com', '2023-10-01 12:03:47');
  1. 执行回滚恢复
1
mysql -u root -p test_db < /tmp/rollback_users.sql
  1. 验证恢复结果
1
2
SELECT * FROM users;
-- 数据已恢复为误删前的状态

生成标准 SQL(非回滚)

  1. 生成原始操作 SQL
1
2
3
4
5
6
7
./my2sql \
--start-file="mysql-bin.000005" \
--start-datetime="2023-10-01 12:00:00" \
--stop-datetime="2023-10-01 12:05:00" \
--database="test_db" \
--table="users" \
--output="/tmp/original_sql.sql"
  1. 检查生成的 SQL
1
2
3
4
-- /tmp/original_sql.sql 内容示例
DELETE FROM `test_db`.`users` WHERE `id` = 3 AND `name` = 'Charlie' AND `email` = 'charlie@example.com' AND `created_at` = '2023-10-01 12:03:45';
DELETE FROM `test_db`.`users` WHERE `id` = 4 AND `name` = 'David' AND `email` = 'david@example.com' AND `created_at` = '2023-10-01 12:03:46';
DELETE FROM `test_db`.`users` WHERE `id` = 5 AND `name` = 'Eve' AND `email` = 'eve@example.com' AND `created_at` = '2023-10-01 12:03:47';

生成统计信息

  1. 生成操作统计报告
1
2
3
4
5
6
7
./my2sql \
--start-file="mysql-bin.000005" \
--start-datetime="2023-10-01 12:00:00" \
--stop-datetime="2023-10-01 12:05:00" \
--database="test_db" \
--table="users" \
--statistics
  1. 输出示例
1
2
3
4
5
6
7
8
[INFO] 解析时间范围: 2023-10-01 12:00:00 至 2023-10-01 12:05:00
[INFO] 数据库: test_db, 表: users
[INFO] 操作类型统计:
- DELETE: 3 条
- INSERT: 0 条
- UPDATE: 0 条
[INFO] 总操作数: 3
[INFO] 涉及行数: 3

跨 Binlog 文件恢复(进阶)

场景:误删操作跨越多个 Binlog 文件

1
2
3
4
5
6
7
8
9
./my2sql \
--start-file="mysql-bin.000005" \
--start-position=1234 \ # 起始文件的起始位置
--stop-file="mysql-bin.000006" \
--stop-position=5678 \ # 结束文件的结束位置
--database="test_db" \
--table="users" \
--rollback \
--output="/tmp/cross_binlog_rollback.sql"

JSON 格式输出(可选)

生成 JSON 格式的变更记录

1
2
3
4
5
6
7
8
./my2sql \
--start-file="mysql-bin.000005" \
--start-datetime="2023-10-01 12:00:00" \
--stop-datetime="2023-10-01 12:05:00" \
--database="test_db" \
--table="users" \
--output="/tmp/changelog.json" \
--format=json

JSON 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
{
"type": "DELETE",
"database": "test_db",
"table": "users",
"data": {
"id": 3,
"name": "Charlie",
"email": "charlie@example.com",
"created_at": "2023-10-01 12:03:45"
}
},
...
]

注意事项与最佳实践

  1. 时间精度问题
    • 使用 --start-datetime--stop-datetime 时,建议时间范围略大于实际操作时间,防止遗漏事件。
  2. ID 冲突处理
    • 如果误删后已插入相同 ID 的新数据,回滚可能导致主键冲突。需先删除新数据或调整 ID。
  3. 增量备份策略
    • 定期使用 mysqldumpXtraBackup 备份数据库,并记录 Binlog 位置,形成完整的恢复链。
  4. 生产环境验证
    • 在测试环境验证回滚 SQL 的正确性后再执行,避免二次破坏。

通过以上步骤,您可以完整掌握 my2sql 在数据恢复、SQL 生成和统计分析中的使用方法。建议结合 MySQL 官方工具(如 mysqlbinlog)进行交叉验证,确保数据一致性。

五、类似工具对比

工具名称语言是否开源核心优势限制/缺点
my2sqlGo高性能、支持 Rollback、跨平台社区较小,文档较少
mysqlbinlogC++MySQL 官方工具,兼容性好需要安装 MySQL 客户端
binlog2sqlPython功能全面,支持 DDL 解析依赖较多,性能较低
canalJava实时同步、支持 Kafka/RocketMQ配置复杂,主要用于同步场景
DebeziumJava强大的事件捕获能力资源消耗较高

六、总结

my2sql 凭借其高性能的 Go 实现和简洁的命令行设计,成为 MySQL 数据恢复领域的优秀工具。相比其他工具,它在轻量级部署和回滚语句生成功能上具有明显优势。建议在生产环境中定期验证 Binlog 可用性,并结合物理备份(如 mysqldump/XtraBackup)形成完整的数据保护方案。

⚠️ 重要提示:数据恢复前务必先备份当前数据库!