一、 首先安装mysql
为了简便操作,我使用docker进行演示,docker安装mysql的命令如下所示:
docker run -d \ --name mysql \ -p 3306:3306 \ -e tz=asia/shanghai \ -e mysql_root_password=1234 \ -v ./mysql/data:/var/lib/mysql \ -v ./mysql/conf:/etc/mysql/conf.d \ -v ./mysql/init:/docker-entrypoint-initdb.d \ mysql:8.0
- 数据持久化:-v ./mysql/data:/var/lib/mysql 让数据安全地留在了宿主机。
- 配置文件分离:-v ./mysql/conf:/etc/mysql/conf.d 让你可以随意改配置而不用进容器。
- 初始化脚本:-v ./mysql/init:/docker-entrypoint-initdb.d ,你可以把 .sql 建表脚本放这里,容器首次启动会自动执行。
二、binlog介绍
binlog (binary log) 就是 mysql 的“录像机”。
它记录了数据库里所有的修改操作(比如增删改),按时间顺序排列。这就好比你把游戏里所有改变数据的操作都录了下来,存成了一部连续的电影。
对你做游戏来说,binlog 有两个特别实用的用途:
(1)数据的“后悔药”与“时间机器”
开发过程中难免会有误操作,比如不小心执行了一条 sql 删了测试服的用户数据。
没用 binlog:数据可能就真没了,或者只能从昨天凌晨的备份恢复(意味着今天的测试白干了)。
有了 binlog:你可以拿着“录像”快进到出问题的时间点,或者重放这几分钟的记录,把数据精确恢复到误操作前一秒。
(2)做“数据同步”的基石
最常见的需求。比如:
你有一个主库(负责处理用户的账号、库存、写入数据)。
你有一个从库(专门负责给官网提供排行榜查询、或者给后台客服查询数据)。
为了让从库的数据和主库一模一样,mysql 就是利用 binlog 把主库的“录像”同步给从库,让从库照着做一遍。
新手建议:
刚开始做项目时,如果你不会手写脚本来解析 binlog,但一定要确保你的云数据库(比如阿里云 rds 或腾讯云 mysql)开启了 binlog 功能,并且设置了合理的保留时间(比如保留 7 天)。这样即使出问题,运维人员也能帮你把数据救回来。
三、开启binlog(数据备份)
3.1 查找mysql文件
首先,找到mysql的配置文件,如果忘了放哪了,直接让 linux 帮你找,直接全局搜索(最暴力,推荐)
find / -name "mysql" -type d 2>/dev/null
这条命令会从根目录开始找名字叫 mysql 的文件夹。

如果看到路径像 /root/mysql、/home/user/mysql 这样的,大概率就是它了。
(注意:它会搜到系统自带的 /var/lib/mysql,那个是系统的,不是你的,别搞混了,找带自定义路径特征的)
找到正确的路径后(比如是在 /root/mysql),以后的操作都要带上这个绝对路径
进入目录
cd /root/mysql # 换成你 find 出来的真实路径
检查一下目录结构(确认无误)
你应该能看到 data、conf、init 这三个文件夹。
ls -l
查看数据目录
ls -l ./data/
3.2 开启binlog
查看配置目录
ls -l ./conf

没问题!这很正常,说明你的 conf 文件夹目前是空的。
现在我们就在这个空文件夹里创建配置文件。请保持在 /root/mysql 目录下,直接复制并执行下面这段命令:
cat > ./conf/my.cnf << eof [mysqld] # 开启 binlog log-bin=mysql-bin # 服务器 id (随便设个唯一数字) server-id=1 # 设置 binlog 格式为 row (恢复数据最推荐) binlog_format=row # 日志保留 7 天,自动清理防止占满磁盘 expire_logs_days=7 # --- 核心配置:中文支持 --- character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci eof
执行完这一步后,再检查一下:
ls -l ./conf

