mysql数据库管理-GTID详解

news2024/9/22 13:22:31

一、GTID概述

1 sql线程执行的事件也可以通过log_slave_updates系统变量来决定是否写入自己的二进制文件中,这是可以用于级联复制的场景。
  GTID是MYSQL5.6新增的特性,GTID(Global Transaction Identifier)全称为全局事务标示符,用以数据库实例事务唯一标识,其组成主要是source_id和transaction_id 即GTID = source_id:transaction_id。其中source_id是数据库启动自动生成的数据库实例唯一标识,保存在auto.cnf中,而transaction_id则是事务执行的序列号。
二、GTID优缺点
  优点:
    复制安全性更高,一个事务在每个实例上只执行一次;
    故障切换简单,可通过设置MASTER_AUTO_POSITION=1,而非master_log_file和master_log_pos来建立主从关系;
    可根据GTID确定事务最早提交的实例;
  缺点:
    组复制中,必须要求统一开启GTID或者关闭GTID;
    不支持复制create table table_name select ... from table_name_xx ;
    不支持create temporary table和drop temporary table;
    不支持sql_slave_skip_counter,可通过set global gtid_next='' 跳过;
    从库和主库都必须设置log_slave_updates
三、GTID工作原理
  1、master更新数据时,会在事务前产生GTID,一同记录到binlog日志中。
  2、slave端的i/o 线程将变更的binlog,写入到本地的relay log中。
  3、sql线程从relay log中获取GTID,然后对比slave端的binlog是否有记录。
  4、如果有记录,说明该GTID的事务已经执行,slave会忽略。
  5、如果没有记录,slave就会从relay log中执行该GTID的事务,并记录到binlog。
  6、在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有就用全部扫描。
四、GTID开启和关闭
  gtid_mode=ON(必选)
  log_bin=ON(必选)
  log-slave-updates=ON(必选)
  enforce-gtid-consistency(必选)
  log-bin = /home/mysql/mysql-bin(必选)
  binlog_format = MIXED(必选mixed或者row)
  ##  
  change master to master_host = 'ipaddr',master_port = 3306,master_user = 'username',master_password='password',master_auto_position = 1;
五、GTID适用场景
  1、搭建高可用架构,方便主从切换后,新的从库重新指定主库(例如一主二从的结构,A为mater,B为Slave,C为Slave,A宕机切换到B后,C重新指定主库为B)
  2、不经常使用create table table_name select * from table_name/create temporary table/update t1,t2 where ...这种语句的场合
六、GTID相关参数

参数comment
gtid_executed执行过的所有GTID,可通过reset master重置
gtid_purged丢弃掉的GTID,设置后从而导致slave不会再去master请求这些GTIDs,并且Executed_Gtid_Set为空时,才可以设置此值
gtid_modegtid模式
gtid_nextsession级别的变量,下一个gtid
gtid_owned正在运行的gtid
enforce_gtid_consistency

1 什么事GTID

    全局事务标识符GTID的英文全称为Global Transaction Identifier,是在整个复制环境中对一个事务的唯一标识。它是MySQL 5.6加入的一个强大特性,目的在于能够实现主从自动定位和切换,而不像以前需要指定文件和位置。使用GTID复制时,在主库上提交事务时创建事务对应的GTID,从库在应用中继日志时用GTID识别和跟踪每个事务。在启动新从库或因故障转移到新主库时,可以使用GTID来标识复制的位置,极大地简化了这些任务。由于GTID的复制完全基于事务,因此只要在主库上提交的所有事务也在从库上提交,两者之间的一致性就能得到保证。GTID支持基于语句或基于行的复制格式,但为了获得最佳效果MySQL建议使用基于行的格式。GTID始终保留在主库和从库上,这意味着可以通过检查它的二进制日志来确定应用源于哪一个从库的何种事务。而且,一旦在指定库上提交了具有给定GTID的事务,则该库将忽略具有相同GTID的任何后续事务。因此,在主库上提交的事务只会在从库上应用一次,这也有助于保证一致性。

