0、引言html
GTID是MySQL 5.6 的新特性之一,全称global transaction identifier全局事务标志符。GTID官方定义是:mysql
GTID = source_id:transaction_id算法
source_id:源服务器标识(通常是server_uuid),数据保存在auto.cnf 文件sql
transaction_id:是一个从 1 开始的自增计数,表示在这个主库上执行的第 n 个事务,MySQL 会保证事务与 GTID 之间的 1 : 1 映射。安全
server_uuid: mysql 使用128位的server_uuid 替代原先32位的server_id 的大部分功能。 由于server_id依赖于my.cnf的配置,容易产生冲突。自动产生的128位的uuid算法能够保证全部的uuid都不冲突。首次启动mysql 会调用generate_server_uuid()函数自动生成一个server_uuid ,并保存到auto.cnf文件中,删除这个文件,实例下次从新的时候会从新生成。服务器
1、MySQLGTID复制简介微信
一、GTID是一个事务一一对应,而且全局惟一ID。socket
二、一个GTID在一个服务器上只执行一次,避免重复执行致使数据混乱或者主从不一致。ide
三、它用来代替传统复制方法,再也不使用MASTER_LOG_FILE+MASTER_LOG_POS开启复制。而是使用MASTER_AUTO_POSTION=1的方式开始复制。函数
四、它在MySQL-5.6.5开始支持的,MySQL-5.6.10后开始完善。
五、在传统的slave端,binlog是不用开启的,可是在GTID中slave端的binlog是必须开启的,目的是记录执行过的GTID(强制)。
六、GTID将主从复制变得简单化,不须要再找MASTER_LOG_FILE、MASTER_LOG_POS,并且比传统复制更加安全,由于GTID是连续的,在保证数据一致性方面表现优异
2、MySQLGTID实现主从同步的原理
一、master上执行和提交一个事务,这个事务被分配一个GTID,这个GTID会放在事务的前面,一同写入BINLOG
二、当binlog传输到slave,并存储到slave的relay log之后,slave获取GTID,而后设置到gtid_next变量中.也就是告诉Master,下一个要执行的事务的GTID必定是这个变量中的值.
三、SQL thread从relay log中获取GTID,并对比slave 的binlog中是否有该GTID,保证GTID在一个服务器上只执行一次,而且禁止多个线程同时执行一个GTID。若是没有,slave会执行这个GTID,而且将这个GTID和事务一块儿写到本身的binlog中。若是有,忽略。
四、若是gtid_next没有设置,那么就会自动生成一个新的GTID,这就是为何GTID要写在事务的前面
3、MySQLGTID的配置
对于想要搭建基于GTID主从的童鞋们,使用mysql-5.6.5以上版本,建议使用最新版本
一、主:
[mysqld] #GTID: server_id=135 #服务器id gtid_mode=on #开启gtid模式 enforce_gtid_consistency=on #强制gtid一致性,开启后对于特定create table不被支持 在mysql-5.6.9以前,enforce-gtid-consistency对应的是--disable-gtid-unsafe-statements参数. 详细见:http://dev.mysql.com/doc/refman/5.6/en/replication-options-gtids.html #binlog log_bin=mysql-bin log-slave-updates=1 binlog_format=row #强烈建议,其余格式可能形成数据不一致 #relay log skip_slave_start=1
二、从:
[mysqld] #GTID: gtid_mode=on enforce_gtid_consistency=on server_id=143 #binlog log-bin=slave-binlog log-slave-updates=1 binlog_format=row #强烈建议,其余格式可能形成数据不一致 #relay log skip_slave_start=1
4、MySQLGTID主从模式配置
1、在新配置的服务器上搭建GTID主从
启动之后先不要运行事务,而是先change master后,再运行事务
(root@localhost) [(none)]> CHANGE MASTER TO -> MASTER_HOST='xxxxx', -> MASTER_USER='xxxx', -> MASTER_PASSWORD='xxx', -> MASTER_PORT=xxxx, -> MASTER_AUTO_POSITION = 1; Query OK, 0 rows affected, 2 warnings (0.01 sec) change master to master_host='10.0.0.6', master_user='root', master_password='123456', master_port=3306, master_auto_position=1; (root@localhost) [(none)]> start slave; Query OK, 0 rows affected (0.01 sec) (root@localhost) [(none)]> show slave status \G ###能够看到复制工做已经开始且正常 *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event …… …… Slave_IO_Running: Yes Slave_SQL_Running: Yes
2、基于传统复制的MySQL转向GTID复制
a、按本文描述配置参数文件;
b、必定先关闭master的写入,保证全部的slave都已经和master数据同步。而后在重启,全部slave须要加上skip_slave_start的配置参数,避免启劢之后仍是使用老的复制协议.全部服务器设置global.read_only参数,等待主从服务器同步完毕;
mysql> SET @@global.read_only = ON;
c、依次重启主从服务器;
d、使用change master 更新主从配置;
mysql> CHANGE MASTER TO > MASTER_HOST = xxxx, > MASTER_PORT = xxxx, > MASTER_USER = xxxx, > MASTER_PASSWORD = xxxx, > MASTER_AUTO_POSITION = 1;
e、从库开启复制
mysql> START SLAVE;
f、验证主从复制
5、搭建基于MySQL GTID的从库
两种方式:
一、若是你的master全部的binlog还在,能够选择相似于刚才的方法,安装slave后,直接change master到master。原理是直接获取master全部的gtid并执行。
优势:是简单
缺点:是若是binlog太多,数据彻底同步须要的时间较长,而且master一开始就启用了GTID
总结:适用于master也是新建不久的状况。
二、经过master或者其余slave的备份搭建新的slave.
原理:获取master的数据,和这些数据对应的GTID范围,而后经过在slave设置@@GLOBAL.GTID_PURGED从而跳过备份包含的GTID
优势:是能够避免第一种方法中的不足
缺点:是相对来讲会复杂一点点
总结:适用于拥有较大数据集的状况
三、经过mysqldump搭建基于GTID的从库
l 备份从库
[root@bogon ~]# mysqldump -h10.0.0.7 -uroot -p123456 --master-data=2 --triggers --routines --events --single-transaction --all-databases >all.sql
若是主从不是一个版本,从master上备份到salve,启动实例后,应该再执行mysql_upgrade升级相关表结构performance_schema、information_schema以及mysql等系统表结构。
此时报错
[root@bogon ~]# mysql <all.sql ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.
l 在slave上执行
root@localhost [(none)]>show variables like 'gtid_purged'; +---------------+--------------------------------------------+ | Variable_name | Value | +---------------+--------------------------------------------+ | gtid_purged | 60b08d3b-9c23-11e6-81c2-000c29d40ed7:1-605 | +---------------+--------------------------------------------+ 1 row in set (0.00 sec)
l 在master上执行
root@localhost [(none)]>show master status; +------------------+----------+--------------+------------------+--------------------------------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+--------------------------------------------+ | mysql-bin.000001 | 7527969 | | | 60b08d3b-9c23-11e6-81c2-000c29d40ed7:1-605 | +------------------+----------+--------------+------------------+--------------------------------------------+ (END)
l 在新的slave上执行
root@localhost [(none)]>reset master; Query OK, 0 rows affected (0.01 sec) root@localhost [(none)]>SET GLOBAL gtid_purged='60b08d3b-9c23-11e6-81c2-000c29d40ed7:1-605'; Query OK, 0 rows affected (0.01 sec)
l 链接到主
root@localhost [(none)]>change master to master_host='10.0.0.6', master_user='root', master_password='123456', master_port=3306, master_auto_position=1; Query OK, 0 rows affected, 2 warnings (0.13 sec) root@localhost [(none)]>start slave; Query OK, 0 rows affected (0.01 sec) root@localhost [(none)]>show slave status\G
l 校验数据一致性
四、用xtrabackup搭建基于GTID的从库
l 在主上作:
[root@bogon ~]# innobackupex --user=root --password=123456 --defaults-file=/data/etc/my.cnf --socket=/home/work/mysql/tmp/mysql.sock /home/dbbackup/
l 在从上作:
[root@bogon ~]# innobackupex --copy-back --user=root --password=123456 /data/test/test/2016-12-13_23-05-52/
l 重启slave reset master;
如果在slave作xtrabackup,要注意GTID范围
l 从新链接
change master to master_host='10.0.0.6', master_user='root', master_password='123456', master_port=3306, master_auto_position=1;
l 校验数据一致性
PS:很是抱歉,本文是做者前面整理的,当时没有记录参考文档,再次向原创做者说声抱歉。
为了方便你们交流,本人开通了微信公众号,和QQ群291519319。喜欢技术的一块儿来交流吧