MySQL BinLog

MySQL Binlog 简介

Binlog(Binary Log,二进制日志)是 MySQL 数据库中用于记录数据库更改操作的一种日志文件。它主要记录了数据库的 数据变更事件(如 INSERT、UPDATE、DELETE 等操作)以及某些 DDL(数据定义语言,如 CREATE、ALTER、DROP 等)操作。Binlog 是 MySQL 高可用性和数据恢复的核心组件之一,常用于以下场景:

  1. 主从复制:主库将 binlog 传输到从库,从库通过重放 binlog 实现数据同步。
  2. 数据恢复:结合全量备份,binlog 可以实现增量恢复,恢复到某个时间点或某个事务。
  3. 数据分析:用于审计或分析数据库的操作历史。

Binlog 的工作原理

Binlog 的格式

MySQL 支持三种 binlog 格式:

配置 binlog 格式的方法:

SET GLOBAL binlog_format = 'ROW'; -- 设置为 Row 模式

启用 Binlog

要使用 binlog,需要在 MySQL 配置文件(通常是 my.cnfmy.ini)中启用:

[mysqld]
log_bin = mysql-bin
binlog_format = ROW
server_id = 1 -- 每个实例需要唯一 ID,主从复制时必须配置

启用后,MySQL 会生成 binlog 文件,通常位于数据目录下。

查看和管理 Binlog


MySQL 备份与回档

备份和回档是数据库管理中至关重要的操作,用于防止数据丢失和恢复到特定状态。结合 binlog,可以实现 全量备份增量恢复

备份类型

常用备份工具

备份策略

数据回档(恢复)

数据回档通常结合全量备份和 binlog 实现 Point-in-Time Recovery (PITR),即恢复到某一特定时间点。

恢复步骤:

  1. 恢复全量备份

  2. 确定恢复的时间点或位置

  3. 应用 binlog

  4. 验证数据

示例场景:恢复到某时间点

假设数据库在 2025-08-20 12:00:00 发生误操作,需要恢复到该时间点: 1. 恢复最近的全量备份(例如 2025-08-19 的备份)。 2. 使用 mysqlbinlog 提取 2025-08-19 到 2025-08-20 12:00:00 的 binlog 事件。 3. 执行提取的 SQL 语句,完成恢复。

注意事项


总结

mysql docker-compose样例

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