与MySQL守旧复制相比较,GTID有啥特殊的复制姿势

与MySQL古板复制比较,GTID有怎么样优异的复制姿势?

前言

正文为DBA+社群的投稿文章:


GTID(Global Transaction
ID)是MySQL5.6引进的机能,能够在集群全局范围标志事务,用于替代过去通过binlog文件偏移量定位复制地点的历史观办法。借助GTID,在发生主备切换的境况下,MySQL的别的Slave能够活动在新主上找到科学的复制地点,那大大简化了复杂复制拓扑下集群的护卫,也缩减了人工设置复制地点产生误操作的危害。其余,基于GTID的复制能够忽略已经施行过的专门的学问,裁减了数量产生不相同样的危害。

与MySQL古板复制相比较,GTID有啥特殊的复制姿势?

GTID虽好,要想使用熟知还需尽量领悟其规律与风味,极度要静心与价值观的基于binlog文件偏移量复制方式不平等的地点。 本文概述了有关GTID的多少个常见难题,希望能对掌握和使用基于GTID的复制有所帮忙。

前言

GTID(Global Transaction
ID)是MySQL5.6引进的功用,可以在集群全局范围标记事务,用于替代过去透过binlog文件偏移量定位复制地点的古板格局。借助GTID,在产生主备切换的情景下,MySQL的别的Slave能够活动在新主上找到科学的复制地方,那大大简化了复杂复制拓扑下集群的爱惜,也回退了人工设置复制地方发生误操作的高危机。别的,基于GTID的复制能够忽略已经奉行过的政工,减弱了数据发生不雷同的风险。

GTID虽好,要想利用熟悉还需足够通晓其规律与特色,极度要留神与历史观的基于binlog文件偏移量复制形式分裂的地方。本文概述了关于GTID的多少个周边难点,希望能对精晓和行使基于GTID的复制有所援助。

GTID长什么样

GTID长什么样

依据官方文书档案定义,GTID由source_id加transaction_id构成。

GTID = source_id:transaction_id 

上面的source_id提醒发起事务的MySQL实例,值为该实例的server_uuid。server_uuid由MySQL在率先次运行时自动生成并被长久化到auto.cnf文件里,transaction_id是MySQL实例上推行的职业序号,从1初始递增。
举例:

e6954592-8dba-11e6-af0e-fa163e1cf111:1 

一组连续的事情能够用’-‘连接的事情序号范围表示。比如

e6954592-8dba-11e6-af0e-fa163e1cf111:1-5 

更相像的景况是GTID的聚合。GTID集结能够分包来自多少个source_与MySQL守旧复制相比较,GTID有啥特殊的复制姿势。id的事情,它们之间用逗号分隔;假若来自同一source_id的职业序号有四个范围区间,各组范围里边用冒号分隔,举个例子:

e6954592-8dba-11e6-af0e-fa163e1cf111:1-5:11-18,e6954592-8dba-11e6-af0e-fa163e1cf3f2:1-27 

即,GTID集结具备如下的花样定义:

gtid_set:    uuid_set [, uuid_set] ...    | ''uuid_set:    uuid:interval[:interval]...uuid:    hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhhh:    [0-9|A-F]interval:    n[-n]    (n >= 1) 

听别人讲官方文书档案定义,GTID由source_id加transaction_id构成。

何以查看GTID

能够因此MySQL的多少个变量查占星关的GTID音信。

  • gtid_executed
    在当下实例上实践过的GTID集结;
    实际上富含了具有记录到binlog中的事务。所以,设置set
    sql_log_bin=0后进行的政工不会生成binlog
    事件,也不会被记录到gtid_executed中。实施RESET
    MASTECRUISER能够将该变量置空。

  • gtid_purged
    binlog不容许长久驻留在服务上,必要定时开展清理(通过expire_logs_days可以调整订期清理间隔),不然一定它会把磁盘用尽。gtid_purged用于记录已经被拔除了的binlog事务集合,它是gtid_executed的子集。只有gtid_executed为空时工夫手动设置该变量,此时会同期创新gtid_executed为和gtid_purged同样的值。gtid_executed为空意味着要么从前未曾运转过基于GTID的复制,要么试行过RESET
    MASTE奥德赛。施行RESET
    MASTEKuga时同样也会把gtid_purged置空,即始终维持gtid_purged是gtid_executed的子集。

  • gtid_next
    会话级变量,提示怎样产生下四个GTID。可能的取值如下:

    • AUTOMATIC:
      自动生成下一个GTID,完成上是分配二个脚下实例上从没有过推行过的序号最小的GTID。
    • ANONYMOUS:
      设置后进行专业不会发生GTID。
    • 显式钦定的GTID:
      能够钦赐大肆情势合法的GTID值,但不可能是当前gtid_executed中的已经满含的GTID,不然,下一次实施事务时会报错。

这个变量能够透过show命令查看,比方

mysql> show global variables like 'gtid%';+----------------------+------------------------------------------+| Variable_name        | Value                                    |+----------------------+------------------------------------------+| gtid_deployment_step | OFF                                      || gtid_executed        | e10c75be-5c1b-11e6-ab7c-000c296078ae:1-6 || gtid_mode            | ON                                       || gtid_owned           |                                          || gtid_purged          |                                          |+----------------------+------------------------------------------+5 rows in set (0.02 sec)mysql> show  variables like 'gtid_next';+---------------+-----------+| Variable_name | Value     |+---------------+-----------+| gtid_next     | AUTOMATIC |+---------------+-----------+1 row in set (0.00 sec) 

GTID = source_id:transaction_id

怎么着产生GTID

GTID的更改受gtid_next控制。
在Master上,gtid_next是默许的AUTOMATIC,即在每便事务提交时自动生成新的GTID。它从此时此刻已施行的GTID集结(即gtid_executed)中,找四个大于0的未使用的最小值作为下个业务GTID。同一时间在binlog的骨子里的更新职业事件前边插入一条set
gtid_next事件。

以下是一条insert语句生成的binlog记录

mysql> use `test`Database changedmysql> insert into tbx1 values(1);Query OK, 1 row affected (0.01 sec)mysql> show binlog events IN 'binlog.000015';+---------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+| Log_name      | Pos | Event_type     | Server_id | End_log_pos | Info                                                              |+---------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+...| binlog.000015 | 707 | Gtid           |         1 |         755 | SET @@SESSION.GTID_NEXT= 'e10c75be-5c1b-11e6-ab7c-000c296078ae:9' || binlog.000015 | 755 | Query          |         1 |         834 | BEGIN                                                             || binlog.000015 | 834 | Query          |         1 |         934 | use `test`; insert into tbx1 values(1)                            || binlog.000015 | 934 | Xid            |         1 |         965 | COMMIT /* xid=20 */                                               | 

在Slave上回看主库的binlog时,施夷光行set gtid_next
…,然后再实施真正的insert语句,确定保障在主和备上那条insert对应于同样的GTID。

一般景况下,GTID集结是连接的,但运用三十二线程复制(MTS)以及因此gtid_next实行人工干预时会导致gtid空洞。举例上面这样:

