设为首页 收藏本站
查看: 307|回复: 0

[经验分享] Mysql5.6.21-GTID复制

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-4-15 09:01:47 | 显示全部楼层 |阅读模式
什么是GTID:GTID(global transaction id)是对于一个已提交事务的编号,并且是一个全局唯一编号。


组成部分: UUID+TID

什么是UUID:Mysql实例的唯一标识。
什么是TID:TID代表了该实例上已经提交的事务数量,随着事务提交单调递增。

例子:6dec6fd5-eb1f-12e4-6532-000c29e336f3:20

GTID功能目的:
1:根据GTID可以知道事务最初是在哪个实例上提交的。
2:GTID的存在方便了复制的故障转移。
在5.6版本前,Replication的Failover操作过程。
QQ截图20150415090048.png

当A服务器宕机,业务需要切换到B服务器上。需要将C的复制源改成B服务器。
执行以下命令:
CHANGE MASTER TO MASTER_HOST='xxx', MASTER_LOG_FILE='xxx', MASTER_LOG_POS='nnnn'

难点在于,同一个事务在每台机器上的binlog名字和位置都不一样。怎么找到C服务器当前同步停止点,对应服务器B的master_log_file和master_log_pos是什么的时候就称为了难题。这就是MMM,MHA出现的根本原因。

在5.6版本后,Replication的Failover操作过程。
由于同一个事务GTID在所有节点上的值一致。那么根据C服务器当前停止点的GTID就能唯一定位到服务器B的gtid,甚至由于Master_Auto_position功能的出现,我们根本不需要自动GTID的具体值,直接使用
CHANGE MASTER TO MASTER_HOST='xxx', MASTER_AUTO_POSITION命令可以完成故障转移工作。


GTID搭建
实验环境:3台服务器,A,B,C
QQ截图20150415090112.png
A:192.168.112.131
B:192.168.112.132
C:192.168.112.129



一:A服务器:192.168.112.131
1:添加复制账号.
GRANT REPLICATION SLAVE ON *.* TO 'ruser'@'192.168.112.%' IDENTIFIED BY 'rpass';
QQ截图20150415090132.png

2:配置文件添加以下信息,启用GTID模式。
vim /data/mysqldata/3306/my.cnf
---------------------------------------------------
server-id=1
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
slave-parallel-workers=3
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log-events=1
report-host=192.168.112.131
---------------------------------------------------

3:重启动Mysql服务




二:B服务器:192.168.112.132
1:配置文件添加以下信息,启用GTID模式。
vim /data/mysqldata/3306/my.cnf
---------------------------------------------------
server-id=10
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
slave-parallel-workers=3
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log-events=1
report-host=192.168.112.132
---------------------------------------------------


2:重启动Mysql服务


3:连接Mysql,建立主从关系。
sql>change master to master_host='192.168.112.131', master_user='ruser',master_password='rpass',master_auto_position=1;


sql>start slave;
sql>show slave status\G
查看slvae状态,获取关键参数值:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes


三:测试主从同步
A主数据库:
sql> create database testhuang;
Query OK, 1 row affected (0.01 sec)



B从数据库:
sql> show databases;
+-----------------------+
| Database         |
+-----------------------+
| information_schema   |
| mysql          |
| performance_schema  |
| test            |
| testhuang         |
+-----------------------+
5 rows in set (0.00 sec)

sql> show slave status\G
Retrieved_Gtid_Set: 7edc6fd5-e1bf-11e4-8842-000c29e512d6:1
Executed_Gtid_Set: 7edc6fd5-e1bf-11e4-8842-000c29e512d6:1



四:模拟binlog日志文件过期

模拟master-slave运行多时,master服务器的部分binlog因为expire_logs_days过期而被删除,此时需要添加多一台slave数据库。
A:192.168.112.131
B:192.168.112.132

服务器A:
1:查看当前主mysql数据库binlog日志文件,以及GTID。
sql>show master status;
wKiom1UsxTHyO3IQAAEOUfcqURc376.jpg


