MySQL GTID复制
什么是GTID
什么是GTID呢, 简而言之,就是全局事务ID(global transaction identifier ),最初由google实现,官方MySQL在5.6才加入该功能。
GTID是事务提交时创建分配的唯一标识符,所有事务均与GTID一一映射。
GTID的格式类似于:
5882bfb0-c936-11e4-a843-000c292dc103:1
这个字符串,用“:”分开,前面表示这个服务器的server_uuid,这是一个128位的随机字符串,在第一次启动时生成(函数generate_server_uuid),对应的variables是只读变量server_uuid。 它能以极高的概率保证全局唯一性,并存到文件
DATADIR/auto.cnf中。因此要注意保护这个文件不要被删除或修改。
第二部分是一个自增的事务ID号,事务id号+server_uuid来唯一标示一个事务。
一个GTID的生命周期包括:
1.事务在主库上执行并提交
给事务分配一个gtid(由主库的uuid和该服务器上未使用的最小事务序列号),该GTID被写入到binlog中。
2.备库读取relaylog中的gtid,并设置session级别的gtid_next的值,以告诉备库下一个事务必须使用这个值
3.备库检查该gtid是否已经被其使用并记录到他自己的binlog中。slave需要担保之前的事务没有使用这个gtid,也要担保此时已读取gtid,但未提交的事务也不能使用这个gtid.
4.由于gtid_next非空,slave不会去生成一个新的gtid,而是使用从主库获得的gtid。这可以保证在一个复制拓扑中的同一个事务gtid不变。
由于GTID在全局的唯一性,通过GTID,我们可以在自动切换时对一些复杂的复制拓扑很方便的提升新主库及新备库,例如通过指向特定的GTID来确定新备库复制坐标。
mysql> show global variables like '%gtid%';
+--------------------------+------------------------------------------+
| Variable_name | Value |
+--------------------------+------------------------------------------+
| enforce_gtid_consistency | ON |
| gtid_executed | 5882bfb0-c936-11e4-a843-000c292dc103:1-6 |
| gtid_mode | ON |
| gtid_owned | |
| gtid_purged | |
+--------------------------+------------------------------------------+
5 rows in set (0.00 sec) mysql> show global variables like '%uuid%';
+---------------+--------------------------------------+
| Variable_name | Value |
+---------------+--------------------------------------+
| server_uuid | 5882bfb0-c936-11e4-a843-000c292dc103 |
+---------------+--------------------------------------+
1 row in set (0.00 sec) shell> cat auto.cnf
[auto]
server-uuid=5882bfb0-c936-11e4-a843-000c292dc103
设置GTID复制
- 同步主从数据
mysql> SET @@global.read_only = ON;
Query OK, 0 rows affected (0.01 sec) - 停止所有数据库
shell> mysqladmin -u root -p shutdown
设置开发GTID模式并启动所有数据库
shell> vi my.cnf 添加如下内容
================================================================
[mysqld]
gtid_mode=ON
log-slave-updates=ON
enforce-gtid-consistency=ON #强制GTID的一致性
================================================================从库指定主库
mysql> CHANGE MASTER TO
-> MASTER_HOST = host,
-> MASTER_PORT = port,
-> MASTER_USER = user,
-> MASTER_PASSWORD = password,
-> MASTER_AUTO_POSITION = 1; mysql> START SLAVE;
Query OK, 0 rows affected (0.04 sec)禁止read-only模式
mysql> SET @@global.read_only = OFF;
Query OK, 0 rows affected (0.00 sec)
多线程复制基于库
MySQL 5.6之前的版本,同步复制是单线程的,队列的,只能一个一个执行,在5.6里,可以做到多个库之间的多线程复制,例如数据库里,存放着用户表,商品表,价格表,订单表,那么将每个业务表单独放在一个库里,这时就可以做到多线程复制,但一个库里的表,多线程复制是无效的。 注,每个数据库仅能使用一个线程,复制涉及到多个数据库时多线程复制才有意义
GTID复制的限制
GTID 模式实例和非GTID模式实例是不能进行复制的,要求非常严格,要么都是GTID,要么都不是
gtid_mode 是只读的,要改变状态必须1)关闭实例、2)修改配置文件、3) 重启实例
- 更新非事务引擎表
在同一事务中更新事务表与非事务表将导致多个GTIDs分配给同一事务
mysql> cretea table tt (id int) engine=myisam;
mysql> insert into tt values(1),(2);
mysql> cretea table t (id int) engine=innodb;
mysql> insert into t values(1),(2);
mysql> set autocommit = 0;
mysql> begin; mysql> update t set id = 3 where id =2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> update tt set id = 3 where id =2;
ERROR 1785 (HY000): When @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1, updates to non-transactional tables can
only be done in either autocommitted statements or single-statement transactions, and never in the same
statement as updates to transactional tables.
- CREATE TABLE … SELECT statements
不安全的基于语句复制,实际是两个独立的事件,一个用于建表,一个用于向新表插入源表数据。
mysql> create table t engine=innodb as select * from tt;
ERROR 1786 (HY000): CREATE TABLE ... SELECT is forbidden when @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1.
- 临时表
事务内部不能执行创建删除临时表语句,但可以在事务外执行,但必须设置set autocommit = 1
mysql> create temporary table tttt(id int);
ERROR 1787 (HY000): When @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1, the statements CREATE TEMPORARY TABLE and
DROP TEMPORARY TABLE can be executed in a non-transactional context only, and require that AUTOCOMMIT = 1.
mysql> set autocommit = 1;
Query OK, 0 rows affected (0.00 sec) mysql> create temporary table tttt(id int);
Query OK, 0 rows affected (0.04 sec)
- 不执行不支持的语句
启用--enforce-gtid-consistency选项启动GTID模式,上述不支持的语句将会返回错误。
运维操作
a. 忽略复制错误
当备库复制出错时,传统的跳过错误的方法是设置sql_slave_skip_counter,然后再START SLAVE。
但如果打开了GTID,就会设置失败:
mysql> stop slave;
Query OK, 0 rows affected (0.03 sec) mysql> set global sql_slave_skip_counter = 1;
ERROR 1858 (HY000): sql_slave_skip_counter can not be set when the server is running with @@GLOBAL.GTID_MODE = ON.
Instead, for each transaction that you want to skip, generate an empty transaction with the same GTID as the transaction
提示的错误信息告诉我们,可以通过生成一个空事务来跳过错误的事务。
我们手动产生一个备库复制错误:
[slave]
mysql> alter table t add primary key pk_id(id);
Query OK, 2 rows affected (0.12 sec)
Records: 2 Duplicates: 0 Warnings: 0 mysql> insert into t values(1);
mysql> insert into t values(4);
mysql> insert into t values(5); mysql> show master status ;
+-------------------+----------+--------------+------------------+-------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------------------------------+
| mysql-info.000004 | 914 | | | 5882bfb0-c936-11e4-a843-000c292dc103:1-17 |
+-------------------+----------+--------------+------------------+-------------------------------------------+
1 row in set (0.00 sec) mysql> show slave status \G
*************************** 1. row ***************************
...
Slave_IO_Running: Yes
lave_SQL_Running: No
Last_Errno: 1062
Last_Error: Could not execute Write_rows event on table db_test.t; Duplicate entry '1' for key 'PRIMARY',
Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-info.000004, end_log_pos 401
Retrieved_Gtid_Set: 5882bfb0-c936-11e4-a843-000c292dc103:1-15
Executed_Gtid_Set: 5882bfb0-c936-11e4-a843-000c292dc103:1-14,
f1e6584a-c935-11e4-a840-000c29348dbe:1
Auto_Position: 1
1 row in set (0.00 sec) mysql> SET @@SESSION.GTID_NEXT= '5882bfb0-c936-11e4-a843-000c292dc103:15';
Query OK, 0 rows affected (0.00 sec) mysql> begin;
Query OK, 0 rows affected (0.00 sec) mysql> commit;
Query OK, 0 rows affected (0.00 sec) mysql> SET SESSION GTID_NEXT = AUTOMATIC; mysql> start slave; mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Last_Errno: 0
Retrieved_Gtid_Set: 5882bfb0-c936-11e4-a843-000c292dc103:1-17
Executed_Gtid_Set: 5882bfb0-c936-11e4-a843-000c292dc103:1-17,
f1e6584a-c935-11e4-a840-000c29348dbe:1
Auto_Position: 1
1 row in set (0.00 sec)
再查看show slave status,就会发现错误事务已经被跳过了。这种方法的原理很简单,空事务产生的GTID加入到GTID_EXECUTED中,
这相当于告诉备库,这个GTID对应的事务已经执行了,此时主从数据不一致。
b.重指主库
c.适当减小binlog文件的大小
MySQL GTID复制的更多相关文章
- MySQL GTID复制Slave跳过错误事务Id以及复制排错问题总结
GTID复制典型的复制错误有两种:1,数据对象级别的错误,包括主库上update的数据在从库上不存在,主从逐渐冲突,库表索引等对象的冲突等等, 如果是纯粹的跳过错误的话,这一类的错误需要跳过思路是 ...
- MYSQL GTID 复制
MySQL5.7以后都基本用GTID方式复制了,相对于binlog和position号方式,在failover时候减少很多人工切换操作 GTID,global transaction identiti ...
- MySQL GTID复制错误处理之跳过错误
某Slave报错信息: mysql> show slave status\G; mysql> show slave status\G; ************************** ...
- 【3.2】【mysql基本实验】mysql GTID复制(基于空数据的配置)
概述:本质上和传统异步复制没什么区别,就是加了GTID参数. 且可以用传统的方式来配置主从,也可以用GTID的方式来自动配置主从. 这里使用GTID的方式来自动适配主从. 需要mysql5.6.5以上 ...
- (5.8)mysql高可用系列——MySQL中的GTID复制(实践篇)
一.基于GTID的异步复制(一主一从)无数据/少数据搭建 二.基于GTID的无损半同步复制(一主一从)(mysql5.7)基于大数据量的初始化 正文: [0]概念 [0.5]GTID 复制(mysql ...
- 与MySQL传统复制相比,GTID有哪些独特的复制姿势?
与MySQL传统复制相比,GTID有哪些独特的复制姿势? http://mp.weixin.qq.com/s/IF1Pld-wGW0q2NiBjMXwfg 陈华军,苏宁云商IT总部资深技术经理,从事数 ...
- mysql之 MySQL 主从基于 GTID 复制原理概述
一. 什么是GTID ( Global transaction identifiers ):MySQL-5.6.2开始支持,MySQL-5.6.10后完善,GTID 分成两部分,一部分是服务的UUid ...
- mysql之 mysql 5.6不停机主从搭建(一主一从基于GTID复制)
环境说明:版本 version 5.6.25-log 主库ip: 10.219.24.25从库ip:10.219.24.22os 版本: centos 6.7已安装热备软件:xtrabackup 防火 ...
- MySQL的GTID复制与传统复制的相互转换
主库:192.168.225.128:3307从库1:192.168.225.129:3307 Gtid作为5.6版本以来的杀手级特性,却因为不支持拓扑结构内开关而饱受诟病.如果你需要从未开启GTID ...
随机推荐
- ArrayList遍历的4种方法
public class ArrayListDemo { public static void main(String args[]){ List<String> list = new A ...
- Service-level agreement
Service-level agreement - Wikipedia https://en.wikipedia.org/wiki/Service-level_agreement
- 通过命令打包apk
平时使用android studio打包,方便快捷,对命令不太熟悉,但在上传apk包到应用市场时,需要认领apk,“认领页的[选择APK]”不是上传您要更新的APK应用文件,而是下载我们提供的空包文件 ...
- XMU C语言程序设计实践(5)
• 使用动态链表完成一个简单的商品库存信息管理系统. • 商品信息包括如下字段:商品号.商品名称.商品库存 • 函数 create:接收用户输入的商品号和商品名称的 ...
- iOS UI控件之间的关系图
- 恢复MySQL数据库删除的数据
在日常运维工作中,对于数据库的备份是至关重要的!数据库对于网站的重要性使得我们对 MySQL 数据库的管理不容有失!然而是人总难免会犯错误,说不定哪天大脑短路了,误操作把数据库给删除了,怎么办? 下面 ...
- 编译android内核和文件系统,已经安装jdk,提示build/core/config.mk:268: *** Error: could not find jdk tools.jar
1:确保安装jdk,如果没有安装请移布:http://www.cnblogs.com/jiuyueguang/p/3156621.html 2:如果已经安装了jdk,还是提示此错误, 解决方法 请确保 ...
- Maze 解题报告
Maze Description You are given a special Maze described as an n*m matrix, please find the shortest ...
- Silverlight 2中实现文件上传和电子邮件发送
Silverlight 2中实现文件上传和电子邮件发送 [收藏此页] [打印] 作者:IT168 TerryLee 2008-05-30 内容导航: 使用Web Service上传文件 [I ...
- 使用gcc找出头文件的路径
参考 http://stackoverflow.com/questions/13079650/how-can-i-find-the-header-files-of-the-c-programming- ...