MariaDB GTID 复制

网上关于MySQL官方版本的GTID复制文章很多,我就不再赘述。我这里主要想写一点关于MariaDB的GTID复制特性。相比官方mysql的GTID复制,MariaDB更加的方便好用。

参考文档 https://mariadb.com/kb/en/mariadb/gtid/

MariaDB GTID组成

MariaDB的全局事物ID由下列三部分组成

”域识别符“-”服务器标识符“(server_id)-”事物识别符“

域识别符是MariaDB 10.0新引入的概念,可以将其理解为每个复制集群分配到唯一ID。域识别符主要是为了在引入多源复制后,把各事务在全局范围内区分开来。

服务器标识符就是复制中使用的server_id系统变量。最后的事物识别符是依次增1的8字节常数值。

MariaDB的GTID是以事务为单位进行分配的。当使用不支持事务的存储引擎时,GTID会以SQL语句为单位进行分配。

下面将详细说明一下GTID复制相关内容。

一、搭建GTID复制从库

从库导入主库的备份数据,目前mysql主要由以下两种方式进行备份:

1、mydumper逻辑备份(或者mysqldump逻辑备份)

可以到备份目录文件下获取备份完成时主库最后执行完事务的GTID.

more metadata

Started dump at: 2017-06-17 10:55:40

SHOW MASTER STATUS:

Log: mysql-bin.000056

Pos: 9637

GTID:0-64236-299476

GTID:0-64236-299476 就是后面从库导入备份数据后,从这个GTID开始进行复制的位置。

2、xtrabackup备份

more xtrabackup_binlog_info 

mysql-bin.000104 95830984 0-691253306-60596652

0-691253306-60596652 是后面从库数据导入后进行复制的起始位置。

搭建步骤如下:

实验机器:10.24.64.236 主库,10.24.64.239 从库。

从库导入主库的备份数据(mydumper或者xtrabackup备份)后,执行以下命令。

a. set global gtid_slave_pos='0-64236-299476';

b. show variables like 'gtid%';确认gtid_slave_pos位置有效。

MariaDB [jira]> show variables like 'gtid%'; 

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

| Variable_name | Value |

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

| gtid_binlog_pos | |

| gtid_binlog_state | |

| gtid_current_pos | 0-64236-299476 |

| gtid_domain_id | 0 |

| gtid_ignore_duplicates | OFF |

| gtid_seq_no | 0 |

| gtid_slave_pos | 0-64236-299476 |

| gtid_strict_mode | OFF |

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

c. change master to master_host='10.24.64.236',master_user='rep',master_password='xxx',master_use_gtid=slave_pos;

d.start slave; show slave status\G 确认复制搭建成功。

MariaDB [jira]> show slave status\G

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

Slave_IO_State: Waiting for master to send event

Master_Host: 10.24.64.236

Master_User: rep

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000056

Read_Master_Log_Pos: 9637

Relay_Log_File: relay-bin.000002

Relay_Log_Pos: 670

Relay_Master_Log_File: mysql-bin.000056

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

...

Master_Server_Id: 64236

Master_SSL_Crl: 

Master_SSL_Crlpath: 

Using_Gtid: Slave_Pos

Gtid_IO_Pos: 0-64236-299476

二、GTID复制与传统复制之间的切换

1、GTID复制切换到传统复制

stop slave;

change master to master_use_gtid=no;

start slave;

shwo slave status\G 

Using_Gtid: No 可以确认已经由GTID复制切换到传统复制。

MariaDB [test]> show slave status\G

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

Slave_IO_State: Waiting for master to send event

Master_Host: 10.24.64.236

Master_User: rep

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000056

Read_Master_Log_Pos: 9955

Relay_Log_File: relay-bin.000002

Relay_Log_Pos: 537

Relay_Master_Log_File: mysql-bin.000056

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

..

Using_Gtid: No

Gtid_IO_Pos: 0-64236-299478

我们再在236主库任意插入一条数据,可以发现239从库的GTID也跟着在增长。并且和236主库的gtid_current_pos保持一致。

GTID由原来的 Gtid_IO_Pos: 0-64236-299478 增长到现在的 gtid_slave_pos | 0-64236-299479。

MariaDB [test]> show variables like 'gtid%';

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

| Variable_name | Value |

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

| gtid_binlog_pos | 0-64236-299479 |

| gtid_binlog_state | 0-64236-299479 |

| gtid_current_pos | 0-64236-299479 |

| gtid_domain_id | 0 |

| gtid_ignore_duplicates | OFF |

| gtid_seq_no | 0 |

| gtid_slave_pos | 0-64236-299479 |

| gtid_strict_mode | OFF |

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

8 rows in set (0.00 sec)

2、传统复制切换到GTID复制

从库执行以下命令:

stop slave;

change master to master_use_gtid=slave_pos;或者执行 change master to master_use_gtid=current_pos

