MySQL 的 GTID (全局事务标识符)详细介绍

一、GTID的组成

MySQL的GTID

show global variables like '%gtid_purged%';
Variable_nameValue
gtid_purged1cba627b-199b-11f0-8e76-00163e0ab58b:1-77

 MySQL的uuid

show global variables like 'server_uuid';
Variable_nameValue
server_uuid2018e1d4-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=ONenforce_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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值