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 
相关推荐
Dreamboat¿1 小时前
SQL 注入漏洞
数据库·sql
曹牧2 小时前
Oracle数据库中,将JSON字符串转换为多行数据
数据库·oracle·json
被摘下的星星2 小时前
MySQL count()函数的用法
数据库·mysql
末央&2 小时前
【天机论坛】项目环境搭建和数据库设计
java·数据库
徒 花2 小时前
数据库知识复习07
数据库·作业
素玥3 小时前
实训5 python连接mysql数据库
数据库·python·mysql
jnrjian3 小时前
text index 查看index column index定义 index 刷新频率 index视图
数据库·oracle
瀚高PG实验室3 小时前
审计策略修改
网络·数据库·瀚高数据库
言慢行善3 小时前
sqlserver模糊查询问题
java·数据库·sqlserver
韶博雅3 小时前
emcc24ai
开发语言·数据库·python