整体思路

用 Docker 起两个 MySQL 容器,一个当主库(Master),一个当从库(Slave),让从库通过 binlog 实时同步主库的数据变化。

mysql-master (写入端) → binlog → mysql-slave (只读同步端)

第一步:创建工作目录

mkdir -p ~/mysql-cluster/master/conf
mkdir -p ~/mysql-cluster/slave/conf
cd ~/mysql-cluster

第二步:配置主库(Master)

创建主库配置文件:

nano master/conf/my.cnf

写入:

[mysqld]
server-id=1
log-bin=mysql-bin
binlog-format=ROW
binlog-do-db=test_db

说明:

  • server-id:主从架构里每个节点必须有唯一ID

  • log-bin:开启binlog日志,这是主从同步的核心机制——主库把所有写操作记录成binlog,从库靠"回放"这份日志来同步数据

  • binlog-format=ROW:记录每一行数据的实际变化(相比STATEMENT记录SQL语句,ROW格式更精确可靠,是目前主流做法)

  • binlog-do-db:只对指定的数据库记录binlog

第三步:配置从库(Slave)

nano slave/conf/my.cnf

写入:

[mysqld]
server-id=2
relay-log=relay-bin
read-only=1
  • server-id=2:必须和主库不同

  • relay-log:从库用来暂存主库传来的binlog的"中转日志"

  • read-only=1:从库设为只读,防止误写入破坏同步一致性

第四步:编写 docker-compose.yml

nano docker-compose.yml

version: '3.8'
services:
  mysql-master:
    image: mysql:8.0
    container_name: mysql-master
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: YourPassword123
      MYSQL_DATABASE: test_db
    ports:
      - "3306:3306"
    volumes:
      - master-data:/var/lib/mysql
      - ./master/conf:/etc/mysql/conf.d

  mysql-slave:
    image: mysql:8.0
    container_name: mysql-slave
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: YourPassword123
    ports:
      - "3307:3306"
    volumes:
      - slave-data:/var/lib/mysql
      - ./slave/conf:/etc/mysql/conf.d
    depends_on:
      - mysql-master

volumes:
  master-data:
  slave-data:

启动:

docker-compose up -d

第五步:在主库创建同步专用账号

docker exec -it mysql-master mysql -uroot -p

进去后执行:

CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'ReplPassword123';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

SHOW MASTER STATUS;

记下最后这条命令输出的 FilePosition 两个值(比如 mysql-bin.000003157),下一步要用到。

第六步:在从库配置同步

docker exec -it mysql-slave mysql -uroot -p

进去后执行(把IP、File、Position换成你实际的值):

CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='mysql-master',
  SOURCE_USER='repl',
  SOURCE_PASSWORD='ReplPassword123',
  SOURCE_LOG_FILE='mysql-bin.000003',
  SOURCE_LOG_POS=157;

START REPLICA;

SHOW REPLICA STATUS\G

关键检查点:输出里找这两行,必须都是 Yes 才算同步成功:

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

第七步:验证同步是否生效

主库建个表插条数据:

-- 在mysql-master里
USE test_db;
CREATE TABLE test_table (id INT, name VARCHAR(20));
INSERT INTO test_table VALUES (1, 'hello');

从库查:

-- 在mysql-slave里
USE test_db;
SELECT * FROM test_table;

如果从库能查到刚才插入的数据,说明一主一从同步成功