Migration from classic replication to GTID replication(Online)

从mysql 5.6.5版本号開始支持GTID,如今大部分生产环境也開始慢慢切换到GTID模式。为什么要切换到GTID复制模式?

●Setting up MySQL replication is so simple now!

● Consistency is guaranteed between master and slaves.

● Simple to determine inconsistency.

● Simple to do Point in Time Recovery (PiTR).

● Fail-over process become much easier.

● Automatic fail-over scripts are easy to implement now.

因为改变GTID_MODE 变量须要重新启动mysql,所以这让我们不停库切换到GTID变得不可能。以下有两篇文章介绍了怎样在线切换,booking.com和facebook的两种方案

In a previous post I was talking about How
to Setup MySQL Replication
 using the classic method (based on binary logs information). In this article I‘ll go through the transaction-based replication implementation using GTID in
different scenarios.

The following topics will be covered in this blog:

What is the concept of GTID protocol?

GTID is a Global Transaction IDentifier which introduced in MySQL 5.6.5. It‘s not only unique on the server it was originated but it‘s unique among all servers in a replication setup.

GTID also guarantee consistency because once a transaction is committed on a server, any other transaction having the same GTID will be ignored, i.e. a committed transaction on a master will be applied only once on the slaves.

GTID consists of two parts separated by a column {source_id:transactions_id}.

WHERE

  • source_id: Normally the server‘s UUID on which the transaction originates. e.g. "b9b4712a-df64-11e3-b391-60672090eb04" .
  • transaction_id: A sequence number determining the order of the committed transaction.

The following is the GTID for the third transaction on a server having the uuid "b9b4712a-df64-11e3-b391-60672090eb04":

b9b4712a-df64-11e3-b391-60672090eb04:3

As a new protocol in MySQL there is a set of new related variables, the following are the most important ones (IMHO):

  • gtid-mode: ON|OFF to enable or disable GTID, this is not a Boolean variable (0 and 1 are not acceptable).
  • enforce-gtid-consistency: prevent executing the non transactionally safe statements, like: 
    • CREATE TABLE .. SELECT.
    • CREATE TEMPORARY TABLE (inside a transaction).
    • Statements that update nontransactional tables inside a transaction.
  • gtid_purged: The set of transactions that have been purged from the binary logs.
  • gtid_executed: The set of transactions which already executed on that server.
  • gtid_next: The GTID which will be used for the next transaction.

GTID Replication Implementation

Fresh Installations

Fresh installation means that there‘s no data yet in the master or in other words, we are building a replication setup from scratch.

The implementation process is divided into two parts:

MASTER‘S SIDE CONFIGURATION:

  • Add the following variables to the MySQL configuration file (my.cnf):

    [mysqld] server-id=1 log-bin=mysql-bin binlog_format=ROW gtid-mode=on enforce-gtid-consistency log-slave-updates
  • Restart MySQL so that configuration changes take place:
    shell> service mysql restart
  • Create a MySQL user to be used by the slave:
    SQL> GRANT REPLICATION SLAVE ON *.* TO ‘slave_user_name‘@‘slave_ip‘ IDENTIFIED BY ‘s3cret‘;

SLAVE‘S SIDE CONFIGURATION:

  • Add the following variables to the my.cnf file:

    [mysqld] server-id=2 log-bin=mysql-bin binlog_format=ROW relay_log=relay-log skip-slave-start gtid-mode=on enforce-gtid-consistency log-slave-updates
  • Restart MySQL so that configuration changes take place:
    shell> service mysql restart
  • Set the master information on the slave‘s:

    Unlike the classic method, we don‘t need the master‘s binary log information and only what we need is to specify MASTER_AUTO_POSITION=1 instead:

    SQL> CHANGE MASTER TO -> MASTER_HOST=‘master_ip‘, -> MASTER_PORT=3306, -> MASTER_USER=‘slave_user_name‘, -> MASTER_PASSWORD=‘s3cret‘, -> MASTER_AUTO_POSITION=1;
  • Start replication:
    SQL> START SLAVE;
  • Check the replication status:
    SQL> show slave status\G Slave_IO_State: Waiting for master to send event Master_Host: 127.0.0.1 Master_User: gtid_repl Master_Port: 3320 Connect_Retry: 60 Master_Log_File: mysql-bin.000007 Read_Master_Log_Pos: 191 Relay_Log_File: relay-log.000004 Relay_Log_Pos: 401 Relay_Master_Log_File: mysql-bin.000007 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: . . . . Retrieved_Gtid_Set: b9b4712a-df64-11e3-b391-60672090eb04:1-2 Executed_Gtid_Set: b9b4712a-df64-11e3-b391-60672090eb04:1-2 Auto_Position: 1

