1、GTID主从复制
1.1 GTID概念介绍
GTID即全局事务ID (global transaction identifier), 其保证为每一个在主上提交的事务在复制集群中可以生成一个唯一的ID。
官网:https://dev.mysql.com/doc/refman/5.7/en/replication-gtids-lifecycle.html
1.2 GTID的组成部分
前面是server_uuid:后面是一个序列号 UUID:每个mysql实例的唯一ID,由于会传递到slave,所以也可以理解为源ID。 Sequence number:在每台MySQL服务器上都是从1开始自增长的序列,一个数值对应一个事务。
1.3 GTID比传统复制的优势
- 更简单的实现failover,不用以前那样在需要找log_file和log_Pos。
- 更简单的搭建主从复制。
- 比传统复制更加安全。
- GTID是连续没有空洞的,因此主从库出现数据冲突时,可以用添加空事物的方式进行跳过。
- 多线程复制
1.4 GTID和Binlog的关系
- GTID在binlog中的结构
- GTID event 结构
- Previous_gtid_log_event Previous_gtid_log_event 在每个binlog 头部都会有每次binlog rotate的时候存储在binlog头部Previous-GTIDs在binlog中只会存储在这台机器上执行过的所有binlog,不包括手动设置gtid_purged值。换句话说,如果你手动set global gtid_purged=xx; 那么xx是不会记录在Previous_gtid_log_event中的。
1.5 GTID的工作原理
- master更新数据时,会在事务前产生GTID,一同记录到binlog日志中。
- slave端的i/o 线程将变更的binlog,写入到本地的relay log中。
- sql线程从relay log中获取GTID,然后对比slave端的binlog是否有记录。
- 如果有记录,说明该GTID的事务已经执行,slave会忽略。
- 如果没有记录,slave就会从relay log中执行该GTID的事务,并记录到binlog。
- 在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有就用全部扫描。
1.6GTID相关参数
参数 | comment |
---|---|
gtid_executed | 执行过的所有GTID |
gtid_purged | 丢弃掉的GTID |
gtid_mode | GTID模式 |
gtid_next | session级别的变量,下一个gtid |
gtid_owned | 正在运行的GTID |
enforce_gtid_consistency | 保证GTID安全的参数 |
1.7GTID主从复制配置
环境说明
数据库角色 | IP | 应用与系统版本 |
---|---|---|
主数据库 | 192.168.111.135 | centos8/redhat8 mysql-5.7 |
从数据库 | 192.168.111.138 | centos8/redhat8 mysql-5.7 |
1.7.1 主库配置
代码语言:javascript复制#在/etc/my.cnf文件中,添加以下配置,重启mysql
[root@localhost ~]# vim /etc/my.cnf
[mysqld]
log-bin=mysql_bin #开启二进制日志
server-id=1 #设置从库的唯一标识符,主库的server-id值必须小于从库的该值
gtid_mode=on #启动事务ID模式
enforce-gtid-consistency=true #强制GTID一致,不允许事务违反GTID一致性
log-slave-updates=on #告诉从库将主从复制语句也记录在binlog日志,从库需要开启binlog
#重启服务生效
[root@localhost ~]# systemctl restart mysqld
#主库授权复制用户
mysql> grant replication slave on *.* to 'zhao'@'%' identified by 'Passwd123!';
Query OK, 0 rows affected, 1 warning (0.00 sec)
1.7.2 从库配置
代码语言:javascript复制#在/etc/my.cnf文件中,添加以下配置,重启mysql
[root@localhost ~]# vim /etc/my.cnf
server-id=2
relay-log=myrelay
gtid_mode=on
enforce-gtid-consistency=true
log-slave-updates=on
read_only=on
master-info-repository=TABLE
relay-log-info-repository=TABLE
#重启服务生效
[root@localhost ~]# systemctl restart mysqld
#从库设置要同步的主库信息,并开启同步
mysql> change master to master_host='192.168.111.135',master_port=3306,master_user='zhao',master_password='Passwd123!',master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave statusG;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.111.135
Master_User: zhao
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql_bin.000001
Read_Master_Log_Pos: 437
Relay_Log_File: myrelay.000002
Relay_Log_Pos: 650
Relay_Master_Log_File: mysql_bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
......
1.7.3 测试验证
代码语言:javascript复制#主数据库
mysql> create database zhao;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
--------------------
| Database |
--------------------
| information_schema |
| mysql |
| performance_schema |
| sys |
| zhao |
--------------------
5 rows in set (0.00 sec)
#从数据库
mysql> show databases;
--------------------
| Database |
--------------------
| information_schema |
| mysql |
| performance_schema |
| sys |
| zhao |
--------------------
5 rows in set (0.00 sec)