1 GTID的格式与存储

1单个GTID

GTID与主库上提交的每个事务相关联。此标识符不仅对发起事务的库是唯一的,而且在给定复制拓扑结构中的所有库中都是唯一的。GTID是由冒号分隔的一对坐标来表示的,例如:
8eed0f5b-6f9b-11e9-94a9-005056a57a4e:23​​
前一部分是主库的server_uuid,后面一部分是主库上按提交事务的顺序确定的序列号,提交的事务序号从1开始。上面的GTID表示:具有8eed0f5b-6f9b-11e9-94a9-005056a57a4e的服务器上提交的第23个事务具有此GTID。MySQL 5.6后使用自动生成的128位server_uuid以避免冲突。数据目录下的auto.cnf文件用来保存server_uuid。MySQL启动的时候会读取auto.cnf文件,如果没有读取到则会生成一个server_id,并保存到auto.cnf文件中。
在主库上提交客户端事务时,如果事务已写入二进制日志,则会为其分配新的GTID,保证为客户事务生成单调递增且没有间隙的GTID。如果未将客户端事务写入二进制日志(例如,因为事务已被过滤掉,或者事务是只读的),则不会在源服务器上为其分配GTID。从库上复制的事务保留与主库上事务相同的GTID。即使从库上未开启二进制日志,GTID也会被保存。MySQL系统表mysql.gtid_executed用于保存MySQL服务器上应用的所有事务的GTID,但存储在当前活动二进制日志文件中的事务除外。
GTID的自动跳过功能意味着一旦在指定服务器上提交了具有给定GTID的事务,则该服务器将忽略使用相同GTID执行的任何后续事务(这种情况是可能发生的,如手工设置了gtid_next时)。这有助于保证主从一致性,因为在主库上提交的事务在从库上应用不超过一次。如果具有给定GTID的事务已开始在服务器上执行但尚未提交或回滚,则任何在该服务器上启动具有相同GTID的并发事务都将被阻止。服务器既不执行并发事务也不将控制权返回给客户端。一旦先前的事务提交或回滚,就可以继续执行在同一个GTID上被阻塞的并发会话。如果是回滚,则一个并发会话继续执行事务,并且在同一个GTID上阻塞的任何其他并发会话仍然被阻止。如果是提交,则所有并发会话都将被阻止,并自动跳过事务的所有语句。mysqlbinlog输出中的GTID_NEXT包含事务的GTID,用于标识复制中的单个事务。

2 GTID跳过功能测试

C:\Users\Administrator>net stop mysql80
mysql80 服务正在停止.
mysql80 服务已成功停止。


C:\Users\Administrator>net start  mysql80
mysql80 服务正在启动 .
mysql80 服务已经启动成功。

mysql> show master status \G
*************************** 1. row ***************************
             File: log.000018
         Position: 429
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set: 55390eba-d320-11eb-8e31-00ffaabbccdd:1
1 row in set (0.00 sec)

mysql> set gtid_next='55390eba-d320-11eb-8e31-00ffaabbccdd:1';
Query OK, 0 rows affected (0.00 sec)

mysql> truncate table t1;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
+------+
4 rows in set (0.00 sec)

mysql> show master status \G
*************************** 1. row ***************************
             File: log.000018
         Position: 156
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)

mysql> show variables like '%gtid%';
+----------------------------------+-----------+
| Variable_name                    | Value     |
+----------------------------------+-----------+
| binlog_gtid_simple_recovery      | ON        |
| enforce_gtid_consistency         | ON        |
| gtid_executed                    |           |
| gtid_executed_compression_period | 0         |
| gtid_mode                        | ON        |
| gtid_next                        | AUTOMATIC |
| gtid_owned                       |           |
| gtid_purged                      |           |
| session_track_gtids              | OFF       |
+----------------------------------+-----------+
9 rows in set, 1 warning (0.01 sec)