2:模拟添加数据,切换binlog日志。
flush logs;
spacer.jpg wKioL1Usxl_RHQcmAAL5hukXAdA615.jpg



3:查看binlog日志位置,GTID位置。
wKiom1UsxPSgIJY8AAFH_T71p1s553.jpg


4:手动清除binlog,模拟binlog过期被清除,这里清除06之前的文件,就是说,t1-t4表的日志会丢失。
sql>purge binary logs to 'mysql-bin.000006';


5:可以通过gitd_purge状态参数看到,GTID被清除的事务序号1-5。
sql>show global variables like '%gtid%';
spacer.jpg wKiom1UsxMqwYOncAAGPfs9gc2k156.jpg
在数据库B-slave中,是可以发现t1-t6表的存在,因为已经同步过去了。我们再新增加slave-C的时候,就会发现C无法读取binlog日志而报错。可以通过跳过的方式解决。这样的话就会造成数据库binlog不存在的数据丢失,这个也没办法修复的。因为主从原理就是这样,只能是通过备份/还原的方式去重建。




五:GTID-跳过被清除的事务。
A:192.168.112.131
B:192.168.112.132
C:192.168.112.129

安装mysql参考之前的文章,数据库C添加GTID重要参数。重启动mysql,连接主库-A。

1:修改配置文件,添加以下内容。
vim /data/mysqldata/3306/my.cnf
---------------------------------------------------
server-id=12
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
slave-parallel-workers=3
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log-events=1
report-host=192.168.112.129
---------------------------------------------------

2:重启动mysql服务


3:连接主数据库,知道GTID的好处了吧。
sql>change master to master_host='192.168.112.131', master_user='ruser',master_password='rpass',master_auto_position=1;
sql>start slave;
sql>show slave status\G;
观察报错字段:
Slave_IO_Running: No
Slave_SQL_Running: Yes
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has
purged binary logs containing GTIDs that the slave requires.'

IO错误:读取主的二进制日志致命错误1236,备库请求的GTID的事务内容被清除。


4:跳过被清除的GTID事务。
刚才我们再主库上通过gtid_pirged状态参数查看到1-5的二进制日志文件已经丢失。那么我们跳过该事务。
sql>stop slave;
sql>reset master;
sql>set global gtid_purged = '7edc6fd5-e1bf-11e4-8842-000c29e512d6:1-5';
sql>start slave
不知道我们是否发现,虽然跳过了1-5的事务,但是实际testhuang数据库还是没有创建的,如果跳过的该事务,肯定还会报错。报错没有找到testhuang数据库。


查看slave状态参数:sql>showslave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: No
Last_SQL_Error: Worker 2 failed executing transaction '' at master log mysql-bin.000006, end_log_pos 346; Error 'Unknown database 'testhuang'' on query. Default database: 'testhuang'. Query: 'create table t5(id int)'
Retrieved_Gtid_Set: 7edc6fd5-e1bf-11e4-8842-000c29e512d6:6-7
Executed_Gtid_Set: 7edc6fd5-e1bf-11e4-8842-000c29e512d6:1-5
可以看到,IO线程正常了,但是sql线程异常,确实提示是没有找到testhuang数据库。
在看看后面两个参数,先解释一下:
Retrieved_Gtid_Set:记录了relay日志从Master获取了binlog日志的位置,没错吧,只能拿到事务6-7的日志了。
Executed_Gtid_Set:记录本机执行的binlog日志位置(如果是从机,包括Master的binlog日志位置和slave本身的binlog日志位置)可以从Last_SQL_Error看到创建t5失败。所以这里还是执行1-5,等于没执行。。


5:手动建立testhuang数据库,重新执行跳过事务。
sql>create database testhuang;
sql>stop slave;
sql>reset master;
sql>set global gtid_purged = '7edc6fd5-e1bf-11e4-8842-000c29e512d6:1-5';
sql>start slave
下图是我拼起来的,观察几个重要的参数就可以了
sql>show slave status\G
wKiom1Usxd_yU1QQAAIL8a2lx8Q581.jpg
呵呵,slave3 建立起来了,虽然数据丢失了,不是我们想要的结果,没办法,日志都没了,怎么复制,不然就违背mysql的复制原理了,但不可否认,是不是符合前面说的,同一个事务所有GTID都是一致的。





