1. GTID的格式和存储

GTID即全局事务ID(global transaction identifier),GTID实际上是由server_uuid:transaction_id组成的。其中server_uuid是一个MySQL实例的唯一标识,存放在数据目录的auto.cnf文件下,transaction_id代表了该实例上已经提交的事务数量,并且随着事务提交单调递增,所以GTID能够保证每个MySQL实例事务的执行(不会重复执行同一个事务,并且会补全没有执行的事务)。

1.1 GTID 集

GTID集是一组全局事务标识符,如下所示:

gtid_set:

uuid_set [, uuid_set] ...

| ''

uuid_set:

uuid:interval[:interval]...

uuid:

hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh

h:

[0-9|A-F]

interval:

n[-n]

(n >= 1)

GTID集在MySQL服务器中以多种方式使用。 例如,gtid_executed和gtid_purged系统变量存储的值表示为GTID集。 此外,函数GTID_SUBSET()和GTID_SUBTRACT()需要GTID集作为输入。 当从服务器变量返回GTID集时,UUID按字母顺序排列,数值间隔按升序合并。

1.2 mysql.gtid_executed 表

GTID存储在mysql数据库中名为gtid_executed的表中。 对于它表示的每个GTID或GTID集合,该表中的一行包含原始服务器的UUID,以及该集合的起始和结束事务ID; 对于仅引用单个GTID的行,这两个最后两个值是相同的。

当slave禁用binlog时,mysql.gtid_executed表使slave能够使用GTID,并且它可以在二进制日志丢失时保留GTID历史记录。

当gtid_mode为ON或ON_PERMISSIVE时,GTID仅存储在mysql.gtid_executed表中,存储GTID的位置取决于是启用还是禁用binlog:

如果禁用二进制日志记录(log_bin为OFF),或者如果禁用log_slave_updates,则服务器将属于每个事务的GTID与表中的事务一起存储。 此外,该表可以定期压缩; 此情况仅不适用于复制中的master,因为在主服务器上,必须启用二进制日志记录才能进行复制。

如果启用了二进制日志记录(log_bin为ON),则无论何时轮询二进制日志或关闭服务器,服务器都会将写入先前二进制日志的所有事务的GTID写入mysql.gtid_executed表。 这种情况适用于复制主服务器或启用了二进制日志记录的复制从服务器。

如果服务器意外停止,则当前二进制日志中的GTID集不会保存在mysql.gtid_executed表中。 在这种情况下,这些GTID会在恢复期间添加到表和gtid_executed系统变量中的GTID集合中。

启用二进制日志记录时,mysql.gtid_executed表不会为所有已执行的事务提供GTID的完整记录。 该信息由gtid_executed系统变量的全局值提供。

命令RESET MASTER将重置mysql.gtid_executed表。

1.3 mysql.gtid_executed 表压缩

启用GTID时,服务器会定期在mysql.gtid_executed表上执行此类压缩。 通过设置gtid_executed_compression_period系统变量,您可以控制压缩表之前允许的事务数,从而控制压缩率。 该变量的默认值为1000; 这意味着,默认情况下,在每1000次事务之后执行表的压缩。 将gtid_executed_compression_period设置为0可以防止执行压缩; 但是,如果执行此操作,您应该为gtid_executed表可能需要的磁盘空间量的大幅增加做好准备。

【注意】:

启用binlog时,且不使用gtid_executed_compression_period的值,会在每个binlog轮换时压缩mysql.gtid_executed表。

压缩前:

mysql> SELECT * FROM mysql.gtid_executed;

+--------------------------------------+----------------+--------------+

| source_uuid | interval_start | interval_end |

|--------------------------------------+----------------+--------------|

| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 37 | 37 |

| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 38 | 38 |

| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 39 | 39 |

| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 40 | 40 |

| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 41 | 41 |

| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 42 | 42 |

| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 43 | 43 |

...

压缩后:

+--------------------------------------+----------------+--------------+

| source_uuid | interval_start | interval_end |

|--------------------------------------+----------------+--------------|

| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 37 | 43 |

...

mysql.gtid_executed表的压缩由名为thread/sql/compress_gtid_table的专用前台线程执行。 该线程未在SHOW PROCESSLIST的输出中列出,但可以将其视为performance_schema.threads表中的一行,如下所示:

mysql> SELECT * FROM performance_schema.threads WHERE NAME LIKE '%gtid%'\G

*************************** 1. row ***************************

THREAD_ID: 26

NAME: thread/sql/compress_gtid_table

TYPE: FOREGROUND

PROCESSLIST_ID: 1

PROCESSLIST_USER: NULL

PROCESSLIST_HOST: NULL

