MySQL 5.7.6: 如何不停服务开启复制拓扑内的GTID

相关worklog:
http://dev.mysql.com/worklog/task/?id=7083    (强烈建议阅读)
Gtid作为5.6版本以来的杀手级特性,却因为不支持拓扑结构内开关而饱受诟病。如果你需要从未开启GTID的环境升级到开启GTID,需要把这个复制结构里的实例shutdown后,再重启。相信这对于任何24小时服务的互联网应用都是不可接受的。

从5.7.6开始,终于支持在线动态设置gtid_mode和enforce_gtid_consistency了。在介绍如何通过动态设置GTID MODE来开启主备复制结构的GTID之前,我们先介绍几组概念。
匿名事务:对于一个匿名事务,在主库上是不带GTID的,其传递到备库执行也不应该产生GTID。
GTID_MODE
OFF
彻底关闭GTID,如果关闭状态的备库接受到带GTID的事务,则复制中断
OFF_PERMISSIVE
可以认为是关闭GTID前的过渡阶段,主库在设置成该值后不再生成GTID,备库在接受到带GTID 和不带GTID的事务都可以容忍
主库在关闭GTID时,执行事务会产生一个Anonymous_Gtid事件,会在备库执行:
SET @@SESSION.GTID_NEXT= ‘ANONYMOUS’
备库在执行匿名事务时,就不会去尝试生成本地GTID了
ON_PERMISSIVE
可以认为是打开GTID前的过渡阶段,主库在设置成该值后会产生GTID,同时备库依然容忍带GTID和不带GTID的事务
ON
完全打开GTID,如果打开状态的备库接受到不带GTID的事务,则复制中断
配置的兼容性矩阵(从worklog上抄的。。):
   Master GTID_MODE    OFF  OFF_PERMISSIVE  ON_PERMISSIVE  ON
    Slave GTID_MODE
                OFF     Y           Y           N          N
     OFF_PERMISSIVE     Y           Y           Y          Y*
      ON_PERMISSIVE     Y           Y           Y          Y*
                 ON     N           N           Y          Y*

   N - Slave thread will stop with an error instead of connect
   Y - GTID_MODEs are compatible
   * - AUTO_POSITION can be used
        GTID_NEXT    AUTOMATIC  AUTOMATIC   ANONYMOUS  UUID:NUMBER
                     binlog on  binlog off
        GTID_MODE
              OFF    anonymous  anonymous   anonymous  error
   OFF_PERMISSIVE    anonymous  anonymous   anonymous  UUID:NUMBER
    ON_PERMISSIVE    new GTID   anonymous   anonymous  UUID:NUMBER
               ON    new GTID   anonymous   error      UUID:NUMBER

  Legend:
    anonymous - Generate an anonymous transaction.
        error - Generate an error and fail to execute 'SET GTID_NEXT'.
  UUID:NUMBER - Generate a GTID with the specified UUID:NUMBER.
     new GTID - Generate a GTID with an automatically generated number.
可动态配置的ENFORCE_GTID_CONSISTENCY:
WARN
在开启GTID之前,可以设置成WARN来观察实例负载中是否存在不兼容GTID的语句,当前包括:
CREATE TABLE ..SELECT
混合非事务和事务引擎的事务
在开启的事务中执行CREATE/DROP TEMPORARY TABLE
设置成WARN时,用户负载能保证正常,错误日志里会记录下来这些语句信息
ON
打开选项,上述的几种语句将给客户端返回错误。
由于动态设置该选项,我们考虑如下序列,
trx1 begin;
trx1 由于当前选项off,可以执行混合非事务引擎的事务
——另外一个session打开该选项
trx1 commit
为了解决这个问题,在内部检测到GTID不安全的语句时,使用一个计数器统计,只有该值为0时,才允许打开该选项
OFF
关闭该选项,则无法打开GTID_MODE
不管GTID_MODE是否打开还是关闭,总是在ROTATE时产生Previous_gtid_event,其目的是为了防止在反复切换GTID_MODE的过程中,不丢失之前的GTID_EXECUTED和GTID_PURGED。(WL#7592)
CREATE TABLE AS SEELCT这样的SQL,在gtid 打开时,依然不允许执行,但在enforce_gtid_consistency刮泥时, 格式发生了变化,在之前的版本中的binlog格式为:
BEGIN;CREATE TABLE;INSERT;COMMIT;
新的版本修改成了:
Anonymous_Gtid;
CREATE;
Anonymous_Gtid;
BEGIN;INSERT;COMMIT
步骤:
我们来看看如何通过动态设置升级主备。(注意你的复制结构里的实例必须全部先升级到5.7.6及之后的版本)
(你也可以从官方文档http://dev.mysql.com/doc/refman/5.7/en/replication-mode-change-online-enable-gtids.html 来获得开启gtid的流程)
我们假定你的workload 是和Gtid相兼容的,因此跳过设置enforce_gtid_consistency=warn这个步骤以观察不兼容gtid的负载
Step 1:
在每台实例上执行:SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON
Step 2:
在每台实例上执行:SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE
当设成OFF_PERMISSIVE时,备库可以接受任何带GTID或不带GTID的事务,但此时还没有事务拥有GTID
Step 3:
在每台实例上执行:SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE
当设成ON_PERMISSIVE时,主库开始生成GTID,备库依然容忍带GTID和不带GTID的事务。
Step 4:
检查实例上的status变量ONGOING_ANONYMOUS_TRANSACTION_COUNT值为0
假定这种场景:
a.事务设置GTID_NEXT=‘ANONYMOUS’,然后执行事务,这是允许的,因为当前GITD_MODE为ON_PERMISSIVE
b.另外一个session设置GTID_MODE = ON;
c.事务提交
这可能产生不一致的状态,即打开GTID后,依然存在匿名事务,因此在内部维持了一个计数器ONGOING_ANONYMOUS_TRANSACTION_COUNT来维持匿名事务的数量,只有这个值为0时,再去设置GIT_MODE为ON
Step 5:
等待所有的复制完成,没有延迟,做一次flush logs,然后将前面的日志purge掉, 这些日志包含带GTID和不带GTID的事务。
Step 6:
在每台实例上执行:SET @@GLOBAL.GTID_MODE = ON
当然这些配置需要写入配置文件中,防止重启后丢失
基本上和开启的步骤是互逆的。
Step 1:
通过change master关闭MASTER_AUTO_POSITION
Step 2:
在每台实例上执行:
SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;
Step 3:
在每台实例上执行:
SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
Step 4:
确认所有的gtid_owned集合为空,通过show variables查看
Step5:
等待当前日志已完全被备库复制完成,关闭GTID,设置GTID_MODE=OFF
同样的,这些混合了GTID和非GTID的事务也需要被purge掉。
关于如何确认匿名事务(没有gtid的事务)被完全执行完成,参考文档http://dev.mysql.com/doc/refman/5.7/en/replication-mode-change-online-verify-transactions.html
另外强烈推荐阅读worklog:http://dev.mysql.com/worklog/task/?id=7083 在这个worklog中以大篇幅的字数介绍了所有可能遇到的情况及处理策略。。

原创文章,转载请注明: 转载自Simple Life

本文链接地址: MySQL 5.7.6: 如何不停服务开启复制拓扑内的GTID

Post Footer automatically generated by wp-posturl plugin for wordpress.


Comments

Leave a Reply

Your email address will not be published. Name and email are required


Current month ye@r day *