MySQL通过binlog恢复数据

MySQL通过binlog恢复数据

一、背景

在MySQL中,如果不小心删除了数据,可以利用二进制日志(binlog)来恢复数据。

  • 实质就是将binlog记录中的事件再次执行一遍。

二、前提条件

  1. 启用二进制日志:确保 MySQL 启用了二进制日志功能。
  2. 有足够的权限:确保有权限访问和读取二进制日志文件。

三、恢复步骤

  1. 找到相关的二进制日志文件

    bash 复制代码
    查看是否开启二进制日志文件
    SHOW VARIABLES LIKE 'log_bin%';
    
    查看二进制日志文件位置
    SHOW VARIABLES LIKE 'log_bin_basename';
    
    查看二进制日志文件列表
    SHOW BINARY LOGS;
  2. 使用 mysqlbinlog 工具提取日志事件位置

    • 先使用show binlog events命令查看binlog记录,确定事件开始位置和结束位置。

      sql 复制代码
      查看二进制日志记录
      show binlog events in 'binlog.00001';
    • 再使用 mysqlbinlog 提取开始位置和结束位置的日志:

      bash 复制代码
      mysqlbinlog /path/to/binlog.000001 --start-position=13508 --stop-position=14142 | mysql -u username -p database_name
      • 替换 /path/to/binlog.000001 为二进制日志文件路径
      • 修改stop-positionstop-position
      • 替换 username 为MySQL 用户名database_name数据库名称
  3. 使用 mysqlbinlog 工具提取日志时间段

    • 使用 mysqlbinlog 提取特定时间段的日志:

      bash 复制代码
      mysqlbinlog /path/to/binlog.000001 --start-datetime="YYYY-MM-DD HH:MM:SS" --stop-datetime="YYYY-MM-DD HH:MM:SS" | mysql -u username -p database_name
      • 替换 /path/to/binlog.000001 为二进制日志文件路径
      • 修改 start-datetimestop-datetime
      • 替换 username 为MySQL 用户名database_name数据库名称

注意事项

  • 备份当前数据:在进行数据恢复操作之前,最好先备份当前数据库,以防止进一步的数据丢失。
  • 测试恢复脚本:在生产环境中执行恢复脚本之前,可以先在测试环境中进行测试,确保恢复操作的正确性。
  • mysqlbinlog命令只用于恢复,不能用于回滚。适用数据迁移,数据同步的场景。

四、实操

1.插入数据

  1. mysql -u root -p 登陆

    sql 复制代码
    ➜  ~ mysql -u root -p                  
    Enter password: 
    Welcome to the MySQL monitor.  Commands end with ; or \\g.
    Your MySQL connection id is 40
    Server version: 8.4.3 MySQL Community Server - GPL
  2. 插入两条数据

    sql 复制代码
    mysql> use ban;
    
    mysql> INSERT INTO t_user (id, name, phone) VALUES ('1', '小明', '110');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> INSERT INTO t_user (id, name, phone) VALUES ('2', '小红', '120');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from t_user;
    +----+--------+-------+---------------------+---------------------+
    | id | name   | phone | create_dt           | update_dt           |
    +----+--------+-------+---------------------+---------------------+
    | 1  | 小明   | 110   | 2025-01-24 15:19:39 | 2025-01-24 15:19:39 |
    | 2  | 小红   | 120   | 2025-01-24 15:19:46 | 2025-01-24 15:19:46 |
    +----+--------+-------+---------------------+---------------------+
    2 rows in set (0.00 sec)

2.删除数据

sql 复制代码
mysql> delete from t_user where id in(1,2);
Query OK, 2 rows affected (0.00 sec)

mysql> select * from t_user;
Empty set (0.00 sec)

3.通过binlog恢复删除的数据

  1. 找到二进制日志文件:/usr/local/mysql/data/binlog.000002

    sql 复制代码
    mysql> SHOW VARIABLES LIKE 'log_bin_basename';
    +------------------+------------------------------+
    | Variable_name    | Value                        |
    +------------------+------------------------------+
    | log_bin_basename | /usr/local/mysql/data/binlog |
    +------------------+------------------------------+
    1 row in set (0.01 sec)
    
    mysql> SHOW BINARY LOGS;
    +---------------+-----------+-----------+
    | Log_name      | File_size | Encrypted |
    +---------------+-----------+-----------+
    | binlog.000001 |       668 | No        |
    | binlog.000002 |     14142 | No        |
    | binlog.000003 |       181 | No        |
    | binlog.000004 |       181 | No        |
    | binlog.000005 |       181 | No        |
    +---------------+-----------+-----------+
    5 rows in set (0.01 sec)
  2. 查看二进制日志记录,确认事件开始位置(13508)和结束位置(14142)

    sql 复制代码
    mysql> show binlog events in 'binlog.00002';
    
    | Log_name      | Pos   | Event_type     | Server_id | End_log_pos | Info  
    | binlog.00002 | 13508 | Anonymous_Gtid |         1 |       13587 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
    | binlog.00002 | 13587 | Query          |         1 |       13669 | BEGIN                               
    | binlog.00002 | 13669 | Table_map      |         1 |       13734 | table_id: 109 (ban.t_user)          
    | binlog.00002 | 13734 | Write_rows     |         1 |       13794 | table_id: 109 flags: STMT_END_F     
    | binlog.00002 | 13794 | Xid            |         1 |       13825 | COMMIT /* xid=1058 */               
    | binlog.00002 | 13825 | Anonymous_Gtid |         1 |       13904 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
    | binlog.00002 | 13904 | Query          |         1 |       13986 | BEGIN                               
    | binlog.00002 | 13986 | Table_map      |         1 |       14051 | table_id: 109 (ban.t_user)          
    | binlog.00002 | 14051 | Write_rows     |         1 |       14111 | table_id: 109 flags: STMT_END_F     
    | binlog.00002 | 14111 | Xid            |         1 |       14142 | COMMIT /* xid=1059 */               
  3. 使用 mysqlbinlog 恢复数据

    bash 复制代码
    ➜  ~ mysqlbinlog /usr/local/mysql/data/binlog.00002 --start-position=13508 --stop-position=14142 | mysql -u root -p ban 

