通过这篇文章了解GTID和MySQL
要谈GTID,我们先了解一下MySQL主从复制。
为什么需要Mysql主从复制
我们来说一下为什么大多数情况下Mysql经常采用Mysql主从模式部署。主要原因如下:
- 对数据进行热备份,当主库宕机时,备份数据库可以及时替代主库,保证业务可用性,一定程度上防止数据丢失。
- 实现读写分离,写入主库,从库读取,减轻主库的读写压力。当主库进行写过程并被锁定时,从库的读操作不会被阻塞,提高了数据查询的效率。
- 应对业务量不断增加、I/O访问频率高单机无法满足的问题。添加多个从库来执行加载可以降低整体I/O访问频率,提高单机I/O性能。
数据库中常用的主从复制方式
基于Binlog复制模型
MySQL主从复制默认是异步的。 MySQL所有的增删改查都记录在Binlog中。 Slave节点连接Master时,主动接收Master发送的最新的Binlog文件。并将Binlog保存到本地relay log中,然后执行relay log更新的内容。站点同步的原理如下:
1、主库会生成几个binlog日志文件。
2、 请求库 I/O 线程指定位置的 binlog 日志文件(站点)中的指定文件。
3、主库dump线程从指定位置获取binlog日志。
4、主库根据从库发来的位置信息读取binlog,然后打印binlog到从库。
5、从库将接收到的binlog写入本地中继日志(relay-log)文件。
6、 从库的 SQL 线程读取并解析中继日志文件。
7、从库的 SQL 线程重播中继日志中的命令。
如果使用站点同步,两种场景下的操作步骤都比较复杂。
有痛点
痛点一:首次开启主从复制步骤复杂,必须一致。
痛点二:恢复主从复制步骤复杂
- 找到从复制线程停止的点。
- 解决复制异常中的事务。如果无法解决,则必须手动跳过指定类型的错误,例如通过设置slave_skip_errors = 1032,1062。当然,这个假设是跳过这样的错误是没有损失的。 (1062错误是插入数据时唯一键冲突;1032错误是删除数据时找不到该行)
GTID复制模式
针对基于Binlog复制模式解决的痛点,一个新的该模式是MySQL 5.6中提供的数据恢复思想,这就是基于GTID的复制模式。 MySQL可以通过内部机制GTID自动寻找同步点,并且通过GTID可以保证主库提出的每个事务在集群中都有唯一的事务ID,这就加强了数据库主从的一致性和容错性。错误恢复数据。如果主库宕机,发生主从切换,GTID方法可以让其他从库自动找到新主库的副本位置。此外,GTID可以忽略已经执行的事务,从而减少数据错误的可能性。 GTID同步的原理如下:
- 主节点在遇到交易之前会生成一个
GTID
,记录在❿❙❙❙❿❙❿❙交易中。 - 从节点
I/O线程
读取主节点binlog❿❿ ❿❿它在从属文件中。中继日志
在日志中。从节点配置主节点的GTID
的值和gtid_next
,这是下一个要读取的GTID值。 - 从节点SQL线程从中继日志中读取
gtid_next
中的值,然后查找自己的binlog GTID 。
- 如果有这条记录,则表示
GTID
的交易已被执行,将被忽略。 - 如果没有这样的记录,则从节点从中继日志中执行GTID的事务,并将其记录在自己的
binlog
日志中。同时,在读取和执行交易之前,首先检查其他session
是否持有GTID
,确保不重复。
GTID相关概念介绍
什么是GTID
GTID
指的是全局事务ID,全称是❀全局事务有以下特点: GTID交易全局唯一,一笔交易对应一个GTID值。
GTID 由 server_uuid
+ tid❙ 组成,其中: ❿
随机值。生成后,该值存储在数据目录下的server_uuid
是MySQL第一次启动时自动生成的(128位) auto.cnf
文件中。
组合风格如下:
26630fed-fe68-11ec-b051-000c29509871:1-27
GTID相对于传统复制的优势
- 主从设置更简单,无需手动指定位置。
- 复制集群具有统一的标识,更易于识别和管理。
- 故障转移更容易。不需要像传统复制那样找到log_file和log_position的位置。
- 通常情况下,GTID是连续的,没有空洞,可以更好地保证数据的一致性。
- 相比ROW复制模式,数据安全性更高,切换更容易。
- 它比传统复制更安全。 GTID在MySQL实例上只执行一次,避免重复执行导致数据混乱或主从不一致。
GTID 使用限制
GTID 复制适用于事务。一笔交易只对应一个GTID。这里有很多限制。主要限制如下:
- 在复制组中,必须打开或关闭GTID。
- 需要重新启动才能启用 GTID(5.7 除外)
- 不支持
创建表 table_name select * from table_name
语句副本。
原理:
会生成两条sql,一条是DDL建表SQL,一条是insert和插入数据的sql。因为 DDL 会导致自动提交,所以这条 sql 至少需要两个 GTID,但 GTID 模式下这条 sql 只能生成一个 GTID)
- 不允许在一个事务中包含两个事务表(使用
InnoDB
存储引擎表)的操作还包括非事务性表(与MyISAM
存储引擎表)。 - 不支持创建或删除临时表操作,例如
CREATE TEMPORARY TABLE或DROP TEMPORARY TABLE
语句操作。 - 使用GTID复制从库中跳过错误时,不支持参数
sql_slave_skip_counter
的语法。传统复制可以使用此命令来跳过事务。
如何开启GTID模式
主要在Mysql配置文件中添加以下2个配置:
#开启 gtid 模式
gtid_mode=on
#配置不允许任何事务违反 GTID 一致性,用于保证数据一致性
enforce_gtid_consistency=on
从库配置同步参数:使用协议_ID_position的主从关系。与之前的 Binlog 复制方式相比,Binlog 的 POS 站点改为 Master_Auto_position = 1
自动获取 Binlog POS 站点的配置。 MySQL服务重启或启动时2秒。
如何确定复制方法是 GTID 还是 pos
显示从站状态 检查 Auto_Position 字段。 0为Pos模式,1为Gtid模式。
mysql> show slave status\G;
Auto_Position: 1
gtid 改为 pos 模式:
change master to master_auto_position=0;
当前执行 gtid 信息
mysql> SELECT @@GLOBAL.GTID_EXECUTED;
+-------------------------------------------------------------------------------------+
| @@GLOBAL.GTID_EXECUTED |
+-------------------------------------------------------------------------------------+
| 26630fed-fe68-11ec-b051-000c29509871:1-31,
bf480f97-fe64-11ec-9b9d-000c29af7696:1-3 |
+-------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM mysql.gtid_executed;
+--------------------------------------+----------------+--------------+
| source_uuid | interval_start | interval_end |
+--------------------------------------+----------------+--------------+
| 26630fed-fe68-11ec-b051-000c29509871 | 1 | 29 |
| 26630fed-fe68-11ec-b051-000c29509871 | 30 | 30 |
| bf480f97-fe64-11ec-9b9d-000c29af7696 | 1 | 1 |
+--------------------------------------+----------------+--------------+
mysql.gtid_execulated 表由 MySQL 服务器提供,供内部使用。当在副本上禁用二进制日志记录时,它允许副本使用 GTID,并允许在二进制日志记录丢失时保留 GTID 状态。 RESET MASTER命令,gtid_executed表被删除。
如果服务意外停止,则当前二进制日志文件中的gtid不会存储在gtid_executed表中。在恢复期间,这些 GTID 将添加到二进制日志文件表中,以便复制可以继续。
关于 gtid_execulated 表
当 MySQL 服务器启用二进制日志记录时,仅在二进制轮转期间更新 mysql.gtid_execulated 表。因为在重启等情况下,仍然可以通过扫描二进制日志来确定当前运行的GTID位置。 。
简单来说,这个表会记录当前执行的GTID。 MySQL 5.6中必须配置log_slave_updates参数的最重要原因是slave重启后,无法知道当前slave运行的GTID位置,因为变量gtid_execulated是一个内存值:MySQL 5.7使得gtid_execulated 值是持久的。使用的技术与MySQL 5.6处理SQL线程存储位置的方式相同,这意味着GTID值被持久化在InnoDB表中并与用户事务一起提交以实现数据一致性。触发条件:
- 如果binlog轮转(flush binlog_logs/达到max_binlog_size)或者服务关闭,所有写入binlog的Gtid信息都会写入到mysql.gtid_executed表中。
- 从库:如果没有启用log_bin或者没有启用log_slave_updates,则从库会对应用中继日志中的每个事务执行一次mysql.gtid_execulated操作。
简单分析GTID同步状态
除了传统的binlog和pos值查看之外,GTID模式可以更直观地看到特定事务的执行情况。
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.77.135
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-binlog.000043
Read_Master_Log_Pos: 666
Relay_Log_File: gtidb-relay-bin.000002
Relay_Log_Pos: 585
Relay_Master_Log_File: master-binlog.000043
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: 666
Relay_Log_Space: 792
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: 100
Master_UUID: 26630fed-fe68-11ec-b051-000c29509871
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: 26630fed-fe68-11ec-b051-000c29509871:32
Executed_Gtid_Set: 26630fed-fe68-11ec-b051-000c29509871:1-32,
bf480f97-fe64-11ec-9b9d-000c29af7696:1-3
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
- GTID相关的密钥参数描述
参数名称 | 缩写简介 |
---|---|
retresded_gtid_set_set_gtids的主节点执行从属节点有 | |
Auto_Position | 自动维护position位置,显示为1 |
gtid skip gtid_next
stop slave;
set gtid_next='26630fed-fe68-11ec-b051-000c29509871:37'
begin;commit;
set gtid_next='automatic';
start slave;
注:此操作与sql_slave_skips数据一致性类似,不能保证数据一致性不会跳过。需要人工干预。强烈建议从Machinestarts开始read_only=1
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。