数据库GTID认识

数据库中GTID

1.GTID的概述

1、全局事物标识:global transaction identifieds。
2、GTID事物是全局唯一性的,且一个事务对应一个GTID。

3、一个GTID在一个服务器上只执行一次,避免重复执行导致数据混乱或者主从不一致。

4、GTID用来代替classic的复制方法,不在使用binlog+pos开启复制。而是使用master_auto_postion=1的方式自动匹配GTID断点进行复制。

5、MySQL-5.6.5开始支持的,MySQL-5.6.10后开始完善。

6、在传统的slave端,binlog是不用开启的,但是在GTID中,slave端的binlog是必须开启的,目的是记录执行过的GTID(强制)。

GTID概念:

GTID=source_id:sequence_id

source_id使用服务器的uuid来进行标志

sequence_id系统顺序分配的序列号,连续并且有序.

GTID的便利性:

根据GTID可以快速查看事务在哪个实例上提交的.

根据GTID可以复制更加简单,确保每个事务只能被执行一次.

根据GTID可以更加方便的实现failover,不用再去找master_log_file和master_log_pos.

2.GTID的组成部分:

前面是server_uuid:后面是一个序列号. 例如:server_uuid:sequence number
7800a22c-95ae-11e4-983d-080027de205a:10

UUID:每个mysql实例的唯一ID,由于会传递到slave,所以也可以理解为源ID。

Sequence number:在每台MySQL服务器上都是从1开始自增长的序列,一个数值对应一个事务。

3.GTID比传统复制的优势:

1、更简单的实现failover,不用以前那样在需要找log_file和log_Pos。
2、更简单的搭建主从复制。

3、比传统复制更加安全。

4、GTID是连续没有空洞的,因此主从库出现数据冲突时,可以用添加空事物的方式进行跳过。(故障转移上有优势)

4.GTID参数

gtid_executed:
在当前实例上执行过的GTID集合; 实际上包含了所有记录到binlog中的事务。所以,设置set sql_log_bin=0后执行的事务不会生成binlog 事件,也不会被记录到gtid_executed中。执行RESET MASTER可以将该变量置空。

gtid_purged:

binlog不可能永远驻留在服务上,需要定期进行清理(通过expire_logs_days可以控制定期清理间隔),否则迟早它会把磁盘用尽。gtid_purged用于记录已经被清除了的binlog事务集合,它是gtid_executed的子集。只有gtid_executed为空时才能手动设置该变量,此时会同时更新gtid_executed为和gtid_purged相同的值。gtid_executed为空意味着要么之前没有启动过基于GTID的复制,要么执行过RESET MASTER。执行RESET MASTER时同样也会把gtid_purged置空,即始终保持gtid_purged是gtid_executed的子集。

gtid_next:

会话级变量,指示如何产生下一个GTID。可能的取值如下:

1)AUTOMATIC:

自动生成下一个GTID,实现上是分配一个当前实例上尚未执行过的序号最小的GTID。

2)ANONYMOUS:

设置后执行事务不会产生GTID。

3)显式指定的GTID:

可以指定任意形式合法的GTID值,但不能是当前gtid_executed中的已经包含的GTID,否则,下次执行事务时会报错。

5.从库与主库对应的事务的GTID为什么是相同的?

查看主库binlog里的GTID:发现是set @@global.gtid_purged=…从库的binlog也是一样.
原因: 从库设置gtid为AUTOMATIC后,从库执行中继日志时会先执行set @ @ global.gtid_purged =…故两者GTID相同.且会往后传递.

6.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、slave在接受master的binlog时,会校验master的GTID是否已经执行过(一个服务器只能执行一次)。

7、为了保证主从数据的一致性,多线程只能同时执行一个GTID。

7.MySQL GTID的开启

5.6不能在线开启GTID 5.7可以在线开启GTID
修改GTID需要添加的参数:

MySQL的Master和Slave必须同时开启或者关闭enforce-gtid-consistency和gtid-mode功能,即GTID开关要保持一致。

开启GTID功能,需要同时开启log-bin和log_slave_updates功能,另外还需要开启enforce_gtid_consistency功能。

先开启log_bin(只读参数)功能.(show variables like ‘log_bin’;)

gtid_mode=on #开启gtid

log_slave_updates=1和 enforce_gtid_consistency=1 #保证gtid的一致性

可以将参数添加到配置文件里:

gtid_mode=on

enforce_gtid_consistency=1

log_salve_updates=1(这个参数可能有问题)

在主库和从库查看gtid_mode状态:(show variables like ‘gtid_mode’;)

清除之前的slave信息: 在从库stop slave; reset slave; 在主库reset master;

在主库show master status\G;发现有Executer_Gtid_Set有了数据.这就是当前的Gtid.

在binlog里查看GTID: mysqlbinlog mysql-bin.000008 -vv >/tmp/gtid.sql.

8.GTID在线搭建