mysql> show master status;+---------------+----------+--------------+------------------+------------------------------------------+| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |+---------------+----------+--------------+------------------+------------------------------------------+| binlog.000015 |      965 |              |                  | e10c75be-5c1b-11e6-ab7c-000c296078ae:1-9 |+---------------+----------+--------------+------------------+------------------------------------------+1 row in set (0.00 sec)mysql> set gtid_next='e10c75be-5c1b-11e6-ab7c-000c296078ae:12';Query OK, 0 rows affected (0.00 sec)mysql> begin;Query OK, 0 rows affected (0.00 sec)mysql> commit;Query OK, 0 rows affected (0.00 sec)mysql> set gtid_next='AUTOMATIC';Query OK, 0 rows affected (0.00 sec)mysql> show master status;+---------------+----------+--------------+------------------+---------------------------------------------+| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                           |+---------------+----------+--------------+------------------+---------------------------------------------+| binlog.000015 |     1158 |              |                  | e10c75be-5c1b-11e6-ab7c-000c296078ae:1-9:12 |+---------------+----------+--------------+------------------+---------------------------------------------+1 row in set (0.00 sec) 

继续试行事务,MySQL会分配一个微细的未使用GTID,也正是从出现空洞的地点分配GTID,最后会把空洞填上。

mysql> insert into tbx1 values(1);Query OK, 1 row affected (0.01 sec)mysql> show master status;+---------------+----------+--------------+------------------+----------------------------------------------+| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                            |+---------------+----------+--------------+------------------+----------------------------------------------+| binlog.000015 |     1416 |              |                  | e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10:12 |+---------------+----------+--------------+------------------+----------------------------------------------+1 row in set (0.00 sec) 

那意味着严苛来讲大家即不能够假诺GTID集结是接连的,也不能够假定GTID序号大的业务在GTID序号小的业务之后施行,事务的逐一应由业务记录在binlog中的前后相继顺序决定。

上面的source_id提醒发起事务的MySQL实例,值为该实例的server_uuid。server_uuid由MySQL在首先次运转时自动生成并被长久化到auto.cnf文件里,transaction_id是MySQL实例上实践的工作序号,从1最早递增。
比如:

GTID的长久化

GTID相关的新闻存储在binlog文件中,为此MySQL5.6新增加了下边2个binlog事件。

  • Previous_gtids_log_event在每一种binlog文件的启幕部分,记录在该binlog文件在此以前已试行的GTID群集。
  • Gtid_log_event即日前看到的set gtid_next
    …,它现身在各类事情的前方,注脚下二个业务的gtid。

身体力行如下:

mysql> show binlog events IN 'binlog.000015';+---------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+| Log_name      | Pos | Event_type     | Server_id | End_log_pos | Info                                                              |+---------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+| binlog.000015 |   4 | Format_desc    |         1 |         120 | Server ver: 5.6.31-77.0-log, Binlog ver: 4                        || binlog.000015 | 120 | Previous_gtids |         1 |         191 | e10c75be-5c1b-11e6-ab7c-000c296078ae:1-6                          || binlog.000015 | 191 | Gtid           |         1 |         239 | SET @@SESSION.GTID_NEXT= 'e10c75be-5c1b-11e6-ab7c-000c296078ae:7' || binlog.000015 | 239 | Query          |         1 |         318 | BEGIN                                                             || binlog.000015 | 318 | Query          |         1 |         418 | use `test`; insert into tbx1 values(1)                            || binlog.000015 | 418 | Xid            |         1 |         449 | COMMIT /* xid=13 */                                               || binlog.000015 | 449 | Gtid           |         1 |         497 | SET @@SESSION.GTID_NEXT= 'e10c75be-5c1b-11e6-ab7c-000c296078ae:8' || binlog.000015 | 497 | Query          |         1 |         576 | BEGIN                                                             || binlog.000015 | 576 | Query          |         1 |         676 | use `test`; insert into tbx1 values(1)                            || binlog.000015 | 676 | Xid            |         1 |         707 | COMMIT /* xid=17 */                                               || binlog.000015 | 707 | Gtid           |         1 |         755 | SET @@SESSION.GTID_NEXT= 'e10c75be-5c1b-11e6-ab7c-000c296078ae:9' || binlog.000015 | 755 | Query          |         1 |         834 | BEGIN                                                             || binlog.000015 | 834 | Query          |         1 |         934 | use `test`; insert into tbx1 values(1)                            || binlog.000015 | 934 | Xid            |         1 |         965 | COMMIT /* xid=20 */                                               |+---------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+14 rows in set (0.00 sec) 

MySQL服务器运行时,通过读binlog文件,发轫化gtid_executed和gtid_purged,使它们的值能和上次MySQL运转时同样。

  • gtid_executed被安装为新型的binlog文件中Previous_gtids_log_event和所有Gtid_log_event的并集。
  • gtid_purged为最老的binlog文件中Previous_gtids_log_event。

鉴于这两个主要的变量值记录在binlog中,所以开启gtid_mode时必须同时在主库上开启log_bin在备库上开启log_slave_updates。

然则,在MySQL5.7中向来不那一个界定。MySQL5.7中,新扩大二个系列表mysql.gtid_executed用于长久化已举行的GTID集结。当主库上一直不拉开log_bin或在备库上未曾张开log_slave_updates时,mysql.gtid_executed会跟客户业务一同每一遍换代。不然只在binlog日志发生rotation时更新mysql.gtid_executed。

e6954592-8dba-11e6-af0e-fa163e1cf111:1

什么样安插基于GTID的复制

MySQL服务器的my.cnf配置文件中扩展GTID相关的参数

log_bin                        = /mysql/binlog/mysql_binlog_slave_updates              = truegtid_mode                      = ON enforce_gtid_consistency       = true relay_log_info_repository      = TABLErelay_log_recovery             = ON 

然后在Slave上指定MASTER_AUTO_POSITION = 1执行CHANGE MASTER
TO即可。比如:

CHANGE MASTER TO MASTER_HOST='node1',MASTER_USER='repl',MASTER_PASSWORD='repl',MASTER_AUTO_POSITION=1; 

一组一而再的事务能够用’-‘连接的事情序号范围表示。举例

依照GTID的复制怎么做事

在MASTER_AUTO_POSITION = 1的场馆下
,MySQL会动用COM_BINLOG_DUMP_GTID公约进行复制。进度如下:

备库发起复制连接时,将和睦的已接受和已执行的gtids的并集(前边称为slave_gtid_executed)发送给主库。即上面的集纳:

UNION(@@global.gtid_executed, Retrieved_gtid_set - last_received_GTID) 

主库将自个儿的gtid_executed与slave_gtid_executed的差集的binlog发送给Slave。主库的binlog
dump进程如下:

  1. 检查slave_gtid_executed是不是是主库gtid_executed的子集,如否那么主备数据大概不平等,报错。
  2. 检查主库的purged_executed是否是slave_gtid_executed的子集,如否代表缺点和失误备库需求的binlog,报错
  3. 从最后八个Binlog伊始扫描,获取文件底部的PREVIOUS_GTIDS_LOG_EVENT,假如它是slave_gtid_executed的子集,则那是须求发送给Slave的第多少个binlog文件,不然继续向前扫描。
  4. 从第3步找到的binlog文件的始发读取binlog记录,判定binlog记录是或不是已被含有在slave_gtid_executed中,假使已包涵跳过不发送。

从地方的进度可以,在钦命MASTE奇骏_AUTO_POSITION =
1时,Master发送哪些binlog记录给Slave,取决于Slave的gtid_executed和Retrieved_Gtid_Set以及Master的gtid_executed,和relay_log_info以及master_log_info中保存的复制位点未有关系。

e6954592-8dba-11e6-af0e-fa163e1cf111:1-5

何以修复复制错误

在依据GTID的复制拓扑中,要想修复Slave的SQL线程错误,过去的SQL_SLAVE_SKIP_COUNTE奥德赛情势不再适用。必要通过安装gtid_next或gtid_purged完毕,当然前提是一度确定保证基本数据一致,仅仅要求跳过复制错误让复制继续下去。比方上边包车型客车风貌:

