How to create/restore a slave using GTID replication in MySQL 5.6

时间:2022-03-29 03:44:07

MySQL 5.6 is GA! Now we have new things to play with and in my personal opinion the most interesting one is the new Global Transaction ID (GTID) support in replication. This post is not an explanation of what is GTID and how it works internally because there are many documents about that:

http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html

One thing that worths to mention is that if you want GTID support log_slave_updates will need to be enabled in slave server and the performance impact should be taken in account.

Anyway, this post tends to be more practical, we will see how to create/restore new slaves from a master using GTID.

How to set up a new slave

The first thing that we need to know is that now Binary Logs and Position are not needed anymore with GTID enabled. Instead we need to know in which GTID is the master and set it on the slave. MySQL keeps two global variables with GTID numbers on it:

gtid_executed: it contains a representation of the set of all transaction logged in the binary log
gtid_purged: it contains a representation of the set of all transactions deleted from the binary log

So now, the process is the following:

  • take a backup from the master and store the value of gtid_executed
  • restore the backup on the slave and set gtid_purged with the value of gtid_executed from the master

The new mysqldump can do those tasks for us. Let’s see an example of how to take a backup from the master and restore it on the slave to set up a new replication server.

master > show global variables like 'gtid_executed';
+---------------+-------------------------------------------+
| Variable_name | Value |
+---------------+-------------------------------------------+
| gtid_executed | 9a511b7b-7059-11e2-9a24-08002762b8af:1-13 |
+---------------+-------------------------------------------+
master > show global variables like 'gtid_purged';
+---------------+------------------------------------------+
| Variable_name | Value |
+---------------+------------------------------------------+
| gtid_purged | 9a511b7b-7059-11e2-9a24-08002762b8af:1-2 |
+---------------+------------------------------------------+

Now we take a backup with mysqldump from the master:

# mysqldump --all-databases --single-transaction --triggers --routines --host=127.0.0.1 --port=18675 --user=msandbox --password=msandbox > dump.sql

It will contain the following line:

# grep PURGED dump.sql
SET @@GLOBAL.GTID_PURGED='9a511b7b-7059-11e2-9a24-08002762b8af:1-13';

Therefore during the dump recover process on the slave it will set GTID_PURGED to the GTID_EXECUTED value from the master.

So now, we just need to recover the dump and start the replication:

slave1 > show global variables like 'gtid_executed';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| gtid_executed | |
+---------------+-------+
slave1 > show global variables like 'gtid_purged';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| gtid_purged | |
+---------------+-------+
slave1 > source dump.sql;
[...]
slave1 > show global variables like 'gtid_executed';
+---------------+-------------------------------------------+
| Variable_name | Value |
+---------------+-------------------------------------------+
| gtid_executed | 9a511b7b-7059-11e2-9a24-08002762b8af:1-13 |
+---------------+-------------------------------------------+
slave1 > show global variables like 'gtid_purged';
+---------------+-------------------------------------------+
| Variable_name | Value |
+---------------+-------------------------------------------+
| gtid_purged | 9a511b7b-7059-11e2-9a24-08002762b8af:1-13 |
+---------------+-------------------------------------------+

The last step is to configure the slave using the auto-configuration method of GTID:

slave1 > CHANGE MASTER TO MASTER_HOST="127.0.0.1", MASTER_USER="msandbox", MASTER_PASSWORD="msandbox", MASTER_PORT=18675, MASTER_AUTO_POSITION = 1;

How to restore a slave in a bad and fast way

Let’s imagine that our slave has been down for several days and the binary logs from the master have been purged. This is the error we are going to get:

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.'

So, let’s try to solve it. First we have the bad and fast way, that is, point to another GTID that the master has in the binary logs. First, we get the GTID_EXECUTED from the master:

master > show global variables like 'GTID_EXECUTED';
+---------------+-------------------------------------------+
| Variable_name | Value |
+---------------+-------------------------------------------+
| gtid_executed | 9a511b7b-7059-11e2-9a24-08002762b8af:1-14 |
+---------------+-------------------------------------------+

And we set it on the slave:

slave> set global GTID_EXECUTED="9a511b7b-7059-11e2-9a24-08002762b8af:1-14"
ERROR 1238 (HY000): Variable 'gtid_executed' is a read only variable

Error! Remember, we get the GTID_EXECUTED from the master and set is as GTID_PURGED on the slave.