Adding New Slave

It‘s a very simple process to add a new slave to a running replication (or setup replication with existing data) where GTID is being used:

  • Backup the master server

    shell> mysqldump -u root -p --all-databases --flush-privileges --single-transaction --flush-logs --triggers --routines --events --hex-blob >/path/to/backupdir/full_backup-$TIMESTAMP.sql
  • On the new slave, use the same MySQL configuration as described above (except the server id which should be unique) and restart it.
  • Restore the backup file taken from the master.
  • Use change master to with MASTER_AUTO_POSITION=1
  • Start the slave.

Is it so simple like that!! How did the slave know the backup position?

What if some transactions were executed on the master after that backup?

Actually, when GTID is enabled, mysqldump includes the last transaction ID (GTID) at the time of taking the backup:

-- -- GTID state at the beginning of the backup -- SET @@GLOBAL.GTID_PURGED=‘b9b4712a-df64-11e3-b391-60672090eb04:1-7‘;

After restoring the backup the variable GTID_EXECUTED will be equal to GTID_PURGED (the above value) and when the slave starts it first sends the range of GTIDs it has executed (GTID_EXECUTED) to the master so that the master
can sends back every missing transaction which was not applied yet on the slave.

Migration from classic replication to GTID replication

How to perform the migration?

To migrate an already running replication using the classical method to GTID replication, the following steps should be done:

  • Ensure that all servers (master and slaves) are in the same point by setting the master server as read only (SET GLOBAL read_only=ON;) and wait until all slaves catch up the master‘s data.
  • Shutdown MySQL on all servers and add the GTID variables to the configuration files.
  • Beside the GTID variables, add read-only to the master‘s configuration and skip-slave-start to the slaves configurations.
  • Start MySQL service on all servers.
  • Issue the change master command with MASTER_AUTO_POSITION=1 on all slaves and then start them.
  • Make the master writable again by SET GLOBAL read_only=OFF; (don‘t forget to remove/hash it from the master‘s my.cnf file as well).

Is online migration from classic to GTID replication available?

At the time of writing this article, the online migration is not applicable - as you can see from the above steps - we have to shutdown ALL servers at the same time and that is because of two reasons:

  • GTID can NOT be enabled online because GTID_MODE is a read only variable (having this variable to be dynamic is already inOracle‘s
    plan
    ).
  • Replication can NOT be established between two or more servers having different values for GTID_MODE, i.e. either GTID is enabled on ALL servers or disabled on ALL servers.

Workaround ?

?

There‘s a feature request (by MySQL Devs team at Booking.com)
to have an extra GTID mode (ANONYMOUS_IN-GTID_OUT) which allows a slave to receives anonymous transactions (transactions from master having GTID_MODE = OFF which do not have GTIDs) and assigns GTIDs for those transactions. In this case, this slave could be
used as an intermediate server between master having GTID disabled and slaves having GTID enabled (it will be slave for the master and master for the other slaves)

The online migration steps would be:

  • Restart a slave (lets name it slaveA) using the GTID_MODE = ANONYMOUS_IN-GTID_OUT.
  • Rolling restart to the other slaves to use the normal GTID_MODE=ON and pointing them to slaveA as a new master.
  • Point the application to write to slaveA instead of the old master.
  • Restart the old master to use GTID_MODE=ON and having slaveA as a master.