mysql> set gtid_next='55390eba-d320-11eb-8e31-00ffaabbccdd:1';
Query OK, 0 rows affected (0.00 sec)

mysql> truncate table t1;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
+------+
4 rows in set (0.00 sec)

mysql>

实验2 相同的gtid 事务1提交,事务2 被跳过。

准备两个脚本

set gtid_next='55390eba-d320-11eb-8e31-00ffaabbccdd:2';

begin;

delete from t1 where id=1;

select sleep(10);

COMMIT;

set gtid_next=automatic

set gtid_next='55390eba-d320-11eb-8e31-00ffaabbccdd:2';

begin;

delete from t2 where id=1;

select sleep(10);

COMMIT;

set gtid_next=automatic

mysql> create table t2 as select * From t1;
ERROR 1837 (HY000): When @@SESSION.GTID_NEXT is set to a GTID, you must explicitly set it to a differe
nt value after a COMMIT or ROLLBACK. Please check GTID_NEXT variable manual page for detailed explanat
ion. Current @@SESSION.GTID_NEXT is '55390eba-d320-11eb-8e31-00ffaabbccdd:1'.
mysql> set gtid_next=automatic;
Query OK, 0 rows affected (0.00 sec)

mysql> create table t2 as select * From t1;
Query OK, 4 rows affected (0.06 sec)
Records: 4  Duplicates: 0  Warnings: 

执行

mysql -uroot -123 test< 1.sql

mysql -uroot -123 test< 2.sql  同时执行。  ---事务1提交,事务2倍跳过。

实验2 相同的gtid 事务1回滚,事务2 被提交。

set gtid_next='55390eba-d320-11eb-8e31-00ffaabbccdd:2';

begin;

delete from t1 where id=1;

select sleep(10);

COMMIT;

set gtid_next=automatic

set gtid_next='55390eba-d320-11eb-8e31-00ffaabbccdd:2';

begin;

delete from t2 where id=1;

select sleep(10);

COMMIT;

set gtid_next=automatic

在sleep期间执行s2,事务1回滚前,事务2被阻塞,事务1 回滚,事务2提交。

GTID集合

表示方法

55390eba-d320-11eb-8e31-00ffaabbccdd:1-1000:1002,1003-1000011

GTID集可以包括单个GTID和GTID范围的任意组合,甚至它可以包括源自不同服务器的GTID。例如一个存储在从库gtid_executed系统变量中的GTID集可能如下:
565a6b0a-6f05-11e9-b95c-005056a5497f:1-20,
​​​​​8eed0f5b-6f9b-11e9-94a9-005056a57a4e:1-321​​

mysql> show variables like '%gtid_executed%';
+----------------------------------+------------------------------------------+
| Variable_name                    | Value                                    |
+----------------------------------+------------------------------------------+
| gtid_executed                    | 55390eba-d320-11eb-8e31-00ffaabbccdd:1-2 |
| gtid_executed_compression_period | 0                                        |
+----------------------------------+------------------------------------------+
2 rows in set, 1 warning (0.01 sec)


表示该从库已从两个主库应用了事务,也有可能是在从库执行的写操作。当从库变量返回GTID集时,UUID按字母顺序排列,并且数值间隔按升序合并。
MySQL服务器中很多地方都用到GTID集,例如:gtid_executed和gtid_purged系统变量存储的值是GTID集;START SLAVE的UNTIL SQL_BEFORE_GTIDS和UNTIL SQL_AFTER_GTIDS子句的值是GTID集;内置函数GTID_SUBSET()和GTID_SUBTRACT()需要GTID集作为输入等。

4 GTID表,mysql.gtid_executed

mysql> desc mysql.gtid_executed
    -> ;
+----------------+----------+------+-----+---------+-------+
| Field          | Type     | Null | Key | Default | Extra |
+----------------+----------+------+-----+---------+-------+
| source_uuid    | char(36) | NO   | PRI | NULL    |       |
| interval_start | bigint   | NO   | PRI | NULL    |       |
| interval_end   | bigint   | NO   |     | NULL    |       |
+----------------+----------+------+-----+---------+-------+
3 rows in set (0.01 sec)
表记录的是服务器上已经执行过的GTID集合。

