基于二进制包最小化安装,GTID 主从复制架构
- 主库:192.168.195.141
- 从库:192.168.195.142
1. 环境信息
| 项目 | 主库 (Master) | 从库 (Slave) |
|---|---|---|
| IP | 192.168.195.141 | 192.168.195.142 |
| MySQL版本 | 8.0.35(二进制包,glibc2.17) | 8.0.35(二进制包,glibc2.17) |
| server-id | 1 | 2 |
| gtid_mode | ON | ON |
| 角色 | Master | Slave |
2. 安装 MySQL(两台均执行)
2.1 创建用户与组
bash
groupadd mysql
useradd -g mysql mysql
2.2 解压二进制包
bash
cd /usr/local/
wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.35-linux-glibc2.17-x86_64.tar.xz
tar xvf mysql-8.0.35-linux-glibc2.17-x86_64.tar.xz
ln -s mysql-8.0.35-linux-glibc2.17-x86_64 mysql
验证:
bash
/usr/local/mysql/bin/mysql --version
# /usr/local/mysql/bin/mysql Ver 8.0.35 for Linux on x86_64 (MySQL Community Server - GPL)
2.3 创建数据目录
bash
mkdir -p /data/mysql/3306/data
chown mysql.mysql /data/mysql/3306/data/
3. 编辑配置文件
3.1 主库 /etc/my.cnf(141)
ini
[client]
socket = /data/mysql/3306/data/mysql.sock
[mysqld]
basedir = /usr/local/mysql
datadir = /data/mysql/3306/data
user = mysql
port = 3306
socket = /data/mysql/3306/data/mysql.sock
log_error = /data/mysql/3306/data/mysqld.err
log_timestamps = system
log-bin = mysql-bin
server-id = 1
gtid_mode = ON
enforce_gtid_consistency = ON
参数解释:
log-bin = mysql-bin:开启 binlog,主库必须开启。server-id = 1:服务器唯一标识,主从环境中每个实例必须不同。gtid_mode = ON:开启 GTID 复制。GTID(Global Transaction Identifier)为每个事务分配全局唯一ID,格式为source_id:transaction_id,其中 source_id 是实例的 server_uuid,transaction_id 是事务序列号。enforce_gtid_consistency = ON:强制 GTID 一致性,只允许事务安全的语句执行。如果要将 gtid_mode 设置为 ON,则此参数必须为 ON。
3.2 从库 /etc/my.cnf(142)
ini
[client]
socket = /data/mysql/3306/data/mysql.sock
[mysqld]
basedir = /usr/local/mysql
datadir = /data/mysql/3306/data
user = mysql
port = 3306
socket = /data/mysql/3306/data/mysql.sock
log_error = /data/mysql/3306/data/mysqld.err
log_timestamps = system
server-id = 2
gtid_mode = ON
enforce_gtid_consistency = ON
与主库的区别:
server-id = 2:从库的 server-id 必须与主库不同。- 从库不需要显式配置
log-bin,MySQL 8.0 默认开启 binlog。
4. 初始化实例(两台均执行)
bash
/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --initialize
获取临时密码:
bash
grep "temporary password" /data/mysql/3306/data/mysqld.err
# 主库:A temporary password is generated for root@localhost: .saCq4xRHi_T
# 从库:A temporary password is generated for root@localhost: W+CeE>Vdl4v_
5. 配置 systemd 服务(两台均执行)
5.1 创建 /etc/systemd/system/mysqld.service
ini
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
Type=forking
PIDFile=/data/mysql/3306/data/mysqld.pid
TimeoutSec=0
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --pid-file=/data/mysql/3306/data/mysqld.pid --daemonize $MYSQLD_OPTS
EnvironmentFile=-/etc/sysconfig/mysql
LimitNOFILE = 65535
Restart=on-failure
RestartPreventExitStatus=1
PrivateTmp=false
5.2 创建 /etc/sysconfig/mysql
ini
MYSQLD_OPTS=
6. 启动实例(两台均执行)
bash
systemctl daemon-reload
systemctl start mysqld
systemctl enable mysqld
7. 修改 root 密码(两台均执行)
bash
/usr/local/mysql/bin/mysql -uroot -S /data/mysql/3306/data/mysql.sock -p
sql
alter user user() identified by 'Root@123456';
8. 搭建 GTID 主从复制
8.1 主库创建复制用户
sql
-- 在主库(141)执行
CREATE USER 'repl'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
8.2 从库建立 GTID 复制
sql
-- 在从库(142)执行
CHANGE MASTER TO
MASTER_HOST='192.168.195.141',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_AUTO_POSITION=1,
GET_MASTER_PUBLIC_KEY=1;
START SLAVE;
参数解释:
MASTER_AUTO_POSITION=1:使用 GTID 自动定位,无需手动指定MASTER_LOG_FILE和MASTER_LOG_POS。从库 IO 线程连接主库时,会自动交换 GTID 信息,从库告诉主库自己已执行了哪些事务,主库只发送缺失的事务。
GET_MASTER_PUBLIC_KEY=1:MySQL 8.0 默认使用 caching_sha2_password 认证插件,非 SSL 连接时需获取主库公钥完成认证。
GTID 复制 vs 位置点复制的区别:位置点复制:需要先在主库 mysqldump 备份(
--master-data=2),scp 到从库恢复,再根据备份中的CHANGE MASTER TO MASTER_LOG_FILE=..., MASTER_LOG_POS=...建立复制。GTID 复制:无需备份恢复,直接用
MASTER_AUTO_POSITION=1建立复制,从库自动获取缺失的事务。简化了配置过程。
8.3 验证主从状态
sql
-- 在从库(142)执行
show slave status\G
Slave_IO_State: Waiting for source to send event
Master_Host: 192.168.195.141
Master_User: repl
Master_Port: 3306
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 1025
Relay_Log_File: MYSQL142-relay-bin.000002
Relay_Log_Pos: 1241
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Exec_Master_Log_Pos: 1025
Seconds_Behind_Master: 0
Master_Server_Id: 1
Master_UUID: 0e5d8ecd-8376-11f1-81e9-000c29048d1f
Retrieved_Gtid_Set: 0e5d8ecd-8376-11f1-81e9-000c29048d1f:1-3
Executed_Gtid_Set: 0e5d8ecd-8376-11f1-81e9-000c29048d1f:1-3,
1a860de9-8376-11f1-9808-000c29a59955:1
Auto_Position: 1
Get_master_public_key: 1
重点关注:
Slave_IO_Running: Yes和Slave_SQL_Running: Yes,两个均为 Yes 代表主从复制搭建成功。Auto_Position: 1,表示使用 GTID 自动定位。Retrieved_Gtid_Set:已从主库获取的 GTID 事务集。Executed_Gtid_Set:已执行的 GTID 事务集。
9. 验证主从复制
9.1 主库 show processlist
sql
-- 在主库(141)执行
show processlist;
+----+-----------------+---------------------+------+-------------+--------+--------------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-----------------+---------------------+------+-------------+--------+--------------------------------------------------+------------------+
| 5 | event_scheduler | localhost | NULL | Daemon | 147 | Waiting on empty queue | NULL |
| 11 | repl | 192.168.195.142:60596 | NULL | Binlog Dump GTID | 53 | Source has sent all binlog to replica; waiting for more updates | NULL |
| 13 | root | localhost | NULL | Query | 0 | init | show processlist |
+----+-----------------+---------------------+------+-------------+--------+--------------------------------------------------+------------------+
注意 :GTID 复制下,主库的 Binlog Dump 线程显示为 Binlog Dump GTID ,与位置点复制的 Binlog Dump 不同。
9.2 从库 show processlist
sql
-- 在从库(142)执行
show processlist;
+----+-------------+-----------------+------+---------+--------+--------------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-------------+-----------------+------+---------+--------+--------------------------------------------------+------------------+
| 5 | event_scheduler | localhost | NULL | Daemon | 147 | Waiting on empty queue | NULL |
| 10 | system user | connecting host | NULL | Connect | 70 | Waiting for source to send event | NULL |
| 11 | system user | | NULL | Query | 38 | Replica has read all relay log; waiting for more updates | NULL |
| 12 | system user | | NULL | Query | 38 | Waiting for an event from Coordinator | NULL |
| 13 | system user | | NULL | Connect | 70 | Waiting for an event from Coordinator | NULL |
| 14 | system user | | NULL | Connect | 70 | Waiting for an event from Coordinator | NULL |
| 15 | system user | | NULL | Connect | 70 | Waiting for an event from Coordinator | NULL |
| 18 | root | localhost | NULL | Query | 0 | init | show processlist |
+----+-------------+-----------------+------+---------+--------+--------------------------------------------------+------------------+
- 10 是 IO 线程(Waiting for source to send event)
- 11 是 协调线程(Replica has read all relay log; waiting for more updates)
- 12-15 是 SQL 工作线程(Waiting for an event from Coordinator)
9.3 数据同步测试
主库写入测试数据:
sql
-- 在主库(141)执行
CREATE DATABASE test_gtid;
USE test_gtid;
CREATE TABLE t1 (id INT PRIMARY KEY, name VARCHAR(20));
INSERT INTO t1 VALUES (1,'gtid_data');
SELECT * FROM t1;
-- +----+-----------+
-- | id | name |
-- +----+-----------+
-- | 1 | gtid_data |
-- +----+-----------+
从库查询验证:
sql
-- 在从库(142)执行
SELECT * FROM test_gtid.t1;
-- +----+-----------+
-- | id | name |
-- +----+-----------+
-- | 1 | gtid_data |
-- +----+-----------+
数据一致,GTID 主从复制工作正常。
10. GTID 相关参数确认
10.1 主库(141)
gtid_mode = ON
enforce_gtid_consistency = ON
gtid_executed = 0e5d8ecd-8376-11f1-81e9-000c29048d1f:1-6
gtid_next = AUTOMATIC
gtid_purged =
10.2 从库(142)
gtid_mode = ON
enforce_gtid_consistency = ON
gtid_executed = 0e5d8ecd-8376-11f1-81e9-000c29048d1f:1-6,
1a860de9-8376-11f1-9808-000c29a59955:1
gtid_next = AUTOMATIC
gtid_purged =
说明:
- 从库的
gtid_executed包含两个 UUID 的事务:主库的0e5d8ecd-8376-11f1-81e9-000c29048d1f:1-6(通过复制获取)和从库自身的1a860de9-8376-11f1-9808-000c29a59955:1(本地事务)。gtid_next = AUTOMATIC:自动获取下一个 GTID 值,默认值。
11. 连接信息
bash
# 主库(141)
/usr/local/mysql/bin/mysql -uroot -S /data/mysql/3306/data/mysql.sock -p'Root@123456'
# 从库(142)
/usr/local/mysql/bin/mysql -uroot -S /data/mysql/3306/data/mysql.sock -p'Root@123456'
12. GTID 复制的限制
- 不支持
CREATE TABLE ... SELECT ...语句。从 MySQL 8.0.21 开始,该限制被取消。 - 不允许在事务、存储过程、函数、触发器中执行
CREATE TEMPORARY TABLE或DROP TEMPORARY TABLE操作。从 MySQL 8.0.13 开始,如果 binlog 格式为 ROW 或 MIXED,该限制被取消。 - 不能将 InnoDB 表和非 InnoDB 表放到一个事务内操作。