Note: This is not yet available in Oracle binaries

More information on this could be find here.

GTID Benefits

  • Simplifies the setup of MySQL replication as master‘s binary logs information is not needed anymore (binary log file name and position).
  • Consistency is guaranteed between master and slave as the committed transaction on the master will be applied only once on the slave.
  • Simple to determine whether masters and slaves are consistent or not.
  • Fail-over process is much easier. When the master fail to operate, no need to calculate a slave‘s binary logs information before promoting it to be new master. MASTER_AUTO_POSITION=1 will do the job as all transactions
    in all servers inside the replication have the same GTID.
  • Automatic fail-over scripts is now much easier to implement.

In a future post, I will write about how to troubleshoot GTID replication.

Online GTID rollout now available in Percona Server 5.6

Global Transaction IDs (GTIDs) are one of my favorite features of MySQL 5.6. The main limitation is that you must stop all the servers at the same time to allow GTID-replication. Not everyone can afford to take a downtime so this
requirement has been a showstopper for many people. Starting with Percona Server 5.6.22-72.0 enabling GTID replication can be done without almost no
downtime
. Let’s see how to do it.

Implementation of the Facebook patch

Finding a solution to migrate to GTIDs with no downtime is not a new idea, and several companies have already developed their own patch. The 2 best known implementations are the one from Facebook and
the one from Booking.com.

Both options have pros and cons, and we finally chose to port the Facebook patch and add a new setting (gtid_deployment_step).

Performing the migration

Let’s assume we have a master-slaves setup with 4 servers A, B, C and D. A is the master:

The 1st step is to take each slave out of rotation, one at a time, and set gtid_mode = ON andgtid_deployment_step
= ON
 (and also log_binlog_slave_updates andenforce_gtid_consistency).

gtid_deployment_step = ON means that a server will not generate GTIDs when it executes writes, but it will
record a GTID in its binary log if it gets an event from the replication stream tagged with a GTID.

The 2nd step is to promote one of the slaves to become the new master (for instance C) and to disablegtid_deployment_step.
It is a regular slave promotion so you should do it the same way you deal with planned slave promotions (for instance using MHA or your own scripts). Our
patch doesn’t help you do this promotion.

At this point replication will break on the old master as it has gtid_mode = OFF andgtid_deployment_step
= OFF
.

Don’t forget that you need to use CHANGE MASTER TO MASTER_AUTO_POSITION = 1 to enable GTID-based replication.

The 3rd step is to restart the old master to set gtid_mode = ON. Replication
will resume automatically, but don’t forget to set MASTER_AUTO_POSITION = 1.

The final step is to disable gtid_deployment_step on all slaves. This can be done dynamically:

Shell

1

mysql>SETGLOBALgtid_deployment_step=OFF;

and you should remove the setting from the my.cnf file so that it is not set again when the server is restarted.

Optionally, you can promote the old master back to its original role.

That’s it, GTID replication is now available without having restarted all servers at the same time!

Limitations

At some point during the migration, a slave promotion is needed. And at this point, you are still using position-based replication. The patch will not help you with this promotion so use your regular failover scripts. If you have
no scripts to deal with that kind of situation, make sure you know how to proceed.

Also be aware that this patch provides a way to migrate to GTIDs with no downtime, but not a way to migrate away from GTIDs with no downtime. So test carefully and make sure you understand all the new stuff that comes with GTIDs,
like the new replication protocol, or how to skip
transactions
.

Other topologies

If you are using master-master replication or multiple tier replication, you can follow the same steps. With multiple tier replication, simply start by setting gtid_mode
= ON
 and gtid_deployment_step = ON for the leaves first.

Conclusion

If you’re interested by the benefits of GTID replication but if taking a downtime has always scared you, you should definitely download the latest Percona
Server 5.6
 and give it a try!

时间: 2024-12-23 00:51:20

Migration from classic replication to GTID replication(Online)的相关文章

MySQL5.6 GTID Replication

