概念介绍说明:
GTID(global transaction id)是对于一个已提交事务的唯一编号,并且是一个全局唯一编号(主从复制过程);
是数据库5.6版本开始的一个功能新特性,主要是用于解决主从复制的一致性问题;
复制原理机制:
- master节点在更新数据的时候,会在事务前产生GTID信息,一同记录到binlog日志中;
- slave节点的io线程将主库推送的binlog写入到本地relay log中;
- 然后SQL线程从relay log中读取GTID,设置gtid_next的值为该gtid,然后对比slave端的binlog是否有记录;
- 如果有记录的话,说明该GTID的事务已经运行,slave会忽略;
- 如果没有记录的话,slave就会执行该GTID对应的事务,并记录到binlog中。

功能应用实践:
① 主从复制GTID功能实现环境:
为了实现GTID机制的主从复制,需要准备好主从架构环境:
| 主机角色 | 主机名称 | 地址信息 |
|---|---|---|
| 主库服务器 | db-01 | 192.168.10.101 |
| 从库服务器 | db-02 | 192.168.10.102 |
| 从库服务器 | db-03 | 192.168.10.103 |
对原有数据库服务环境清理:
# 在所有主从节点均进行清理操作:
[root@master ~]# pkill mysqld
[root@master ~]# rm -rf /data/3306/*
[root@master ~]# rm -rf /data/binlog/*
[root@master ~]# mv /etc/my.cnf /tmp
[root@master ~]# mkdir -p /data/3306/data /data/binlog
[root@master ~]# chown -R mysql.mysql /data/*
-- 所有数据库主从节点均进行以上清理操作;
② 主从复制GTID功能配置编写
# 配置参数信息
gtid-mode=on
-- 启用gtid复制方式,默认采用传统的复制方式
enforce-gtid-consistency=true
-- 开启gtid所有节点的强制一致性
log-slave-updates=1
-- 定义slave更新是否记入二进制日志,从而增强数据一致性,是在高可用架构中重要配置环节
# 主库db01配置文件编写
cat >/etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=51
port=3306
secure-file-priv=/tmp
autocommit=0
log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db01 [\\d]>
EOF
# 主库db02配置文件编写
cat >/etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=52
port=3306
secure-file-priv=/tmp
#autocommit=0
log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db02 [\\d]>
EOF
# 主库db03配置文件编写
cat >/etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=53
port=3306
secure-file-priv=/tmp
#autocommit=0
log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db03 [\\d]>
EOF
# 进行数据库所有节点初始化操作
[root@master ~]# mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/3306/data
[root@master-02 ~]# mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/3306/data
[root@master-03 ~]# mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/3306/data
# 启动数据库所有节点服务
[root@master ~]# /etc/init.d/mysqld start
[root@master-02 ~]# /etc/init.d/mysqld start
[root@master-03 ~]# /etc/init.d/mysqld start
③ 主从复制GTID配置重构主从
# 重构主从关系-主库操作
db01 [(none)]>create user repl@'192.168.30.%' identified with mysql_native_password by '123456';
Query OK, 0 rows affected (0.01 sec)
db01 [(none)]>grant replication slave on *.* to repl@'192.168.30.%';
Query OK, 0 rows affected (0.00 sec)
-- 主库上创建主从复制用户信息
# 重构主从关系-从库操作
db02 [(none)]>change master to
master_host='192.168.30.101',
master_user='repl',
master_password='123456',
master_auto_position=1;
-- 表示让从库自己找寻复制同步数据的起点;
-- 在第一次启动gtid功能时,会读取从库中的binlog日志信息,根据主库uuid信息,获取从库中执行过的主库gtid信息
-- 从从库中没有执行过的主库gtid信息之后进行进行数据同步操作
db02 [(none)]> start slave;
-- 其他从库一并操作
知识扩展:实现自动获取同步位置点
主从同步获取主库的gtid信息,获取同步位置点,并且不断更新位置点:
db01 [(none)]>show master status;
+-----------------------+-----------+-------------------+-----------------------+-------------------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------------+-----------+-------------------+-----------------------+-------------------------------------------------------+
| mysql-bin.000002 | 681 | | | 3cfa5898-771a-11ed-b8d7-000c2996c4f5:1-2 |
+-----------------------+-----------+-------------------+-----------------------+-------------------------------------------------------+
1 row in set (0.00 sec)
-- 主库查看状态信息,获取gtid同步信息,gtid信息将会存储的位置:binlog、relaylog、master-info(uuid)
db02 [(none)]>show master status;
+-----------------------+-----------+-------------------+-----------------------+-------------------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------------+-----------+-------------------+-----------------------+-------------------------------------------------------+
| mysql-bin.000002 | 695 | | | 3cfa5898-771a-11ed-b8d7-000c2996c4f5:1-2 |
+-----------------------+-----------+-------------------+-----------------------+-------------------------------------------------------+
1 row in set (0.00 sec)
db03 [(none)]>show master status;
+-----------------------+-----------+-------------------+-----------------------+-------------------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------------+-----------+-------------------+-----------------------+-------------------------------------------------------+
| mysql-bin.000002 | 695 | | | 3cfa5898-771a-11ed-b8d7-000c2996c4f5:1-2 |
+-----------------------+-----------+-------------------+-----------------------+-------------------------------------------------------+
1 row in set (0.00 sec)
-- 从库查看状态信息,获取gtid同步信息;gtid信息将会存储的位置:binlog、relaylog、master-info(uuid)
-- show binlog events in 'mysql-bin.000002' 获取从库自己的binlog信息,得到gitd同步的位置点;
知识扩展:进行全备恢复数据时不要加 set-gtid-purged参数
如果是已经运行很久的数据库,需要构建主从,都是需要备份恢复主库数据后,再开启实现主从功能的;
在mysqldump进行备份数据时,不要加set-gtid-purged参数,否则会造成从库依旧从第一个gtid信息开始同步数据;
造成主从同步数据信息冲突,影响主从构建过程,导致主从同步过程失败;
# 未加set-gtid-purged参数实现的数据备份效果
[root@master ~]# mysqldump -A --master-data=2 --single-transaction >/tmp/full.sql
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events.
[root@master ~]# vim /tmp/full.sql
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '3cfa5898-771a-11ed-b8d7-000c2996c4f5:1-2';
-- 表示让从库删除1-2的集合信息,即通过备份文件已经恢复了1-2的数据,可以从1-2之后进行数据信息同步;
# 已加set-gtid-purged参数实现的数据备份效果
[root@master ~]# mysqldump -A --master-data=2 --single-transaction --set-gtid-purged=OFF >/tmp/full02.sql
[root@master ~]# vim /tmp/full.sql
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '3cfa5898-771a-11ed-b8d7-000c2996c4f5:1-2';
SET SQL_LOG_BIN=0;
-- 以上信息不会出现在备份文件中
-- 表示会让从库把备份文件中的操作语句,再次根据gtid请求执行一遍,容易产生异常冲突问题;