Binlog(Binary Log,二进制日志)是 MySQL 数据库中用于记录数据库更改操作的一种日志文件。它主要记录了数据库的 数据变更事件(如 INSERT、UPDATE、DELETE 等操作)以及某些 DDL(数据定义语言,如 CREATE、ALTER、DROP 等)操作。Binlog 是 MySQL 高可用性和数据恢复的核心组件之一,常用于以下场景:
mysql-bin.000001
,
mysql-bin.000002
)。MySQL 支持三种 binlog 格式:
NOW()
)导致主从不一致。配置 binlog 格式的方法:
SET GLOBAL binlog_format = 'ROW'; -- 设置为 Row 模式
要使用 binlog,需要在 MySQL 配置文件(通常是 my.cnf
或
my.ini
)中启用:
[mysqld]
log_bin = mysql-bin
binlog_format = ROW
server_id = 1 -- 每个实例需要唯一 ID,主从复制时必须配置
启用后,MySQL 会生成 binlog 文件,通常位于数据目录下。
查看 binlog 文件列表:
SHOW BINARY LOGS;
查看当前正在写入的 binlog:
MASTER STATUS; SHOW
查看 binlog 内容:
使用 mysqlbinlog
工具解析 binlog 文件:
mysqlbinlog --verbose mysql-bin.000001
清理 binlog:
binlog 文件会占用磁盘空间,可定期清理:
PURGE BINARY LOGS TO 'mysql-bin.000010'; -- 删除指定文件之前的 binlog
PURGE BINARY LOGS BEFORE '2025-08-01 00:00:00'; -- 删除指定时间前的 binlog
备份和回档是数据库管理中至关重要的操作,用于防止数据丢失和恢复到特定状态。结合 binlog,可以实现 全量备份 和 增量恢复。
mysqldump
或 xtrabackup
。mysqldump
),适合小规模数据库。xtrabackup
),速度快,适合大规模数据库。逻辑备份工具,生成可执行的 SQL 脚本。
示例:
mysqldump -u root -p --databases mydb > mydb_backup.sql
优点:跨版本、跨平台兼容性好。
缺点:备份和恢复速度较慢,适合中小型数据库。
物理备份工具,适合大规模数据库。
支持热备份(不锁表)、增量备份。
示例:
xtrabackup --backup --target-dir=/backup/
数据回档通常结合全量备份和 binlog 实现 Point-in-Time Recovery (PITR),即恢复到某一特定时间点。
恢复全量备份:
如果使用 mysqldump
:
mysql -u root -p mydb < mydb_backup.sql
如果使用 xtrabackup
:
xtrabackup --copy-back --target-dir=/backup/
确定恢复的时间点或位置:
找到需要恢复到的时间点或 binlog 位置(position)。
使用 mysqlbinlog
查看 binlog 事件:
mysqlbinlog --start-datetime="2025-08-20 10:00:00" --stop-datetime="2025-08-20 12:00:00" mysql-bin.000001 > events.sql
应用 binlog:
将解析出的 binlog 事件应用到数据库:
mysql -u root -p < events.sql
验证数据:
假设数据库在 2025-08-20 12:00:00 发生误操作,需要恢复到该时间点: 1.
恢复最近的全量备份(例如 2025-08-19 的备份)。 2. 使用
mysqlbinlog
提取 2025-08-19 到 2025-08-20 12:00:00 的
binlog 事件。 3. 执行提取的 SQL 语句,完成恢复。
mysqldump
和 xtrabackup
。docker pull mysql:latest
version: '3'
services:
mysql:
image: mysql:latest
container_name: mysql-container
environment:
MYSQL_ROOT_PASSWORD: password
# MYSQL_DATABASE: mydb
MYSQL_USER: username
MYSQL_PASSWORD: password
volumes:
- mysql-data:/var/lib/mysql
ports:
- "3306:3306"
command: --log-bin=mysql-bin --server-id=1 --binlog-format=STATEMENT
volumes:
mysql-data:
root@ser745692301841:/dev_dir/docker# ls
docker-compose.yml
root@ser745692301841:/dev_dir/docker# docker-compose up -d
root@ser745692301841:/dev_dir/docker# docker volume ls
DRIVER VOLUME NAME
local docker_mysql-data
root@ser745692301841:/dev_dir/docker# docker volume inspect docker_mysql-data
[
{"CreatedAt": "2025-08-22T01:16:19Z",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "docker",
"com.docker.compose.version": "1.29.2",
"com.docker.compose.volume": "mysql-data"
},
"Mountpoint": "/var/lib/docker/volumes/docker_mysql-data/_data",
"Name": "docker_mysql-data",
"Options": null,
"Scope": "local"
}
]
root@ser745692301841:/dev_dir/docker# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
67d01f13e776 mysql:latest "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp mysql-container
root@ser745692301841:/dev_dir/docker# docker-compose down
Stopping mysql-container ... done
Removing mysql-container ... done
Removing network docker_default
root@ser745692301841:/dev_dir/docker# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
root@ser745692301841:/dev_dir/docker# docker-compose up -d
Creating network "docker_default" with the default driver
Creating mysql-container ... done
root@ser745692301841:/dev_dir/docker# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d64819718025 mysql:latest "docker-entrypoint.s…" 4 seconds ago Up 3 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp mysql-container
root@ser745692301841:/dev_dir/docker# docker exec -it mysql-container bash
bash-5.1# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 9.3.0 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
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 'binlog_format';
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| binlog_format | STATEMENT |
+---------------+-----------+
1 row in set (0.023 sec)
mysql>
mysql> CREATE DATABASE mydb;
Query OK, 1 row affected (0.007 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.011 sec)
mysql> use mydb;
Database changed
mysql> CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.028 sec)
mysql> show tables;
+----------------+
| Tables_in_mydb |
+----------------+
| users |
+----------------+
1 row in set (0.005 sec)
mysql> desc users;
+------------+--------------+------+-----+-------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+-------------------+
| id | int | NO | PRI | NULL | auto_increment |
| username | varchar(50) | NO | UNI | NULL | |
| email | varchar(100) | NO | UNI | NULL | |
| password | varchar(255) | NO | | NULL | |
| created_at | timestamp | YES | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
+------------+--------------+------+-----+-------------------+-------------------+
5 rows in set (0.005 sec)
mysql> show create table users;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| users | CREATE TABLE `users` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`email` varchar(100) NOT NULL,
`password` varchar(255) NOT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.020 sec)
mysql> SHOW BINARY LOGS;
+------------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000001 | 181 | No |
| mysql-bin.000002 | 736 | No |
+------------------+-----------+-----------+
2 rows in set (0.001 sec)
mysql> SHOW VARIABLES LIKE 'log_bin%';
+---------------------------------+--------------------------------+
| Variable_name | Value |
+---------------------------------+--------------------------------+
| log_bin | ON |
| log_bin_basename | /var/lib/mysql/mysql-bin |
| log_bin_index | /var/lib/mysql/mysql-bin.index |
| log_bin_trust_function_creators | OFF |
+---------------------------------+--------------------------------+
4 rows in set (0.009 sec)
binlog文件是bin格式不能使用cat和vim查看,需要使用mysql提供的mysqlbinlog
sh-5.1# mysqlbinlog mysql-bin.000002 > mysql-bin.000002.txt