mysql GTID主从复制故障后不停机恢复同步流程

GTID实现主从复制数据同步

GTID是一个基于原始mysql服务器生成的一个已经被成功执行的全局事务ID,它由服务器ID以及事务ID组成,这个全局事务ID不仅仅在原始服务器上唯一,在所有主从关系的mysql服务器上也是唯一的。正式因为这样一个特性使得mysql主从复制变得更加简单,以及数据库一致性更可靠。

 

介绍

GTID的概念

  1.  全局事务标识:global transaction identifiers
  2.  GTID是一个事务一一对应,并且全局唯一ID
  3.  一个GTID在一个服务器上只执行一次,避免重复执行导致数据混乱不一致
  4.  不再使用传统的MASTER_LOG_FILE+MASTER_LOG_POS开启复制,而是采用MASTER_AUTO_POSTION=1的方式开启复制。
  5.  MYSQL-5.6.5及后续版本开始支持

 

GTID的组成

GTID = server_uuid:transaction_id

server_uuid:mysql服务器的唯一标识,查看方法mysql客户端内:show variables like '%server_uuid%';

transaction_id:此id是当前服务器中提交事务的一个序列号,从1开始自增长,一个数值对应一个事务

GTID号示例:c9fba9e2-db3b-11eb-81d4-000c298d8da1:1-5

 

GTID的优势

  1.  实现主从更简单,不用像以前一样寻找log_file和log_pos
  2.  比传统的主从更加安全
  3.  GTID是连续没有空洞的,保证数据一致性,零丢失。

 

GTID工作原理

  1. master更新数据时,会在事务前产生GTID,一同记录到binlog日志中
  2. slave端的I/O线程将变更的binlog,写入到本地的relay log中
  3. SQL线程从relay log中获取GTID,然后对比slave端的binlog是否有记录(所以MySQL5.6 slave端必须开启binlog)
  4. 如果有记录,说明该GTID的事务已经执行,slave会忽略
  5. 如果没有记录,slave就会从relay log中执行该GTID的事务,并记录到binlog
  6. 在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有就用全部扫描

 

开始配置GTID复制

主:192.168.152.253   Centos7

从:192.168.152.252   Centos8

测试数据库:vfan

测试表:student

 

1、修改mysql服务配置文件,添加以下参数,随后重启:

server-id=100    #server id
log-bin=/var/lib/mysql/mysql-bin  #开启binlog并指定存储位置
expire_logs_days=10  #日志保存时间为10天
gtid_mode=on  #gtid模块开关
enforce_gtid_consistency=on  #启动GTID强一致性,开启gtid模块必须开启此功能。
binlog_format=row  #bin_log日志格式,共有三种STATEMENT、ROW、MIXED;默认为STATEMENT
skip_slave_start=1  #防止复制随着mysql启动而自动启动

主服务器和从服务器的配置一致即可,server-id更改一下

 

2、在主服务器中创建从服务器连接的用户

CREATE USER 'copy'@192.168.152.252' IDENTIFIED BY ';
GRANT REPLICATION SLAVE ON *.* TO ;
flush privileges;

创建完毕记得要测试下slave机是否能登录成功

 

3、使用mysqldump使两数据库数据同步

主mysql执行:
mysqldump -uroot -proot1 vfan > dump2.sql
scp dump2.sql 192.168.152.252:/data/

从mysql执行:
mysql> source /data/dump2.sql

 

当前主、从服务器数据内容一致,都是以下数据:

mysql> select * from student;
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | Tony |  18 |
|  2 | Any  |  17 |
|  3 | Goy  |  20 |
|  4 | Baly |  5 | Heg  |  19 |
|  6 | hhh  | 100 |
|  7 | lll  |  99 |
+----+------+-----+
7 rows in set (0.01 sec)

 

4、开启主从复制