在从库上创办表tb1

mysql> set sql_log_bin=0;Query OK, 0 rows affected (0.00 sec)mysql> create table tb1(id int primary key,c1 int);Query OK, 0 rows affected (1.06 sec)mysql> set sql_log_bin=1;Query OK, 0 rows affected (0.00 sec) 

在主库上创设表tb1

mysql> create table tb1(id int primary key,c1 int);Query OK, 0 rows affected (1.06 sec) 

鉴于从库上那一个表已经存在,从库的复制SQL线程出错截止。

mysql> show slave status\G*************************** 1. row ***************************               Slave_IO_State: Waiting for master to send event                  Master_Host: 192.168.125.134                  Master_User: sn_repl                  Master_Port: 3306                Connect_Retry: 60              Master_Log_File: binlog.000001          Read_Master_Log_Pos: 1422               Relay_Log_File: mysqld-relay-bin.000003                Relay_Log_Pos: 563        Relay_Master_Log_File: binlog.000001             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: 1050                   Last_Error: Error 'Table 'tb1' already exists' on query. Default database: 'test'. Query: 'create table tb1(id int primary key,c1 int)'                 Skip_Counter: 0          Exec_Master_Log_Pos: 1257              Relay_Log_Space: 933              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: NULLMaster_SSL_Verify_Server_Cert: No                Last_IO_Errno: 0                Last_IO_Error:                Last_SQL_Errno: 1050               Last_SQL_Error: Error 'Table 'tb1' already exists' on query. Default database: 'test'. Query: 'create table tb1(id int primary key,c1 int)'  Replicate_Ignore_Server_Ids:              Master_Server_Id: 1                  Master_UUID: e10c75be-5c1b-11e6-ab7c-000c296078ae             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: 161203 15:14:17               Master_SSL_Crl:            Master_SSL_Crlpath:            Retrieved_Gtid_Set: e10c75be-5c1b-11e6-ab7c-000c296078ae:5-6            Executed_Gtid_Set: e10c75be-5c1b-11e6-ab7c-000c296078ae:1-5                Auto_Position: 11 row in set (0.00 sec) 

从上面的输出能够明白,从库已经实行过的作业是’e10c75be-5c1b-11e6-ab7c-000c296078ae:1-5′,实施出错的业务是’e10c75be-5c1b-11e6-ab7c-000c296078ae:6’,当前主备的数额实际上是毫无二致的,能够透过安装gtid_next跳过那些出错的作业。

在从库上进行以下SQL:

mysql> set gtid_next='e10c75be-5c1b-11e6-ab7c-000c296078ae:6';Query OK, 0 rows affected (0.00 sec)mysql> begin;Query OK, 0 rows affected (0.00 sec)mysql> commit;Query OK, 0 rows affected (0.00 sec)mysql> set gtid_next='AUTOMATIC';Query OK, 0 rows affected (0.00 sec)mysql> start slave;Query OK, 0 rows affected (0.02 sec) 

设置gtid_next的方法二回只能跳过多少个作业,要批量的跳过事务可以通过安装gtid_purged完结。借使下边包车型大巴场景:

主库春天实施的事体

mysql> show master status;+---------------+----------+--------------+------------------+-------------------------------------------+| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                         |+---------------+----------+--------------+------------------+-------------------------------------------+| binlog.000001 |     2364 |              |                  | e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10 |+---------------+----------+--------------+------------------+-------------------------------------------+1 row in set (0.00 sec) 

从库桃浪实践的职业

mysql> show master status;+---------------+----------+--------------+------------------+------------------------------------------+| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |+---------------+----------+--------------+------------------+------------------------------------------+| binlog.000001 |     1478 |              |                  | e10c75be-5c1b-11e6-ab7c-000c296078ae:1-6 |+---------------+----------+--------------+------------------+------------------------------------------+1 row in set (0.00 sec) 

假使经过修复从库已经和主库的多少一致了,但鉴于复制错误Slave的SQL线程还是高居终止状态。未来能够通过把从库的gtid_purged设置为和主库的gtid_executed同样跳过不平等的GTID使复制继续下去,步骤如下。

在从库上举行

mysql> reset master;Query OK, 0 rows affected (0.01 sec)mysql> set GLOBAL gtid_purged='e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10';Query OK, 0 rows affected (0.03 sec)mysql> show master status;+---------------+----------+--------------+------------------+-------------------------------------------+| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                         |+---------------+----------+--------------+------------------+-------------------------------------------+| binlog.000002 |      191 |              |                  | e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10 |+---------------+----------+--------------+------------------+-------------------------------------------+1 row in set (0.00 sec) 

那时从库的Executed_Gtid_Set已经包括了主库上’1-10’的事体,再展开复制会从前面包车型地铁事体开头执行,就不会出错了。

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

使用gtid_next和gtid_purged修复复制错误的前提是,跳过那么些事情后仍可以够保险主备数据一致。借使做不到,将在考虑pt-table-sync可能拉备份的办法了。

更相像的场馆是GTID的集中。GTID集结能够分包来自七个source_id的事体,它们之间用逗号分隔;如若来自同一source_id的业务序号有多少个范围区间,各组范围之间用冒号分隔,例如:

GTID与备份恢复生机

在做备份恢复的时候,一时供给还原出来的MySQL实例能够视作Slave连上原来的主库继续复制,那就要求从备份恢复生机出来的MySQL实例具有和数量一致的gtid_executed值。那也是通过安装gtid_purged实现的,上边看下mysqldump做备份的例子。

e6954592-8dba-11e6-af0e-fa163e1cf111:1-5:11-18,

经过mysqldump进行备份

由此mysqldump做贰个全量备份

[[email protected] ~]# mysqldump --all-databases --single-transaction --routines --events --host=127.0.0.1 --port=3306 --user=root > dump.sql 

变迁的dump.sql文件里满含了安装gtid_purged的语句

dump.sql:

SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;SET @@SESSION.SQL_LOG_BIN= 0;...SET @@GLOBAL.GTID_PURGED='e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10';...SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN; 

苏醒数据前须要先通过reset master清空gtid_executed变量

[[email protected] ~]# mysql -h127.1 -e 'reset master'[[email protected] ~]# mysql -h127.1 <dump.sql 

不然施行设置GTID_PU巴博斯 SLS级GED的SQL时会报上面包车型的士荒唐

ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty. 

那儿重操旧业出的MySQL实例的GTID_EXECUTED和备份时点一致

mysql> show master status;+---------------+----------+--------------+------------------+-------------------------------------------+| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                         |+---------------+----------+--------------+------------------+-------------------------------------------+| binlog.000002 |      191 |              |                  | e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10 |+---------------+----------+--------------+------------------+-------------------------------------------+1 row in set (0.00 sec) 

是因为复原出的MySQL实例已经棉被服装置的不利的GTID_EXECUTED,以master_auto_postion
= 1的措施CHANGE MASTEEscort到原本的主节点就能够开头复制。

CHANGE MASTER TO MASTER_HOST='node1', MASTER_USER='repl', MASTER_PASSWORD='repl', MASTER_AUTO_POSITION = 1 

假如不期待备份文件中变化设置GTID_PURGED的SQL,可以给mysqldump传入–set-gtid-purged=OFF关闭。

与MySQL守旧复制相比较,GTID有啥特殊的复制姿势。e6954592-8dba-11e6-af0e-fa163e1cf3f2:1-27

通过Xtrabackup进行备份

比较mysqldump,Xtrabackup是效能更加高何况被大范围运用的备份情势。使用Xtrabackup举行备份的比喻如下。

