简介
GTID工作原理简单介绍
1.master更新数据的时候,会在事务前产生GTID,一同记录到binlog日志中。
2.slave端的io线程将binlog写入到本地relay log中。
3.然后SQL线程从relay log中读取GTID,设置gtid_next的值为该gtid,然后对比slave端的binlog是否有记录
4.如果有记录的话,说明该GTID的事务已经运行,slave会忽略
5.如果没有记录的话,slave就会执行该GTID对应的事务,并记录到binlog中
GTID工作原理深入理解
gtid在master和slave上持久化保存,即使删除了日志,也会记录到previous_gtid中。
1.binlog文件中记录的格式是先记录gtid,然后再记录事务相关的操作。
2.gtid_next 是基于会话的,不同会话的gtid_next不同。
3.如果mysql是5.6版本,那么主从必须开启log_slave_updates参数,此时slave对比自己的binlog查看是否有记录。如果mysql是5.7版本,那么主从不需要开启此参数(级联主从除外),mysql5.7提供了gtid_excuted系统表来记录复制的信息,以此减少从库的压力。
GTID模式的主从配置介绍
主从服务同时开启gtid模式
从MySQL 5.6.5 开始新增了一种基于 GTID 的复制方式。通过 GTID 保证了每个在主库上提交的事务在集群中有一个唯一的ID。这种方式强化了数据库的主备一致性,故障恢复以及容错能力。
GTID (Global Transaction ID)是全局事务ID,当在主库上提交事务或者被从库应用时,可以定位和追踪每一个事务,对DBA来说意义就很大了,我们可以适当的解放出来,不用手工去可以找偏移量的值了,而是通过CHANGE MASTER TO MASTER_HOST='xxx', MASTER_AUTO_POSITION=1的即可方便的搭建从库,在故障修复中也可以采用MASTER_AUTO_POSITION=‘X’的方式。
可能大多数人第一次听到GTID的时候会感觉有些突兀,但是从架构设计的角度,GTID是一种很好的分布式ID实践方式,通常来说,分布式ID有两个基本要求:
1)全局唯一性
2)趋势递增
这个ID因为是全局唯一,所以在分布式环境中很容易识别,因为趋势递增,所以ID是具有相应的趋势规律,在必要的时候方便进行顺序提取,行业内适用较多的是基于Twitter的ID生成算法snowflake,所以换一个角度来理解GTID,其实是一种优雅的分布式设计。
如何开启GTID?
如何开启GTID呢,我们先来说下基础的内容,然后逐步深入,通常来说,需要在my.cnf中配置如下的几个参数:
-
server_id=1
-
log-bin
-
gtid_mode=ON
-
enforce_gtid_consistency=1
部署
修改配置文件
主节点编辑配置文件,添加参数:
[root@localhost tmp]# vim /etc/my.cnf
[mysqld]
log_bin
server_id=1
gtid_mode=ON
enforce_gtid_consistency=1
[root@localhost tmp]# systemctl restart mysqld # 重启mysql生效
从节点编辑配置文件,添加参数:
[root@localhost tmp]# vim /etc/my.cnf # 编辑配置文件
[mysqld]
# log_bin # 从服务器log_bin可开可不开,不影响复制功能
server_id=2 # 注意id的唯一性
gtid_mode=ON
enforce_gtid_consistency=1
[root@localhost tmp]# systemctl restart mysqld # 重启mysql生效
配置用户
主节点配置rep用户:
grant replication slave,replication client on *.* to 'rep'@'%'; # mysql5和8的用户创建命令不同,此处注意。
设置从服务器主从关系
从节点上进行操作:
#二进制文件位置由master_auto_position=1参数自动确定
mysql> change master to master_host='192.168.137.100',master_user='rep',master_password='test@A123456',master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.00 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.137.100
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: localhost-bin.000003
Read_Master_Log_Pos: 154
Relay_Log_File: localhost-relay-bin.000002
Relay_Log_Pos: 375
Relay_Master_Log_File: localhost-bin.000003
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: 154
Relay_Log_Space: 586
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: d4194c0e-35e2-11eb-a021-000c291c0d9f
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave 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:
Executed_Gtid_Set:
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
到此MySQL主从模式已经配置完成。
注意:
在从库上执行 show slave statusG
显示报错:
Last_IO_Error: error connecting to master 'rep@127.0.0.1:3316' - retry-time: 60 retries: 2 message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
考虑到我的MySQL8 ,
查看主库:
SELECT plugin FROM user
where user = 'rep';
原来是主库rep的plugin是caching_sha2_password 导致连接不上,修改为mysql_native_password即可解决。
ALTER USER 'rep'@'%' IDENTIFIED WITH mysql_native_password BY 'root';