基于GTID的复制

Ⅰ、GTID的介绍

  • global transaction id identifier 全局事务id
  • gtid = server_uuid + transaction_id
  • server_uuid是全局唯一的,5.6开始才有,表示当前实例的uuid,保存在数据目录中的auto.conf文件中
  • transaction_id是自增的
  • gtid的作用是替代filename + position

主:show master status;

(root@localhost) [test]> show master status;
+------------+----------+--------------+------------------+----------------------------------------+
| File       | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------+----------+--------------+------------------+----------------------------------------+
| bin.000006 |      408 |              |                  | d565cde8-0573-11e8-89b2-525400a4dac1:1 |
+------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)
Executed_Gtid_set:server_id:1-xxxx     表示产生了xxx个事务

从:show master status;
Retrieved_Gtid_Set: d565cde8-0573-11e8-89b2-525400a4dac1:1
Executed_Gtid_Set: d565cde8-0573-11e8-89b2-525400a4dac1:1
也能看到事务号

tips:
如果做了A和B做了双主,B上一直在同步A上数据,这时候在B上写入一个事务

A上看下Executed_Gtid_set,会发现有两个值

一个是自己做主当前的事务号,一个是同步的从上的事务号

Ⅱ、GTID的意义

之前的复制基于(file,pos),当主从发生宕机,切换的时候有问题

slave保存的是原master上的(file,pos),无法直接指向新master上的(file,pos)

mha通过relay log来判断(非常有技术性)

gtid实现了真正的全局唯一位置(所有机器上都是统一的)

更容易进行failover操作

举例:

a是master,b c d是slave,a挂了,b做主,c d做change master

此时c d 上的pos却还是a上面的pos,和b没有对应关系,文件名,文件大小,position完全不一样,change不起来

使用gtid的话,b上保存着c和d回放的位置G_a、G_b(b是通过选举出来的,保存着最多的日志)

Ⅲ、gtid配置

[mysqld]
log_bin
gtid_mode = ON
log_slave_updates = 1          5.6必须开,5.7可以不开
enforce-gtid-consistency = 1

tips:

  • MySQL5.6必须开启参数log_slave_updates,5.7.6开始无需配置
  • MySQL5.6升级到gtid模式需要停机重启
  • MySQL5.7.6版本开始可以在线升级gtid模式
  • 5.6中gtid用的比较少,最重要的原因在于gtid要么开要么不开,不能做到非gtid升级到gtid
  • gtid是一切高可用基础(gr,mha),强烈建议打开,5.6就有了,很成熟了
5.7的gtid_mode可选值
ON                      完全打开GTID,如果打开状态的备库接受到不带GTID的事务,则复制中断
ON_PERMISSIVE           可以认为是打开gtid前的过渡阶段,主库在设置成该值后会产生GTID,同时备库依然容忍带GTID和不带GTID的事务
OFF_PERMISSIVE          可以认为是关闭GTID前的过渡阶段,主库在设置成该值后不再生成GTID,备库在接受到带GTID和不带GTID事务都可以容忍
                        主库在关闭GTID时,执行事务会产生一个Anonymous_Gtid事件,会在备库执行:set @@session.gtid_next='anonymous'
OFF                     彻底关闭GTID,如果关闭状态的备库收到带GTID的事务,则复制中断
之前只有ON和OFF

平滑开启gtid
set global gtid_mode = 'off_permissive';
set global gtid_mode = 'on_permissive';
set global enforce_gtid_consistency = 'on'
set global gtid_mode = 'ON';

平滑关闭gtid
stop slave;
set global gtid_mode = 'on_permissive';
set global gtid_mode = 'off_permissive';
change master to master_auto_position = 0;
set global gtid_mode = 'OFF';
set global enforce_gtid_consistency = 'off'
start slave;

主从上都依次敲下来

Ⅳ、简单说下搭建过程

大同小异,全备+binlog

开启gtid后,mysqldump备份单库时会报warning,意思是gtid包含所有事务,只备份了单库,忽略即可

用mydumper备份,看下metadata文件,找到gitd:xxxxxx:x-xxx

这玩意等同于mysqldump备份文件中set @@global.gtid_purged='xxxx:x-xxx';

表示这部分gtids对应的事务已经在备份中了,slave在还原备份后复制时,需要跳过这些gtids

reset master;   清空@@GLOBAL.GTID_EXECUTED,不然执行下一步会报错
SET @@GLOBAL.GTID_PURGED = '找出来的位置'
以上操作mysqldump出来的文件导入无需操作,mydumper要手动,因为myloader不执行这个

最后一把change master送给大家
change master to master_host='127.0.0.1', master_port=3306, master_user='rpl', master_password='123', MASTER_AUTO_POSITION=1;
start slave;

tips:

  • binlog文件中会有两个关于gtid的event——Previous_gtids和Gtid
  • 通过扫描binlog中的gtid值,可以知道gtid与filename-pos的对应关系,如果binlog很大,扫描量也很大,所以用Previous_gtid来记录之前一个binlog文件中最大的gtid
  • 如果要找的gtid比previous_gtids大,就扫描当前文件,反之扫之前的文件,依次类推
  • binlog在rotate的时候,是知道当前最大gtid的,将该值,写入下个binlog的文件头,即previous_gtids

Ⅴ、GTID复制中处理报错小技巧

这里模拟一个1062错误即可,不演示

报错会告诉你对应的gtid

操作步骤如下:

  • 我们将gtid_next指向报错的gtid

报错中没有gtid,则用Retrieved_Gtid_Set和Executed_Gtid_Set对比一下就知道哪个事务执行出错了

(root@localhost) [(none)]> set gtid_next='xxxxxx:xxxx';  # 设置为之前失败的那个GTID的值
Query OK, 0 rows affected (0.00 sec)
  • 执行一个空事务
(root@localhost) [(none)]> begin;commit;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
  • 将gtid_next还原为automatic
(root@localhost) [(none)]> set gtid_next="automatic";
Query OK, 0 rows affected (0.00 sec)

(root@localhost) [(none)]> stop slave;
Query OK, 0 rows affected (0.01 sec)
(root@localhost) [(none)]> start slave;
Query OK, 0 rows affected (0.07 sec)

该操作类似于sql_slave_skip_counter,只是跳过错误,不能保证数据一致性,需要人工介入,固强烈建议从机开启read_only=1

Ⅵ、GTID的限制

  • 在开启GTID后,不能在一个事物中使用创建临时表的语句,需要使得 autocommit=1;才可以。5.7开始直接创建临时表已经可以创建了
  • 在开启GTID后,不能使用create table select ... 的语法来创建表了,因为这其实是多个事物了,GTID没法对应
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容