# 数据恢复

`my2sql` 是一款用 Go 语言编写的 MySQL binlog 解析工具，主要用于**数据快速回滚（闪回）**、生成原始 SQL、DML 统计以及大事务分析等场景。

### 🎯 核心功能
*   **数据快速回滚**：解析 `ROW` 格式的 binlog，将 `DELETE`、`UPDATE` 等误操作反向生成对应的 `INSERT`、`UPDATE` 语句，实现数据闪回。
*   **生成原始 SQL**：将 binlog 中的事件还原为可读的 `INSERT`、`UPDATE`、`DELETE` 等 DML 语句，便于审计和排查。
*   **DML 统计与大事务分析**：生成 DML 操作统计信息，帮助定位频繁更新的表；同时可识别长事务和大事务，辅助性能优化。
*   **支持多种数据类型**：对 `JSON`、`BLOB`、`TEXT`、`Emoji` 等数据类型有良好支持。

### ⚙️ 工作原理与核心优势
*   **核心原理**：基于 `go-mysql` 库解析 binlog 事件，结合连接的 MySQL 实例中的 `information_schema` 元数据（表结构、列信息），将二进制事件翻译成可读的 SQL 语句。
*   **高性能**：相比 Python 编写的 `binlog2sql`，`my2sql` 的解析速度可提升 **5 倍以上**。例如解析 1.1G 的 binlog 生成回滚 SQL，`my2sql` 仅需 **1分40秒**，而 `binlog2sql` 需要 **65分钟**。
*   **离线解析**：支持 `-mode file` 模式，直接解析本地 binlog 文件，避免对线上主库造成额外压力。
*   **增强版特性**：部分增强版支持按时间智能读取所需 binlog 文件、根据 SQL 文本模糊匹配、支持 `binlog_transaction_compression=on` 等。

### 📋 使用前提与权限要求
*   **MySQL 配置**：需开启 binlog，且 `binlog_format=ROW`，建议 `binlog_row_image=FULL`。
*   **连接账号权限**：需要 `SELECT` 和 `REPLICATION CLIENT` 权限，用于查询元数据和 binlog 状态信息。
*   **MySQL 8.0 注意**：连接账号的密码认证插件需为 `mysql_native_password`，否则可能无法连接解析。

### 🚀 安装与快速开始
*   **下载二进制**（最简单）：
    ```bash
    wget https://github.com/liuhr/my2sql/blob/master/releases/centOS_release_7.x/my2sql
    chmod +x my2sql && mv my2sql /usr/local/bin/
    ```
    
*   **源码编译**：安装 Go 环境后，`git clone` 源码并编译即可。

### 🔑 重要参数说明
| 参数 | 说明 |
| :--- | :--- |
| **`-mode`** | `repl`（默认，伪装从库拉取 binlog）或 `file`（离线解析本地文件） |
| **`-local-binlog-file`** | 当 `-mode=file` 时，指定 binlog 文件路径 |
| **`-work-type`** | `2sql`（生成原始 SQL）、`rollback`（生成回滚 SQL）、`stats`（仅统计） |
| **`-sql`** | 过滤要解析的 SQL 类型，可选 `insert`、`update`、`delete`，默认全部解析 |
| **`-databases` / `-tables`** | 按库名、表名过滤，多个用逗号分隔 |
| **`-file-per-table`** | 为每个表生成独立的 SQL 文件 |
| **`-output-dir`** | 指定输出结果的目录 |
| **`-add-extraInfo`** | 在每条生成的 SQL 前添加库表、时间、binlog 位置等注释信息 |
| **`-threads`** | 并发线程数，默认 2 |

### 📊 性能对比
| 场景 | my2sql | binlog2sql |
| :--- | :--- | :--- |
| 1.1G binlog 生成回滚 SQL | **1分40秒** | 65分钟 |
| 1.1G binlog 生成原始 SQL | **1分30秒** | 50分钟 |
| 1.1G binlog 生成 DML 统计 | **40秒** | 不支持 |