六:GTID-完整Slave创建。
A:192.168.112.131
B:192.168.112.132
C:192.168.112.129
还是拿服务器C来做完全恢复,来个最干净的环境,把上面的数据库初始化。

前面说过日志文件丢失了,就没办法做恢复了,我们可以把数据备份出来,然后导入到C服务器上,再进行主从数据同步。考虑到A是主库,生产部建议在主库上做备份。因为这里的备份考虑到数据的一致性,我们需要先把表都锁起来。禁止写入,但是生产啊,怎么能这样做呢,,只要锁从库-B了。。


1:B库,锁表,禁止写入数据。
记住,一定要停止主从关系后锁表,哈哈,主从都停止了,还有数据写入么。。停止了直接被备份就好了。。。
sql> stop slave;  
sql> flush tables with read lock;
wKiom1UsxoOytL-0AACRqVJZL_Q528.jpg



2:模拟主库现在又有数据写入了。。。。有真实感了没有?
A库:插入几行数据。
sql>flush logs;
sql>create table t7(id int);
sql>create table t8(id int);
sql>flush logs;
sql>create table t9(id int);
sql>create table t10(id int);



3:备份B库。全备?单库备,任你选,但是恢复的方式不一样。因为全备会把GTID信息备份过去,单库备份还原的话不会。

全备:
$ mysqldump -umysql-admin -p --all-databases > all.sql

Enter password:
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events.
发现报错,不过是Warning,说的就是导出GTID,默认情况下导出所有事务,如果你不是用来做slave,就添加--set-gtid-purged=OFF。一个完整的转储, --all-databases --triggers --routines --events。



这样执行就不爆Warning了。
$mysqldump -umysql-admin -p --all-databases --triggers --routines --events --set-gtid-purged=ON > all.sql


4:释放从库B锁,启动slave线程
sql>unlock tables;
sql>start slave;


5:导入数据库C。
$ /usr/local/mysql56/bin/mysql -umysql-admin -p < all.sql
Enter password:
ERROR 1839 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_MODE = ON.
wKiom1UsxmGDptEQAAC0pGzjdNo304.jpg
报错了,就是说要开启GTID。因为C库是刚初始化的,还没有在my.cnf里面添加GTID参数,添加完后,重起mysql,再次导入。



添加GTID参数后,重启动mysql,再次导入。
$ /usr/local/mysql56/bin/mysql -umysql-admin -p < all.sql
wKioL1UsyNLBiP07AABs9nvmJ-8730.jpg
大功告成。。。。



6:重建立主从关系。
先查看几个表数据的情况。
sql>show databases;
sql>use testuhang;
sql>show tables;
wKioL1UsyDHD7XyuAAEZvXb-nZ4383.jpg
可以看到t1-t6表就对了。锁表前,就是写到t6。


sql>show master status;
wKiom1UsxvDD4foUAAFEZEKTbDA830.jpg
看看GTID事务,,数据非常吻合。因为备份的时候,刚好执行了7个事务。



连接主数据库。
sql>change master to master_host='192.168.112.131', master_user='ruser',master_password='rpass',master_auto_position=1;


如果看到以下结果,恭喜你。恢复成功。
wKioL1UsyKnRZYCLAAMVJ715VgE484.jpg


sql>show slave status\G
wKioL1UsyLWg-Ng-AAHNnwTPOFQ367.jpg
可以看到retrieved_Gtid_Set的值是8-11,因为1-7的事务是通过恢复出来的,并不是从主库拉取过来的。



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-57275-1-1.html 上篇帖子: MySQL基于LVM快照的备份恢复 下篇帖子: mysql数据5.6.0和5.1.7的null字段索引测试
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表