首页 > 数据库 > MySQL > mysql replication之GTID
5.6引入,在整个复制拓扑结构内,每个事务拥有自己全局唯一标识,,每个GTID对应一个事务;。
GTID包含两个部分,一部分是实例的UUID,另一部分是实例内递增的整数,GTID = server_uuid:transaction_id,。
注:第一次启动mysql会生成server_uuid并存于数据目录的auto.cnf;
一旦GTID对应的事务被执行,会加入当前实例的gtid_executed集合,后续相同GTID的事务则直接被忽略;
流程
1 主库执行事务,分配GTID并记入binlog;
2 slave解析binlog,将GTID赋给gtid_next并于下一个事务使用此GTID,gtid_next位于session context;
3 slave使用GTID前先做检查,确保其既没有被使用过(gtid_executed), 也没有被其他session正在使用(gtid_owned),多个客户端不可并发运行同一个事务;
配置参数
主备都要声明 gtid-mode = ON & enforce-gtid-consistency = ON;
Gtid_executed:实例已执行的所有GTID集合;服务器启动时,读取最新的binlog,赋予union(previous_gtids_log_event, gtid_log_event);
Gtid_purged:已清除的binlog中包含的GTID集合;服务器启动时,读取最旧binlog的previous_gtid_log_event并将其赋值;每purge一个binlog,则重置一次;reset master会将其重置为空;
注:任意时刻,实例当前binlog中可以找到的事务范围为GTID_SUBTRACT(@@global.gtid_executed, @@global.gtid_purged);
Gtid_owned:只读变量,分别描述session和global当前拥有的gtid集合;
Gtid_next:
指定下一个GTID获取的方式,有3种选项
1 automatic,使用下一个自动产生的GTID;
2 anonymous,不使用GTID;
3 GTID(格式为UUID:NUMBER),即下一个事务采用此GTID;
转化replication
对已有的replication,将其转化为GTID模式;
1 将主备都设置为read-only,并确保slave与master同步;
2 master和slave,开启GTID,binlog和log-slave-updates(备库);
3 将slave以auto-positioning方式连接到master;
4 去除master和slave的read-only限制;
具体步骤
1
主备均执行SET @@global.read_only = ON;
2
重启master
mysqld_safe --gtid_mode=ON --log-bin --log-slave-updates --enforce-gtid-consistency &
重启slave,禁止启动IO和SQL thread
mysqld_safe --gtid_mode=ON --log-bin --log-slave-updates --skip-slave-start --enforce-gtid-consistency &
注: --gtid_mode为枚举而非布尔类型,故只能声明on或者off,赋值0或1会出现问题;--enforce-gtid-consistency则是禁止gtid unsafe语句执行;
3 slave指向master
mysql> CHANGE MASTER TO
> MASTER_HOST = host,
> MASTER_PORT = port,
> MASTER_USER = user,
> MASTER_PASSWORD = password,
> MASTER_AUTO_POSITION = 1;
注:若要使用file+position模式,须将MASTER_AUTO_POSITION = 0
开启slave IO和SQL线程,
mysql> START SLAVE;
4 去除master和slave的read-only限制
SET @@global.read_only = OFF;
除此之外还有其他方法http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-failover.html
限制
GTID依附于事务,
1 更新非事务引擎
非事务引擎单条DML被视为一个事务,倘若在一个事务中和innodb混合使用,可能导致单条事务生成多个GTID;
2 create table … select
若采用row-based,该sql常常被分解成两个独立事件:a 创建表;b 插入数据;
事务可能会为这两个事件分配同一个GTID,导致slave把后面的insert忽略;
3 临时表
手工创建的临时表应该独立于任何事务之外(autocommit = 1);
4 不支持sql_slave_skip_counter
slave若要跳过事务,需设置gtid_executed或gtid_next;
5 mysql_upgrade
其会更新系统表(MyISAM),因此使用时须设置—gtid-mode=off,或者—write-binlog=off(5.6.7默认开启);
GTID的开销
1 previous_gtid_log_event
位于binlog开头,记录此binlog之前的GTID列表(对应@@gtid_purged ),外加40字节 * number_of_masters;
2 Gtid_log_event
44字节,位于每个事务之前;
https://blogs.oracle.com/MySQL/entry/deep_dive_into_gtids_and
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/15480802/viewspace-1432655/ ,如需转载,请注明出处,否则将追究法律责任。