1. 前言 实际开发、生产场景中会出现,RDS 宕机时数据记录未入库导致数据丢失;误更新、误删除操作导致记录被修改或数据丢失的情况;对于 MySQL 我们可以通过 BinLog 找回误删除的数据。
BinLog 是 MySQL 自带的日志,偏向逻辑性的日志,记录的是对哪个表的哪一行做了更新操作,更新前后的值是什么。
2. BinLog 说明 Binary Logging 是个存储二进制文件,有两种文件类型
索引文件 文件名后缀为.index; 用于记录哪些日志文件正在被使用
日志文件 文件名后缀为.00000*; 记录数据库所有的 DDL 和 DML (除了数据查询语句)语句事件
通过设置配置文件 my.ini 的 log_bin 属性来开启日志功能,此时对数据库的操作会记录 binlog 日志并写入磁盘文件。
编辑 my.ini 可开启并配置 Binlog 策略
1 2 3 4 5 6 7 8 9 10 11 12 # Binary Logging. # binlog 日志文件路径 log-bin=C:/ProgramData/MySQL/BinlogData # binlog 日志格式 binlog_format=ROW # binlog 过期清理时间/天 expire_logs_days=90 # binlog 日志文件大小/个 max_binlog_size=100M # binlog 缓存大小 binlog_cache_size=4M max_binlog_cache_size=512M
通过应用程序 mysqlbinlog.exe 可以从日志文件中读取指定时间段的数据库语句变更详细日志。
1 mysqlbinlog --base64-output=decode-rows -v --database=<数据库名称> --start-datetime="<起始时间>" --stop-datetime="<截至时间>" <日志文件> > <输出文件>
如下所示某时刻的变更详细日志,某数据库在 211129 16:53:31 时刻一条更新操作日志,根据该日志可清晰的指定更新前的数据,依据该日志可恢复记录数据到更新前的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #211129 16 :53 :31 server id 1 end_log_pos 743 CRC32 0xd38b2db6 Update_rows: table id 337 flags: STMT_END_F ### UPDATE `ecrm_jd`.`xxl_job_user` ### WHERE ### @1 = 2 ### @2 = 'admin11' ### @3 = 'e10adc3949ba59abbe56e057f20f883e' ### @4 = 1 ### @5 = NULL ### SET ### @1 = 2 ### @2 = 'niaonao' ### @3 = 'e10adc3949ba59abbe56e057f20f883e' ### @4 = 1 ### @5 = NULL
3. BinLog 配置是否被开启 查看是否开启 BinLog,属性 log_bin 的值为 OFF 则没开启该功能无法通过本文下面的 BigLog 方式恢复数据。log_bin 的值为 ON 则支持恢复数据。
1 2 3 4 5 6 7 8 9 10 11 mysql> show variables like 'log_bin%'; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | log_bin | OFF | | log_bin_basename | | | log_bin_index | | | log_bin_trust_function_creators | OFF | | log_bin_use_v1_row_events | OFF | +---------------------------------+-------+ 5 rows in set (0.01 sec)
4. BinLog 配置怎么开启 找到 MySQL 的配置文件,配置文件路径 C:\ProgramData\MySQL\MySQL Server 5.6\my.ini
只需要把 log-bin
开放后(去除属性前面的 # 注释)重启服务即可,不生效则确认 my.ini 配置无误多次重启后生效。 可指定文件生成路径,默认在相对路径下。 此处指定 binlog 文件生成配置 C:\ProgramData\MySQL\BinlogData,日志记录格式配置为 MIXED,单文件最大 100M,三个月清理历史文件。 log-bin 不指定时,默认使用的设置是 log-bin=mysql-bin;binlog_format 默认使用 STATEMENT;
1 2 3 4 5 6 7 8 9 10 11 12 # Binary Logging. # binlog 日志文件 log-bin=C:\ProgramData\MySQL\BinlogData # binlog 日志格式 binlog_format=ROW # binlog 过期清理时间/天 expire_logs_days=90 # binlog 日志文件大小/个 max_binlog_size=100M # binlog 缓存大小 binlog_cache_size=4M max_binlog_cache_size=512M
重启服务 服务名称就是 MySQL56,可通过 WIN+R,输入 services.msc 查看服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 PS C:\Users\Lenovo> net stop MySQL56 MySQL56 服务正在停止. MySQL56 服务已成功停止。 PS C:\Users\Lenovo> net start MySQL56 MySQL56 服务正在启动 . MySQL56 服务已经启动成功。 PS C:\Users\Lenovo> mysql - u root - p Enter password: * * * * Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.6 .21 - log MySQL Community Server (GPL) Copyright (c) 2000 , 2014 , Oracle and / or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and / or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show variables like 'log_bin%' ; + | Variable_name | Value | + | log_bin | ON | | log_bin_basename | C:\ProgramData\MySQL\BinlogData | | log_bin_index | C:\ProgramData\MySQL\BinlogData.index | | log_bin_trust_function_creators | OFF | | log_bin_use_v1_row_events | OFF | + 5 rows in set (0.00 sec)
可以通过 show variables like 'log_bin%'
看到此时配置 log_bin 已开启为 ON.
5. 误更新或删除数据 以数据库 ecrm_jd 的用户表 xxl_job_user 演示,更新一条记录,删除两条记录。 再根据 binlog 日志来追踪数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 mysql> use ecrm_jd; Database changed mysql> select * from xxl_job_user; + | id | username | password | role | permission | + | 1 | admin | e10adc3949ba59abbe56e057f20f883e | 1 | NULL | + 1 row in set (0.00 sec)mysql> insert xxl_job_user(username,password,role) values ('admin11' , 'e10adc3949ba59abbe56e057f20f883e' , 1 ),('admin12' , 'e10adc3949ba59abbe56e057f20f883e' , 1 ),('admin13' , 'e10adc3949ba59abbe56e057f20f883e' , 0 ); Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from xxl_job_user; + | id | username | password | role | permission | + | 1 | admin | e10adc3949ba59abbe56e057f20f883e | 1 | NULL | | 2 | admin11 | e10adc3949ba59abbe56e057f20f883e | 1 | NULL | | 3 | admin12 | e10adc3949ba59abbe56e057f20f883e | 1 | NULL | | 4 | admin13 | e10adc3949ba59abbe56e057f20f883e | 0 | NULL | + 4 rows in set (0.00 sec)mysql> update xxl_job_user set username = 'niaonao' where id = 2 ; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> delete from xxl_job_user where id in (1 ,4 ); Query OK, 2 rows affected (0.01 sec) mysql> select * from xxl_job_user; + | id | username | password | role | permission | + | 2 | niaonao | e10adc3949ba59abbe56e057f20f883e | 1 | NULL | | 3 | admin12 | e10adc3949ba59abbe56e057f20f883e | 1 | NULL | + 2 rows in set (0.00 sec)
6. binlog 日志跟踪查找被删除的数据
这里是 2021-11-29 16:56 左右修改的,在 C:\ProgramData\MySQL 下找到 <filename>.000003 日志文件。 通过应用程序 mysqlbinlog 查看 binlog。 去安装路径下找到应用程序 ~\MySQL Server 5.6\bin\mysqlbinlog.exe
WIN+R 输入 cmd 打开命令行窗口,切换到 mysqlbinlog 所在目录,执行以下命令导出脚本。
1 mysqlbinlog --base64-output=decode-rows -v --database=<数据库名称> --start-datetime="<起始时间>" --stop-datetime="<截至时间>" <日志文件> > <输出文件>
此处从文件 BinlogData.000003 中解析导出数据库 ecrm_jd 在 2021-11-29 16:50:00 ~ 2021-11-29 17:30:00 时间内的日志,输出到文件 binlog202111291650.sql
1 C:\Program Files (x86)\MySQL\MySQL Server 5.6\bin>mysqlbinlog --base64-output=decode-rows -v --database=ecrm_jd --start-datetime="2021-11-29 16:50:00" --stop-datetime="2021-11-29 17:30:00" C:\ProgramData\MySQL\BinlogData.000003 > binlog202111291650.sql
打开文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 ; ; ; DELIMITER ; # at 4 #211129 15 :20 :44 server id 1 end_log_pos 120 CRC32 0x7b673bd6 Start : binlog v 4 , server v 5.6 .21 - log created 211129 15 :20 :44 at startup # Warning: this binlog is either in use or was not closed properly. ROLLBACK ;# at 120 #211129 16 :52 :19 server id 1 end_log_pos 195 CRC32 0xeeb79b0f Query thread_id= 4 exec_time= 0 error_code= 0 SET TIMESTAMP = 1638175939 ;SET @@session .pseudo_thread_id= 4 ;SET @@session .foreign_key_checks= 1 , @@session .sql_auto_is_null= 0 , @@session .unique_checks= 1 , @@session .autocommit= 1 ;SET @@session .sql_mode= 1344274432 ;SET @@session .auto_increment_increment= 1 , @@session .auto_increment_offset= 1 ;; SET @@session .character_set_client= 28 ,@@session .collation_connection= 28 ,@@session .collation_server= 33 ;SET @@session .lc_time_names= 0 ;SET @@session .collation_database= DEFAULT ;BEGIN ; # at 195 #211129 16 :52 :19 server id 1 end_log_pos 263 CRC32 0xd1715424 Table_map: `ecrm_jd`.`xxl_job_user` mapped to number 337 # at 263 #211129 16 :52 :19 server id 1 end_log_pos 439 CRC32 0x93f08743 Write_rows: table id 337 flags: STMT_END_F ### INSERT INTO `ecrm_jd`.`xxl_job_user` ### SET ### @1 = 2 ### @2 = 'admin11' ### @3 = 'e10adc3949ba59abbe56e057f20f883e' ### @4 = 1 ### @5 = NULL ### INSERT INTO `ecrm_jd`.`xxl_job_user` ### SET ### @1 = 3 ### @2 = 'admin12' ### @3 = 'e10adc3949ba59abbe56e057f20f883e' ### @4 = 1 ### @5 = NULL ### INSERT INTO `ecrm_jd`.`xxl_job_user` ### SET ### @1 = 4 ### @2 = 'admin13' ### @3 = 'e10adc3949ba59abbe56e057f20f883e' ### @4 = 0 ### @5 = NULL # at 439 #211129 16 :52 :19 server id 1 end_log_pos 470 CRC32 0x48cdfe14 Xid = 391 COMMIT ;# at 470 #211129 16 :53 :31 server id 1 end_log_pos 545 CRC32 0xdc9527f7 Query thread_id= 4 exec_time= 0 error_code= 0 SET TIMESTAMP = 1638176011 ;BEGIN ; # at 545 #211129 16 :53 :31 server id 1 end_log_pos 613 CRC32 0x7b2ee120 Table_map: `ecrm_jd`.`xxl_job_user` mapped to number 337 # at 613 #211129 16 :53 :31 server id 1 end_log_pos 743 CRC32 0xd38b2db6 Update_rows: table id 337 flags: STMT_END_F ### UPDATE `ecrm_jd`.`xxl_job_user` ### WHERE ### @1 = 2 ### @2 = 'admin11' ### @3 = 'e10adc3949ba59abbe56e057f20f883e' ### @4 = 1 ### @5 = NULL ### SET ### @1 = 2 ### @2 = 'niaonao' ### @3 = 'e10adc3949ba59abbe56e057f20f883e' ### @4 = 1 ### @5 = NULL # at 743 #211129 16 :53 :31 server id 1 end_log_pos 774 CRC32 0x0423f88b Xid = 397 COMMIT ;# at 774 #211129 16 :54 :21 server id 1 end_log_pos 849 CRC32 0x6280ce3c Query thread_id= 4 exec_time= 0 error_code= 0 SET TIMESTAMP = 1638176061 ;BEGIN ; # at 849 #211129 16 :54 :21 server id 1 end_log_pos 917 CRC32 0xd4ee0972 Table_map: `ecrm_jd`.`xxl_job_user` mapped to number 337 # at 917 #211129 16 :54 :21 server id 1 end_log_pos 1044 CRC32 0xcc058cef Delete_rows: table id 337 flags: STMT_END_F ### DELETE FROM `ecrm_jd`.`xxl_job_user` ### WHERE ### @1 = 1 ### @2 = 'admin' ### @3 = 'e10adc3949ba59abbe56e057f20f883e' ### @4 = 1 ### @5 = NULL ### DELETE FROM `ecrm_jd`.`xxl_job_user` ### WHERE ### @1 = 4 ### @2 = 'admin13' ### @3 = 'e10adc3949ba59abbe56e057f20f883e' ### @4 = 0 ### @5 = NULL # at 1044 #211129 16 :54 :21 server id 1 end_log_pos 1075 CRC32 0x23f55056 Xid = 401 COMMIT ;DELIMITER ; # End of log file ROLLBACK ;; ;
通过程序 mysqlbinlog 恢复的日志中可以查看指定时间段内的数据库操作语句,找到误 UPDATE、DELETE 语句可以看到被删除的记录属性和属性值,依据该日志可恢复该记录。
参考博客:mysql 恢复 delete 删除的数据 mysql 中 binlog_format 的三种模式 binlog 介绍 binlog 浅析 Powered By niaonao
__END__