MySQL之GTID复制

阅读: 评论:0

MySQL之GTID复制

MySQL之GTID复制

MySQL之GTID复制

mysql事务

为什么数据库需要事务?

  • 你表弟向你借500元,你打开APP、爽快的给他转账了,你的卡余额提示少了500
  • 你给表弟发了个微信,说,钱打过去了
  • 你表弟说:没收到啊哥,你别骗我行吗
  • 你钱扣少了,你表弟缺没收到钱,这事办的?咋整

讲道理应该是这样

  1. 超哥发起转账,转给表弟
  2. 超哥卡里少了500元
  3. 表弟卡里多了500元

这三步骤、必然不得出问题,上面的案例,就是这三步发生了问题!

如果有事务、就不会发生这样的事

事务就是

这三件事、三个动作,是一根绳上的蚂蚱,要么都成功,要么都失败

转账要么到表弟账户、要么就转不出去、回到自己卡里

事务的ACID特性

TRANSACTION 事务

Atomicity原子性

原子性强调转账的三个步骤要么成功、要么失败

在一个事务中的所有SQL语句,要么全部执行成功,要么全部失败,即使成功的SQL语句也会被撤销,回到执行之前的状态。

Consistency一致性

一致性是指数据库从一个状态、变为另一个状态

事务开始前、与结束后,数据库的完整性约束没有被破坏。

例如转账,无论成功、或者失败、这500不会多、也不会少

要么超哥卡里扣了500元、表弟多了500元

要么超哥转账失败500元未动、表弟一毛钱也没拿到

这个总和永远是500元,不多也不少

Isolation隔离性

隔离性指的是每个读写事务对其他的事务操作,都是相互隔离不受影响的。

例如同是工商银行

  • 超哥转账操作不会影响到小猪佩奇的转账操作

Durability持久性

事务一旦提交后,结果就是永久性生效。

超哥转账500给了表弟,表弟也收到钱了,这件事就结束了,真实生效了。

事务的实现

更多高级mysql知识,超哥后期会再补充

GTID是什么

从 MySQL 5.6.5 开始新增了一种基于 GTID 的复制方式。

通过 GTID 保证了每个在主库上提交的事务在集群中有一个唯一的ID。

这种方式强化了数据库的主备一致性,故障恢复以及容错能力。

在原来基于二进制日志的复制中,从库需要告知主库要从哪个偏移量进行增量同步,如果指定错误会造成数据的遗漏,从而造成数据的不一致。

借助GTID,在发生主备切换的情况下,MySQL的其它从库可以自动在新主库上找到正确的复制位置,这大大简化了复杂复制拓扑下集群的维护,也减少了人为设置复制位置发生误操作的风险。

另外,基于GTID的复制可以忽略已经执行过的事务,减少了数据发生不一致的风险。

GTID长啥样

GTID (Global Transaction ID) 是对于一个已提交事务的编号,并且是一个全局唯一的编号。

GTID 实际上 是由 UUID+TID 组成的。

其中 UUID 是一个 MySQL 实例的唯一标识。

TID 代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。下面是一个GTID的具体形式:

形式语法  
GTID = source_id :transaction_id具体结果
2E11FA47-61CA-11E1-9E33-C70AA9429562:28

在上面的定义中,每一个GTID均代表一个数据库的事务,等号右边的source_id表示执行事务的源服务器主库的uuid(也就是server_uuid)

而transaction_id是一个从1开始的自增的序列号,表示在这个主库上执行的第n个事务。

只要保证每台数据库的server_uuid全局唯一,以及每台数据库生成的transaction_id自身唯一,就能保证GTID的全局唯一性。

server_uuid是什么

还记得以前我们在myf中配置了一个参数

server_id=5

并且超哥要求master、slave的server_id必须唯一

为什么换成server_uuid

MySQL 5.6用128位的server_uuid代替了原本32位的server_id的大部分功能。

原因很简单,server_id依赖于myf的手工配置,有可能会产生冲突,而自动产生128位uuid的算法可以保证所有的MySQL uuid都不会发生冲突。

在进行首次启动时,MySQL会自动生成一个server_uuid,并且保存到数据库目录下的autof文件里,这个文件目前存在的唯一目的就是保存server_uuid。

在MySQL再次启动时其会读取autof文件,继续使用上次生成的server_uuid。

使用GTID

GTID复制原理流程

  • master进行数据更新时、在事务前产生GTID号、一起记录到binlog日志。

  • slave的I/O线程将变更的binlog数据,写入到本地中继日志relay_log

  • slave的SQL线程从中继日志中获取

    GTID
    

    号,和本地的binlog对比查看是否有记录

    • 有记录,说明该GTID事务已执行,slave数据库会忽略
  • 如果没有记录,slave数据库从relay_log中继日志中获取数据,且执行该GTID的事务,记录到binlog中