slave1 > set global GTID_PURGED="9a511b7b-7059-11e2-9a24-08002762b8af:1-14";
ERROR 1840 (HY000): GTID_PURGED can only be set when GTID_EXECUTED is empty.

Error again, GTID_EXECUTED should be empty before changing GTID_PURGED manually but we can’t change it with SET because is a read only variable. The only way to change it is with reset master (yes, on a slave server):

slave1> reset master;
slave1 > show global variables like 'GTID_EXECUTED';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| gtid_executed | |
+---------------+-------+
slave1 > set global GTID_PURGED="9a511b7b-7059-11e2-9a24-08002762b8af:1-14";
slave1> start slave io_thread;
slave1> show slave status\G
[...]
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
[...]

Now, if you don’t get any error like primary/unique key duplication then you can run the pt-table-checksum and pt-table-sync.

How to restore a slave in a good and slow way

The good way is mysqldump again. We take a dump from the master like we saw before and try to restore it on the slave:

slave1 [localhost] {msandbox} ((none)) > source dump.sql;
[...]
ERROR 1840 (HY000): GTID_PURGED can only be set when GTID_EXECUTED is empty.
[...]

Wop! It is important to mention that these kind of error messages can dissapear on the shell buffer because the restore of the dump will continue. Be cautious.

Same problem again so same solution too:

slave1> reset master;
slave1> source dump.sql;
slave1> start slave;
slave1> show slave status\G
[...]
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
[...]

Conclusion

With the new GTID we need to change our minds. Now binary log and position is not something we need to take in account, gtid_executed and gtid_purged are our new friends. Newer versions of Xtrabackup have full support of GTID. You can check the following blog post:

https://www.percona.com/blog/2013/05/09/how-to-create-a-new-or-repair-a-broken-gtid-based-slave-with-percona-xtrabackup/

注:

1、若要启用gtid,则slave server需要启用log_slave_updates参数。

2、使用gtid搭建的主从复制,不再关注binary log和position,现在关注gtid_executed和gtid_purged。

3、若要更新gtid_purged,则需要gtid_executed为空。

It is possible to update the value of this variable, but only when gtid_executed is the empty string, and therefore gtid_purged is the empty string. This can occur either when replication has not been started previously, or when replication was not previously using GTIDs. Prior to MySQL 5.7.6, this variable was settable only when gtid_mode=ON. In MySQL 5.7.6 and later, this variable is settable regardless of the value of gtid_mode.

Issuing RESET MASTER causes the value of this variable to be reset to an empty string.

执行reset master 可以清空global下的gtid_purged和gtid_extcuted,但不包括session值。

RESET MASTER also clears the values of the gtid_purged system variable as well as the global value of the gtid_executed system variable (but not its session value); that is, executing this statement sets each of these values to an empty string (''). In MySQL 5.7.5 and later, this statement also clears the mysql.gtid_executed table (see mysql.gtid_executed Table).

4、当主从中断了,而且主机已将从库需要的日志删除,就会报:

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.

此时,可以使用:

方法1:

 slave1> reset master;
slave1> show global variables like 'GTID_EXECUTED';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| gtid_executed | |
+---------------+-------+
slave1> set global GTID_PURGED="9a511b7b-7059-11e2-9a24-08002762b8af:1-14";
slave1> start slave io_thread;
slave1> show slave status\G

不过,这样做完后,需要检查一下数据是否一致,可能会出现数据不一致的情况。

方法2:

是从主机重新dump一份数据,导入。

 slave1> reset master;
slave1> source dump.sql;
slave1> start slave;
slave1> show slave status\G

此时,从库中的gtid_purged和gtid_extcuted值已不可用,而又无法修改,所以要使用reset master清空。

参考:

https://www.percona.com/blog/2013/05/09/how-to-create-a-new-or-repair-a-broken-gtid-based-slave-with-percona-xtrabackup/

http://dev.mysql.com/doc/refman/5.7/en/reset-master.html

http://dev.mysql.com/doc/refman/5.7/en/replication-options-gtids.html#sysvar_gtid_purged