mysql.gtid_executed表供MySQL服务器内部使用。

当从库禁用二进制日志时用该表记录GTID,或者当二进制日志丢失时,可从该表查询GTID状态。RESET MASTER命令将重置mysql.gtid_executed表,清空表数据。和所有系统表一样,用户不要修改该表。
仅当gtid_mode设置为ON或ON_PERMISSIVE时,GTID才存储在mysql.gtid_executed表中。存储的GTID值取决于是否启用二进制日志:
•  对于从库,如果禁用了二进制日志记录(skip-log-bin)或log_slave_updates,则服务器将在该表中存储每个事务的GTID。
•  如果启用了二进制日志记录,当刷新二进制日志或重启服务器时,服务器都会将当前二进制日志中所有事务的GTID写入mysql.gtid_executed表。这种情况适用于主库或启用了二进制日志记录的从库。

启用二进制日志记录时,mysql.gtid_executed表并不保存所有已执行事务GTID的完整记录,该信息由gtid_executed全局系统变量的值提供,每次提交事务后更新。如果服务器意外停止,则当前二进制日志文件中的GTID集不会保存在mysql.gtid_executed表中。在MySQL实例恢复期间,这些GTID将从二进制日志文件添加到表中。即使服务器处于只读模式,MySQL服务器也可以写入mysql.gtid_executed表,这样二进制日志文件仍然可以在只读模式下轮转。如果无法访问mysql.gtid_executed表时进行二进制日志文件轮转,则继续使用二进制日志文件存储GTID,同时在服务器上记录警告信息:

前面已经提到,mysql.gtid_executed表的记录可能并不是完整的已执行GTID,而且有不可访问的可能性,例如误删除此表,因此建议始终通过查询@@global.gtid_executed来确认MySQL服务器的GTID状态,而不是查询mysql.gtid_executed表。mysql.gtid_executed表可能随着事务量的增多而快速膨胀,存储了源自同一个服务器的大量不同的单个GTID,这些GTID构成一个范围,例如:

为了节省空间,MySQL服务器定期压缩mysql.gtid_executed表,方法是将每个这样的行集替换为跨越整个事务标识符间隔的单行,如下所示:

通过设置gtid_executed_compression_period系统变量,可以控制压缩表之前允许的事务数,从而控制压缩率。此变量的默认值为1000,指的是在每1000次事务之后执行表的压缩。把gtid_executed_compression_period设置为0,将不执行压缩。注意,启用二进制日志时不使用gtid_executed_compression_period的值,并在每个二进制日志轮转时压缩mysql.gtid_executed表。mysql.gtid_executed表的压缩由名为thread/sql/compress_gtid_table的专用前台线程执行。此线程未在SHOW PROCESSLIST的输出中列出,但可以从performance_schema.threads中查询到:

通常该线程都处于暂停状态,只有当满足条件时被唤醒,如达到gtid_executed_compression_period或发生了二进制日志轮转(如flush logs等)时。
 

1 reset master对 master 主机GTID的严重影响。

从库上执行reset master只是清空从库的gtid_executed,随着复制的继续,其gtid_executed的值也将随之变化,对复制和主从数据一致性没有影响。下面继续实验,看一下在主库上执行reset master会产生哪些影响。

(6)在主库上执行以下语句:

 

(7)在上一步执行期间,开启一个新会话在主库上执行reset master。
(8)查看从库的复制状态。从show slave status的输出中可以看到复制的I/O线程已停止,并报以下错误:

 

由于主库正在执行事务中间进行了reset master,从库无法读取主库的二进制日志而报错。更有甚之,这些二进制日志的丢失是永久性的,结果很可能需要从头重建复制。由此实验得出的结论是,作为一条基本原则,不要随意在主库上执行reset master,这样做极有可能导致复制停止或造成主从数据不一致等严重后果,而且不易恢复。

