文章目录
GTID模式实现MySQL 主从复制

GTID介绍
从mysql数据库从5.6.5开始新增一种基于GDIT的复制方式。通过GDIT保证每个主库上提交的事务在集群中有一个唯一的ID.这种方式强化了数据库的主备一致性,故障恢复以及容错能力。
GTID (Global Transaction ID) 在整个事务流程中每一个事务 ID 是全局唯一的,且在整个主从复制架构中该 ID 都不会相同。GTID 实际上 是由 UUID+TID 组成的。其中 UUID 是一个 MySQL 实例的唯一标识。TID 代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。
- server_uuid:server_uuid 是在 Mysql 首次启动过程中自动生成的一个uuid(128位) 随机值,生成后会将该值存储到数据目录的auto.cnf 中。因为是随机值,所以不同服务器的 Mysql 的server_uuid 都是不相同的。
- transaction_id(tid):代表了该实例上已经提交的事务数量,是一个整数,初始值是 1 ,每次提交事务的时候分配给这个事务并加1 。
- GTID是用来代替传统复制的方法,GTID复制与普通复制模式的最大不同就是不需要指定二进制文件名和位置。
搭建过程
1、开启数据库GTID
该步骤,主从数据库都要执行。
如果数据库已经在使用了,就按照下面的方式进行开启,首先先检查前置环境:
bash
# 前置检查
mysql> SHOW VARIABLES LIKE 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set (0.01 sec)
mysql> SHOW VARIABLES LIKE 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.00 sec)
mysql> SELECT trx_id, trx_started, trx_state FROM INFORMATION_SCHEMA.INNODB_TRX WHERE TIMESTAMPDIFF(SECOND, trx_started, NOW()) > 60;
Empty set (0.00 sec)
mysql> SELECT trx_id, trx_started, trx_state FROM INFORMATION_SCHEMA.INNODB_TRX WHERE TIMESTAMPDIFF(SECOND, trx_started, NOW()) > 30;
Empty set (0.00 sec)
mysql> SET GLOBAL enforce_gtid_consistency = WARN;
Query OK, 0 rows affected (0.00 sec)
mysql>
环境检查完成后,主数据库,开启数据库GTID:
bash
# 开启GTID
mysql> SET GLOBAL enforce_gtid_consistency = ON;
Query OK, 0 rows affected (0.00 sec)
mysql> SET GLOBAL gtid_mode = OFF_PERMISSIVE;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW STATUS LIKE 'Anonymous_gtid_transactions';
Empty set (0.00 sec)
mysql> SET GLOBAL gtid_mode = ON_PERMISSIVE;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW STATUS LIKE 'Anonymous_gtid_transactions';
Empty set (0.00 sec)
mysql> SET GLOBAL gtid_mode = ON;
Query OK, 0 rows affected (0.01 sec)
mysql> SHOW VARIABLES LIKE '%gtid%';
+----------------------------------+-------------------------------------------+
| Variable_name | Value |
+----------------------------------+-------------------------------------------+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed | ec7295d4-478e-11f0-97a3-e0008469f653:1-12 |
| gtid_executed_compression_period | 0 |
| gtid_mode | ON |
| gtid_next | AUTOMATIC |
| gtid_owned | |
| gtid_purged | |
| session_track_gtids | OFF |
+----------------------------------+-------------------------------------------+
9 rows in set (0.01 sec)
mysql> SELECT @@GLOBAL.gtid_executed;
+--------------------------------------------+
| @@GLOBAL.gtid_executed |
+--------------------------------------------+
| ec7295d4-478e-11f0-97a3-e0008469f653:1-141 |
+--------------------------------------------+
1 row in set (0.00 sec)
如果是初始的数据库,那么可以直接在配置文件里面编写配置:
bash
vim /etc/mysql/mysql.conf.d/mysqld.cnf
server_id = 1
enforce_gtid_consistency = ON
gtid_mode = ON
# 重启数据库即可
2、导出数据库表
使用备份脚本的方式,要在你的备份脚本中加入 GTID 相关标签,核心是添加 --set-gtid-purged=ON(或 AUTO)参数 ------ 这是 mysqldump 携带 GTID 信息的关键,同时保留原脚本中适配 GTID 的参数。
bash
# 增加--set-gtid-purged=ON参数
mysqldump -h"$MYSQL_HOST" -P"$MYSQL_PORT" -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" \
--all-databases \
--single-transaction \
--routines \
--triggers \
--events \
--source-data=2 \
--flush-logs \
--max-allowed-packet=512M \
--set-gtid-purged=ON \
> "$BACKUP_FILE" 2>> "$LOG_FILE"
数据库备份脚本参考以下文章:
https://blog.csdn.net/2401_83649605/article/details/154486622?spm=1001.2014.3001.5502
3、导入从数据库
使用上面的脚本的话,可以直接这样执行导入操作:
bash
# 输入数据库密码即可(tips:最好主从数据库密码一致,没别的意思就是方便)
$ gunzip < mysql_full_backup_20251105_105304.sql.gz | mysql -u root -p
4、开启主从配置
根据个人环境更改相应配置:
bash
RESET SLAVE ALL;
CHANGE MASTER TO
MASTER_HOST='192.168.119.1',
MASTER_PORT=3306,
MASTER_USER='repl', # 主从同步用户,自行创建
MASTER_PASSWORD='mysql_password', # repl用户密码
MASTER_CONNECT_RETRY=10,
MASTER_AUTO_POSITION=1; # id:1-xxx 冒号后面的数字
START SLAVE IO_THREAD;
START SLAVE SQL_THREAD;
验证主从配置:
bash
# 已经开启了主从同步
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 192.168.119.3
Master_User: repl
Master_Port: 12105
Connect_Retry: 10
Master_Log_File: binlog.000236
Read_Master_Log_Pos: 1258
Relay_Log_File: master-relay-bin.000002
Relay_Log_Pos: 596
Relay_Master_Log_File: binlog.000236
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1258
Relay_Log_Space: 969
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: e0674f87-4791-11f0-8c77-24a52cab5029
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: e0674f87-4791-11f0-8c77-24a52cab5029:5
Executed_Gtid_Set: e0674f87-4791-11f0-8c77-24a52cab5029:1-5
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set, 1 warning (0.00 sec)
# 接下来等待主从数据同步
# 当满足以下条件时,说明主从数据完全一致,同步进入稳定状态:
# Seconds_Behind_Master=0;
# 从库Executed_Gtid_Set = 主库gtid_executed;
# 主库执行测试事务(如INSERT/UPDATE),从库能实时同步(延迟≤1 秒)。
主从同步状态判断依据:
Master_Log_File 和 Read_Master_Log_Pos 这两个参数合起来表示的是读到的主库的最新位点,第一参数是代表读取到了哪个文件,第二个是读取到的文件的位置。
Relay_Master_Log_File 和 Exec_Master_Log_Pos,这两个参数合起来表示的是从库执行的最新位点。
如果红色框起来的两个参数:Master_Log_File 和 Relay_Master_Log_File 相等,则说明从库读到的最新文件和主库上生成的文件相同,这里都是 mysql-bin.000934。
如果蓝色框起来的两个参数 Read_Master_Log_Pos 和 Exec_Master_Log_Pos 相等,则说明从库读到的日志文件的位置和从库上执行日志文件的位置相同,这里都是 59521082。
当上面两组参数都相等时,则说明没有延迟。