How to create/restore a slave using GTID replication in MySQL 5.6的更多相关文章

  1. MySQL 5.6 GTID Replication【转】

    一. MySQL 5.6引入了GTID的概念,那么GTID是何方神圣?其实也不复杂,就是一个全局事务标示符.使用GTID时,每次事务提交都会在binlog里生成1个唯一的标示符,它由UUID和事务ID ...

  2. 基于GTID搭建主从MySQL

    目录 基于gtid搭建主从MySQL 一.GTID的使用 二.GTID的简介 三.GTID的构成 四.查看GTID的执行情况 4.1 gtid_executed 4.2 gtid_own 4.3 gt ...

  3. 基于GTID Replication主从数据不一致操作

    基本的M-S结构   现在master与slave主机数据一致:   mysql> select * from t1; +------+ | id   | +------+ |    1 | | ...

  4. 【转】How to create a new user and grant permissions in MySQL

    MySQL is one of the most popular database management systems. In this tutorial we will cover the ste ...

  5. MySQL5.6 GTID Replication

    MySQL 5.6 的新特性之一,是加入了全局事务 ID (Global Transaction ID) 来强化数据库的主备一致性,故障恢复,以及容错能力.官方文档:http://dev.mysql. ...

  6. MySQL 5.6 GTID Replication

    一. MySQL 5.6引入了GTID的概念,那么GTID是何方神圣?其实也不复杂,就是一个全局事务标示符.使用GTID时,每次事务提交都会在binlog里生成1个唯一的标示符,它由UUID和事务ID ...

  7. slave IO流程之一:mysql登陆过程(mysql_real_connect)

    最近看了slave IO的源码,发现slave IO的写relay log貌似是单线程单连接的,这让我有点小失望. slave IO的主函数是handle_slave_io,处理流程如下: 图1 ha ...

  8. Repair MySQL 5.6 GTID replication by injecting empty transactions

    Since SQL_SLAVE_SKIP_COUNTER doesn’t work with GTID we need to find a way to ignore that transaction ...

  9. How To Create a New User and Grant Permissions in MySQL

    How to Create a New User Let’s start by making a new user within the MySQL shell: CREATE USER 'newus ...

随机推荐

  1. 初探接口测试框架--python系列4

    点击标题下「蓝色微信名」可快速关注 坚持的是分享,搬运的是知识,图的是大家的进步,没有收费的培训,没有虚度的吹水,喜欢就关注.转发(免费帮助更多伙伴)等来交流,想了解的知识请留言,给你带来更多价值,是 ...

  2. IoC(控制反转)

    在传统的编程中,我们通过内部代码来控制组件之间的关系,但是这种实现方式,容易造成组件之间的高耦合.IoC能够很好地解决这个问题,它将组件间的关系从程序内部上提到外部容器来管理.IoC的核心目标是通过简 ...

  3. ubuntu12.10+NDK r9 编译 ffmpeg 的一些参考资料Perhaps you should add the directory containing `libssl.pc'

    首先入门级的 编译宝典: https://trac.ffmpeg.org/wiki/CompilationGuide/Android http://www.roman10.net/how-to-bui ...

  4. Excel01-不同的单元格输入同一数据

    第一步:按住Ctrl键,选择不同的单元格 第二步:选择完最后一个单元格后,输入需要的数据“YES”,按Ctrl+Enter键结束. 提示:按Ctrl+; 输入当前日期,再按ctrl+Enter实现全部 ...

  5. android-服务Service

    服务是在后台运行,负责更新内容提供器.发出意图.触发通知,它们是执行持续或定时处理的方式. 多线程一般捆绑服务执行任务,因为在activity中开辟多线程执行任务的话,子线程的生命周期得不到保障,可能 ...

  6. 原创-angularjs2不同组件间的通信

    AngualrJs2官方方法是以@Input,@Output来实现组件间的相互传值,而且组件之间必须父子关系,下面给大家提供一个简单的方法,实现组件间的传值,不仅仅是父子组件,跨模块的组件也可以实现传 ...

  7. 洛谷 P1903 [国家集训队]数颜色 / 维护队列

    墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. \(Q\) \(L\) \(R\) 代表询问你从第L支画笔到第R支画笔*有几种不同 ...

  8. ng工程升级cli版本

    全局更新ng 然后在工程里 ng update @angular/cli @angular/core

  9. ELK-elasticsearch-6.3.2插件【head,bigdesk,cerebro[kopf]】安装

    参考博客:linux下ElasticSearch.6.2.2集群安装与head.Kibana.X-Pack..插件的配置安装 参考博客:ELK5.5.1 插件安装实践纪要(head/bigdesk/k ...

  10. nohup 和 &的含义

    https://www.cnblogs.com/jinxiao-pu/p/9131057.html