当前位置:

首页 > 编程开发 > MySQL的binlog如何恢复数据

MySQL的binlog如何恢复数据

1.binlogbinlog我们中文一般称作归档日志,如果大家看过松哥之前发的MySQL主从搭建,应该对这个日志有印象,当我们搭建MySQL主从的时候就离不开binlog(传送门:MySQL8主从复制踩坑指南)。binlog是MySQLServer层的日志,而不是存储引擎自带的日志,它记录了所有的DDL和DML(不包含数据查询语句)语句,而且是以事件形式记录,还包含语句所执行的消耗的时间等,需要注意的是:binlog是一种逻辑日志,他里边所记录的是一条SQL语句的原始逻辑,例如给某一个字段+1,注意这个区

本文目录

    1. binlog

    binlog 我们中文一般称作归档日志,如果大家看过松哥之前发的 MySQL 主从搭建,应该对这个日志有印象,当我们搭建 MySQL 主从的时候就离不开 binlog(传送门:MySQL8 主从复制踩坑指南)。

    binlog 是 MySQL Server 层的日志,而不是存储引擎自带的日志,它记录了所有的 DDL 和 DML(不包含数据查询语句)语句,而且是以事件形式记录,还包含语句所执行的消耗的时间等,需要注意的是:

    • binlog 是一种逻辑日志,他里边所记录的是一条 SQL 语句的原始逻辑,例如给某一个字段 +1,注意这个区别于 redo log 的物理日志(在某个数据页上做了什么修改)。

    • binlog 文件写满后,会自动切换到下一个日志文件继续写,而不会覆盖以前的日志,这个也区别于 redo log,redo log 是循环写入的,即后面写入的可能会覆盖前面写入的。

    • 一般来说,我们在配置 binlog 的时候,可以指定 binlog 文件的有效期,这样在到期后,日志文件会自动删除,这样避免占用较多存储空间。

    根据 MySQL 官方文档的介绍,开启 binlog 之后,大概会有 1% 的性能损耗,不过这还是可以接受的,一般来说,binlog 有两个重要的使用场景:

    • MySQL 主从复制时:在主机上开启 binlog,主机将 binlog 同步给从机,从机通过 binlog 来同步数据,进而实现主机和从机的数据同步。

    • MySQL 数据恢复,通过使用 mysqlbinlog 工具再结合 binlog 文件,可以将数据恢复到过去的某一时刻。

    2. 开启 binlog

    为了演示方便,松哥这里在 Docker 中安装了 MySQL,我们以此为例来开始今天的演示。如果小伙伴们还不懂 docker 的使用,可以在公众号后台回复 docker,有松哥写的教程。

    首先我们在 docker 中安装好 MySQL,然后进入到容器中,通过如下命令可以查看 binlog 是否开启:

    MySQL的binlog如何恢复数据

    这个 OFF 就表示 binlog 是一个关闭状态,没有开启,接下来我们来开启 binlog。

    开启 binlog 主要是修改 MySQL 的配置文件 mysqld.cnf,该文件在容器的 /etc/mysql/mysql.conf.d 目录下。

    MySQL的binlog如何恢复数据

    针对该配置文件,我们做如下修改:

    # 这个参数表示启用 binlog 功能,并指定 binlog 的存储目录
    log-bin=javaboy_logbin
    
    # 设置一个 binlog 文件的最大字节
    # 设置最大 100MB
    max_binlog_size=104857600
    
    # 设置了 binlog 文件的有效期(单位:天)
    expire_logs_days = 7
    
    # binlog 日志只记录指定库的更新(配置主从复制的时候会用到)
    #binlog-do-db=javaboy_db
    
    # binlog 日志不记录指定库的更新(配置主从复制的时候会用到)
    #binlog-ignore-db=javaboy_no_db
    
    # 写缓存多少次,刷一次磁盘,默认 0 表示这个操作由操作系统根据自身负载自行决定多久写一次磁盘
    # 1 表示每一条事务提交都会立即写磁盘,n 则表示 n 个事务提交才会写磁盘
    sync_binlog=0
    
    # 为当前服务取一个唯一的 id(MySQL5.7 之后需要配置)
    server-id=1

    各项配置的含义松哥已经在注视中说明了。截图如下:

    MySQL的binlog如何恢复数据

    配置完成后,执行如下命令重启 mysql 容器(mysql1 是我这里容器的名字):

    docker restart mysql1

    重启之后,再次执行 show variables like 'log_bin%'; 即可看到 binlog 已经开启了。

    MySQL的binlog如何恢复数据

    这里除了 log_bin 变量外,还有两个变量名也值得我们关注:

    • log_bin_basename:这个是将来产生的 binlog 日志文件的名称前缀,换句话说,根据大家目前所看到的配置,将来产生的 binlog 日志文件名为 javaboy_logbin.xxx,这个文件中将会用来记录所有的 DDL 和 DML 语句事件。

    • log_bin_index:这个是 binlog 的索引文件,保存了所有 binlog 的目录,因为 binlog 可能会有多个。我们可以来查看一下现在的 javaboy_logbin.index 文件:

    MySQL的binlog如何恢复数据

    可以看到,目前只有一个 logbin 文件。

    3. 常见 binlog 操作

    接下来我们再来介绍几个常见的 binlog 操作命令。

    1. 查看所有 binlog 日志

    通过如下方式我们可以查看 binlog 日志列表:

    show master logs;

    MySQL的binlog如何恢复数据

    可以看到,我这里目前只有一个日志文件,文件名为 javaboy_logbin.000001,File_size 表示这个文件占用的字节大小是 154。

    1. 查看 master 状态

    这个命令我们在搭建 MySQL 主从的时候经常会用到,如下:

    MySQL的binlog如何恢复数据

    这个时候可以看到最新的 binlog 日志文件名称以及最后一个操作事件的 Position 值(这个值有啥用,我们后面会给大家详细介绍)。

    1. 刷新 binlog

    正常来说,一个 binlog 写满之后,会自动切换到下一个 binlog 开始写,不过我们也可以执行一个 flush logs 命令来手动刷新 binlog,手动刷新 binlog 之后,就会产生一个新的 binlog 日志文件,接下来所有的 binlog 日志都将记录到新的文件中。如下:

    MySQL的binlog如何恢复数据

    由上图可以看到,我们刷新日志之后,再通过 show master logs 去查看日志,发现日志文件已经多了一个新产生的了,然后再通过 show master status 去查看最新的日志文件信息,发现也已经变为 javaboy_logbin.000002。

    1. 重置 binlog

    reset master 可以重置 binlog 日志文件,让日志重新从 000001 开始记录,不过如果当前主机有一个或者多个从机在运行,那么该命令就运行不了(因为从机是通过 binlog 来实现数据库同步的,主机把 binlog 清空了,从机会报找不到 binlog 的错误)。

    MySQL的binlog如何恢复数据

    1. 查看 binlog

    由于 binlog 是二进制日志文件,所以要是直接打开,那肯定是看不了的:

    MySQL的binlog如何恢复数据

    没有看到任何有用的信息。

    为了查看 binlog,MySQL 为我们提供了两个官方工具,我们一个一个来看,首先是 mysqlbinlog 命令,如下:

    MySQL的binlog如何恢复数据

    虽然看起来乱糟糟的,不过仔细看着其实都有迹可循。因为我这里是一个新安装的数据库,里边只是创建了一个名为 javaboy 的库,然后创建了一个名为 user 的表加了两条数据,其他什么事情都没做,所以创建库的脚本我们其实能够从纷杂的文件中找到。

    产生的日志文件中有一个 end_log_pos 是日志文件的 pos 点,这个将来在数据恢复的时候有用。

    不过这种查看方式不够人性化,我们说 binlog 是按照事件来记录日志的,所以如果我们能够按照事件的方式查看日志,就会好很多,我们再来看看如下一个命令:

    show binlog events [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count];

    这个表示以事件的方式来查看 binlog,这里涉及到几个参数:

    • log_name:可以指定要查看的 binlog 日志文件名,如果不指定的话,表示查看最早的 binlog 文件。

    • pos:从哪个 pos 点开始查看,凡是 binlog 记录下来的操作都有一个 pos 点,这个其实就是相当于我们可以指定从哪个操作开始查看日志,如果不指定的话,就是从该 binlog 的开头开始查看。

    • offset:这是是偏移量,不指定默认就是 0。

    • row_count:查看多少行记录,不指定就是查看所有。

    我们来看一个简单的例子:

    show binlog events in 'javaboy_logbin.000001';

    MySQL的binlog如何恢复数据

    这下就清晰多了,我们可以看到之前的所有操作,例如:

    • 在 Pos 219-322 之间创建了一个库。

    • 在 Pos 387-537 之间创建了一张表。

    • 在 Pos 677-780 之间添加了一条记录。

    • …

    4. 数据恢复实战

    好啦,有了前面的基础知识准备,接下来松哥来给大家手把手演示一个删库/恢复的场景。

    我先来说说我这个数据库目前的情况。

    这是一个新安装的数据库,里边我新建了一个数据库名为 javaboy,javaboy 库中新建了一张表名为 user,user 中有两条记录,如下:

    MySQL的binlog如何恢复数据

    现在假设我们定期(每周三凌晨三点)对数据库进行备份。

    现在凌晨三点了,数据库自动备份开始了,我们通过如下命令将数据库备份成 SQL 脚本,如下:

    mysqldump -uroot -p --flush-logs --lock-tables -B javaboy>/root/javaboy.bak.sql

    MySQL的binlog如何恢复数据

    这里有几个参数跟大家解释下:

    • -u、-p 这两个就不用说了。

    • –flush-logs:这个表示在导出之前先刷新 binlog,刷新 binlog 之后将会产生新的 binlog 文件,后续的操作都存在新的 binlog 中。

    • –lock-tables:这个表示开始导出前,锁定所有表。需要注意的是当导出多个数据库时,–lock-tables 分别为每个数据库锁定表,因此这个选项不能保证导出文件中的表在数据库之间的逻辑一致性,不同数据库表的导出状态可以完全不同。

    • -B:这个表示指定导出的数据库名称,如果使用 --all-databases 或者 -A 代替 -B 表示导出所有的数据库。

    以上命令执行完成后,会在 /root 目录下生成一个 javaboy.bak.sql 文件,该文件就是备份的 sql 文件了。

    这是星期三凌晨三点发生的事情。

    接下来到了星期四早上,来上班了,一顿操作后,往数据库中又添加了两条操作,如下:

    MySQL的binlog如何恢复数据

    接下来,小 X 今天跟领导吵架了很不爽,决定删除跑路:

    MySQL的binlog如何恢复数据

    领导发现了大惊,当即要求立马恢复数据。这时候该你表现了。

    首先,我们有星期三凌晨的备份文件,先用那个文件进行数据恢复:

    MySQL的binlog如何恢复数据

    恢复之后,现在到星期三早上凌晨三点的数据有了。

    从星期三早上凌晨三点到星期四的数据现在没了。

    这个时候我们就要借助于 binlog 来恢复了。大家还记得,我们星期三凌晨三点执行备份的时候,用了一个参数叫做 --flush-logs,使用了该参数表示从备份那一刻起,新的 binlog 将产生在一个新的日志文件中,对于我们这里来说,新的 binlog 文件当然就是 javaboy_logbin.000002 了,我们去查看一下该文件:

    show binlog events in 'javaboy_logbin.000002';

    我这里生成的该文件比较长,我截取其中一部分:

    MySQL的binlog如何恢复数据

    可以看到,在 764-865 这个 Pos 中发生了删库跑路事件,那么我们只需要回放该文件将数据恢复到 764 这个位置即可。

    由于 javaboy_logbin.000002 文件是在星期三凌晨三点备份之后产生的新文件,因此这个文件从起始到 764 这个 Pos 之间的操作,就是星期三凌晨三点到删库之前的操作了。

    那么我们来看下通过 binlog 来恢复数据的命令:

    mysqlbinlog /var/lib/mysql/javaboy_logbin.000002 --stop-position=764 --database=javaboy | mysql -uroot -p

    那么这里涉及到两个参数:

    • –stop-position=764 表示恢复到 764 这个 Pos,不指定的话就把按整个文件恢复了,如果按当前文件恢复的话,由于这个 binlog 文件中有删除数据库的语句,那么就会导致执行完该 binlog 之后,javaboy 库又被删除了。

    • –database=javaboy 表示恢复 javaboy 这个库。

    另外还有一个我们这里没用到的参数叫做 --start-position,这个表示起始的 Pos,不指定的话表示从头开始数据恢复。

    好啦,弄完之后,再来查看数据库:

    MySQL的binlog如何恢复数据

    数据恢复啦~

    注意:所有操作之前,记得该备份就备份(防止你操作错了又回不去),松哥为了省事上面省略了一些备份操作。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 MySQL
    相关文章 更多
    navicat导入数据库步骤详解及常见问题处理教程
    navicat导入数据库步骤详解及常见问题处理教程

    详解Navicat导入数据库的标准步骤,涵盖SQL脚本执行与CSV数据导入两种核心场景。针对导入过程中常见的字符集乱码、主键冲突及外键约束错误,提供具体的设置方法与修复建议,确保数据迁移准确无误。

    SQL主键约束和唯一约束有什么区别
    SQL主键约束和唯一约束有什么区别

    深入理解SQL PRIMARY KEY与UNIQUE约束的区别。文章从行标识与重复限制的目标出发,详解主键的非空特性、外键引用角色以及多数据库对NULL值的处理差异。结合users表实战示例,指导开发者如何根据字段稳定性与业务语义合理选择约束类型,避免设计误区。

    SQL约束有哪些类型及作用
    SQL约束有哪些类型及作用

    刚开始设计关系型数据库?了解PRIMARY KEY、FOREIGN KEY、UNIQUE、NOT NULL、CHECK、DEFAULT等约束的作用、语法和排错方法。本文以PostgreSQL语法为主,结合用户订单场景,清晰展示如何防止脏数据并处理常见约束冲突。

    SQL游标常见错误排查:死锁与资源未释放问题
    SQL游标常见错误排查:死锁与资源未释放问题

    深入解析SQL游标导致的死锁与资源未释放问题。通过PostgreSQL与MySQL语法对比,展示如何识别长事务持锁、分析锁等待链,并提供短事务提交、异常清理及批量处理的最佳实践,确保数据库连接与锁资源及时释放。

    SQL中怎么创建和删除约束
    SQL中怎么创建和删除约束

    后端开发者在维护数据库时,常需对现有表添加主键、唯一或外键约束。若直接执行ADD CONSTRAINT,往往因存量数据不合规导致报错。本文详解操作前的数据清洗步骤、标准SQL语法及MySQL等特殊写法,帮助你在生产环境安全完成结构变更。

    SQL分组统计查询:GROUP BY与HAVING子句用法示例
    SQL分组统计查询:GROUP BY与HAVING子句用法示例

    针对 SQL 初学者的分组统计实战指南。深入解析 GROUP BY 分组机制、WHERE 与 HAVING 的执行时机差异,以及 COUNT 函数对 NULL 值的处理逻辑。通过具体代码示例演示如何正确筛选聚合结果,并排查因 JOIN 连接导致的统计数据异常,提升报表准确性。

    SQL Server与MySQL游标基本语法及完整代码示例
    SQL Server与MySQL游标基本语法及完整代码示例

    本文详细对比SQL Server和MySQL中游标的基本用法。从DECLARE声明到FETCH遍历,再到CLOSE关闭与DEALLOCATE/Handler清理,解析两者在语法结构、变量接收及异常处理上的核心差异。通过标准代码示例展示如何安全使用游标,避免资源泄漏,适用于需要进行数据库存储过程开发或跨平台迁移的开发者。

    SQL多表连接区别:INNER JOIN与LEFT JOIN的使用场景
    SQL多表连接区别:INNER JOIN与LEFT JOIN的使用场景

    深入解析SQL中INNER JOIN与LEFT JOIN的核心区别。通过users和orders表实例,展示匹配行保留与NULL补位机制,重点讲解ON与WHERE子句中放置右表过滤条件的不同后果,提供防止LEFT JOIN退化的实战技巧及行数异常排查步骤。

    SQL CHECK约束的用法与取值范围限制
    SQL CHECK约束的用法与取值范围限制

    深入理解 SQL CHECK 约束在 PostgreSQL、MySQL 等数据库中的实现差异。文章通过订单业务场景,讲解如何定义单列范围与多列逻辑约束,分析 NULL 值对布尔条件的影响,并提供修改已有表结构时的安全操作建议,帮助开发者构建更健壮的数据完整性防线。

    SQL外键约束怎么用及级联操作说明
    SQL外键约束怎么用及级联操作说明

    后端开发中,如何正确使用 SQL 外键约束来维护订单与明细表的关系?本文通过 PostgreSQL 示例,深入讲解外键的创建语法、插入顺序要求,以及 ON DELETE CASCADE、RESTRICT、SET NULL 等策略的实际影响与风险控制,助你构建健壮的数据库结构。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。