通过Xtrabackup创三个全量备份(能够在Slave上创办备份,避防止对主库的质量冲击)

innobackupex --defaults-file=/etc/my.cnf --host=127.1 --user=root --password=mysql --no-timestamp --safe-slave-backup --slave-info /mysql/bak 

使用日志

innobackupex --apply-log /mysql/bak 

查看备份目录中的xtrabackup_binlog_info文件能够找到备份时已经推行过的gtids

[[email protected] ~]# cat /mysql/bak/xtrabackup_binlog_infomysql_bin.000001    191 e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10 

是因为备份时增添了”–slave-info”选项並且从Slave节点拉取的备份,所以会生成xtrabackup_slave_info文件,也得以从那一个文件里搜寻建立复制的SQL语句。

[[email protected] ~]# cat /mysql/bak/xtrabackup_slave_infoSET GLOBAL gtid_purged='e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10';CHANGE MASTER TO MASTER_AUTO_POSITION=1 

将备份文件传送到新的节点node3的/mysql/bak目录并复苏(假使一直把备份传输到数码目录了,这一步能够简轻易单)。

[[email protected] ~]# innobackupex --defaults-file=/etc/my.cnf --copy-back /mysql/bak 

启动MySQL。

[[email protected] ~]# mysqld --defaults-file=/home/mysql/etc/my.cnf --skip-slave-start & 

若是是从Slave拉的备份,决不能直接打开Slave复制,这时的gtid_executed是荒谬的。供给手动设置gtid_purged后再start
slave

reset master;SET GLOBAL gtid_purged='e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10';CHANGE MASTER TO MASTER_HOST='node1',MASTER_USER='repl',MASTER_PASSWORD='repl',MASTER_AUTO_POSITION=1;start slave; 

即,GTID会集具有如下的款式定义:

GTID与MHA

MHA是被广泛使用MySQL HA组件,MHA 0.56自此帮衬基于GTID的复制。
MHA在failover时会自动决断是还是不是是GTID based
failover,要求满意上面3个标准即为GTID based failover

  • 具有节点gtid_mode=1
  • 怀有节点Executed_Gtid_Set不为空
  • 起码三个节点Auto_Position=1

和以前的基于binlog文件地方的复制相比,基于GTID复制下,MHA在故障切换时的转换珍贵如下:

  • 基于binlog文件地方的复制

    • 在Master宕机后会尝试从Master上拷贝binlog日志进行填补   
    • 假设候选Master不拥有最新的relay log,会从有着新型relay
      log的Slave上生成差距的binlog传送到候选Master并施行补给  
    • 新Master的日记补偿到位后,一样采取选拔差别binlog的秘技将别的Slave和新Master同步后再change
      master到新Master  
  • 基于GTID的复制  

    • 只要候选Master不具备最新的relay
      log,让候选Master连上全数新型relay log的Salve举行补充。  
    • 尝试从binlog server上拉取缺点和失误的binlog并利用
    • 新Master的数量同步到最新后,让别的的Slave连上新Master并等待数据产生联合。而且能够给masterha_master_switch传入–wait_until_gtid_in_sync=1参数使其不等其它Slave实现多少同步,以加快切换速度。

在GTID形式下MHA不会尝试从旧Master上拷贝binlog日志举行补偿,所以在MySQL进度crash而OS仍旧健康的景观下,应尽量不要做主备切换而是原地重启MySQL,除非有别的能确认保证切换后不丢数据的艺术。

在GTID形式下MHA辅助在复制拓扑中追加一个或八个binlog
server起到日志补偿的效果,非GTID形式下就是配置了binlog
server也会被MHA忽略。

日记补偿能够说是MHA中最复杂也最杰出的部分,有了GTID后故障切换变得更简约了,不再要求原来复杂的binlog日志剖析和补偿。所以Oracle官方推出了只补助GTID复制的切换工具mysqlfailover,在GTID的援救下,大家有越来越多可相信的HA工具得以选用。

gtid_set:

GTID与crash safe slave

crash safe slave是MySQL 5.6提供的作用,意思是说在slave
crash后,把slave重新拉起来能够持续从Master举行理并答复制,不见面世复制错误也不会见世数量分化等。

uuid_set [, uuid_set] …

基于binlog文件地方的复制

在基于binlog文件地方的复制下,要力保crash safe
slave,配置下边包车型地铁参数就可以。

relay_log_info_repository      = TABLErelay_log_recovery             = ON 

如此那般可行的案由是,relay_log_info_repository = TABLE时,apply

| ”

event和更新relay_log_info表的操作被含有在同三个作业里,innodb要么让它们同一时间生效,要么同临时间不奏效,保险位点消息和已经使用的政工精确相配。同一时间relay_log_recovery

ON时,会抛弃master_log_info中记录的复制位点,依照relay_log_info的实行职位再次从Master获取binlog,那就逃避了是因为未共同刷盘导致的binlog文件接受地方和实在不等同以及relay
log文件被截断的题目。

在同期使用MTS(multi-threaded slave)时,为保障crash safe
slave基于binlog文件地方的复制还须求安装sync_relay_log=1,因为MySQL在Crash苏醒时必得先经过读取relay
log补齐MTS导致的事务空洞。

uuid_set:

基于GTID的复制

地点的装置并不适用于依赖GTID的复制。在依据GTID的复制下,crash的Slave重启后,从binlog中深入分析的gtid_executed决定了要apply哪些binlog记录,所以binlog必须和innodb存款和储蓄引擎的数量保持一致。要马到功成那或多或少,要求把sync_binlog和innodb_flush_log_at_trx_commit都安装为1,即所谓的”双1″。

别的mysql运行时,会从relay
log文件中获得已接收的GTIDs并更新Retrieved_Gtid_Set。由于relay
log文件或然不完全,所以需求摒弃已吸收接纳的relay
log文件。因而relay_log_recovery = ON也是必需的。

这么,对于基于GTID的复制,保险crash safe slave的设置就是底下那样。

sync_binlog                    = 1innodb_flush_log_at_trx_commit = 1relay_log_recovery             = ON 

至于咋样设置以保险crash safe slave,官方文书档案有显著记载,见17.3.2
Handling an Unexpected Halt of a Replication Slave。