根据GTID号就可以知道事务最初是在哪个数据库上提交的

有了GTID号、可以方便主从复制的故障切换

主从故障切换

如图、在没有GTID以前,主从复制的故障切换

  • master-A宕机,需要将应用程序切换到master-B
  • slave-C得和master-B建立新的复制关系

只需要在slave-C上执行新的change master to xxx ,指定master-B即可

问题是,同一个事务、在每台服务器上的binlog名字和位置点、可能都是不一样的

比如执行一条SQL,创建了一个新数据库,执行了一个事务,在master-A机器的binlog中数据位置如下

mysql> show master status-> ;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |     557 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

但是可能在机器master-B中的bin中,同一个SQL执行后,binlog数据位置可能是

mysql> show master status-> ;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000005 |     1251 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

那么这就是一个难题了,如果master-A宕机,需要切换到master-B

slave-C如何知道当前同步的起停数据位置点呢?master_log_file和master_log_pos填什么?

这就是为什么mysql官方开发了GTID复制方法。

往后,同一个事务的GTID在所有节点上都是一致的,slave-C机器根据GTID就可以知道数据的停止点在哪。

并且,mysql还提供了非常方便的参数master_auto_position,能够自动的获取GTID值,让运维更加省心了。

GRID优缺点

优点

  • 根据GTID可以明确知道事务最开始是在哪个数据库提交的
  • GTID对于宕机切换,非常方便,明确数据起止点。

缺点

  • 开启了GTID的数据库,和未开启的数据库实例之间、是无法混用复制的

GTID复制实践

环境准备

可以是单机多实例

也可以是多服务器

这里超哥用两台linux虚拟机服务器、初始化安装好mysql

配置文件

m1 10.211.55.12 3306
m2 10.211.55.9  3306

m1 myf

[root@mysql-server56 ~]# cat /mm_data/3306/myf
[client]
default-character-set=utf8[mysqld]
character-set-server=utf8
socket=/mm_data/3306/mysql.sock
basedir=/application/mysql-5.6.40-linux-glibc2.12-x86_64/
datadir=/mm_data/3306/data
log-bin=/mm_data/3306/mysql-binserver-id=1
expire_logs_days=7
log-slave-updates=1
binlog-format=ROW
gtid-mode=on
enforce-gtid-consistency=true[mysqld_safe]
log-error=/mm_data/3306/mysql_3306_error.log
pid-file=/mm_data/3306/mysqld_3306.pid
sql_mode=NO_ENGINE_SUBSTITUTION,STRTICT_TRANS_TABLES
[root@mysql-server56 ~]#

slave myf

[client]
default-character-set=utf8[mysqld]
character-set-server=utf8
socket=/mm_data/3306/mysql.sock
basedir=/application/mysql-5.6.40-linux-glibc2.12-x86_64/
datadir=/mm_data/3306/data
log-bin=/mm_data/3306/mysql-bin
server-id=2
expire_logs_days=7
log-slave-updates=1
binlog-format=ROW
gtid-mode=on
enforce-gtid-consistency=true[mysqld_safe]
log-error=/mm_data/3306/mysql_3306_error.log
pid-file=/mm_data/3306/mysqld_3306.pid
sql_mode=NO_ENGINE_SUBSTITUTION,STRTICT_TRANS_TABLES

除了server-id完全一致,重启2个机器的mysql

参数解释

Mater1–GTID主从复制

m1操作,创建用于slave复制的账号、权限

mysql> grant replication slave on *.* to 'repl'@'10.211.55.%' identified by 'repl888';
Query OK, 0 rows affected (0.01 sec)mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

导出主库数据

备注

mysql提示: 当前数据库实例中开启了 GTID 功能, 在开启有 GTID 功能的数据库实例中, 导出其中任何一个库, 如果没有显示地指定--set-gtid-purged参数, 都会提示这一行信息. 意思是默认情况下, 导出的库中含有 GTID 信息, 如果不想导出包含有 GTID 信息的数据库, 需要显示地添加--set-gtid-purged=OFF参数. 于是乎, dump 变成了如下样子➜ mysqldump -uroot -p --set-gtid-purged=OFF userdb > userdb.sql使用以上这条命令 dump 出来的库是不包含 GTID 信息的

命令

[root@mysql-server56 ~]# mysqldump -S /mm_data/3306/mysql.sock  -A -B -x --set-gtid-purged=OFF|gzip > /mm_data/m1_alldb_$(date +%F).
[root@mysql-server56 ~]#

