背景
最近开发的时候,Mysql 中配置了一条非常复杂且重要的数据记录,但是由于之后的一次不规范的 Update 操作,本想只更新其中一个字段值,结果却更新了整个记录,导致保存了 JSON 文本的字段值被初始成了默认值,数据丢失。从新配置该值太麻烦,于是踏上了数据恢复之路。
Binary Log
binlog 是 Mysql sever 层维护的一种二进制日志,与 innodb 引擎中的 redo/undo log 是完全不同的日志;其主要是用来记录对 mysql 数据更新或潜在发生更新的 SQL 语句,并以”事务”的形式保存在磁盘中;
binlog 虽然没有记录每次 query 操作,但是记录表结构和数据记录的每次变动操作,足以用来恢复数据。更多 binlog 的介绍请访问参考文章。
流程
查看 binlog 配置
登录 mysql,执行show variables like '%log_bin%';
1 | mysql> show variables like '%log_bin%'; |
检查 log_bin
是否为 ON 状态。如果是 OFF 就没戏了。log_bin_basename
值是日志的文件基本路径,实际文件名会追加序号,例如 mysql-bin.000001
,序号越大日志时间越新。
mysqlbinlog
mysqlbinlog 是 binlog 日志解析工具,需要用它进行日志操作。在安装了 mysql 数据库的情况下,如果直接执行 mysqlbinlog
提示没有该命令,就需要用绝对路径去执行了,在 mysql 安装目录的 bin 目录下,也可以通过 find / -name mysqlbinlog -print
查找。
mysqlbinlog 支持条件查询输出等,直接输出到控制台不方便查看,我这里直接输出到 sql 文件里,然后用 vim 查询相关字段,找到最新一次 update 操作,然后向前定位就能找到原数据了。
输入到 sql 的命令:
1 | /www/server/mysql/bin/mysqlbinlog -v --base64-output=decode-rows mysql-bin.000007 --start-datetime="2019-06-9 9:00:00" --stop-datetime="2019-06-9 23:00:00" > output.sql |
为了避免无关数据量太多,可以用开始时间、结束时间进行范围限定,也可以通过 query 类型限定。
结语
本文只是介绍了我的这种特殊场景下的 binlog 的使用,没有对 binlog 展开详细讲解,只是起到一个抛砖引玉的作用,请合理参考。