GTID复制

GTID复制

GTID原理介绍

GTID又叫全局事物ID,是一个已提交事物的编号,并且是一个全局唯一的编号,mysql5.6版本之后再主从复制类型上新增了GTID复制。
GTID是由server_uuid和事物ID组成的,即GTID=server_uuid:transaction_id.
server_id是数据库启动过程中自动生成的,每台机器的server-uuid不一样,
show global variables like ‘%uuid%’;
±--------------±-------------------------------------+
| Variable_name | Value |
±--------------±-------------------------------------+
| server_uuid | d915aee5-d6bd-11e7-ac78-000c29491195 |
±--------------±-------------------------------------+
1 row in set (0.01 sec)
server-uuid 存放在数据目录的auto.cnf文件下,而transaction_id就是事物提交时由系统顺序分配的一个不会重复的序列号。

GTID存在的价值

(1)GTID使用master_auto_position=1代替了基于binlog和position号的主从复制搭建方式,更便于主从复制的搭建。
(2)GTID可以知道事物在最开始是在哪个实例上提交的。
(3)GTID方便实现主从之间的failover,不需要繁琐的去找position和binlog了。

GTID复制的搭建

master:192.168.136.138
slave: 192.168.136.139

在master192.168.136.138上修改my.cnf文件,
log-bin=mysql-bin
server-id=138
gtid_mode=on
enforce-gtid-consistency=true
log-slave-updates=ON
重启mysql。
创建一个用户,用于slave执行复制
GRANT REPLICATION SLAVE ON . to ‘backup’@’%’ identified by ‘123’;

Slave192.168.136.139中的操作
(1)配置GTID
修改 /etc/my.cnf,在[mysqld]下添加:
server_id=139
log-bin=mysql-bin
read_only=on
gtid_mode=on
enforce-gtid-consistency=true
master_info_repository=TABLE
relay_log_info_repository=TABLE
log-slave-updates=ON
保存后重启MySQL
使用 change master 命令配置 master 信息
change master to master_host=‘192.168.136.138’,master_user=‘backup’,master_password=‘123’,master_auto_position = 1;
start slave;
检查slave状态
mysql> show slave status \G;
以下两项为 YES 说明复制成功
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
可以到master中做一些测试操作,到slave中检查是否已经同步

在主库执行show master status命令,通过Executed_Gtid_Set来查看执行过的GTID,
show master status\G
*************************** 1. row ***************************
File: mysql-bin.000001
Position: 591
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 807de6b3-c4d3-11e7-954f-000c29b46750:1-2
1 row in set (0.00 sec)

主库在执行flush logs;binlog数会自动加1,备库不会刷新。

几个重要的命令:

RESET MASTER

删除所有binlog,删除index file 中记录的所有binlog,只保留./mysql-bin.000001 文件,将日志索引文件清空,创建一个新的日志文件,这个命令通常仅仅用于第一次用于搭建主从关系的时的主库,
注意
reset master 不同于purge binary log的两处地方
1 reset master 将删除日志索引文件中记录的所有binlog文件,创建一个新的日志文件 起始值从000001 开始,然而purge binary log 命令并不会修改记录binlog的顺序的数值

备机运行reset master出现如下情景。
首先主备关系正常。
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

master:
show master status;
±-----------------±---------±-------------±-----------------±------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
±-----------------±---------±-------------±-----------------±------------------------------------------+
| mysql-bin.000005 | 447 | | | 807de6b3-c4d3-11e7-954f-000c29b46750:1-17 |
±-----------------±---------±-------------±-----------------±------------------------------------------+
1 row in set (0.00 sec)

slave:
show master status;
±-----------------±---------±-------------±-----------------±-------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
±-----------------±---------±-------------±-----------------±-------------------------------------------+
| mysql-bin.000001 | 886 | | | 807de6b3-c4d3-11e7-954f-000c29b46750:15-17 |
±-----------------±---------±-------------±-----------------±------------------------------------------
(这里看到gtid从15开始从新接入了)
Retrieved_Gtid_Set: 807de6b3-c4d3-11e7-954f-000c29b46750:1-17
Executed_Gtid_Set: 807de6b3-c4d3-11e7-954f-000c29b46750:15-17