可是中间关于GTID的记叙中留存笔误,将relay_log_recovery=1写成了relay_log_recovery=0(#83711)。同不通常候也从没提到必需设置”双1″,可是”双1″是必不可缺的,不然crash的Slave重启后,可能会再也应用binlog
event也说不定会管窥蠡测应用binlog event(#70659)。在那之中遗漏应用binlog
event的场所更吓人,因为Slave在不触发SQL错误的动静下就默默的和Master分裂了。

uuid:interval[:interval]…

设置”双1″对质量的震慑

鉴于安全着想,刚毅推荐设置”双1″。”双1″会叠合每一种业务的RT,但得益于MySQL的组提交机制,高并发下”双1″对系统一整合体tps的震慑在可承受范围内。

sysbencholtp.lua10张表每张表100w记录(qps/并发数)皇家赌场手机版 1

皇家赌场手机版 2
对立异同一行那样不能够有效互动的场所,”双1″对品质的震慑非常大。

sysbenchupdate_non_index.lua1张表1条记录(qps/并发数)皇家赌场手机版 3

皇家赌场手机版 4
对无法管用互动的Slave replay,存在一样的主题材料。

皇家赌场手机版,透过钦赐tx-rate施行sysbench的update_non_index.lua脚本压测30秒,实现后检查主备延迟。

能够窥见在Slave被陈设为”双1″的情形下,延迟那么些悲凉,1000之上的qps就能够现出延迟,非”双1″下qps到五千上述才会冒出延迟(主库配置为”双1″)。

sysbenchupdate_non_index.lua1张表100w条记录
128并发(延迟/qps)皇家赌场手机版 5

皇家赌场手机版 6
如上测量检验遇到是Percona Server 5.6运维在布局HDD的8
core虚机,由于测量试验结果和系统IO本事有比较大关系,仅供参考。

uuid:

怎么在非”双1″下保障crash safe slave

倘假若MySQL
5.7能够关闭log_slave_updates,这样MySQL会将已实施的GTIDs实时记下到系统表mysql.gtid_executed中,mysql.gtid_executed是和顾客业务一同付给的,因而得以确认保证和事实上的数目一致。

log_slave_updates              = OFFrelay_log_recovery             = ON 

一经是MySQL 5.6方可选择如下变化的措施。

依照基于binlog文件复制时crash safe
slave的须要安装relay_log_info_repository = TABLE

relay_log_info_repository      = TABLErelay_log_recovery             = ON 

在Slave
crash后,根据relay_log_info_repository设置相应的gitd_purged再张开复制,步骤如下。

  1. 启航mysql,但不开启复制

    mysqld --skip-slave-start 
    
  2. 在Slave上改动为基于binlog文件地点的复制

    change master to MASTER_AUTO_POSITION = 0 
    
  3. 启动slave IO线程

    start slave io_thread 
    

    此处不能够开发银行SQL线程,假诺接受到的GTID已经在Slave的gtid_executed里了,会被Slave
    skip掉。

  4. 检查binlog传输的启幕地点(即Retrieved_Gtid_Set的值)

    show slave status\G 
    

    要是输出的Retrieved_Gtid_Set值为e10c75be-5c1b-11e6-ab7c-000c296078ae:7-10

  5. 在Master上检查gtid_executed

    show master status 
    

    设若输出的Executed_Gtid_Set值为e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10

  6. 在Slave上设置gitd_purged为binlog传输地方的前头的GTID的集纳

    reset master;set global gitd_purged='e10c75be-5c1b-11e6-ab7c-000c296078ae:1-6'; 
    
  7. 修改回auto position的复制

    change master to MASTER_AUTO_POSITION = 1 
    
  8. 启动slave SQL线程

    start slave sql_thread 
    

可是,这种更改的点子不吻合四线程复制。因为八线程复制恐怕发生gtid
gap和Gap-free low-watermark
position,那会促成Salve上海重机厂复apply已经apply过的event。后果正是数码不一样样恐怕复制中断,除非设置binlog格式为row方式并且slave_exec_mode=IDEMPOTENT,slave_exec_mode=IDEMPOTENT允许Slave重放binlog时马虎重复键和找不到键的失实,使得binlog重放具有幂等性,但那也意味着一旦真的出现了主备数据分歧样也会被它忽略。

hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh

MTS下蓄意的主题素材

在同有的时候间利用MTS(slave_parallel_workers> 1)时,固然按下边crash safe
slave的渴求安装了依照GTID的复制,Slave crash后再重启还是会促成复制中断。

经过强制杀掉MySQL所在虚机的措施模拟Slave宕机,然后再起步MySQL,mysql日志中有如下错误音信:

---------------------------------2016-10-26 21:00:23 2699 [Warning] Neither --relay-log nor --relay-log-index were used; so replication may break when this MySQL server acts as a slave and has his hostname changed!! Please use '--relay-log=mysql-relay-bin' to avoid this problem.2016-10-26 21:00:24 2699 [Note] Slave: MTS group recovery relay log info based on Worker-Id 1, group_relay_log_name ./mysql-relay-bin.000011, group_relay_log_pos 2017523 group_master_log_name binlog.000007, group_master_log_pos 20173632016-10-26 21:00:24 2699 [ERROR] Error looking for file after ./mysql-relay-bin.000012.2016-10-26 21:00:24 2699 [ERROR] Failed to initialize the master info structure2016-10-26 21:00:24 2699 [Note] Check error log for additional messages. You will not be able to start replication until the issue is resolved and the server restarted.2016-10-26 21:00:24 2699 [Note] Event Scheduler: Loaded 0 events2016-10-26 21:00:24 2699 [Note] mysqld: ready for connections.Version: '5.6.31-77.0-log'  socket: '/data/mysql/mysql.sock'  port: 3306  Percona Server (GPL), Release 77.0, Revision 5c1061c--------------------------------- 

运转slave时也会报错

mysql> start slave;ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository 

出现这种气象的原故在于,relay_log_recovery=1且slave_parallel_workers>1的意况下,mysql运行时会进去MTS
Group恢复生机流程,即读取relay
log,尝试填补由于多线程复制导致的gap。然后relay
log文件由于不是实时刷新的,在relay log文件中找不到gap对应的relay
log记录(覆盖了gap的relay
log开始和结束地方分别被叫做低水位和高水位,低水位点即slave_relay_log_info.Relay_log_pos的值)就可以报这几个错。

骨子里,在GTID情势下,slave在apply
event的时候能够跳过重复事件,所以能够安全的从低水位点应用日志,没供给深入分析relay
log文件。
那看起来是贰个bug,于是提交了二个bug报告#83713,如今还并没有收到回复。

作为逃避方法,能够经过解除relay log文件,跳过这几个破绽百出。实施步骤如下

reset slave;change master to MASTER_AUTO_POSITION = 1start slave; 

在此地,单纯的调reset
slave无法把状态清理透彻,内部的Relay_log_info.inited标记位依旧处于未被初始化状态,此时调用start
slave仍旧会战败。由此要求补一刀change master。

h:

Master的crash safe

日前一向在讲crash safe slave,Master的crash safe一样首要。
要想Master保持crash
safe需求按上边包车型客车参数进行安装,不然不但会遗弃事务,gtid_executed还大概和实在的innodb存储引擎中的数据不等同。

sync_binlog                    = 1innodb_flush_log_at_trx_commit = 1 

在Master配置为”双1″的图景下,Master
crash后,若无发生failover,能够持续作为Master。
借使发生了failover,能够检查旧Master和新Master上由旧Master实施的作业集合是不是同样。

 show master status 

只要一样,可以按MASTEWrangler_AUTO_POSITION =
1的不二等秘书籍将旧Master作为Slave和新Master建设构造复制关系。不然,思索做事情补偿或从新Master上拉取备份进行苏醒。

在Master配置不是”双1″的情形下,在Master
crash后由于不便正确理解旧Master上到底实行了什么事情,安全的做法是实践主备切换,并从新Master上拉取备份,把旧Master作为新Master的Slave进行还原。

本文为DBA+社会群众体育的投稿小说:
与MySQL守旧复制相比较,GTID有何样…

[0-9|A-F]

interval:

n[-n]

(n >= 1)

何以查看GTID

可以由此MySQL的几个变量查占卜关的GTID消息。

  1. gtid_executed

    在当下实例上实行过的GTID集结;
    实际上富含了有着记录到binlog中的事务。所以,设置set
    sql_log_bin=0后实行的事务不会生成binlog
    事件,也不会被记录到gtid_executed中。实践RESET
    MASTESportage能够将该变量置空。

  2. gtid_purged

    binlog不恐怕长久驻留在服务上,要求定时举行清理(通过expire_logs_days能够决定按时清理间隔),不然一定它会把磁盘用尽。gtid_purged用于记录已经被拔除了的binlog事务集合,它是gtid_executed的子集。只有gtid_executed为空时本事手动设置该变量,此时会同临时候立异gtid_executed为和gtid_purged一样的值。gtid_executed为空意味着要么以前未曾运行过基于GTID的复制,要么试行过RESET
    MASTECRUISER。实施RESET
    MASTE兰德冠道时相同也会把gtid_purged置空,即始终维持gtid_purged是gtid_executed的子集。

  3. gtid_next

    会话级变量,提醒怎么着爆发下多少个GTID。或然的取值如下:

    1)AUTOMATIC:

    自动生成下多少个GTID,落成上是分配三个脚下实例上从未有超过实际践过的序号最小的GTID。

    2)ANONYMOUS:

    安装后实践专门的学问不会发生GTID。

    3)显式钦赐的GTID:

    能够钦定任意格局合法的GTID值,但不能够是时下gtid_executed中的已经包括的GTID,不然,下一次实施事务时会报错。

