当前位置: 代码网 > it编程>数据库>Mysql > MySQL通过Binlog实现数据备份和恢复

MySQL通过Binlog实现数据备份和恢复

2026年01月15日 Mysql 我要评论
一、首先安装mysql为了简便操作,我使用docker进行演示,docker安装mysql的命令如下所示:docker run -d \ --name mysql \ -p 3306:3306 \

一、 首先安装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 -p1234

4.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数据备份和恢复的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com