### 💡 适用场景
*   **误操作恢复**：误 `DELETE`、误 `UPDATE` 后快速生成反向 SQL 恢复数据。
*   **主从切换数据修复**：新主库丢失数据时，从 binlog 中提取变更进行补偿。
*   **变更审计**：将 binlog 还原为可读 SQL，审计数据库变更历史。
*   **性能分析**：定位频繁更新的表、发现大事务和长事务。

### ⚠️ 注意事项
*   **生成列问题**：对于 `STORED` 生成列，`my2sql` 默认会将其包含在生成的 `INSERT` 中，导入时会报错。部分版本无 `-skip-generated-columns` 参数，需手动或脚本处理 SQL 文件。
*   **GTID 冲突**：启用 GTID 的环境，重放时可能因事务冲突被跳过，可考虑加 `--skip-gtids` 参数（如果工具支持）。
*   **大小写敏感**：若数据库名/表名不区分大小写，过滤时需使用小写。
*   **时间范围**：按时间过滤时，建议开始时间减 1 分钟、结束时间加 1 分钟，避免边界遗漏。

你使用的 `my2sql` 版本确实不支持 `-skip-generated-columns` 参数，这个报错说明你用的版本里没有包含这个功能。

### 为什么没有这个参数

你使用的 `my2sql` 版本（原版或部分增强版）的参数列表中，并没有 `-skip-generated-columns` 这个选项。这个参数可能是某个特定分支或较新版本才加入的功能，你手头的二进制文件里没有包含。

### 替代方案：手动处理生成的 SQL

既然工具本身无法跳过生成列，最直接的办法就是在导入前**手动编辑生成的 SQL 文件**，把生成列 `fpdmfphm` 从 `INSERT` 语句中删掉。

`my2sql` 在回滚模式下，会把 `DELETE` 操作转换成对应的 `INSERT` 语句。因为 `fpdmfphm` 是 `STORED` 生成列，它的值会被记录在 binlog 里，所以生成的 `INSERT` 语句会包含这一列。

**操作步骤：**

1.  先用你原本的命令生成回滚 SQL（不加 `-skip-generated-columns`）：
    ```bash
    ./my2sql \
      -host 127.0.0.1 -port 3306 \
      -user your_user -password 'your_password' \
      -work-type rollback \
      -sql delete \
      -databases crrcdb \
      -tables your_table \
      -file-per-table \
      -mode file \
      -local-binlog-file crrcdb-binlog/crrcdb-binlog.000650 \
      -output-dir ./sql \
      -add-extraInfo
    ```

2.  打开 `./sql/` 目录下生成的 `.sql` 文件，你会看到类似这样的 `INSERT` 语句：
    ```sql
    INSERT INTO `crrcdb`.`your_table` (`id`, `invoice_code`, `invoice_number`, `fpdmfphm`, ...) VALUES (1, '123', '456', '123456', ...);
    ```

3.  手动把 `fpdmfphm` 这一列从**列清单**和对应的 **`VALUES` 值**中删掉，变成：
    ```sql
    INSERT INTO `crrcdb`.`your_table` (`id`, `invoice_code`, `invoice_number`, ...) VALUES (1, '123', '456', ...);
    ```

4.  处理完所有文件后，再导入数据库：
    ```bash
    mysql -u root -p crrcdb < ./sql/your_table.sql
    ```

如果表很多、文件很大，手动改会很麻烦，可以考虑用 `sed` 或 Python 脚本批量处理，但一定要先在测试环境验证。

### 其他可能的替代工具

如果你不想手动处理，可以尝试其他支持跳过生成列的 binlog 解析工具，比如 **`binlog2sql`** 的某些版本，或者 **`reverse_sql`**。不过工具的支持情况需要你自行验证。

**总结**：你当前的 `my2sql` 版本没有 `-skip-generated-columns` 参数，最实际的办法是生成 SQL 后手动或脚本化地去掉生成列，再导入恢复。