那些变量能够透过show命令查看,举个例子:

皇家赌场手机版 7

怎么着产生GTID

GTID的转移受gtid_next控制。
在Master上,gtid_next是暗中认可的AUTOMATIC,即在历次事务提交时自动生成新的GTID。它从当前已实施的GTID会集(即gtid_executed)中,找多少个大于0的未利用的最小值作为下个业务GTID。同时在binlog的实际的更新工作事件后边插入一条set
gtid_next事件。

以下是一条insert语句生成的binlog记录:

皇家赌场手机版 8

在Slave上回看主库的binlog时,先试行set gtid_next
…,然后再试行真正的insert语句,确认保障在主和备上那条insert对应于同样的GTID。

一般情状下,GTID集合是连接的,但运用二十八线程复制(MTS)以及通过gtid_next举行人工干预时会导致gtid空洞。举例上边那样:

皇家赌场手机版 9

继续试行事务,MySQL会分配二个异常的小的未利用GTID,约等于从出现空洞的地点分配GTID,最后会把空洞填上。

皇家赌场手机版 10

那意味严厉来说大家即不能够如果GTID集结是接连的,也不可能假定GTID序号大的政工在GTID序号小的专门的学业之后试行,事务的逐个应由业务记录在binlog中的前后相继顺序决定。

GTID的持久化

GTID相关的音信存款和储蓄在binlog文件中,为此MySQL5.6新添了上面2个binlog事件。

  • Previous_gtids_log_event 在各个binlog文件的初始部分,记录在该binlog文件在此之前已实行的GTID会集。

  • Gtid_log_event 即日前看到的set gtid_next
    …,它出现在种种事情的前方,申明下贰个事务的gtid。

演示如下:

皇家赌场手机版 11

MySQL服务器运营时,通过读binlog文件,最初化gtid_executed和gtid_purged,使它们的值能和上次MySQL运转时一样。

  • gtid_executed被安装为流行的binlog文件中Previous_gtids_log_event和所有Gtid_log_event的并集。

  • gtid_purged为最老的binlog文件中Previous_gtids_log_event。

由于那八个主要的变量值记录在binlog中,所以开启gtid_mode时必需同一时候在主库上开启log_bin在备库上张开log_slave_updates。

而是,在MySQL5.7中绝非那个限制。MySQL5.7中,新添三个体系表mysql.gtid_executed用于长久化已举办的GTID集结。当主库上并未有拉开log_bin或在备库上一贯不拉开log_slave_updates时,mysql.gtid_executed会跟客户业务一同每一次换代。不然只在binlog日志产生rotation时更新mysql.gtid_executed。

哪些布署基于GTID的复制

MySQL服务器的my.cnf配置文件中追加GTID相关的参数

log_bin                                 = /mysql/binlog/mysql_bin

log_slave_updates                = true

gtid_mode                            = ON 

enforce_gtid_consistency      = true 

relay_log_info_repository       = TABLE

relay_log_recovery                = ON

然后在Slave上指定MASTER_AUTO_POSITION = 1执行CHANGE MASTER
TO即可。比如:

CHANGE MASTER TO
MASTER_HOST=’node1′,MASTER_USER=’repl’,MASTER_PASSWORD=’repl’,MASTER_AUTO_POSITION=1;

听闻GTID的复制怎样专门的职业

在MASTER_AUTO_POSITION = 1的情状下
,MySQL会使用 COM_BINLOG_DUMP_GTID 商谈实行理并答复制。进程如下:

备库发起复制连接时,将谐和的已接受和已进行的gtids的并集(前边称为slave_gtid_executed)发送给主库。即下边包车型大巴成团:

UNION(@@global.gtid_executed, Retrieved_gtid_set –
last_received_GTID)

主库将和睦的gtid_executed与slave_gtid_executed的差集的binlog发送给Slave。主库的binlog
dump进度如下:

  1. 检查slave_gtid_executed是还是不是是主库gtid_executed的子集,如否那么主备数据也许不雷同,报错。

  2. 检查主库的purged_executed是否是slave_gtid_executed的子集,如否代表缺点和失误备库供给的binlog,报错

  3. 从最终二个Binlog开首扫描,获取文件头部的PREVIOUS_GTIDS_LOG_EVENT,假使它是slave_gtid_executed的子集,则那是亟需发送给Slave的第二个binlog文件,不然继续向前扫描。

  4. 从第3步找到的binlog文件的上马读取binlog记录,判别binlog记录是或不是已被含有在slave_gtid_executed中,假若已盈盈跳过不发送。

从上面包车型大巴经过能够,在钦赐MASTEMurano_AUTO_POSITION =
1时,Master发送哪些binlog记录给Slave,取决于Slave的gtid_executed和Retrieved_Gtid_Set以及Master的gtid_executed,和relay_log_info以及master_log_info中保存的复制位点没有提到。

如何修复复制错误

在依附GTID的复制拓扑中,要想修复Slave的SQL线程错误,过去的SQL_SLAVE_SKIP_COUNTE途观格局不再适用。须求通过设置gtid_next或gtid_purged达成,当然前提是已经确认保障基本数据一致,仅仅要求跳过复制错误让复制继续下去。比如上面包车型客车光景:

在从库上创建表tb1

mysql> set sql_log_bin=0;

Query OK, 0 rows affected (0.00 sec)

mysql> create table tb1(id int primary key,c1 int);

Query OK, 0 rows affected (1.06 sec)

mysql> set sql_log_bin=1;

Query OK, 0 rows affected (0.00 sec)

在主库上开创表tb1:

mysql> create table tb1(id int primary key,c1 int);

Query OK, 0 rows affected (1.06 sec)

由于从库上那么些表已经存在,从库的复制SQL线程出错结束。

皇家赌场手机版 12皇家赌场手机版 13

地点的输出能够知晓,从库已经施行过的政工是’e10c75be-5c1b-11e6-ab7c-000c296078ae:1-5′,试行出错的作业是’e10c75be-5c1b-11e6-ab7c-000c296078ae:6’,当前主备的数码实际上是同样的,能够经过安装gtid_next跳过这些出错的政工。

在从库上执行以下SQL:

mysql> set gtid_next=’e10c75be-5c1b-11e6-ab7c-000c296078ae:6′;

Query OK, 0 rows affected (0.00 sec)

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

mysql> set gtid_next=’AUTOMATIC’;

Query OK, 0 rows affected (0.00 sec)

mysql> start slave;

Query OK, 0 rows affected (0.02 sec)

设置gtid_next的格局一次只好跳过三个事情,要批量的跳过事务能够因而安装gtid_purged实现。若是上边的场景:

主库桐月推行的事务

皇家赌场手机版 14

从库阳节举办的事体

皇家赌场手机版 15

