1.创建my-master.conf

[mysqld]
# 基础配置
server-id = 1 # 唯一标识主库
port = 3306
bind-address = 0.0.0.0 # 允许所有IP连接

# 二进制日志配置(主从复制核心)
log-bin = mysql-bin # 启用二进制日志
binlog-format = ROW # 行模式日志(推荐)
expire_logs_days = 7 # 日志保留7天
max_binlog_size = 100M # 单个日志文件最大100MB

# GTID 配置(简化复制管理)
gtid-mode = ON
enforce-gtid-consistency = ON

# 数据持久化
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1

# 其他优化
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci


2.创建my-slave.conf

[mysqld]
# 基础配置
server-id = 2 # 唯一标识从库(必须不同)
port = 3306
bind-address = 0.0.0.0 # 允许所有IP连接
read_only = ON # 从库只读(防止误写)

# 二进制日志配置(可选,用于级联复制)
log-bin = mysql-bin
binlog-format = ROW

# GTID 配置
gtid-mode = ON
enforce-gtid-consistency = ON

# 复制控制(启动时不自动开启复制)
skip-slave-start = ON

# 数据持久化
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1

# 其他优化
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

 

 

(2) 主库配置参数说明

参数作用
--server-id=1 唯一标识主库(从库需不同)
--log-bin=mysql-bin 启用二进制日志(主从同步依赖此日志)
--binlog-format=ROW 设置二进制日志格式为行模式(推荐)
--gtid-mode=ON 启用全局事务标识符(GTID)
--enforce-gtid-consistency=ON 强制 GTID 一致性

 

 

 

构建docker-compose.yml

version: '3.8'

services:
  mysql-master:
    image: mysql:8.0
    container_name: mysql-master
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
    volumes:
      - ./my-master.conf:/etc/mysql/conf.d/master.cnf
      - mysql-master-data:/var/lib/mysql
    ports:
      - "3306:3306"
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

  mysql-slave:
    image: mysql:8.0
    container_name: mysql-slave
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
    volumes:
      - ./my-slave.conf:/etc/mysql/conf.d/slave.cnf
      - mysql-slave-data:/var/lib/mysql
    ports:
      - "3307:3306"
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

volumes:
  mysql-master-data:
  mysql-slave-data:

 

 

3. 配置主库并创建复制账户

(1) 进入主库容器

 
docker exec -it mysql-master mysql -uroot -prootpassword

(2) 创建复制账户

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

 

(3) 查看主库状态

SHOW MASTER STATUS\G

 

5. 配置从库同步主库

 

(1) 进入从库容器

 
 
docker exec -it mysql-slave mysql -uroot -prootpassword

 

 

(2) 配置复制链路

CHANGE MASTER TO
  MASTER_HOST='mysql-master',
  MASTER_USER='repl',
  MASTER_PASSWORD='repl_password',
  MASTER_AUTO_POSITION=1;

(3) 启动复制

START SLAVE;

(4) 查看从库状态

SHOW SLAVE STATUS\G

6. 验证主从同步

(1) 在主库创建测试数据

CREATE DATABASE test;
USE test;
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(20));
INSERT INTO users (name) VALUES ('Alice');

(2) 在从库检查数据

 
 
SELECT * FROM test.users;

若输出 Alice 表示同步成功。


7. 关键注意事项

  • 数据一致性:主从配置前确保主库无写入操作,否则需先同步数据。

  • 网络互通:主从容器必须处于同一 Docker 网络(mysql-replication)。

  • 防火墙设置:确保容器间 3306 端口开放。

  • GTID 优势:使用 GTID 模式可简化故障转移和主从切换。

 

8. 扩展:多从库配置

若需添加更多从库,重复步骤 4 和 5,注意修改 server-id

docker run -d \
  --name mysql-slave2 \
  --network mysql-replication \
  -e MYSQL_ROOT_PASSWORD=root_password \
  -v $(pwd)/slave2-data:/var/lib/mysql \
  -p 3308:3306 \
  mysql:8.0 \
  --server-id=3 \
  ...