6 GTID生命周期

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/177155.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

17种编程语言实现排序算法-计数排序

开源地址 https://gitee.com/lblbc/simple-works/tree/master/sort/ 覆盖语言&#xff1a;C、C、C#、Java、Kotlin、Dart、Go、JavaScript(JS)、TypeScript(TS)、ArkTS、swift、PHP。 覆盖平台&#xff1a;安卓(Java、Kotlin)、iOS(SwiftUI)、Flutter(Dart)、Window桌面(C#)、…

力扣sql简单篇练习(五)

力扣sql简单篇练习(五) 1 游戏玩法分析 I 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # 第一次登录平台的日期就代表是时间靠前的日期 # 窗口函数是Mysql8版本后才能使用 SELECT e.player_id,e.event_date first_login FROM (SELECT player_id,e…

五、python-地图可视化篇(黑马程序猿-python学习记录)

黑马程序猿的python学习视频&#xff1a;https://www.bilibili.com/video/BV1qW4y1a7fU/ 目录 1. 基础地图 2. 设置分段 1. 基础地图 from pyecharts.charts import Map # 准备地图对象 map Map() # 准备数据 data[ ("北京",99), ("上海",199), ("…

17种编程语言实现排序算法-堆排序

开源地址 https://gitee.com/lblbc/simple-works/tree/master/sort/ 覆盖语言&#xff1a;C、C、C#、Java、Kotlin、Dart、Go、JavaScript(JS)、TypeScript(TS)、ArkTS、swift、PHP。 覆盖平台&#xff1a;安卓(Java、Kotlin)、iOS(SwiftUI)、Flutter(Dart)、Window桌面(C#)、…

Maplab 2.0发布:多传感器融合的SLAM框架,支持多机器人、语义回环检测功能

摘要 将多种传感器和深度学习集成到SLAM系统中是当前研究的重要领域。多模态是一块跳板&#xff0c;既可以在挑战场景下增强鲁棒性&#xff0c;又可以解决不同传感器配置的多机系统建图问题。Maplab 2.0提供了一个更加通用的开源平台&#xff0c;最初的Maplab用于创建和管理视…

5-3中央处理器-数据通路的功能和基本结构

文章目录一.功能二.基本结构三.数据流向&#xff08;一&#xff09;内部单总线方式1.寄存器之间的数据传送2.主存与CPU之间的数据传送3.执行算术或逻辑运算&#xff08;二&#xff09;专用数据通路方式一.功能 数据在功能部件之间传送的路径称为数据通路。路径上的部件称为数据…

合宙ESP32C3上手使用

概述经典款是有ch343 ttl 转usb 需要安装驱动 GPIO20/21新款使用usb 直连不需要驱动 USB GPIO18/19ESP32C3 是ESP-RISC-V CPU 是基于 RISC-V ISA 的 32 位内核&#xff0c;包括基本整数 (I)&#xff0c;乘法/除法 (M) 和压缩 (C) 标准扩展。ESP-RISC-V CPU 内核具有 4 级有序标…

【蓝桥杯】简单数论1——GCDLCM

GCD 最大公约数Greatest Common Divisor(GCD)&#xff1a;整数a和b的GCD是指能同时整除a和b的最大整数&#xff0c;记为gcd(a,b)。由于-a的因子和a的因子相同&#xff0c;因此gcd(a, b) gcd(al, |bl)。编码时只关注正整数的最大公约数。 GCD性质 (1) gcd(a, b) gcd(a, ab) …

一、python准备工作篇(黑马程序猿-python学习记录)

黑马程序猿的python学习视频&#xff1a;https://www.bilibili.com/video/BV1qW4y1a7fU/ 目录 1. python官网 2. 检查是否安装完毕 3. pycharm官网 5. phcharm更换主题 6. 新建第一个python文件 7. pycharm字体大小设置 8. 设置快捷键 设置字体大小 ​​​​​​​9. 安装中文…