mysql> CHANGE MASTER TO MASTER_HOST=192.168.152.253',MASTER_USER=3306,MASTER_AUTO_POSITION=1;
Query OK,0 rows affected,2 warnings (0.04 sec)

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

## 查看slave状态
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 152.253
                  Master_User: copy
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000014
          Read_Master_Log_Pos: 897
               Relay_Log_File: kubenode2-relay-bin.000002
                Relay_Log_Pos: 416
        Relay_Master_Log_File: mysql-bin.
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

 

5、检查是否同步

主服务器中插入数据:
mysql> INSERT INTO student(name,age) VALUES(gogoo50),(zhazha25);
Query OK,1)">2 rows affected (0.03 sec)
Records: 2  Duplicates: 0  Warnings: 0

从服务器中读取:
mysql>  from student;
+----+--------+-----+
| id | name   | age |
+----+--------+-----+
|  1 | Tony   |  2 | Any    |  3 | Goy    |  4 | Baly   |  5 | Heg    |  6 | hhh    | 7 | lll    |  99 |
|  8 | gogoo  |  50 |
|  9 | zhazha |  25 |
+----+--------+-----+
9 rows 0.00 sec)

数据已经同步,基础的主从复制已经搭建完成

 

现在模拟一个主从复制架构中,从服务器中途复制失败,不再同步主服务器的场景,并要求不停业务进行数据同步修复,恢复一致。

1、首先先模拟一个数据插入的场景

vim insert.sh

#!/usr/bin/env bash

values=(`find /usr/ -type d | awk -F /' {print $NF}' | sort -u`)

while true
do
age=$(( $RANDOM%100 ))
name=${values[$(( $RANDOM%6 ))]}

mysql -h127.1 -P3306 -uroot -proot1 -e "INSERT INTO vfan.student(name,age) VALUES('"${name}',${age});" &> /dev/null 
sleep $(( $RANDOM%5 ))
done

运行脚本,数据在随机插入(插入时间间隔 < 5s)

目前主mysql数据:

mysql>  from student;
+----+---------------------+-----+
| id | name                | age |
......
|  97 | _                   |   2 |
|  98 | 00bash              |  15 |
|  99 | 00bash              |  52 |
| 100 | 00bash              |  43 |
| 101 | _                   |  65 |
| 102 | 00                  |  67 |
+-----+---------------------+-----+
102 rows 0.01 sec)

 

2、数据还在陆续插入,此时模拟slave节点宕机或异常(在此就直接stop slave;)

mysql> stop slave;
Query OK,1)">0.01 sec)

 

3、此时主库数据还在增加,而从库已经不同步,以下是从库数据:

mysql> 
......
| 82 | 00bash              |  50 |
| 83 | 00systemd-bootchart |  36 |
| 84 | 00bash              |  48 |
| 85 | 00systemd-bootchart |  41 |
| 86 | 72 |
+----+---------------------+-----+
86 rows 0.00 sec)

 

4、开始从库恢复数据

思路:

 先通过mysqldump全量备份当前的数据,由于不能影响业务,所以在mysqldump数据时不能造成锁表。要保持数据写入

 由于mysqldump时数据还在写入,所以有一部分数据还是会同步不全,所以导入mysqldump的数据后,跳过dump中包含的GTID事务,再重新建立一次主从配置,开启slave线程,恢复数据并同步。

 

1)mysqldump不锁表备份数据

mysqldump -uroot -proot1 --single-transaction --master-data=2 -R vfan | gzip > dump4.sql

主要起作用参数:--single-transaction

 

2)查看当前mysqldump导出数据的GTID号

[root@TestCentos7 data]# grep GLOBAL.GTID_PURGED dump4.sql 
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ c9fba9e2-db3b-11eb-81d4-000c298d8da1:1-228';

以上的 c9fba9e2-db3b-11eb-81d4-000c298d8da1:1-228 表示MASTER机执行到的GTID事务号

 

3)去从数据库导入