要是经过修复从库已经和主库的数码一致了,但鉴于复制错误Slave的SQL线程如故高居终止状态。未来能够通过把从库的gtid_purged设置为和主库的gtid_executed一样跳过不雷同的GTID使复制继续下去,步骤如下。

在从库上举行

皇家赌场手机版 16

此刻从库的Executed_Gtid_Set已经满含了主库上’1-10’的事务,再张开复制会以前面包车型客车事情伊始试行,就不会出错了。

mysql> start slave;

Query OK, 0 rows affected (0.01 sec)

使用gtid_next和gtid_purged修复复制错误的前提是,跳过那四个事情后还能够确认保证主备数据一致。假诺做不到,就要思量pt-table-sync或许拉备份的法子了。

GTID与备份复苏

在做备份恢复生机的时候,一时须要还原出来的MySQL实例能够当做Slave连上原本的主库继续复制,那将要求从备份苏醒出来的MySQL实例具备和数码一致的gtid_executed值。那也是经过设置gtid_purged达成的,下面看下mysqldump做备份的事例。

1、通过mysqldump举办备份

因此mysqldump做一个全量备份:

[root@node1 ~]# mysqldump –all-databases –single-transaction
–routines –events –host=127.0.0.1 –port=3306 –user=root >
dump.sql

扭转的dump.sql文件里带有了安装gtid_purged的语句

SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;

SET @@SESSION.SQL_LOG_BIN= 0;

SET @@GLOBAL.GTID_PURGED=’e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10′;

SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;

恢复生机数据前须要先经过reset master清空gtid_executed变量

[root@node2 ~]# mysql -h127.1 -e ‘reset master’

[root@node2 ~]# mysql -h127.1 <dump.sql

再不施行设置GTID_PU福特ExplorerGED的SQL时会报上边包车型地铁谬误

ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set
when @@GLOBAL.GTID_EXECUTED is empty.

此刻过来出的MySQL实例的GTID_EXECUTED和备份时点一致:

皇家赌场手机版 17

由于复原出的MySQL实例已经被安装了情有可原的GTID_EXECUTED,以master_auto_postion
= 1的章程CHANGE MASTE瑞鹰到原本的主节点就能够开头复制。

CHANGE MASTER TO MASTER_HOST=’node1′, MASTER_USER=’repl’,
MASTER_PASSWORD=’repl’, MASTER_AUTO_POSITION = 1

一经不愿意备份文件中生成设置GTID_PURGED的SQL,可以给mysqldump传入–set-gtid-purged=OFF关闭。

2、通过Xtrabackup进行备份

比较mysqldump,Xtrabackup是成效越来越高并且被广泛采纳的备份方式。使用Xtrabackup进行备份的举例如下。

通过Xtrabackup创四个全量备份(能够在Slave上开创备份,防止止对主库的习性冲击)

innobackupex –defaults-file=/etc/my.cnf –host=127.1 –user=root
–password=mysql –no-timestamp –safe-slave-backup –slave-info
/mysql/bak

使用日志

innobackupex –apply-log /mysql/bak

翻开备份目录中的xtrabackup_binlog_info文件能够找到备份时已经推行过的gtids

[root@node2 ~]# cat /mysql/bak/xtrabackup_binlog_info

mysql_bin.000001    191    e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10

是因为备份时增加了”–slave-info”选项并且从Slave节点拉取的备份,所以会生成xtrabackup_slave_info文件,也可以从这几个文件里搜索创设复制的SQL语句。

[root@node2 ~]# cat /mysql/bak/xtrabackup_slave_info

SET GLOBAL gtid_purged=’e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10′;

CHANGE MASTER TO MASTER_AUTO_POSITION=1

将备份文件传送到新的节点node3的/mysql/bak目录并苏醒(纵然间接把备份传输到数量目录了,这一步能够省略)。

[root@node3 ~]# innobackupex –defaults-file=/etc/my.cnf –copy-back
/mysql/bak

启动MySQL。

[root@node3 ~]# mysqld –defaults-file=/home/mysql/etc/my.cnf
–skip-slave-start &

若果是从Slave拉的备份,一定不能一贯张开Slave复制,那时的gtid_executed是不对的。必要手动设置gtid_purged后再start
slave

MASTER_HOST=’node1′,MASTER_USER=’repl’,MASTER_PASSWORD=’repl’,MASTER_AUTO_POSITION=1;

start slave;

GTID与MHA

MHA是被普及利用MySQL HA组件,MHA 0.56后头支持基于GTID的复制。
MHA在failover时会自动推断是或不是是GTID based
failover,必要满意上边3个典型化即为GTID based failover

  • 抱有节点gtid_mode=1

  • 具有节点Executed_Gtid_Set不为空

  • 至少一个节点Auto_Position=1

和事先的基于binlog文件地方的复制比较,基于GTID复制下,MHA在故障切换时的更改根本如下:

基于binlog文件地点的复制

  • 在Master宕机后会尝试从Master上拷贝binlog日志举行填空

  • 借使候选Master不具有最新的relay log,会从具有最新relay
    log的Slave上扭转差距的binlog传送到候选Master并进行补充

  • 新Master的日记补偿到位后,同样运用选取差距binlog的法子将另外Slave和新Master同步后再change
    master到新Master

基于GTID的复制

  • 假若候选Master不具有最新的relay log,让候选Master连上具备最新relay
    log的Salve实行增加补充。

  • 品尝从binlog server上拉取缺点和失误的binlog并采纳

  • 新Master的数据同步到新型后,让别的的Slave连上新Master并等待数据产生一块。並且能够给masterha_master_switch传入–wait_until_gtid_in_sync=1参数使其不等任何Slave完结数据同步,以加快切换速度。

GTID格局下MHA不会尝试从旧Master上拷贝binlog日志举行补给,所以在MySQL进度crash而OS依然健康的事态下,应竭尽不要做主备切换而是原地重启MySQL,除非有任何能保障切换后不丢数据的主意。

在GTID形式下MHA帮助在复制拓扑中加进三个或八个binlog
server起到日志补偿的成效,非GTID情势下就算配置了binlog
server也会被MHA忽略。

日志补偿能够说是MHA中最复杂也最特出的一部分,有了GTID后故障切换变得更简短了,不再必要原来复杂的binlog日志深入分析和互补。 所以Oracle官方推出了只辅助GTID复制的切换工具mysqlfailover,在GTID的扶助下,我们有越多可信赖的HA工具得以挑选。

GTID与crash safe salve

crash safe slave是MySQL 5.6提供的功力,意思是说在slave
crash后,把slave重新拉起来能够三番五次从Master举办复制,不会并发复制错误也不会产出数量区别样。

1、基于binlog文件地点的复制

在基于binlog文件位置的复制下,要保管crash safe
slave,配置下边的参数即可。

relay_log_info_repository      = TABLE

relay_log_recovery               = ON

与此相类似可行的因由是,relay_log_info_repository = TABLE时,apply

event和更新relay_log_info表的操作被含有在同一个业务里,innodb要么让它们同不时候生效,要么同一时候不见效,有限帮助位点信息和曾经运用的事情正确相称。同期relay_log_recovery

ON时,会抛弃master_log_info中记录的复制位点,依照relay_log_info的奉行任务再一次从Master获取binlog,那就逃避了由于未共同刷盘导致的binlog文件接受地点和实际不雷同以及relay
log文件被截断的问题。

在同临时间利用MTS(multi-threaded slave)时,为确定保障crash safe
slave基于binlog文件地方的复制还须要设置sync_relay_log=1,因为MySQL在Crash复苏时必需先通过读取relay
log补齐MTS导致的事务空洞。

2、基于GTID的复制