Python机器学习:假设检验

方差分析这部分内容还不是很理解&#xff0c;在这里先做一个笔记&#xff0c;以后有时间再回过头来改一改。 用到的数据集→\rightarrow→Iris 什么是假设检验&#xff1f; 假设检验就是利用样本数据对某个事先做出的统计假设&#xff0c;再按照某种方法去检验&#xff0c;最后…

CSS样式基础内容2

目录 Emmet语法 快速格式化代码 CSS的复合选择器 后代选择器 子选择器 并集选择器 伪类选择器 链接伪类选择器 focus伪类选择器 CSS元素显示模式 块元素 行内元素 行内块元素 元素显示模式转换 案例-简洁版侧边栏 单行文字垂直居中 CSS的背景 背景图片 方位名词…

【蓝桥云课】最大公约数与最小公倍数

一、最大公约数gcd(a,b) 引例&#xff1a; a24&#xff0c;其因子有1、2、3、4、6、8、12、24 b15&#xff0c;其因子有1、3、5、15 最大公约数gcd(a,b)gcd(24,15)3 欧几里得辗转算法&#xff1a; a max(a,b); b min(a,b); while(b>0){t a%b;a b;b t; }运算过程&…

postgresql源码学习(53)—— vacuum②-lazy vacuum之heap_vacuum_rel函数

一、 table_relation_vacuum函数 1. 函数定义 前篇最后&#xff08;https://blog.csdn.net/Hehuyi_In/article/details/128749517&#xff09;&#xff0c;我们提到了table_relation_vacuum函数&#xff08;tableam.h文件&#xff09;&#xff0c;本篇继续学习。 如前面所说&a…

人大金仓数据库对象访问权限

数据库的表、索引、视图等&#xff0c;在数据库中的一切都可以称为数据库对象。 对象分为以下两类 模式&#xff08;SCHEMA&#xff09;对象&#xff1a;可视为一个表的集合&#xff0c;可以理解为一个存储目录&#xff0c;包含视图、索引、数据类型、函数和操作符等。非模式…

AcWing1229.日期问题——学习笔记

目录 题目 代码 AC结果 思路&#xff1a; 一、获取数据 二、验证日期合法性 三、去重 四、排序 五、主方法中调用&输出 题目 1229. 日期问题 - AcWing题库https://www.acwing.com/problem/content/description/1231/ 代码 import java.util.Scanner;public class…

XILINX FPGA OV5640 摄像头驱动(一)

影像行业是一个值得深耕的方向&#xff0c;废话不多说 先看输入和输出 输入是光照&#xff0c;输出是光照的数字信号 image area&#xff1a;说的是感光矩阵&#xff0c;CMOS图像传感器的最核心部分&#xff0c;接收光照产生电信号的部分。决定了图像质量的好坏 矩阵就会行列…

MyBatisPlus笔记

一、MyBatisPlus概述 MyBatisPlus&#xff08;简称 MP&#xff09;是一个MyBatis的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 MyBatis-Plus可以节省我们大量工作时间&#xff0c;所有的CRUD代码它都可以自动化完成&…

leetcode1143 最长公共子序列

题目 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些字符&#xff08;…

因果诊断原理

因果分析在近十来年逐渐倍受关注&#xff0c;其提供了解释因子间因果性的定量分析工具&#xff0c;广泛用于数据分析领域&#xff0c;同时也就用决策分析、作用预估等反事实因果推理中。本文首先对比了因果性和相关性的关系&#xff0c;之后确定因果关系的基本方法&#xff0c;…

博客搭建教程1-Archlinux环境配置

文章目录1 前言2 archlinux镜像下载3 archlinux安装1 前言 这个教程主要讲解linux环境下博客的搭建&#xff0c;这里的linux系统选择archlinux&#xff0c;博客的框架基于hexo框架。 参考博客&#xff1a; 1、ArchLinux安装教程 2、Archlinux2022年7月镜像 手把手安装教程 UE…