通过以上步骤,你已成功搭建 MySQL 主从复制环境。主库写入的数据会自动同步到从库,适用于读写分离、负载均衡和高可用场景。

 

在 MySQL 中,GTID(Global Transaction Identifier,全局事务标识符) 是一种用于唯一标识事务的机制,它简化了主从复制的管理和故障恢复。--enforce-gtid-consistency=ON 的作用是强制确保事务在 GTID 模式下的兼容性和一致性。以下是详细解释:


1. GTID 是什么?

GTID 是 MySQL 主从复制中用于唯一标识事务的全局唯一标识符。
它的格式为:
GTID = server_uuid:transaction_id

  • server_uuid:MySQL 实例的唯一标识符(自动生成)。

  • transaction_id:事务在该实例中的递增序号。

例如:3E11FA47-71CA-11E1-9E33-C80AA9429562:23


2. GTID 的作用

  • 全局唯一性:每个事务的 GTID 在集群中唯一,避免主从数据冲突。

  • 简化复制管理:通过 GTID 而非二进制日志文件名和位置(binlog file + position)定位事务,简化主从切换和故障恢复。

  • 一致性保障:确保事务在主从节点上按相同顺序执行。


3. --enforce-gtid-consistency=ON 的作用

该参数强制 MySQL 在 GTID 模式下 仅执行与 GTID 兼容的事务,防止因某些操作(如非事务性语句)导致主从数据不一致。具体行为如下:

(1) 禁止不安全的 SQL 语句

在 GTID 模式下,以下操作会被禁止(除非显式启用 gtid_next):

  • 非事务性存储引擎的操作(如 MyISAM)。

  • 跨数据库的 DDL 语句(如 CREATE TABLE ... SELECT)。

  • 隐式提交事务的语句(如 CREATE TEMPORARY TABLE)。

(2) 报错示例

若执行以下语句(不兼容 GTID):

sql
复制
CREATE TABLE my_table SELECT * FROM other_table;

MySQL 会抛出错误:

 
复制
Error 1786: Statement violates GTID consistency.

4. 为什么需要强制 GTID 一致性?

  • 数据一致性:确保所有事务都能被正确追踪和复制。

  • 避免隐式风险:防止开发者意外使用与 GTID 不兼容的语句,导致复制中断或数据不一致。

  • 简化运维:强制规范事务行为,降低主从同步的维护成本。


5. 如何查看 GTID?

(1) 查看当前 GTID

sql
复制
SHOW MASTER STATUS;

输出示例:

 
复制
+------------------+----------+--------------+------------------+----------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000003 |      187 |              |                  | server_uuid:1-10                      |
+------------------+----------+--------------+------------------+----------------------------------------+

(2) 查看已执行的事务 GTID

sql
复制
SELECT @@GLOBAL.gtid_executed;

6. 实际应用场景

(1) 主从切换

当主库故障时,只需根据从库的 Executed_Gtid_Set 选择最新的从库提升为主库,无需关心二进制日志位置。

(2) 数据恢复

通过 GTID 可以精准定位需要重放的事务,避免重复执行或遗漏。


7. 注意事项

  • 存储引擎:建议使用 InnoDB 等事务性存储引擎。

  • 版本兼容性:GTID 在 MySQL 5.6+ 中支持,但不同版本行为可能略有差异。

  • 参数依赖:启用 GTID 需同时设置 gtid-mode=ON 和 enforce-gtid-consistency=ON


总结

  • GTID 是全局事务的唯一标识符,用于简化复制和故障恢复。

  • --enforce-gtid-consistency=ON 确保所有操作与 GTID 兼容,避免潜在的数据不一致风险。

  • 在 GTID 模式下,需遵循事务性操作规范,避免使用不兼容的 SQL 语句。

 

 

 

 

posted on 2025-03-22 19:20  輪滑少年  阅读(38)  评论(0)    收藏  举报