在MySQL中,如果不小心删除了数据,可以利用二进制日志(binlog
)来恢复数据。
binlog
记录中的事件再次执行一遍。找到相关的二进制日志文件:
查看是否开启二进制日志文件
SHOW VARIABLES LIKE 'log_bin%';
查看二进制日志文件位置
SHOW VARIABLES LIKE 'log_bin_basename';
查看二进制日志文件列表
SHOW BINARY LOGS;
使用 mysqlbinlog
工具提取日志:事件位置
先使用show binlog events
命令查看binlog
记录,确定事件开始位置和结束位置。
查看二进制日志记录
show binlog events in 'binlog.00001';
再使用 mysqlbinlog
提取开始位置和结束位置的日志:
mysqlbinlog /path/to/binlog.000001 --start-position=13508 --stop-position=14142 | mysql -u username -p database_name
/path/to/binlog.000001
为二进制日志文件路径stop-position
和stop-position
username
为MySQL 用户名,database_name
为数据库名称。使用 mysqlbinlog
工具提取日志:时间段
使用 mysqlbinlog
提取特定时间段的日志:
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-datetime
和 stop-datetime
username
为MySQL 用户名,database_name
为数据库名称。mysqlbinlog
命令只用于恢复,不能用于回滚。适用数据迁移,数据同步的场景。mysql -u root -p
登陆
➜ ~ 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
插入两条数据
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)
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)
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
登陆
➜ ~ 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