同时发现binlog被删除了,只剩下最新的00001,index也被重置。
[root@localhost data]# ll
总用量 123012
-rw-r-----. 1 mysql mysql 56 12月 2 2017 auto.cnf
-rw-r-----. 1 mysql mysql 325 2月 6 00:44 ib_buffer_pool
-rw-r-----. 1 mysql mysql 12582912 2月 6 00:48 ibdata1
-rw-r-----. 1 mysql mysql 50331648 2月 6 00:48 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648 12月 2 2017 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912 2月 6 00:44 ibtmp1
-rw-r-----. 1 mysql mysql 70868 2月 6 00:48 localhost.localdomain.err
-rw-r-----. 1 mysql mysql 5 2月 6 00:44 localhost.localdomain.pid
-rw-r-----. 1 mysql mysql 1697 2月 6 00:48 localhost-relay-bin.000026
-rw-r-----. 1 mysql mysql 660 2月 6 00:48 localhost-relay-bin.000027
-rw-r-----. 1 mysql mysql 58 2月 6 00:48 localhost-relay-bin.index
drwxr-x—. 2 mysql mysql 4096 12月 2 2017 mysql
-rw-r-----. 1 mysql mysql 886 2月 6 00:48 mysql-bin.000001
-rw-r-----. 1 mysql mysql 19 2月 6 00:45 mysql-bin.index
drwxr-x—. 2 mysql mysql 4096 12月 2 2017 performance_schema
drwxr-x—. 2 mysql mysql 12288 12月 2 2017 sys
drwxr-x—. 2 mysql mysql 4096 2月 6 00:45 test
[root@localhost data]# cat mysql-bin.index
./mysql-bin.000001

2 reset master 不能用于有任何slave 正在运行的主从关系的主库。因为在slave 运行时刻 reset master 命令不被支持(5.6后支持),reset master 将master 的binlog从000001 开始记录,slave 记录的master log 则是reset master 时主库的最新的binlog,从库会报错无法找的指定的binlog文件。

In MySQL 5.6.5 and later, RESET MASTER also clears the values of the gtid_purged system variable (known as gtid_lost in MySQL 5.6.8 and earlier) as well as the global value of the gtid_executed (gtid_done, prior to MySQL 5.6.9) system variable (but not its session value); that is, executing this statement sets each of these values to an empty string (’’)

master:使用 reset master命令:
master节点:
mysql> reset master;
Query OK, 0 rows affected (0.04 sec)

mysql> show slave hosts;
Empty set (0.00 sec)

mysql> show master status;
±-----------------±---------±-------------±-----------------±------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
±-----------------±---------±-------------±-----------------±------------------+
| mysql-bin.000001 | 154 | | | |
±-----------------±---------±-------------±-----------------±------------------+
1 row in set (0.00 sec)

slave节点:
Slave_IO_Running: No
Slave_SQL_Running: Yes

Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: ‘could not find next log; the first event ‘’ at 4, the last event read from ‘./mysql-bin.000005’ at 447, the last byte read from ‘./mysql-bin.000005’ at 447.’

(生产主库切勿使用该命令)

RESET SLAVE

reset slave 将使slave 忘记主从复制关系的位置信息。该语句将被用于干净的启动, 它删除slave_master_info文件和slave_relay_log_info 文件以及所有的relay log 文件并重新启用一个新的relaylog文件。
使用reset slave之前必须使用stop slave 命令将复制进程停止。

注 所有的relay log将被删除不管他们是否被SQL thread进程完全应用(这种情况发生于备库延迟以及在备库执行了stop slave 命令),存储复制链接信息的master.info文件将被立即清除,如果SQL thread 正在复制临时表的过程中,执行了stop slave ,并且执行了reset slave,这些被复制的临时表将被删除。

RESET SLAVE ALL

在 5.6 版本中 reset slave 并不会清理存储于内存中的复制信息比如 master host, master port, master user, or master password,也就是说如果没有使用change master 命令做重新定向,执行start slave 还是会指向旧的master 上面。
当从库执行reset slave之后,将mysqld shutdown 复制参数将被重置。