PROCESSLIST_DB: NULL

PROCESSLIST_COMMAND: Daemon

PROCESSLIST_TIME: 1509

PROCESSLIST_STATE: Suspending

PROCESSLIST_INFO: NULL

PARENT_THREAD_ID: 1

ROLE: NULL

INSTRUMENTED: YES

HISTORY: YES

CONNECTION_TYPE: NULL

THREAD_OS_ID: 18677

thread/sql/compress_gtid_table线程通常会休眠,直到执行了gtid_executed_compression_period事务,然后唤醒以执行mysql.gtid_executed表的压缩,如前所述。 然后它休眠直到另一个gtid_executed_compression_period事务发生,然后唤醒再次执行压缩,无限期地重复此循环。 禁用二进制日志记录时将此值设置为0意味着线程始终处于休眠状态且从不唤醒。

2. GTID 生命周期

GTID的生命周期包括以下步骤:

Master产生GTID:在Master端产生一个GTID的信息,并保存到binlog中。

发送Binlog信息到从库上,将binlog信息发送到SLAVE所在的服务器上。将SLAVE中的gtid_next的值设置为GTID的值。

SLAVE执行GTID。SLAVE首先验证是否在自己的二进制日志中使用了这个GTID号

SLAVE不生成GTID。由于GTID不为空,SLAVE不会尝试为该事务生成新的GTID,而是从gtid_next 中读取GTID值,写入二进制日志中,来标识一个事务的GTID的值。

gtid_purged

gtid_purged系统变量(@@global.gtid_purged)中的GTID集包含已在服务器上提交但在服务器上的任何二进制日志文件中不存在的所有事务的GTID。 以下类别的GTID在此集合中:

在slave上禁用binlog提交的复制事务的GTID

已写入已清除的binlog的事务的GTID

由语句SET @@global.gtid_purged明确添加到集合中的GTID

服务器启动时,将初始化gtid_purged系统变量中的GTID集。 每个二进制日志文件都以事件Previous_gtids_log_event开头,该事件包含所有先前二进制日志文件中的GTID集(由前一个文件的Previous_gtids_log_event中的GTID和文件本身中每个Gtid_log_event的GTID组成)。 最旧的二进制日志文件中的Previous_gtids_log_event的内容用于在服务器启动时初始化gtid_purged集,并在清除二进制日志文件时维护该集。

3. 使用GTID搭建主从

GTID使用master_auto_position=1代替了基于binlog和position号的主从复制搭建方式,更便于主从复制的搭建。

3.1 环境准备

类型

ip

prot

server-id

是否开启binlog

binlog格式

log_slave_updates参数

master

192.168.56.100

3307

1003307

log-bin = /data/mysql/mysql3307/logs/my3307_binlog

binlog_format = row

log_slave_updates=1

slave

192.168.56.200

3307

2003307

log-bin = /data/mysql/mysql3307/logs/my3307_binlog

binlog_format = row

log_slave_updates=1

3.2 配置GTID主从的参数

server_id: 设置MySQL实例的server_id,每个server_id不能一样

gtid_mode=ON: MySQL实例开启GTID模式

enforce_gtid_consitency=ON:使用GTID模式复制时,需要开启参数,用来保证数据的一致性。

log-bin: MySQL必须要开启binlog

log-slave-updates=1:决定SLAVE从Master接收到更新且执行是否记录到SLAVE的binlog中

binlog_format=ROW: binlog格式为row

skip-slave-start=1(可选): 当SLAVE数据库启动的时候,SLAVE不会启动复制

3.3 在master上操作

1) 创建复制账号

create user 'repl'@'%' identified by 'wanbin';

grant replication slave on *.* to 'repl'@'%';

2) master数据库利用xtrabackup备份至slave上

innobackupex --defaults-file=/etc/my3307.cnf -uroot -pmysql --stream=tar ./ |ssh root@mysqldb2 "cat - > /data/backup/dbback`date +%Y%m%d_%H%M%S`.tar"

3.4 在slave上操作

解压备份

mkdir dbback20181012_151213

tar -xvf dbback20181012_151213.tar -C dbback20181012_151213

prepare备份

innobackupex --apply-log /data/backup/dbback20181012_151213/

恢复备份

innobackupex --defaults-file=/etc/my3307.cnf --copy-back /data/backup/dbback20181012_151213/

chown -R mysql:mysql /data/mysql/mysql3307/data

mysqld --defaults-file=/etc/my3307.cnf &

过滤掉已执行过的gtid

1)查看xtrabackup_info文件中的gtid信息

cat xtrabackup_info|grep binlog_pos

binlog_pos = filename 'my3307_binlog.000002', position '2401', GTID of the last change '3a068bf8-cdeb-11e8-8176-080027b0b461:1-10'