1.数据导出导入.
mysqldump -uroot -p -S /tmp/mysql3307.sock --master-data=2 --single-transaction -A > /tmp/all.sql

—导出会有警告,因为会导出GTID.

查看导出文件,确定具体GTID—一般在第24行左右.(在前35行)

从库导入: mysql> source /tmp/all.sql;

导入完成后查看gtid: mysql> select @@global.gtid_purged;

发现@@global.gtid_purged是空的,查看导入数据过程发现错误.

提示:@@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty. 从库的@@GLOBAL.GTID_EXECUTED必须是空的才行.

查看@@GLOBAL.GTID_EXECUTED : mysql> select @@global.gtid_executed;

设置GLOBAL.GTID_EXECUTED为空的方法: 执行mysql> reset master;

注意重新导入前必须确定@@global.gtid_executed为空. 重新数据导入即可.查看gtid.

mysql> select @@global.gtid_purged; —与导出文件中的GTID必定一致.

2.开启主从
change master to master_host=‘192.168.88.2’,master_port=3307,master_user=‘rep’,master_password=‘rep’,master_auto_position=1;

----不用再定位pos点或GTID点.最后参数master_auto_position不是表示定位pos作用,其意思是让数据库打开自动定位pos点功能.

然后从库开启: start slave; show slave status;即可完成主从搭建.

3.步骤总结:
确定主从库都已打开: gtid_mode=on;

  1. 导出:mysqldump -uroot -p -S /tmp/mysql3307.sock --master-data=2 --single-transaction -A > /tmp/all.sql

2.从库导入前: reset master; select @@global.gtid_executed; (为空进行下一步)

3.从库导入并查看是否成功: source /tmp/all.sql 并查看select @@global.gtid_purged;

4.开启主从:change master to master_host=‘192.168.88.3’,master_port=3307,master_user=‘rep’,master_password=‘rep’,master_auto_position=1;

5.从库 : start slave; show slave status\G;

4.Xtrabackup通过GTID在线搭建主从
1、Xtrabackup_binlog_info文件中,包含global.gtid_purged='XXXXXX:XXXX’的信息。

2、然后到slave去手工的 SET GLOBAL.GTID_PURGED=‘XXXXXX:XXXX’。

3、恢复备份,开启change master to 命令。

注意:如果系统运行了很久,无法找到GTID的编号,可以通过上面的方式进行查找。

9.GTID跳过事务冲突

1、这个功能主要跳过事务,代替原来的set global sql_slave_skip_counter = 1。
2、由于在这个GTID必须是连续的,正常情况同一个服务器产生的GTID是不会存在空缺的。所以不能简单的skip掉一个事务,只能通过注入空事物的方法替换掉一个实际操作事务。

Retrieved_Gtid_Set: 02c8aa5e-a0cd-11e8-92c7-000c290206e2:4-6

Executed_Gtid_Set: 02c8aa5e-a0cd-11e8-92c7-000c290206e2:1-5, 053bd58c-a171-11e8-902d-000c290206e2:1

方法:先show slave status \G :找到卡的事务GTID值:

stop slave;

set gtid_next=“6c9da32f-0513-11e4-a949-00e04c8a7573:1”; --跳过此事务.

begin;commit;

set gtid_next=“AUTOMATIC”;

start slave;

10.MySQL GTID5.7新特性—在线启停

老版本的MySQL GTID在开启的时候需要停服务,对服务器影响较大.
1.在每台服务器上设置所有事务都可以违反GTID的事务一致性

set global enforce_gtid_consistency=WARN;

这一步很重要,要确定在做下一步之前,错误日志中不能有警告.

2.在每一台数据库设置确保所有事务不影响GTID的事务一致性

set global enforce_gtid_consistency=ON;

3.在每一台数据库设置新事务是匿名的,同时允许GTID复制是匿名的或者是GTID的

set global gtid_mode=‘OFF_PERMISSIVE’;

4.在每一台数据库设置新事务是GTID的,同时允许GTID复制是匿名的或者是GTID的

set global gtid_mode=’ON_PERMISSIVE’;

show status like ‘ongoing_anonymous_transaction_count’;

显示0值或者空值即可,如果非0 需要等待同步事务全部执行完成。

5.在每一台数据库设置:

set global gtid_mode=‘ON’;

11.GTID的限制:

  1. 不支持非事务引擎(从库报错,stopslave; start slave; 忽略)

  2. 不支持create table select 语句复制(主库直接报错)

  3. 不允许在一个SQL同时更新一个事务引擎和非事务引擎的表

  4. 在一个复制组中,必须要求统一开启CTID或是关闭GTID

  5. 开启DTID需要重启(5.7中不需要)

  6. 开启DTID后,就不再使用原来的传统的复制方式

  7. 对于create temporary table 和drop temporary table语句不支持

  8. 不支持sql_slave_skip_counter

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值