查看GTID信息

mysql> show global variables like '%gtid%';
+---------------------------------+------------------------------------------+
| Variable_name                   | Value                                    |
+---------------------------------+------------------------------------------+
| binlog_gtid_simple_recovery     | OFF                                      |
| enforce_gtid_consistency        | ON     # 确保这里打开                      |
| gtid_executed                   | 20bdbbd9-a5cd-11eb-a6af-001c4279bcf3:1-4 |
| gtid_mode                       | ON     # 确保这里打开        
| gtid_owned                      |                                          |
| gtid_purged                     |                                          |
| simplified_binlog_gtid_recovery | OFF                                      |
+---------------------------------+------------------------------------------+
7 rows in set (0.00 sec)# 查看uuid信息
mysql> show global variables like 'server%';
+----------------+--------------------------------------+
| Variable_name  | Value                                |
+----------------+--------------------------------------+
| server_id      | 1                                    |
| server_id_bits | 32                                   |
| server_uuid    | 20bdbbd9-a5cd-11eb-a6af-001c4279bcf3 |
+----------------+--------------------------------------+
3 rows in set (0.00 sec)# 数据插入后,会生成新的GTID
mysql> show master status;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000004 |      811 |              |                  | 20bdbbd9-a5cd-11eb-a6af-001c4279bcf3:1-4 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)#

发送数据给slave

[root@mysql-server56 ~]# scp -rp /mm_data/m1_alldb_ root@10.211.55.9:/mm_data/
root@10.211.55.9's password:
m1_alldb_             100%  177KB  21.2MB/s   00:00[root@mysql-server56 ~]#

slave操作

导入m1发来的数据

[root@chaoge_slave1 mm_data]# zcat m1_alldb_ |mysql -S /mm_data/3306/mysql.sock
[root@chaoge_slave1 mm_data]#

登录slave,配置m1的复制信息

[root@chaoge_slave1 mm_data]# mysql -S /mm_data/3306/mysql.sock
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 2
Server version: 5.6.40-log MySQL Community Server (GPL)Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or 'h' for help. Type 'c' to clear the current sql> change master to-> master_host='10.211.55.12',-> master_port=3306,-> master_user='repl',-> master_password='repl888',-> master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.02 sec)mysql>

启动slave start

# 启动slave,测试主从复制
mysql> show slave statusG
*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 10.211.55.12Master_User: replMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000004Read_Master_Log_Pos: 657Relay_Log_File: mysqld_3306-relay-bin.000002Relay_Log_Pos: 867Relay_Master_Log_File: mysql-bin.000004Slave_IO_Running: YesSlave_SQL_Running: 

测试数据写入

# master上写入数据
mysql> create database kings_cc;
Query OK, 1 row affected (0.00 sec)mysql># slave检查数据
mysql> show databases like '%kings%';
+--------------------+
| Database (%kings%) |
+--------------------+
| kings_cc           |
+--------------------+
1 row in set (0.00 sec)# 查看slave的GTID信息
# 超哥这里的环境是双主
mysql> show master status;
+------------------+----------+--------------+------------------+--------------------------------------------------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                                                                    |
+------------------+----------+--------------+------------------+--------------------------------------------------------------------------------------+
| mysql-bin.000004 |   644131 |              |                  | 20bdbbd9-a5cd-11eb-a6af-001c4279bcf3:1-4,
7b2ec017-a62c-11eb-a91d-001c426c932a:1-115 |
+------------------+----------+--------------+------------------+--------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

至此基于GTID的主从复制也搭建好了。

数据写入后,GTID变化,事务更新

# master数据更新mysql> create table tanks_cc(id int,name varchar(50));
Query OK, 0 rows affected (0.02 sec)mysql> show master statusG
*************************** 1. row ***************************File: mysql-bin.000004Position: 987Binlog_Do_DB:Binlog_Ignore_DB:
Executed_Gtid_Set: 20bdbbd9-a5cd-11eb-a6af-001c4279bcf3:1-5
1 row in set (0.00 sec)# slave
mysql> show master statusG
*************************** 1. row ***************************File: mysql-bin.000004Position: 644307Binlog_Do_DB:Binlog_Ignore_DB:
Executed_Gtid_Set: 20bdbbd9-a5cd-11eb-a6af-001c4279bcf3:1-5,
7b2ec017-a62c-11eb-a91d-001c426c932a:1-115
1 row in set (0.00 sec)

本文发布于:2024-02-02 16:54:49,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170686408845162.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:MySQL   GTID
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23