服务案例 手把手教你 MySQL 删库不跑路玩转 MySQL 的 binlog ! 来源: 发表时间: 2022-07-03 来源:火狐体育最新官网登录入口 作者:火狐体育app

  我们常常听人说,只要你愿意,MySQL 可以恢复至半个月甚至一个月以内的任何一个状态。网上也有很多删库跑路的段子……

  那么今天松哥想和大家来聊一聊 MySQL 中的 binlog,来手把手教大家如何利用 binlog 来恢复 MySQL 中的数据,这样,以后要是不小心删库了,那也不用跑路了。

  MySQL 中的日志比较重要的有 binlog(归档日志)、redo log(重做日志)以及 undo log,那么跟我们本文相关的主要是 binlog,另外两个日志松哥将来有空了再和大家详细介绍。

  binlog 我们中文一般称作归档日志,如果大家看过松哥之前发的 MySQL 主从搭建,应该对这个日志有印象,当我们搭建 MySQL 主从的时候就离不开 binlog。

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

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

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

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

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

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

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

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

  # 写缓存多少次,刷一次磁盘,默认 0 表示这个操作由操作系统根据自身负载自行决定多久写一次磁盘

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  好啦,今天这篇文章主要是和小伙伴们分享了 MySQL 的 binlog 日志,并通过一个小案例来演示如何通过 binlog 实现数据库的删库恢复。好啦,感兴趣的小伙伴可以试试哦(别在生产库上试哦)~

  2022 Gdevops全球敏捷运维峰会·广州站将于6月17日举办,精选数据库热门议题,共同探讨数据库走向技术融合及国产化下的挑战,部分议题抢先剧透:

上一篇:北京信息科技大学-促进高校分类发展—图书馆文献资源建设—外文数据库项目公开招标公 下一篇:贵州印发新闻系列职称申报评审条件新版试行文件
关注我们
©2022 火狐体育最新登录网址_官网app入口 京公网安备110177777720125 火狐体育最新登录网址|火狐体育app