MySQL 5.6 的新特性之一,是加入了全局事务 ID (Global Transaction ID) 来强化数据库的主备一致性,故障恢复,以及容错能力.官方文档:http://dev.mysql.com/doc/refman/5.6/en/replication-gtids.html在这篇文档里,我们可以知道GTID(全局事务 ID) 的官方定义是:GTID实际上是由UUID+TID组成的,其中UUID是一个MySQL实例的唯一标识,TID代表了该实例上已经提交的事务数量,并且随着事务提交单

maxscale配合MHA搭建读写分离的高可用架构(基于GTID replication主从架构,mysql5.6)

基于GTID的主从replication并配合MHA搭建高可用架构,请参考之前的博客:http://linzhijian.blog.51cto.com/1047212/1906434.这里只叙述如何在此基础上增加maxscale中间件,实现读写分离的功能. MaxScale是maridb开发的一个MySQL数据中间件,其配置简单,能够实现读写分离,并且可以根据主从状态实现写库的自动切换.官方文档:https://mariadb.com/kb/en/mariadb-enterprise/about

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

基本的M-S结构 现在master与slave主机数据一致: mysql> select * from t1; +------+ | id   | +------+ |    1 | |    2 | |    4 | +------+ 3 rows in set (0.00 sec) 我们来模拟故障现象: 在master上,通过设置sql_log_bin来控制命令是否写入二进制日志中,运行命令: set sql_log_bin=OFF; insert into t1 values(5); se

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

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 becau

Repair MySQL 5.6 GTID replication by injecting empty transactions

在前面文章我提到了两种关于如何修复 Mysql 5.6 GTID 主从数据库.我没有提到大家说熟知的方法 - ` GLOBAL SQL_SLAVE_SKIP_COUNTER = n`.原因很简单,如果你使用的是MysqlGTID,它是不工作的.那么问题来了: 有没有简单的方法跳过这单一事务 ?是的!注入空事务.让我们想象一下,从服务器上的复制不工作,因为下面一个错误: Last_SQL_Error: Error 'Duplicate entry '4' for key 'PRIMARY'' on

TimesTen 数据库复制学习:3. 配置Classic Replication单表复制

本文为一个动手实验,配置传统复制模式中的单表复制(非复制整库),配置2个数据库, master和一个subscriber.拓扑如下: 为简化,master和subscriber位于同一主机.同时,为和上一个实验保持一致,master和subscriber的DSN分别为master1和subscriber1. 创建DSN [ODBC Data Sources] master1=TimesTen 11.2.2 Driver subscriber1=TimesTen 11.2.2 Driver [ma

How-to setup gtid on replication

准备工作 Mysql 单机多实例详解What is the GTID of the replication 实验环境 Os: CentOS 6.XMysql: 5.6 单机多实例 [3306,3307]Hostname: lab.suzf.net 场景一:新机器 无数据 对于GTID的配置,主要修改配置文件中与GTID特性相关的几个重要参数 [mysqld_multi] mysqld = /usr/local/mysql/bin/mysqld_safe mysqladmin = /usr/loc

Failed to load slave replication state from table mysql.gtid_slave_pos: 1146: Table 'mysql.gtid_slave_pos' doesn't exist

http://anothermysqldba.blogspot.com/2013/06/mariadb-1003-alpha-install-on-fedora-17.html MariaDB 10.0.3 Alpha install on Fedora 17 x86_64 MariaDB 10.0.3 Alphawas just released. So for those of you that recall my previous MariaDB 5.5 install post, I d

涉及到复制和二进制日志中的选项和变量-Replication and Binary Logging Options and Variables

在搭建复制中,有些参数需要我们留意,在这里罗列出来,供大家参考一下,以GTID为基础 --server-id server-id:这是一个全局的可动态调整的变量,取值范围为0-4294967295,也就是2的32次方减1,这个选项必须在master和slave中都分别进行设置,如果不设置保持默认,则在连接过程中会产生错误.从而复制失败,将这个参数配置在my.cnf配置文件中,然后重启生效 2. --server_uuid server_uuid:这是一个全局只读的变量,非动态变量,以一个字符串的