在5.6.3 版本以及以后 使用 RESET SLAVE ALL 来完全的清理复制连接参数信息。
RESET SLAVE ALL does not clear the IGNORE_SERVER_IDS list set by CHANGE MASTER TO. This issue is fixed in MySQL 5.7. (Bug #18816897)
In MySQL 5.6.7 and later, RESET SLAVE causes an implicit commit of an ongoing transaction. See Section 13.3.3, “Statements That Cause an Implicit Commit”.

栗子:
mysql> reset slave all;
Query OK, 0 rows affected (0.02 sec)

mysql> start slave;
ERROR 1200 (HY000): The server is not configured as slave; fix in config file or with CHANGE MASTER TO。


在备机139执行命令stop slave;
mysql> GRANT REPLICATION SLAVE ON . to ‘backup’@’%’ identified by ‘123’;
Query OK, 0 rows affected, 1 warning (0.01 sec)

在原主机138执行命令:
change master to master_host=‘192.168.136.139’,master_user=‘backup’,master_password=‘123’,master_auto_position = 1;
start slave;

139查看:
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000002
Position: 479
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 807de6b3-c4d3-11e7-954f-000c29b46750:1-3,
d915aee5-d6bd-11e7-ac78-000c29491195:1
1 row in set (0.00 sec)

mysql> insert into t1 select 333;
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0

mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000002
Position: 732
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 807de6b3-c4d3-11e7-954f-000c29b46750:1-3,
d915aee5-d6bd-11e7-ac78-000c29491195:1-2
1 row in set (0.00 sec)

138查看:
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000001
Position: 1322
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 807de6b3-c4d3-11e7-954f-000c29b46750:1-3,
d915aee5-d6bd-11e7-ac78-000c29491195:1-2
1 row in set (0.00 sec)

138:
stop slave;
139:
start slave;

138:
mysql> insert into t1 select 444;
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0

mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000001
Position: 1575
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 807de6b3-c4d3-11e7-954f-000c29b46750:1-4,
d915aee5-d6bd-11e7-ac78-000c29491195:1-2
1 row in set (0.00 sec)

139:
show master status\G
*************************** 1. row ***************************
File: mysql-bin.000002
Position: 976
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 807de6b3-c4d3-11e7-954f-000c29b46750:1-4,
d915aee5-d6bd-11e7-ac78-000c29491195:1-2
1 row in set (0.00 sec)

通过807de6b3-c4d3-11e7-954f-000c29b46750:1-4,说明再次接入主备关系,gtid还是接着上次的写,另外reset slave all后,在配置主备关系,gtid还是能接着上次的继续写。


gtid_executed表

在5.7之后,gtid_executed这个值持久化了,在mysql库下新增了一张表gtid_executed:
select *from mysql.gtid_executed;
±-------------------------------------±---------------±-------------+
| source_uuid | interval_start | interval_end |
±-------------------------------------±---------------±-------------+
| 807de6b3-c4d3-11e7-954f-000c29b46750 | 1 | 6 |
| d915aee5-d6bd-11e7-ac78-000c29491195 | 1 | 2 |
±-------------------------------------±---------------±-------------+
备库执行reset master之后,flush logs,在查看:
mysql> select *from mysql.gtid_executed;
±-------------------------------------±---------------±-------------+
| source_uuid | interval_start | interval_end |
±-------------------------------------±---------------±-------------+
| 807de6b3-c4d3-11e7-954f-000c29b46750 | 7 | 8 |
±-------------------------------------±---------------±-------------+
1 row in set (0.00 sec)

该表会记录已经执行的gtid集合的信息,有了这张表,就不必像5.6版本时必须开启log_slave_updates参数,从库才可以进行复制,GTID会保存在gtid_executed表中,可以关闭从库的binlog,节约binlog的记录开销。另外在执行reset master 时会清空表内所有数据。

MySQL 5.7对于表mysql.gtid_executed的更新策略也有些不同,如果没有主服务器没有开启log_bin或者从服务器没有开启log_slave_updates,其会每一个事物更新表gtid_executed,这样服务器重启后可以快速知道当前服务器执行到的GTID位置。

**(重)**若MySQL服务器启用了二进制日志,则表mysql.gtid_executed的更新仅在二进制rotation时发生,因为发生重启等情况依旧可以通过扫描二进制日志判断得知当前运行的GTID位置。也就是说表gtid_executed并不是实时更新的。

mysql5.7还有一个gtid_executed_compression_period参数,用来控制gtid_executed表的压缩,该参数值默认为1000,意味着表压缩在执行完1000个事物之后开始。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值