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):
CREATE TABLE my_table SELECT * FROM other_table;
MySQL 会抛出错误:
Error 1786: Statement violates GTID consistency.
4. 为什么需要强制 GTID 一致性?
-
数据一致性:确保所有事务都能被正确追踪和复制。
-
避免隐式风险:防止开发者意外使用与 GTID 不兼容的语句,导致复制中断或数据不一致。
-
简化运维:强制规范事务行为,降低主从同步的维护成本。
5. 如何查看 GTID?
(1) 查看当前 GTID
SHOW MASTER STATUS;
输出示例:
+------------------+----------+--------------+------------------+----------------------------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+----------------------------------------+ | mysql-bin.000003 | 187 | | | server_uuid:1-10 | +------------------+----------+--------------+------------------+----------------------------------------+
(2) 查看已执行的事务 GTID
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 语句。
浙公网安备 33010602011771号