scp dump4.sql 152.252:/data

mysql客户端内:
mysql> source /data/dump4.sql

此时从库数据:
mysql>  from student;
| 230 | 53 |
| 231 | 00bash              |  66 |
| 232 | _                   |  18 |
| 233 | 0.33.0              |  98 |
| 234 | 00bash              |  14 |
+-----+---------------------+-----+
234 rows 0.00 sec)

主库数据:
| 454 | _                   |  46 |
| 455 | 03modsign           |  59 |
| 456 | 00systemd-bootchart |  77 |
| 457 | 03modsign           |   6 |
| 458 | 88 |
+-----+---------------------+-----+
458 rows 0.00 sec)

从库数据恢复一部分到234行,主库数据依然在增加,已经是458条

 

4)由于我们mysqldump的数据已经包含了在MASTER执行的 1-228 个事务,所以我们在SLAVE进行同步的时候,要忽略这些事务不再进行同步,不然会出现类似于这种报错:

mysql>137827417
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
                   Last_Errno: 1062
                   Last_Error: Could not execute Write_rows event on table vfan.student; Duplicate entry 87' for key student.PRIMARY1062; handler error HA_ERR_FOUND_DUPP_KEY; the events master log mysql-bin.000002,end_log_pos 10588

 

要想跳过某些GTID,SLAVE必须保证 gtid_purged 参数为空才能正确跳过,查看当前的gtid_purged:

mysql> show global variables like %gtid%;
+----------------------------------+-------------------------------------------------------------------------------------+
| Variable_name                    | Value                                                                               |
+----------------------------------+-------------------------------------------------------------------------------------+
| binlog_gtid_simple_recovery      | ON                                                                                  |
| enforce_gtid_consistency         | ON                                                                                  |
| gtid_executed                    | b30cb2ff-32d4-11eb-a447-000c292826bc:1-2,c9fba9e2-db3b-11eb-81d4-000c298d8da1:80 |
| gtid_executed_compression_period | 1000                                                                                |
| gtid_mode                        | ON                                                                                  |
| gtid_owned                       |                                                                                     |
| gtid_purged                      | c9fba9e2-db3b-11eb-81d4-000c298d8da1:70                                           |
| session_track_gtids              | OFF                                                                                 |
+----------------------------------+-------------------------------------------------------------------------------------+
8 rows 0.02 sec)

 

当前gtid_purged不为空,所以我们要先设置它为空,执行:

mysql> reset master;
Query OK,1)">0.05 sec)

mysql> show global variables like ;
+----------------------------------+-------+
| Variable_name                    | Value |
+----------------------------------+-------+
| binlog_gtid_simple_recovery      | ON    |
| enforce_gtid_consistency         | ON    |
| gtid_executed                    |       |
| gtid_executed_compression_period | 1000  |
| gtid_mode                        | ON    |
| gtid_owned                       |       |
| gtid_purged                      |       |
| session_track_gtids              | OFF   |
+----------------------------------+-------+
0.00 sec)

 

5)gtid_purged为空后,开始重置SLAVE

mysql> reset slave all;
Query OK,1)">0.02 sec)

 

6)重置后,设置跳过的GTID,并重新同步MASTER

mysql> SET @@GLOBAL.GTID_PURGED= sec)

mysql> CHANGE MASTER TO MASTER_HOST=0.04 sec)

 

7)开启SLAVE进程,查看同步状态

mysql>84993
             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: 
                   Last_Error: 
                 Skip_Counter: 
          Exec_Master_Log_Pos: 
              Relay_Log_Space: 85206
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 
                Last_IO_Error: 
               Last_SQL_Errno: 
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 
                  Master_UUID: c9fba9e2-db3b-11eb-81d4-000c298d8da1
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 
          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: c9fba9e2-db3b-11eb-81d4-000c298d8da1:229-519
            Executed_Gtid_Set: c9fba9e2-db3b-11eb-81d4-000c298d8da1:
                Auto_Position: 
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 
            Network_Namespace: 
