• MySQl新特性 GTID


     

    GTID简介

    概念

    全局事务标识符(GTID)是创建的唯一标识符,并与在源(主)服务器上提交的每个事务相关联。此标识符不但是唯一的,而且在给定复制设置中的所有服务器上都是唯一的。所有交易和所有GTID之间都有一对一的映射关系。
    GTID由source_id和transaction_id组成

    GTID = source_id:transaction_id
    

    server_uuid一般为source_id

    GTID集合

    GTID总是保存在主从之间。这意味着您可以通过检查二进制日志来确定应用于任何从属设备的任何事务的来源。另外,一旦给定GTID的事务在给定的服务器上被提交,任何具有相同GTID的后续事务都被该服务器忽略。因此,在主站上提交的事务只在从站上应用一次,这有助于保证一致性。

    GTID的生成和生命周期:
    1,事务在主服务器上执行并提交。使用主服务器的UUID和此服务器上尚未使用的最小非零事务序列号为该事务分配一个GTID; GTID被写入到master的二进制日志中
    2,在将二进制日志数据发送到从站并存储在从站的中继日志中,从站读取GTID并设置gtid_next这告诉slave,下一个事务必须使用这个GTID记录。
    3,从服务器验证这个GTID是否应用此事务。
    4,因为gtid_next不是空的,把git_next也就是从主机中获得的GTID写入到二进制日志中。

    mysql.gtid_executed

    • 该mysql.gtid_executed表使从机能够在从机上禁用二进制日志记录时使用GTID,并且可以在二进制日志丢失时保留GTID历史记录。
    • 若将mysql.gtid_executed表复位,执行RESET MASTER
    • 表格提供会周期性的压缩 当数量达到executed_gtid_compression_period值或者日志轮转时候mysql压缩储存,值默认为1000,压缩线程thread/sql/compress_gtid_table
    mysql> SELECT * FROM performance_schema.threads WHERE NAME LIKE '%gtid%'G
    *************************** 1. row ***************************
              THREAD_ID: 26
                   NAME: thread/sql/compress_gtid_table
                   TYPE: FOREGROUND
         PROCESSLIST_ID: 1
       PROCESSLIST_USER: NULL
       PROCESSLIST_HOST: NULL
         PROCESSLIST_DB: NULL
    PROCESSLIST_COMMAND: Daemon
       PROCESSLIST_TIME: 1509
      PROCESSLIST_STATE: Suspending
       PROCESSLIST_INFO: NULL
       PARENT_THREAD_ID: 1
                   ROLE: NULL
           INSTRUMENTED: YES
                HISTORY: YES
        CONNECTION_TYPE: NULL
           THREAD_OS_ID: 18677
    

    实践

    两台机器
    172.16.10.53
    172.16.10.54

    步骤

    1,将master 设置read-only,使slave赶上master更新速度
    mysql >set global read-only
    注:read-only 设置时候super用户可写,普通用户不可写。
    2,停止两台机器

    >mysqladmin  -uroot -p shutdown
    

    3,修改配置,启用GTID功能,要启用基于GTID的复制,必须通过将gtid_mode变量 设置为启用GTID模式启动每个服务器 ON,并enforce_gtid_consistency 启用变量以确保只记录对基于GTID的复制安全的语句。在slave机器启动之前,使用--skip-slave-start禁用slave的复制进程。
    由于在MySQL 5.7.5中增加了mysql.gtid_executed,所以不需要slave机器启用二进制日志记录来使用GTID 。这意味着您可以使用GTID但没有二进制日志记录的从服务器。为了能够复制,主设备必须始终启用二进制日志记录。而slave,只需要配置这些变量:

    gtid_mode=ON
    enforce-gtid-consistency=true
    

    不过为了高可用的切换,推荐选择如下配置

    gtid_mode=ON #必选
    enforce-gtid-consistency=true #必选
    log-bin=mysql #5.6必选 5.7.5和它之后可选,为了高可用,最好设置
    server-id=1  #开启log-bin的必须设置 
    log-slave-updates=ON # 5.6必选 5.7.5和它之后可选,为了高可用切换,最好设置ON
    

    4, 配置slave使用GTID来进行同步数据,当然需要在master给slave开通权限

    grant  replication slave on *.*  to repl@"172.16.10.53" identified by "password";
    

    设置GTID同步模式

    change master to master_host='172.16.10.53',master_user='repl',master_port=3306,master_password="password",master_auto_position=1;
    

    注意:非端口号需要加上引号
    5,做一个新的备份,启用GTID之前创建的现有备份现在不能再在这些服务器上使用,因为您启用了GTID。在这一点上做一个新的备份,这样你就不会没有可用的备份。
    比如说物理备份。

    6,启动slave的同步进程

    mysql> start slave
    

    问题

    在启动slave同步进程时候,查看日志出现如下问题

    2018-01-17T09:48:18.116983Z 1 [Warning] Slave SQL for channel '': If a crash happens this configuration does not guarantee that the relay log info will be consistent, Error_code: 0
    

    什么!!not consistent,绝对不能忍
    在网上查了下添加如下配置就好了
    在my.cnf中设置,

    relay_log_info_repository = TABLE 
    master_info_repository = TABLE 
    relay_log_recovery = on 
    

    报错原因:
    MySQL5.6版本号開始支持把master.info和relay-log.info的内容写入到mysql库的表中。

    master.info--> mysql.slave_master_info
    relay-log.info--> mysql. slave_relay_log_info
    

    同一时候在MySQL5.6版本号中,添加了 Slave crash-safe replication功能,为了保证mysql的replication可以crash-safe。slave_master_info和slave_relay_log_info表必须使用事务型的存储引擎(InnoDB),不要尝试去手动改动这两张表的内容。
    同一时候,Slave还要开启relay_log_recovery功能。
    解决方法:
    设置master_info_repository和relay_log_info_repository的值为TABLE。同一时候开启relay_log_recovery功能。

    GTID的故障处理和恢复。

    1,简单的复制,在新服务器上重现所有标识符和事务的最简单方法是将新服务器变为具有全部执行历史记录的主服务器的从服务器,并在两台服务器上启用全局事务标识符,缺点是较慢,且需要master保持所有的bin-log
    2,使用mysqldump的方式,设置新slave机器(较快)
    首先使用mysqldump命令备份

    mysqldump --single-transaction --set-gtid-purged=OFF  --triggers --routines --events  -uroot -p >all.sql
    

    此时会出现提示

    mysqldump: [Warning] Using a password on the command line interface can be insecure.
    Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events.
    

    若不需要进行GTID的恢复和从库设置,则可以添加--set-gtid-purged=OFF 关闭(默认为ON)
    若需要进行GTID的主从设置则--set-gtid-purged=ON 既可

    mysqldump --single-transaction --set-gtid-purged=ON  --triggers --routines --events  -uroot -p >all.sql
    

    查看sql文件中会出现以下语句,设置GTID_PURGED来跳过一些事务。

    --
    -- GTID state at the beginning of the backup 
    --
    SET @@GLOBAL.GTID_PURGED='7abe211e-fb4f-11e7-b16e-000c29ba88ca:1-69726';
    

    然后在slave机器上进行恢复(需要slave开启GTID功能),在恢复时候可能需要下面问题。

    [root@localhost ~]# mysql -uroot -pMysql3200$%^ test < /tmp/all.sql   
    mysql: [Warning] Using a password on the command line interface can be insecure.
    ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.
    

    解决办法:登录执行reset master 清空 GTID_EXECUTED

    [root@localhost ~]# mysql -uroot -p                    
    mysql> reset master;
    Query OK, 0 rows affected (0.02 sec)
    

    导入binlog后,再start slave既可。

    mysql> show slave statusG
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 172.16.10.53
                      Master_User: repl
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql.000005
              Read_Master_Log_Pos: 777138
                   Relay_Log_File: localhost-relay-bin.000018
                    Relay_Log_Pos: 88658
            Relay_Master_Log_File: mysql.000005
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
    

    3,使用空事务处理故障
    情况1:
    主键重复

                       Last_Error: Could not execute Write_rows event on table test.a; Duplicate entry '500' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql.000005, end_log_pos 651107
    

    方法1:
    注入空事务

          Last_IO_Error_Timestamp: 
         Last_SQL_Error_Timestamp: 
                   Master_SSL_Crl: 
               Master_SSL_Crlpath: 
               Retrieved_Gtid_Set: 7abe211e-fb4f-11e7-b16e-000c29ba88ca:66253-68381:69091-70362
                Executed_Gtid_Set: 7abe211e-fb4f-11e7-b16e-000c29ba88ca:1-70362,
    9a455b69-fb4f-11e7-b993-000c29e8a43c:1
    
    (root@Slave)[tempdb]>stop slave sql_thread;
    
    (root@Slave)[tempdb]>set gtid_next='7abe211e-fb4f-11e7-b16e-000c29ba88ca:70363';
    
    (root@Slave)[tempdb]>begin;commit;
    
    (root@Slave)[tempdb]>set gtid_next='AUTOMATIC';
    
    (root@Slave)[tempdb]>start slave sql_thread;
    
    (root@Slave)[tempdb]>show slave status G
    

    方法2:
    删除冲突行

    使用GTID的限制

    • 涉及非事务性存储引擎的更新。对使用非事务性存储引擎的表进行的更新与在同一事务中使用事务性存储引擎的表的更新混合在一起会导致将多个GTID分配给同一事务。
    • CREATE TABLE ... SELECT语句。在使用基于行的复制时,该语句实际上被记录为两个单独的事件 - 一个用于创建表,另一个用于将源表中的行插入刚刚创建的新表中。当这个语句在一个事务中被执行时,这些事件在某些情况下可能会被接收到相同的事务标识符,这意味着包含插入事务的事务被从机跳过。
    • 创建临时表。
    • GTID模式和mysql_upgrade,当服务器在启用全局事务标识符(GTID)时候,不要用mysql_upgrade --write-binlog启用二进制日志记录。

    参考链接:
    http://www.cnblogs.com/gcczhongduan/p/4869525.html
    https://dev.mysql.com/doc/refman/5.7/en/replication-gtids-failover.html

  • 相关阅读:
    使用批处理文件轻松更改本地IP地址
    Aveiconifier是一个非常实用方便的制作ico格式文件的小工具~
    C#中选择文件的例子
    WindowsXP命令行修改服务启动选项
    Oracle中数据导入导出技巧
    hibernateTemplateOrder Results
    如何向 Microsoft 管理控制台添加证书管理器
    maven usages
    让Eclipse拥有像Visual Studio一样的强大的提示功能
    jsp页面跳转方法及区别
  • 原文地址:https://www.cnblogs.com/DataArt/p/10089868.html
Copyright © 2020-2023  润新知