3.3 重启生效
重启容器让配置生效:
docker restart mysql
等容器重启完,你的 binlog 功能就已经启动了!随后你可以在 ./data 目录里看到对应的日志文件生成。
四、通过binlog实现数据恢复
4.1 数据恢复前准备,故意制造数据丢失
为了演示,我需要创建一张数据库表
我们就以 test_db 数据库和 tb_user 表为例。这是一个非常标准的实战演练
登录 mysql
docker exec -it mysql mysql -uroot -p1234
建库建表并插入初始数据
create database test_db;
use test_db;
-- 创建用户表
create table tb_user (
id int primary key auto_increment comment '用户id',
username varchar(50) comment '用户名',
role varchar(50) comment '角色'
) engine=innodb default charset=utf8mb4 collate=utf8mb4_unicode_ci comment='用户表';
-- 插入两个初始用户
insert into tb_user (username, role) values ('张三', '程序员');
insert into tb_user (username, role) values ('李四', '医生');
-- 查看当前数据
select * from tb_user;
此时应该有两行数据。
模拟误操作(删表)
-- 灾难发生:误删了用户表 drop table tb_user; -- 确认数据已丢失 show tables;
4.2 开始恢复数据
现在 test_db 里空空如也。接下来我们打开一个新的终端窗口(或者按 ctrl+c 退出当前 mysql 会话),开始在 linux 命令行进行恢复。
查看当前的 binlog 日志文件
ls -lh /root/mysql/data/
有新日志生成: mysql-bin.000001刚刚生成,说明你刚才所有的删表、建表、插入数据的操作,都被忠实地记录在这个小文件里了。
文件夹 test_db:这是你刚才创建的数据库目录,里面的 .ibd 文件就是真正的数据文件。
4.3 分析日志,找到误删的“案发时间点”
我们需要用到mysqlbinlog,那么简单介绍一下mysqlbinlog
mysqlbinlog 是一个独立的工具程序,并不包含在基础的 mysql 镜像里。你现在的镜像里只有数据库服务端(mysqld)和客户端(mysql),没有解析日志的工具(mysqlbinlog)。
这就像你买了一台电视机(数据库服务),它只能放电视,但它没有“录像机编辑功能”(日志工具),那个得单独买。
# 1. 安装官方源 yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-11.noarch.rpm # 2. 安装 8.0 客户端 yum install mysql-community-client -y
检查是否安装成功
mysqlbinlog --version
查看日志(定位误删位置)
# 直接读宿主机文件,不要进 docker mysqlbinlog --no-defaults /root/mysql/data/binlog.000001 | tail -n 30
先确认 mysql 的真实数据目录和 binlog 文件位置
先登录 mysql 客户端
docker exec -it mysql mysql -uroot -p1234
登录后执行以下 sql,查看 binlog 文件的真实存储路径和文件列表:
-- 查看 binlog 文件列表(能看到的才是真实存在的) show binary logs; -- 查看binlog配置 show variables like 'log_bin%'; show variables like 'binlog_format%'; -- 查看 mysql 的数据目录(binlog 默认存在这个目录下) show variables like 'datadir';
4.4 恢复数据
因为我当前在mysql目录中,所以我使用相对路径./data/mysql-bin.000001指定该日志文件哦!
查看日志文件
mysqlbinlog -v ./data/mysql-bin.000001

4.4.1 指定位置点恢复
有两个参数填写,一个是开始位置点,一个是结束位置点。如上图的at就是点位
# at 1008 ← 第一个事务开始 # at 1086 ← begin # at 1151 ← insert操作 # at 1193 ← insert结束 # at 1224 ← commit完成 # at 1301 ← drop table开始
delete/drop语句在位置 1301
有用的数据在位置 1008-1224
# 指定位置点
mysqlbinlog --start-position=107 \
--stop-position=1000 \
./data/mysql-bin.000001 --skip-gtids | docker exec -i mysql mysql -uroot -p1234
如果只恢复单个操作
# 提取第一个完整事务(1008到1224之间的insert操作)
mysqlbinlog --start-position=1008 \
--stop-position=1224 \
./data/mysql-bin.000001 --skip-gtids | docker exec -i mysql mysql -uroot -p1234
提取到drop之前的所有内容
# 提取从开始到drop之前的所有操作
mysqlbinlog --start-position=154 \
--stop-position=1301 \
./data/mysql-bin.000001 --skip-gtids | docker exec -i mysql mysql -uroot -p1234提取到drop之前的所有内容
# 提取整个文件,但跳过drop语句
mysqlbinlog --start-position=154 \
--stop-position=1300 \
./data/mysql-bin.000001 --skip-gtids | docker exec -i mysql mysql -uroot -p12344.4.2 指定时间区域恢复
有两个参数填写,一个是开始时间,一个是结束时间。如果有备份的话,最好回复数据可以填写最后一次备份的结束时间。
#提取删除前的所有操作(从表创建到删除)
mysqlbinlog --start-datetime="2026-01-14 14:00:00" \
--stop-datetime="2026-01-14 14:19:55" \
./data/mysql-bin.000001 --skip-gtids | docker exec -i mysql mysql -uroot -p1234
执行命令后可以发现我们的数据库恢复咯!
以上就是mysql通过binlog实现数据备份和恢复的详细内容,更多关于mysql binlog数据备份和恢复的资料请关注代码网其它相关文章!
发表评论