1 row 0.00 sec)

可以看到,同步正常!

 

8)最后,查看master与slave数据是否一致

MASTER数据:SELECT * FROM student;
| 520 | 00systemd-bootchart |  521 | 00systemd-bootchart |  44 |
| 522 | 03modsign           |  523 | 00systemd-bootchart |  45 |
| 524 | 90 |
| 525 | 03modsign           |  21 |
+-----+---------------------+-----+
525 rows  sec)

SLAVE数据:SELECT * FROM student;
| 519 | 99 |
| 0.00 sec)

在我们修过程中插入的数据也已经全部同步。数据完全一致,主从复制修复完成。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


在正式开始之前,我们先来看下 MySQL 服务器的配置和版本号信息,如下图所示: “兵马未动粮草先行”,看完了相关的配置之后,我们先来创建一张测试表和一些测试数据。 -- 如果存在 person 表先删除 DROP TABLE IF EXISTS person; -- 创建 person 表,其中
&gt; [合辑地址:MySQL全面瓦解](https://www.cnblogs.com/wzh2010/category/1859594.html &quot;合辑地址:MySQL全面瓦解&quot;) # 1 为什么需要数据库备份 - 灾难恢复:当发生数据灾难的时候,需要对损坏的数据进行恢复和
物理服务机的CPU、内存、存储设备、连接数等资源有限,某个时段大量连接同时执行操作,会导致数据库在处理上遇到性能瓶颈。为了解决这个问题,行业先驱门充分发扬了分而治之的思想,对大库表进行分割,&#xA;然后实施更好的控制和管理,同时使用多台机器的CPU、内存、存储,提供更好的性能。而分治有两种实现方式:垂直拆
1 回顾 上一节我们详细讲解了如何对数据库进行分区操作,包括了 垂直拆分(Scale Up 纵向扩展)和&#160;水平拆分(Scale Out 横向扩展) ,同时简要整理了水平分区的几种策略,现在来回顾一下。 2 水平分区的5种策略 2.1 Hash(哈希) 这种策略是通过对表的一个或多个列的Ha
navicat查看某个表的所有字段的详细信息 navicat设计表只能一次查看一个字段的备注信息,那怎么才能做到一次性查询表的信息呢?SELECT COLUMN_NAME,COLUMN_COMMENT,COLUMN_TYPE,COLUMN_KEY FROM information_schema.CO
文章浏览阅读4.3k次。转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52768613前言:数据库每天的数据不断增多,自动删除机制总体风险太大,想保留更多历史性的数据供查询,于是从小的hbase换到大的hbase上,势在必行。今天记录下这次数据仓库迁移。看下Agenda:彻底卸载MySQL安装MySQL_linux服务器进行数据迁移
文章浏览阅读488次。恢复步骤概要备份frm、ibd文件如果mysql版本发生变化,安装回原本的mysql版本创建和原本库名一致新库,字符集都要保持一样通过frm获取到原先的表结构,通过的得到的表结构创建一个和原先结构一样的空表。使用“ALTER TABLE DISCARD TABLESPACE;”命令卸载掉表空间将原先的ibd拷贝到mysql的仓库下添加用户权限 “chown . .ibd”,如果是操作和mysql的使用权限一致可以跳过通过“ALTER TABLE IMPORT TABLESPACE;”命令恢_alter table discard tablespace
文章浏览阅读225次。当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化:单表优化除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑、部署、运维的各种复杂度,一般以整型值为主的表在千万级以下,字符串为主的表在五百万以下是没有太大问题的。而事实上很多时候MySQL单表的性能依然有不少优化空间,甚至能正常支撑千万级以上的数据量:字段尽量使用TINYINT、SMALLINT、MEDIUM_INT作为整数类型而非INT,如果非负则加上UNSIGNEDVARCHAR的长度只分配_开发项目 浏览记录表 过大怎么办
文章浏览阅读1.5k次。Mysql创建、删除用户MySql中添加用户,新建数据库,用户授权,删除用户,修改密码(注意每行后边都跟个;表示一个命令语句结束):1.新建用户登录MYSQL:@>mysql -u root -p@>密码创建用户:mysql> insert into mysql.user(Host,User,Password) values("localhost_删除mysql用户组
MySQL是一种开源的关系型数据库管理系统,被广泛应用于各类应用程序的开发中。对于MySQL中的字段,我们需要进行数据类型以及默认值的设置,这对于数据的存储和使用至关重要。其中,有一个非常重要的概念就是MySQL字段默认字符串。 CREATE TABLE `my_...
MySQL是一个流行的开源关系型数据库管理系统,广泛应用于Web应用程序开发、数据存储和管理。在使用MySQL时,正确设置字符集非常重要,以确保数据的正确性和可靠性。 在MySQL中,字符集表示为一系列字符和字母的集合。MySQL支持多种字符集,包括ASCII、UTF...
MySQL存储函数 n以内偶数 MySQL存储函数能够帮助用户简化操作,提高效率,常常被用于计算和处理数据。下面我们就来了解一下如何使用MySQL存储函数计算n以内的偶数。 定义存储函数 首先,我们需要定义一个MySQL存储函数,以计算n以内的偶数。下...
MySQL是一个流行的关系型数据库管理系统,基于客户机-服务器模式,可在各种操作系统上运行。 MySQL支持多种字符集,不同的字符集包括不同的字符,如字母、数字、符号等,并提供不同的排序规则,以满足不同语言环境的需求。 //查看MySQL支持的字符集与校对规...
在MySQL数据库中,我们有时需要对特定的字符串进行截取并进行分组统计。这种操作对于数据分析和报表制作有着重要的应用。下面我们将讲解一些基本的字符串截取和分组统计的方法。 首先,我们可以使用substring函数对字段中的字符串进行截取。假设我们有一张表stude...
MySQL提供了多种字符串的查找函数。下面我们就一一介绍。 1. LIKE函数 SELECT * FROM mytable WHERE mycolumn LIKE 'apple%'; 其中"apple%"表示以apple开头的字符串,%表示任意多个字符...
MySQL 是一种关系型数据库管理系统,广泛应用于各种不同规模和类型的应用程序中。在 MySQL 中,处理字符串数据是很常见的任务。有时候,我们需要在字符串的开头添加一定数量的 0 ,以达到一定的位数。比如,我们可能需要将一个数字转换为 4 位或 5 位的字符串,不足的...
MySQL是一种流行的关系型数据库管理系统,支持多种数据类型。以下是MySQL所支持的数据类型: 1. 数值型数据类型: - TINYINT 保存-128到127范围内的整数 - SMALLINT 保存-32768到32767范围内的整数 - MEDIU...
MySQL中存储Emoji表情字段类型 在现代互联网生态中,表情符号已经成为人们展示情感和思想的重要方式之一,因此将表情符号存储到数据库中是一个经常出现的问题。MySQL作为最流行的开源关系型数据库管理系统之一,也需要能够存储和管理这些表情符号的字段类型。 UT...
MySQL是一种关系型数据库管理系统。在MySQL数据库中,有多种不同的数据类型。而其中,最常见的数据类型之一就是字符串类型。在MySQL中,字符串类型的数据通常会被存储为TEXT或VARCHAR类型。 首先,让我们来看一下VARCHAR类型。VARCHAR是My...
MySQL字符串取整知识详解 MySQL是一种开源的关系型数据库管理系统,广泛应用于各个领域。在使用MySQL过程当中,我们经常需要对数据进行取整操作。本文将介绍如何使用MySQL字符串取整来处理数据取整问题。 什么是MySQL字符串取整? MySQL...