下边包车型地铁设置并不适用于依赖GTID的复制。在依靠GTID的复制下,crash的Slave重启后,从binlog中深入分析的gtid_executed决定了要apply哪些binlog记录,所以binlog必得和innodb存款和储蓄引擎的多寡保持一致。要到位那或多或少,必要把sync_binlog和innodb_flush_log_at_trx_commit都安装为1,即所谓的”双1″。

别的MySQL运转时,会从relay
log文件中收获已吸取的GTIDs并立异Retrieved_Gtid_Set。由于relay
log文件或许不完整,所以供给抛弃已抽取的relay
log文件。因而relay_log_recovery = ON也是必须的。

如此,对于基于GTID的复制,保障crash safe slave的安装正是上面那样。

sync_binlog                               = 1

innodb_flush_log_at_trx_commit  = 1

relay_log_recovery                     = ON

关于什么设置以担保crash safe slave,官方文书档案有由此可见记载,见 17.3.2
Handling an Unexpected 哈尔t of a Replication Slave。

然而里面有关GTID的记载中设有笔误,将relay_log_recovery=1写成了relay_log_recovery=0 (#83711)。同期也未尝关系必得安装”双1″,然则”双1″是必备的,不然crash的Slave重启后,恐怕会再一次应用binlog
event也可能会窥豹一斑应用binlog event(#70659)。其中遗漏应用binlog
event的景况更可怕,因为Slave在不触发SQL错误的情状下就默默的和Master不同了。

3、设置”双1″对质量的影响

是因为安全思量,刚强推荐设置”双1″。”双1″会增大每种事情的RT,但得益于MySQL的组提交机制,高并发下”双1″对系统一整合体tps的熏陶在可接受范围内。

sysbench oltp.lua 10张表每张表100w记录(qps/并发数)

皇家赌场手机版 18

对立异同一行那样不能有效互动的意况,”双1″对品质的影响非凡大。

sysbench update_non_index.lua 1张表1条记录(qps/并发数)

皇家赌场手机版 19

对不可能使得互动的Slave replay,存在一样的题目。

通过内定tx-rate推行sysbench的update_non_index.lua脚本压测30秒,完结后检查主备延迟。

能够窥见在Slave被安插为”双1″的状态下,延迟十一分沉痛,1000以上的 QPS 就能出现延迟,非”双1″下QPS到五千之上才会现出延迟(主库配置为”双1″)。

sysbench update_non_index.lua 1张表100w条记录 128并发(延迟/qps)

皇家赌场手机版 20

以上测试情形是Percona Server 5.6周转在配置HDD的8
core虚机,由于测量检验结果和系统IO本事有异常的大关系,仅供仿效。

4、怎么着在非”双1″下保险crash safe slave

假定是MySQL
5.7方可关闭log_slave_updates,那样MySQL会将已实践的GTIDs实时记下到系统表mysql.gtid_executed中,mysql.gtid_executed是和顾客业务一齐交给的,因而得以确定保障和骨子里的数量一致。

log_slave_updates              = OFF

relay_log_recovery             = ON

假使是MySQL 5.6得以行使如下变化的主意。

根据基于binlog文件复制时crash safe
slave的须要安装relay_log_info_repository = TABLE

relay_log_info_repository      = TABLE

relay_log_recovery               = ON

在Slave
crash后,根据relay_log_info_repository设置相应的gitd_purged再张开复制,步骤如下。

1.开端MySQL,但不开启复制

mysqld –skip-slave-start

2.在Slave上改动为基于binlog文件地点的复制

change master to MASTER_AUTO_POSITION = 0

3.启动slave IO线程

start slave io_thread

此间无法开发银行SQL线程,要是接受到的GTID已经在Slave的gtid_executed里了,会被Slave
skip掉。

4.检查binlog传输的发端地方(即Retrieved_Gtid_Set的值)

show slave status\G

要是输出的Retrieved_Gtid_Set值为e10c75be-5c1b-11e6-ab7c-000c296078ae:7-10

5.在Master上检查gtid_executed

show master status

假定输出的Executed_Gtid_Set值为e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10

6.在Slave上设置gitd_purged为binlog传输地方的近日的GTID的联谊

reset master;

set global gitd_purged=’e10c75be-5c1b-11e6-ab7c-000c296078ae:1-6′;  

7.修改回auto position的复制

change master to MASTER_AUTO_POSITION = 1

8.启动slave SQL线程

start slave sql_thread

然则,这种变动的法子不切合三十二线程复制。因为四线程复制大概发生gtid
gap和Gap-free low-watermark
position,这会导致Salve上海重机厂复apply已经apply过的event。后果正是数量分化等只怕复制中断,除非设置binlog格式为row方式並且slave_exec_mode=IDEMPOTENT,slave_exec_mode=IDEMPOTENT允许Slave重播binlog时大意重复键和找不到键的错误,使得binlog重播具有幂等性,但那也代表一旦确实出现了主备数据不平等也会被它忽略。

5、MTS下蓄意的难点

在同期选择MTS(slave_parallel_workers > 1)时,固然按上边crash safe
slave的渴求安装了基于GTID的复制,Slave crash后再重启依旧会导致复制中断。

通过强制杀掉MySQL所在虚机的秘籍模拟Slave宕机,然后再起步MySQL,MySQL日志中有如下错误音信:

皇家赌场手机版 21

初始slave时也会报错

mysql> start slave;

ERROR 1872 (HY000): Slave failed to initialize relay log info structure
from the repository

出现这种现象的原因在于,relay_log_recovery=1 且 slave_parallel_workers>1的意况下,mysql运转时会进入MTS
Group苏醒流程,即读取relay
log,尝试填补由于二十八线程复制导致的gap。然后relay
log文件由于不是实时刷新的,在relay log文件中找不到gap对应的relay
log记录(覆盖了gap的relay
log早先和了结地方分别被称之为低水位和高水位,低水位点即slave_relay_log_info.Relay_log_pos的值)就能够报那个错。

实质上,在GTID格局下,slave在apply
event的时候能够跳过重复事件,所以能够安枕而卧的从低水位点应用日志,没须求剖析relay
log文件。
那看起来是一个bug,于是提交了一个bug报告#83713,前段时间还并未接到回复。

作为逃避方法,能够由此解除relay log文件,跳过那么些破绽百出。推行步骤如下:

reset slave;

change master to MASTER_AUTO_POSITION = 1

start slave;

在此间,单纯的调reset
slave不可能把情形清理通透到底,内部的Relay_log_info.inited标识位照旧居于未被开首化状态,此时调用start
slave如故会破产。由此须求补一刀change master。

6、Master的crash safe

前边平素在讲crash safe slave,Master的crash safe同样重要。
要想Master保持crash
safe供给按下边的参数实行安装,不然不但会舍弃事务,gtid_executed还大概和实际的innodb存款和储蓄引擎中的数据分歧样。

sync_binlog                              = 1

innodb_flush_log_at_trx_commit = 1

在Master配置为”双1″的地方下,Master
crash后,如果未有发出failover,能够延续作为Master。
假使产生了failover,能够检查旧Master和新Master上由旧Master试行的政工会集是还是不是一律。

show master status

假定同样,能够按MASTEENCORE_AUTO_POSITION =
1的不二秘技将旧Master作为Slave和新Master创建复制关系。不然,思索做事情补偿或从新Master上拉取备份进行恢复生机。

在Master配置不是”双1″的情景下,在Master
crash后由于难以精确准确理解旧Master上毕竟实行了怎样事情,安全的做法是施行主备切换,并从新Master上拉取备份,把旧Master作为新Master的Slave进行复原。

Leave a Comment.