4.完整示例

sql 复制代码
登陆
➜  ~ mysql -u root -p                  
Enter password: 

插入数据
mysql> use ban;
mysql> INSERT INTO t_user (id, name, phone) VALUES ('1', '小明', '110');
mysql> INSERT INTO t_user (id, name, phone) VALUES ('2', '小红', '120');
mysql> select * from t_user;
+----+--------+-------+---------------------+---------------------+
| id | name   | phone | create_dt           | update_dt           |
+----+--------+-------+---------------------+---------------------+
| 1  | 小明   | 110   | 2025-01-24 15:19:39 | 2025-01-24 15:19:39 |
| 2  | 小红   | 120   | 2025-01-24 15:19:46 | 2025-01-24 15:19:46 |
+----+--------+-------+---------------------+---------------------+
2 rows in set (0.00 sec)

删除数据
mysql> delete from t_user where id in(1,2);
mysql> select * from t_user;
Empty set (0.00 sec)

通过binlog恢复删除的数据

找到二进制日志文件:/usr/local/mysql/data/binlog.000002
mysql> SHOW VARIABLES LIKE 'log_bin_basename';
+------------------+------------------------------+
| Variable_name    | Value                        |
+------------------+------------------------------+
| log_bin_basename | /usr/local/mysql/data/binlog |
+------------------+------------------------------+
1 row in set (0.01 sec)

mysql> SHOW BINARY LOGS;
+---------------+-----------+-----------+
| Log_name      | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 |       668 | No        |
| binlog.000002 |     14142 | No        |
| binlog.000003 |       181 | No        |
| binlog.000004 |       181 | No        |
| binlog.000005 |       181 | No        |
+---------------+-----------+-----------+
5 rows in set (0.01 sec)

查看二进制日志记录,确认事件开始位置(13508)和结束位置(14142)
mysql> show binlog events in 'binlog.00002';

| Log_name      | Pos   | Event_type     | Server_id | End_log_pos | Info  
| binlog.00002 | 13508 | Anonymous_Gtid |         1 |       13587 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
| binlog.00002 | 13587 | Query          |         1 |       13669 | BEGIN                               
| binlog.00002 | 13669 | Table_map      |         1 |       13734 | table_id: 109 (ban.t_user)          
| binlog.00002 | 13734 | Write_rows     |         1 |       13794 | table_id: 109 flags: STMT_END_F     
| binlog.00002 | 13794 | Xid            |         1 |       13825 | COMMIT /* xid=1058 */               
| binlog.00002 | 13825 | Anonymous_Gtid |         1 |       13904 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
| binlog.00002 | 13904 | Query          |         1 |       13986 | BEGIN                               
| binlog.00002 | 13986 | Table_map      |         1 |       14051 | table_id: 109 (ban.t_user)          
| binlog.00002 | 14051 | Write_rows     |         1 |       14111 | table_id: 109 flags: STMT_END_F     
| binlog.00002 | 14111 | Xid            |         1 |       14142 | COMMIT /* xid=1059 */            

使用 mysqlbinlog 恢复数据
➜  ~ mysqlbinlog /usr/local/mysql/data/binlog.00002 --start-position=13508 --stop-position=14142 | mysql -u root -p ban 
相关推荐
island13141 小时前
【QT】 控件 -- 显示类
开发语言·数据库·qt
Andya_net2 小时前
网络安全 | F5-Attack Signatures-Set详解
网络·数据库·web安全
码农幻想梦2 小时前
实验二 数据库的附加/分离、导入/导出与备份/还原
数据库·oracle
hillstream33 小时前
Synology 群辉NAS安装(6)安装mssql
数据库·sqlserver
行十万里人生4 小时前
Qt 控件与布局管理
数据库·qt·microsoft·华为od·华为·华为云·harmonyos
betazhou4 小时前
sysbench压力测试工具mysql以及postgresql
数据库·mysql·postgresql
莳花微语4 小时前
OGG 19C 集成模式启用DDL复制
数据库·oracle
潜水的码不二4 小时前
Redis高阶3-缓存双写一致性
数据库·redis·缓存
落霞的思绪4 小时前
Redis实战(黑马点评)——关于缓存(缓存更新策略、缓存穿透、缓存雪崩、缓存击穿、Redis工具)
数据库·spring boot·redis·后端·缓存
老苏畅谈运维7 小时前
MySQL性能分析的“秘密武器”,深度剖析SQL问题
数据库·sql·mysql