start slave;

show slave status\G 确认复制已经切换成功。

三、主从GTID复制结构中Master切换

A(M)-->B(S) 切换为 A(S)<--B(M) 结构

主从GTID复制结构中Master切换非常简单。

1、先确认从库B已经完全追上主库A

Master_Log_File: mysql-bin.000056 = Relay_Master_Log_File: mysql-bin.000056 && Read_Master_Log_Pos: 10390 = Exec_Master_Log_Pos: 10390 

2、A 上执行

change master to master_host='B',master_port=,master_user='rep',master_password='xxx',master_use_gtid=current_pos;start slave;

这里把 master_use_gtid 配置成 current_pos。

因为该主库没有做过其他数据库的从库,所以slave_pos为空,需要用current_pos。二者区别可以看后面的定义。

3、B 上执行 stop slave;

一主多从结构的主库切换和一主一从切换类似,确认主从数据一致后把原来的从库直接change到新的主库上面就好。

四、在使用GTID的从服务器中跳过事务

场景:

在从库某表中删掉某条记录,然后在主库上执行同样的删除动作。

这时主库会报错如下:

Last_SQL_Error: Could not execute Delete_rows_v1 event on table test.tt; Can't find record in 'tt', Error_code: 1032;

handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000056, end_log_pos 10508

从库找不到需要删除的记录,这时可以手动跳过这个错误。

方法1:

stop slave; set global gtid_slave_pos='0-64236-299482';start slave; 

show slave status\G 确认主从复制恢复正常。

方法2:

stop slave;set global sql_slave_skip_counter=1;start slave;

show slave status\G 确认主从复制恢复正常。

五、GTID使用限制

1、slave的本地写入,需要注意,因为跟master不是同一个GTID范围,写入binlog的值,复制到后续从库,容易失败,需要使用

set sql_log_bin=0,来禁止binlog的写入。

生产环境所有从库已经设置为read_only(普通用户只有select权限,有all/super权限的都不在这个范围内)。如果因为特殊情况需要在从库写入数据,则先临时关闭binlog写入。

2、切换主库前,必须保证主库数据已经全部复制到将要作为新主库的从库。


六、常见复制错误处理

1、主库进行update,delete操作,从库发现没有相应记录,导致复制中断。

Last_SQL_Error: Could not execute Delete_rows_v1 event on table test.tt; Can't find record in 'tt', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000056, end_log_pos 10508

处理方式:

根据复制报错的binlog位置,在主库上解析相应的binlog,确认从库具体因为哪些数据确失导致复制中断。

找出从库缺失的记录之后手动从主库导出,再导入从库。导入的时候,切记要先关闭binlog写入。

set sql_log_bin=0;导入数据;set sql_log_bin=1; 然后重启复制。

2、主库上执行 insert操作,从库已经有相应的记录,导致复制中断。

从库报错如下:

Last_SQL_Error: Could not execute Write_rows_v1 event on table test.tt; Duplicate entry '12' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.000056, end_log_pos 10907

处理方式:

根据报错信息可以知道从库已经存在ID=12的记录,因此复制再次插入同样主键ID记录时,报1062错误。

为了验证这一点,可以解析主库相应位置的binlog。

因此我们可以直接删除从库ID=12的记录,重启复制。

以上错误除了主库delete操作,从库因记录缺失报错可以跳过。其他错误都不能直接跳过,会导致主从数据不一致。

七、GTID有关的三个全局变量

select @@global.gtid_slave_pos, @@global.gtid_binlog_pos,@@global.gtid_current_pos;

gtid_slave_pos:

This variable is the GTID of the last event group replicated on a slave server, for each replication domain.

gtid_binlog_pos:

This variable is the GTID of the last event group written to the binary log, for each replication domain.

gtid_current_pos:

This variable is the GTID of the last change to the database for each replication domain. Such changes can either be master events (ie. local changes made by user or application), or replicated events originating from another master server.


总结

MariaDB10.0.2之后的GTID复制搭建与管理非常方便,整体比MySQL官方版本好用很多。主要有以下优势:

1、MariaDB GTID可以有间断,支持 set global sql_slave_skip_counter=1 跳过错误的语法。

MySQL的GTID是连续的,不支持直接跳过错误的语法,只能采取插入空事务来跳过相应的GTID.

2、MariaDB 复制结构中可以同时混杂传统复制从库和GTID复制从库。但是MySQL不行,必须所有数据库都开启GTID复制。

3、MariaDB GTID和传统复制间的切换是非常方便的无需其他配置。而MySQL就繁琐很多,无法做到平滑过渡,需要修改主库配置并重启。

MariaDB官方文档也推荐使用GTID复制。后续会琢磨一下GTID复制下的高可用工具,目标使MariaDB GTID复制在主库失败的情况下能自动切换,同时不丢失数据

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

推荐阅读更多精彩内容