背景
Navicat
的工具栏有数据传输功能,可以对数据库进行结构和数据的同步
如果是数据库的全部表进行数据传输,执行的语句是
DROP DATABASE `xxx`;
CREATE DATABASE `xxx` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci';
// 建表语句...
// 其他语句...
问题来了,在选择目标数据库时,因为连接名、数据库名称或者是操作者的疏忽的影响,可能会造成选择数据库错误的情况
要是赶上需要同步全库的表结构和表数据,那么目标数据库会被另一个错误的数据库覆盖,造成删库
解决方案
首先,找备份,从备份中恢复数据
要是没有备份怎么办呢?
那可以尝试使用mysqlbinlog
进行处理(当然,前提是开启了binlog
)
- MySql 5.7 及以下版本需要手动开启
- MySQL 8.0 及以上版本默认开启
mysqlbinlog
MySQL 提供的一个命令行工具,用于解析、查看和管理 MySQL 的二进制日志(Binary Log,简称 binlog)
我们可以使用以下命令来查看数据库服务的mysqlbinlog
信息
# 查看 `binlog` 是否开启
SHOW VARIABLES LIKE 'log_bin';
# 查看 `binlog` 文件格式
SHOW VARIABLES LIKE 'binlog_format';
# 查看 `binlog` 文件路径和基础名称
SHOW VARIABLES LIKE 'log_bin_basename';
# 查看当前正在使用的 `binlog` 文件
SHOW MASTER STATUS;
# 获取数据目录路径
SHOW VARIABLES LIKE 'datadir';
也可以在 MySql
数据目录下面查看mysql-bin.000001、mysql-bin.index、binlog.000001等文件
Mysql
数据目录,默认路径通常为
/var/lib/mysql/
(Linux)C:\ProgramData\MySQL\MySQL Server X.X\Data
(Windows)
若使用了
Docker
安装MySql
,且未挂载数据卷,需要进入容器内部查看
具体操作
接下进入正题,怎么恢复?
其实一条命令就可以解决
mysqlbinlog
--skip-gtids
--database=xxx
--stop-datetime="2025-07-01 17:00:00"
F:\binlog\binlog.000001
F:\binlog\binlog.000002
F:\binlog\binlog.000003
F:\binlog\binlog.000004 | mysql -u root -p --force
--skip-gtids
:忽略 binlog 中的 GTID(全局事务标识符)--database=xxx
:仅解析与数据库xxx
相关的操作,过滤其他库的日志--stop-datetime="2025-07-01 17:00:00"
:解析 binlog 直到指定时间点(含该时间点)停止文件路径
:可添加多个文件--force
:强制 MySQL 客户端忽略执行过程中的错误(如语法错误、主键冲突),继续执行后续 SQL
该命令是从建立数据库之初恢复所有数据,适用于无历史数据备份操作的情况(有历史数据备份操作情况可以指定
--start-datatinme
或position
),恢复时长视数据量大小而定 注意未执行完成不能退出,以免数据恢复不全
该命令使用了管道处理,无需中间文件。管道处理是指通过管道符
|
将一个命令的输出作为另一个命令的输入,形成数据流的连续处理链条。
若是
Docker
容器内部不便于操作mysqlbinlog
,也可将日志文件同步到Windows机器,再用管理员方式打开
mysqlbinlog.exe
工具,进行操作
mysqlbinlog.exe
默认位置:
C:\Program Files\MySQL\MySQL Server 8.0\bin
扩展
如果要查看日志对应的sql文件,可以使用
mysqlbinlog
--skip-gtids
--base64-output=DECODE-ROWS
--verbose
--database=xxx
F:\binlog\binlog.000001
F:\binlog\binlog.000002
F:\binlog\binlog.000003
F:\binlog\binlog.000004 > F:\binlog\binlog_000001_000004.sql
--base64-output=DECODE-ROWS
:将 ROW 格式的二进制日志解码为可读的伪 SQL 语句--verbose
或-v
:增强输出可读性,添加注释(如字段类型)和完整的 SQL 语句。
-v
、-vv
和-vvv
参数
-v
(基础详细模式):将 ROW 格式的日志解码为伪 SQL 语句,但仅显示基本的列值(如@1=1
)和简单注释。
### UPDATE `test`.`users` ### WHERE ### @1=1 /* INT meta=0 nullable=0 is_null=0 */ ### @2='Alice' /* VARSTRING(20) */ ### SET ### @1=1 ### @2='Bob'
-vv
(增强详细模式):在-v
基础上增加字段名和完整数据类型注释,输出更接近实际 SQL
### UPDATE `test`.`users` ### WHERE ### `id`=1 /* INT meta=0 nullable=0 is_null=0 */ ### `name`='Alice' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */ ### SET ### `id`=1 ### `name`='Bob'
-vvv
(最高详细模式):在-vv
基础上进一步输出列的 字符集、排序规则 等高级元数据,适合深度分析
### UPDATE `test`.`users` ### WHERE ### `id`=1 /* INT(11) meta=0 nullable=0 is_null=0 charset=utf8mb4 > collation=utf8mb4_general_ci */ ### `name`='Alice' /* VARCHAR(20) meta=20 nullable=1 is_null=0 charset=utf8mb4 > collation=utf8mb4_general_ci */ ### SET ### `id`=1 ### `name`='Bob'
!注意
不推荐将
binlog
文件转化为 sql文件,再导入文件到数据库方法。
对ROW
(binlog文件
默认数据格式)来说,无法转化正确的insert、update
语句,转化的语句是伪sql,并不是可执行sql)