2)查看slave已执行的gtid是否为空,如果不为空,需要执行reset MASTER进行清理,否则无法设置gtid。

root@localhost [(none)] 15:50:41>show master status \G;

*************************** 1. row ***************************

File: my3307_binlog.000002

Position: 234

Binlog_Do_DB:

Binlog_Ignore_DB:

Executed_Gtid_Set: 3a068bf8-cdeb-11e8-8176-080027b0b461:1-10,

ffe86a27-cdef-11e8-bb92-0800275b8a9a:1-2

1 row in set (0.00 sec)

3)执行reset master

root@localhost [(none)] 15:50:52>reset master;

Query OK, 0 rows affected (0.04 sec)

root@localhost [(none)] 15:53:18>show master status\G

*************************** 1. row ***************************

File: my3307_binlog.000001

Position: 154

Binlog_Do_DB:

Binlog_Ignore_DB:

Executed_Gtid_Set:

1 row in set (0.00 sec)

4)执行GTID_PURGED

root@localhost [(none)] 15:56:32>set session sql_log_bin = 0;

root@localhost [(none)] 15:56:53>set global gtid_purged='3a068bf8-cdeb-11e8-8176-080027b0b461:1-10';

root@localhost [(none)] 15:57:58>set session sql_log_bin = 1;

配置主从

执行help change master to 可以获取change master to命令

CHANGE MASTER TO

MASTER_HOST='192.168.56.100',

MASTER_USER='repl',

MASTER_PASSWORD='wanbin',

MASTER_PORT=3307,

master_auto_position=1;

开始主从复制

start slave;

#如果想分别指定启动线程,可以使用如下命令

START SLAVE IO_THREAD;

START SLAVE SQL_THREAD;

#同样关闭命令:

STOP SLAVE;

#分别关闭命令:

STOP SLAVE IO_THREAD;

STOP SLAVE SQL_THREAD;

4. 使用gtid进行复制的限制

由于基于GTID的复制依赖于事务,因此在使用时不支持MySQL中可用的某些功能。本节提供有关使用GTID进行复制的限制和限制的信息。

4.1 非事务性存储引擎的更新

使用GTID时,使用非事务性存储引擎(如MyISAM)对表的更新不能在与使用事务性存储引擎(如InnoDB)的表的更新相同的语句或事务中进行。

此限制是由于对使用非事务性存储引擎的表的更新与对同一事务中使用事务存储引擎的表的更新混合可能导致将多个GTID分配给同一事务。

当master和slave使用不同的存储引擎用于同一个表的相应版本时,也会发生这样的问题,其中一个存储引擎是事务性的而另一个不是。 还要注意,定义为在非事务性表上运行的触发器可能是导致这些问题的原因。

在刚刚提到的任何一种情况下,事务和GTID之间的一对一对应关系被破坏,结果是基于GTID的复制无法正常运行。

4.2 CREATE TABLE … SELECT 语句

CREATE TABLE … SELECT对于基于语句的复制是不安全的。 使用基于行的复制时,此语句实际上记录为两个单独的事件 - 一个用于创建表,另一个用于将源表中的行插入刚刚创建的新表中。 当在事务中执行此语句时,在某些情况下,这两个事件可能会接收相同的事务标识符,这意味着slave将跳过包含插入的事务。 因此,使用基于GTID的复制时不支持CREATE TABLE … SELECT。

4.3 临时表

使用GTID时(即,enforce_gtid_consistency系统变量设置为ON时),事务,过程,函数和触发器内不支持CREATE TEMPORARY TABLE和DROP TEMPORARY TABLE语句。 可以在启用GTID的情况下使用这些语句,但仅限于任何事务之外,并且仅使用autocommit = 1。

4.4 防止执行不受支持的语句

要防止执行会导致基于GTID的复制失败的语句,必须在启用GTID时使用–enforce-gtid-consistency选项启动所有服务器。

4.5 跳过事务

4.6 Ignoring servers

使用GTID时,不推荐使用CHANGE MASTER TO语句的IGNORE_SERVER_IDS选项,因为已经应用的事务会自动被忽略。 在启动基于GTID的复制之前,请检查并清除之前在相关服务器上设置的所有忽略的服务器ID列表。 可以为各个通道发出的SHOW_SLAVE_STATUS语句显示已忽略的服务器ID列表(如果有)。 如果没有列表,则Replicate_Ignore_Server_Ids字段为空。

4.7 GTID mode and mysqldump

如果目标服务器的二进制日志中没有GTID,则可以将使用mysqldump创建的转储导入到启用了GTID模式的MySQL服务器中。

