MySQL复制之GTID跳过与FEDERATED存储引擎

在5.6开始,mysql支持基于gtid的复制。

要启用基于gtid的复制,得使用如下参数:

gtid_mode = ON
enforce_gtid_consistency = ON

gtid就是全局事务id。

全局的意思是在整个复制环境中这个全局中。

基于gtid复制就是master的每一个对数据库引起的变更(专业叫event)都会被标记一个gtid值。

一个gtid值像这样:e2e2f927-e75c-11e5-ac89-5c260a17ccde:20。

一个gtid-sets值表示很多event的集合,像这样:e2e2f927-e75c-11e5-ac89-5c260a17ccde:1-5500,表示e2e2f927-e75c-11e5-ac89-5c260a17ccde这个实例的1到5500号事务。

e2e2f927-e75c-11e5-ac89-5c260a17ccde,表示一个mysql实例的uuid值。20,表示事务号(也可以理解为事务序列号)。

在slave端我们可以show slave status\G一下,然后看到这样的输出:

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.77
                  Master_User: backup
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000018
          Read_Master_Log_Pos: 194
               Relay_Log_File: host_name-relay-bin.000038
                Relay_Log_Pos: 367
        Relay_Master_Log_File: mysql-bin.000018
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 194
              Relay_Log_Space: 744
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 2
                  Master_UUID: e2e2f927-e75c-11e5-ac89-5c260a17ccde
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set: 1cced57b-e75e-11e5-b742-5c260a17ccde:1-6,
e2e2f927-e75c-11e5-ac89-5c260a17ccde:1-5500

                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)


mysql>

红色部分Retrieved_Gtid_Set表示slave端接收到的gtid-set。在slave重启之后,该值会被清空。

而Executed_Gtid_Set表示slave端实际执行的gtid-set。


而我的测试环境中出现如下情况:

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.77
                  Master_User: backup
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000018
          Read_Master_Log_Pos: 1017
               Relay_Log_File: host_name-relay-bin.000038
                Relay_Log_Pos: 551
        Relay_Master_Log_File: mysql-bin.000018
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 1432
                   Last_Error: Error 'server name: 'fedlink' doesn't exist!' on query. Default database: 'test'. Query: 'CREATE TABLE `t_area` (
  `id` varchar(255) NOT NULL,
  `address` varchar(255) DEFAULT NULL,
  `level` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `sort` int(11) NOT NULL,
  `telephone` varchar(255) DEFAULT NULL,
  `visible` bit(1) NOT NULL,
  `parentId` varchar(255) DEFAULT NULL,
  `number` varchar(255) DEFAULT NULL,
  `theCode` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FKCB5AB178745ED9CF` (`parentId`)
) ENGINE=FEDERATED DEFAULT CHARSET=utf8
connection='fedlink/t_area''

                 Skip_Counter: 0
          Exec_Master_Log_Pos: 378
              Relay_Log_Space: 1567
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 1432
               Last_SQL_Error: Error 'server name: 'fedlink' doesn't exist!' on query. Default database: 'test'. Query: 'CREATE TABLE `t_area` (
  `id` varchar(255) NOT NULL,
  `address` varchar(255) DEFAULT NULL,
  `level` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `sort` int(11) NOT NULL,
  `telephone` varchar(255) DEFAULT NULL,
  `visible` bit(1) NOT NULL,
  `parentId` varchar(255) DEFAULT NULL,
  `number` varchar(255) DEFAULT NULL,
  `theCode` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FKCB5AB178745ED9CF` (`parentId`)
) ENGINE=FEDERATED DEFAULT CHARSET=utf8
connection='fedlink/t_area''

  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 2
                  Master_UUID: e2e2f927-e75c-11e5-ac89-5c260a17ccde
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State:
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp: 160322 11:00:14
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set: e2e2f927-e75c-11e5-ac89-5c260a17ccde:5501-5502
            Executed_Gtid_Set: 1cced57b-e75e-11e5-b742-5c260a17ccde:1-6,
e2e2f927-e75c-11e5-ac89-5c260a17ccde:1-5501
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)


mysql>

上述输出可得出,Slave_SQL_Running: No表示复制SQL线程失败停止了。

Retrieved_Gtid_Set是5501-5502,而实际只重演到5501,5502并没有执行。

并且根据Last_Error得出,由于fedlink这个server不存在导致t_area表创建失败,进而导致复制重演SQL线程失败。


那么问题来了:

1. 为什么fedlink这个server的定义没有被复制?

2. 如何解决这个复制错误,以重新启动复制SQL线程?


原来,根据文档对CREATE SERVER的,描述:

In MySQL 5.7, CREATE SERVER is not written to the binary log, regardless of the logging format that is in use.

In MySQL 5.7, ALTER SERVER is not written to the binary log, regardless of the logging format that is in use.

也就是不管binlog_format如何设置,CREATE SERVER与ALTER SERVER操作不会被binlog,也就不会被复制。(我去,这绝对是不应该的)。

那么现在的问题是,如何解决这个复制SQL失败的问题呢?

根据分析,SQL线程失败是由于fedlink这个server在slave端不存在的原因导致的。

所以我们可以手工在slave端执行CREATE SERVER fedlink的语句。

还有另外一种方式(这里其实我并不推荐):我们可以跳过5502这个event。如下:



mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.77
                  Master_User: backup
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000018
          Read_Master_Log_Pos: 1017
               Relay_Log_File: host_name-relay-bin.000038
                Relay_Log_Pos: 551
        Relay_Master_Log_File: mysql-bin.000018
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 1432
                   Last_Error: Error 'server name: 'fedlink' doesn't exist!' on query. Default database: 'test'. Query: 'CREATE TABLE `t_area` (
  `id` varchar(255) NOT NULL,
  `address` varchar(255) DEFAULT NULL,
  `level` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `sort` int(11) NOT NULL,
  `telephone` varchar(255) DEFAULT NULL,
  `visible` bit(1) NOT NULL,
  `parentId` varchar(255) DEFAULT NULL,
  `number` varchar(255) DEFAULT NULL,
  `theCode` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FKCB5AB178745ED9CF` (`parentId`)
) ENGINE=FEDERATED DEFAULT CHARSET=utf8
connection='fedlink/t_area''
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 378
              Relay_Log_Space: 1984
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 1432
               Last_SQL_Error: Error 'server name: 'fedlink' doesn't exist!' on query. Default database: 'test'. Query: 'CREATE TABLE `t_area` (
  `id` varchar(255) NOT NULL,
  `address` varchar(255) DEFAULT NULL,
  `level` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `sort` int(11) NOT NULL,
  `telephone` varchar(255) DEFAULT NULL,
  `visible` bit(1) NOT NULL,
  `parentId` varchar(255) DEFAULT NULL,
  `number` varchar(255) DEFAULT NULL,
  `theCode` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FKCB5AB178745ED9CF` (`parentId`)
) ENGINE=FEDERATED DEFAULT CHARSET=utf8
connection='fedlink/t_area''
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 2
                  Master_UUID: e2e2f927-e75c-11e5-ac89-5c260a17ccde
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State:
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp: 160322 11:28:01
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set: e2e2f927-e75c-11e5-ac89-5c260a17ccde:5501-5502
            Executed_Gtid_Set: 1cced57b-e75e-11e5-b742-5c260a17ccde:1-6,
e2e2f927-e75c-11e5-ac89-5c260a17ccde:1-5501
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)


mysql> stop slave;
Query OK, 0 rows affected (0.09 sec)


mysql> set gtid_next="e2e2f927-e75c-11e5-ac89-5c260a17ccde:5502";
Query OK, 0 rows affected (0.00 sec)


mysql> begin;commit;
Query OK, 0 rows affected (0.00 sec)


Query OK, 0 rows affected (0.02 sec)


mysql> set gtid_next="AUTOMATIC";
Query OK, 0 rows affected (0.00 sec)


mysql> start slave;
Query OK, 0 rows affected (0.07 sec)



mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.77
                  Master_User: backup
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000018
          Read_Master_Log_Pos: 1017
               Relay_Log_File: host_name-relay-bin.000040
                Relay_Log_Pos: 360
        Relay_Master_Log_File: mysql-bin.000018
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1017
              Relay_Log_Space: 777
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 2
                  Master_UUID: e2e2f927-e75c-11e5-ac89-5c260a17ccde
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set: e2e2f927-e75c-11e5-ac89-5c260a17ccde:5501-5502
            Executed_Gtid_Set: 1cced57b-e75e-11e5-b742-5c260a17ccde:1-6,
e2e2f927-e75c-11e5-ac89-5c260a17ccde:1-5502

                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)


mysql> 

复制SQL线程成功启动。

但是很明显,此时有个问题:主备库不一致,1. fedlink这个server存在master端,但是不存在slave端。2. test.t_area表master存在而slave端不存在。


下面来解决这个问题:

先在slave端手工创建t_area表:

mysql> CREATE TABLE `t_area` (
    ->   `id` VARCHAR(255) NOT NULL,
    ->   `address` VARCHAR(255) DEFAULT NULL,
    ->   `level` INT(11) NOT NULL,
    ->   `name` VARCHAR(255) DEFAULT NULL,
    ->   `sort` INT(11) NOT NULL,
    ->   `telephone` VARCHAR(255) DEFAULT NULL,
    ->   `visible` BIT(1) NOT NULL,
    ->   `parentId` VARCHAR(255) DEFAULT NULL,
    ->   `number` VARCHAR(255) DEFAULT NULL,
    ->   `theCode` VARCHAR(255) DEFAULT NULL,
    ->   PRIMARY KEY (`id`),
    ->   KEY `FKCB5AB178745ED9CF` (`parentId`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.35 sec)


mysql>

然后在master端drop表这个表:
mysql> drop table t_area;
Query OK, 0 rows affected (0.14 sec)


mysql>

此时slave端的t_area表也被删除。


然后再在slave端手工创建fedlink:

mysql> CREATE SERVER fedlink
    -> FOREIGN DATA WRAPPER mysql
    -> OPTIONS (
    ->   USER 'root',
    ->   PASSWORD '20127163',
    ->   HOST '192.168.1.166',
    ->   PORT 3306,
    ->   DATABASE 'cms'
    -> ) ;
Query OK, 1 row affected (0.08 sec)


mysql>

再回到master端创建带CONNECTION子句的t_area表:

mysql> CREATE TABLE `t_area` (
    ->   `id` VARCHAR(255) NOT NULL,
    ->   `address` VARCHAR(255) DEFAULT NULL,
    ->   `level` INT(11) NOT NULL,
    ->   `name` VARCHAR(255) DEFAULT NULL,
    ->   `sort` INT(11) NOT NULL,
    ->   `telephone` VARCHAR(255) DEFAULT NULL,
    ->   `visible` BIT(1) NOT NULL,
    ->   `parentId` VARCHAR(255) DEFAULT NULL,
    ->   `number` VARCHAR(255) DEFAULT NULL,
    ->   `theCode` VARCHAR(255) DEFAULT NULL,
    ->   PRIMARY KEY (`id`),
    ->   KEY `FKCB5AB178745ED9CF` (`parentId`)
    -> ) ENGINE=FEDERATED DEFAULT CHARSET=utf8
    -> CONNECTION='fedlink/t_area';
Query OK, 0 rows affected (0.08 sec)


mysql>

观察slave端也成功创建。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值