一、GTID的组成
MySQL的GTID
show global variables like '%gtid_purged%';
Variable_name | Value |
---|---|
gtid_purged | 1cba627b-199b-11f0-8e76-00163e0ab58b:1-77 |
MySQL的uuid
show global variables like 'server_uuid';
Variable_name | Value |
---|---|
server_uuid | 2018e1d4-1b57-11f0-8799-00163e1706db |
server_uuid
是 MySQL 数据库服务器在第一次初始化时生成的。这个 UUID(Universally Unique Identifier)是一个全局唯一的标识符,用于唯一标识 MySQL 数据库服务器实例。server_uuid
通常存储在 MySQL 数据目录下的 auto.cnf
文件中。
cat /data/mysql/data/auto.cnf
GTID 的格式如下:
UUID:sequence
1. UUID(Universally Unique Identifier)
-
UUID 是一个全局唯一的标识符,用于标识生成事务的 MySQL 服务器实例。
-
它是一个 128 位的值,通常以 32 个十六进制字符表示,分为 5 个部分,例如:
1cba627b-199b-11f0-8e76-00163e0ab58b
-
UUID 是在 MySQL 服务器启动时生成的,基于服务器的主机名、MAC 地址和时间戳等信息,确保全球唯一。
2. sequence(序列号)
-
sequence 是一个整数,表示在该服务器上执行的事务的顺序。
-
每个事务在提交时会被分配一个唯一的序列号,序列号从 1 开始递增。
-
例如:
1-77
表示从序列号 1 到 77 的事务。
show global variables like 'gtid_mode';
GTID(全局事务标识符)是 MySQL 5.6 及以后版本引入的一项功能,用于在复制过程中唯一标识事务。gtid_mode
参数用于确定是否启用 GTID 功能。以下是详细介绍:
参数取值及含义
-
OFF:禁用 GTID。服务器不会为事务生成 GTID,二进制日志以传统的文件名和位置的方式记录。
-
ON:启用 GTID。服务器会为每个事务生成唯一的 GTID,并将其记录在二进制日志中。复制基于 GTID 而非文件名和位置。
-
OFF_PERMISSIVE:GTID 被禁用,但允许 GTID 相关操作。通常在启用或禁用 GTID 时作为过渡状态,以确保兼容性。
-
ON_PERMISSIVE:GTID 被启用,但允许非 GTID 相关操作。类似于
OFF_PERMISSIVE
,在启用或禁用 GTID 过程中作为过渡状态,以确保稳定。
二、gtid_executed
gtid_executed
是一个全局系统变量,用于显示当前 MySQL 服务器上已执行的 GTID(全局事务 ID)集合。
show global variables like 'gtid_executed';
select * from mysql.gtid_executed;
三、enforce_gtid_consistency
在MySQL中,enforce_gtid_consistency
这个参数的作用是强制事务遵守GTID(全局事务标识符)规则,确保事务在GTID模式下的一致性和可跟踪性,防止因某些不安全操作导致主从复制数据不一致。当该参数设置为ON时,服务器会在执行事务时检查其是否符合GTID的一致性要求,若不符合则会报错。
以下是一个更详细的例子,展示 enforce_gtid_consistency
参数的作用:
示例
假设我们有一个 MySQL 主从复制环境,主库和从库都配置了 gtid_mode=ON
和 enforce_gtid_consistency=ON
。
在主库上,执行以下 SQL 语句:
SET GLOBAL enforce_gtid_consistency = ON;
然后创建两个表,一个使用 InnoDB 存储引擎,一个使用 MyISAM 存储引擎:
CREATE TABLE t1 (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(10)) ENGINE=InnoDB;
CREATE TABLE t2 (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(10)) ENGINE=myisam;
接下来,尝试在一个事务中对这两个表进行插入操作:
BEGIN;
INSERT INTO t1 (data) VALUES ('test');
INSERT INTO t2 (data) VALUES ('test');
COMMIT;
此时会报错:
Error: Statement violates GTID consistency: Updates to non-transactional tables can only be done in either autocommitted statements or single-statement transactions, and never in the same statement as updates to transactional tables.
在你的例子中,事务中同时更新了事务性表(InnoDB)和非事务性表(MyISAM),这违反了GTID一致性规则。
因为非事务性表的操作(如MyISAM)不能回滚,这可能导致GTID的不一致。如果事务中同时包含对事务性表和非事务性表的更新,那么在事务回滚时,事务性表的更新会被回滚,但非事务性表的更新不会回滚,从而导致主从数据不一致。
四、基于GTID复制的优势
- 可以知道事务在哪个实例上提交的
- 比较方便进行复制结构上的故障转移
- 很方便判断主从一致性
五、使用GTID的注意事项
- 事务和非事务引擎不能在同一个事务里
- 建议设置enforce_gtid_consistency为ON