4.8 GTID mode and mysql_upgrade

当服务器在启用全局事务标识符(GTID)的情况下运行时(gtid_mode = ON),请不要通过mysql_upgrade启用二进制日志记录(–write-binlog选项)。

mysql gtid 复制_MySQL 使用GTID进行复制相关推荐

  1. mysql 组复制和传统复制_MySQL的GTID复制与传统复制的相互切换

    1. GTID复制转换成传统复制 1.1 环境准备 类型 ip prot server-id master 192.168.56.100 3307 1003307 slave 192.168.56.2 ...

  2. mysql gtid 复制_MySQL的GTID复制

    从mysql5.6开始引入全局事务标识符(GTID),即每个事务都有一个唯一的标识符.服务器上的每个事务都被分配一个唯一的事务标识符,这是一个64位非零的数值,根据事务提交的顺序分配.GTID的构成是 ...

  3. mysql在线复制_mysql的两种复制模式

    mysql的复制术语 扩展的方式: Scale up Scale Out 复制: 向外扩展 二进制日志 单向 复制功用: 数据分布 负载均衡:读操作,适用于读密集型的应用 备份 高可用和故障切换 My ...

  4. mysql多源gtid复制_mysql的GTID复制和多源复制

    配置基于GTID的复制 -------------------------------------------- 在参数文件/etc/my.cnf增加下面内容: 主库 master_info_repo ...

  5. mysql 5.6 并行复制_MySQL 5.6并行复制架构

    诚然,MySQL 5.6版本也支持所谓的并行复制,但是其并行只是基于schema的,也就是基于库的.如果用户的MySQL数据库实例中存在多个schema,对于从机复制的速度的确可以有比较大的帮助.My ...

  6. mysql数据库ab复制_mysql replication(AB复制)

    Master配置: yum -y install mysql mysql-server /etc/init.d/mysqld start chkconfig mysqld on mysql_secur ...

  7. mysql主从复制过滤_mysql主从配置及复制过滤

    前提:为了方便搭建,我直接使用了lnmp搭建环境,mysql版本使用5.6版本,数据库为test(在主服务器上创建数据库后备份拉到从服务器) 部署LNMP ( 安装详情请见:https://lnmp. ...

  8. 与MySQL传统复制相比,GTID有哪些独特的复制姿势?

    与MySQL传统复制相比,GTID有哪些独特的复制姿势? http://mp.weixin.qq.com/s/IF1Pld-wGW0q2NiBjMXwfg 陈华军,苏宁云商IT总部资深技术经理,从事数 ...

  9. Mysql进阶(1)——异步复制(主从复制、Gtid复制)、半同步复制

    前言 原理总结 异步复制:在主节点写入日志即返回成功,默认情况下MySQL5.5/5.6/5.7和mariaDB10.0/10.1的复制功能是异步的.异步复制可以实现最佳的性能,主库把binlog日志 ...

最新文章

  1. 【廖雪峰python入门笔记】整数和浮点数
  2. springcloud上传文件_Spring Cloud实战:服务链路追踪Spring Cloud Sleuth
  3. leetcode——242. 有效的字母异位词
  4. WinRAR 在cmd执行rar压缩命令
  5. 记杨绛先生的经典语句
  6. matlab 十字路口左转
  7. 洛谷P3402 【模板】可持久化并查集
  8. python中open打开路径问题_Python学习笔记之open()函数打开文件路径报错问题
  9. 集成海康威视Sadp SDK实现重置密码
  10. Jmeter下载与安装
  11. 【win10安装】磁盘MBR分区表
  12. O2OO是一个汽车故障诊断工具
  13. 15块rmb做一个语音识别控制的0.3W白光LED便利USB灯
  14. 为什么1//0.1等于9.0,而1//-0.1=-10?
  15. 什么是高并发,高并发的解决方案
  16. 100天精通Python(基础篇)——第7天:高级变量类型复习
  17. delphi中常见错误提示说明总结
  18. 【简洁实用】好用的杀毒软件 【网络安全防护】
  19. Vue3 新特性 内置组件 <Teleport>
  20. 解决桌面文件图标变黑方法

热门文章

  1. __builtin_expect作用
  2. ZOJ 2833 Friendship
  3. cssbefore图片大小_css :after和:before
  4. 2021年暑假ACM集训队模拟赛第4场——题解
  5. 【OpenCV】车牌自动识别算法的设计与实现
  6. 前后端分离与不分离的区别
  7. 数学建模之线性规划与LINGO编程
  8. JAVA数组概念与C语言数组概念区别
  9. SAP外向交货中的包装功能
  10. 在Unity中构建Pong克隆:UI和游戏玩法