MySQL GTID复制的具体使用


Posted in MySQL onMay 20, 2022

从MySQL 5.6.5开始新增了一种基于GTID的复制方式。通过GTID保证了每个在主库上提交的事务在集群中有一个唯一的ID。这种方式强化了数据库的主备一致性,故障恢复以及容错能力。

GTID是什么

GTID (Global Transaction ID) 是对于一个已提交事务的编号,并且是一个全局唯一的编号。 GTID实际上是由UUID+TID 组成的。其中UUID是一个 MySQL实例的唯一标识。TID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。

下面是一个GTID的具体形式:3E11FA47-71CA-11E1-9E33-C80AA9429562:23,冒号分割前边为uuid,后边为TID。

GTID集合可以包含来自多个MySQL实例的事务,它们之间用逗号分隔。

如果来自同一MySQL实例的事务序号有多个范围区间,各组范围之间用冒号分隔。例如:e6954592-8dba-11e6-af0e-fa163e1cf111:1-5:11-18,e6954592-8dba-11e6-af0e-fa163e1cf3f2:1-27。

GTID改进有哪些

在原来基于二进制日志的复制中,从库需要告知主库要从哪个偏移量进行增量同步,如果指定错误会造成数据的遗漏,从而造成数据的不一致。借助GTID,在发生主备切换的情况下,MySQL的其它从库可以自动在新主库上找到正确的复制位置,这大大简化了复杂复制拓扑下集群的维护,也减少了人为设置复制位置发生误操作的风险。另外,基于GTID的复制可以忽略已经执行过的事务,减少了数据发生不一致的风险。

主库基于gtid set可以准确的知道从库缺少哪些数据,不会多给从库数据,也不会少给,避免网络带宽浪费。

mysql主从结构在一主一从情况下对于GTID来说就没有优势了,而对于2台主以上的结构优势异常明显,可以在数据不丢失的情况下切换新主。

注意:在构建主从复制之前,在一台将成为主的实例上进行一些操作(如数据清理等),通过GTID复制,这些在主从成立之前的操作也会被复制到从服务器上,引起复制失败。也就是说通过GTID复制都是从最先开始的事务日志开始,即使这些操作在复制之前执行。比如在server1上执行一些drop、delete的清理操作,接着在server2上执行change的操作,会使得server2也进行server1的清理操作。

GTID的工作原理

  • 当一个事务在主库端执行并提交时,产生GTID,一同记录到binlog日志中。
  • binlog传输到slave,并存储到slave的relaylog后,读取这个GTID的这个值设置gtid_next变量,即告诉Slave,下一个要执行的GTID值。
  • sql线程从relay log中获取GTID,然后对比slave端的binlog是否有该GTID。
  • 如果有记录,说明该GTID的事务已经执行,slave会忽略。
  • 如果没有记录,slave就会执行该GTID事务,并记录该GTID到自身的binlog,在读取执行事务前会先检查其他session持有该GTID,确保不被重复执行。

一主一从GTID复制的搭建

主机规划:

  • master:docker,端口3312
  • slave:docker,端口3313

master的配置

配置文件my.cnf内容如下:

$ cat /home/mysql/docker-data/3313/conf/my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html

[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
#datadir=/home/mysql/docker-data/3307/data
#socket=/home/mysql/docker-data/3307/mysql.sock

character_set_server=utf8
init_connect='SET NAMES utf8'

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

#log-error=/home/mysql/docker-data/3307/logs/mysqld.log
#pid-file=/home/mysql/docker-data/3307/mysqld.pid
lower_case_table_names=1
server-id=1403311
log-bin=mysql-bin
binlog-format=ROW
auto_increment_increment=1
auto_increment_offset=1
# 开启gtid
gtid_mode=ON
enforce-gtid-consistency=true

#rpl_semi_sync_master_enabled=1
#rpl_semi_sync_master_timeout=10000

创建docker实例:

$ docker run --name mysql3312 -p 3312:3306 --privileged=true -ti -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=order -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -v /home/mysql/docker-data/3312/conf:/etc/mysql/conf.d -v /home/mysql/docker-data/3312/data/:/var/lib/mysql -v /home/mysql/docker-data/3312/logs/:/var/log/mysql -d mysql:5.7

添加用于复制的用户并授权:

mysql> GRANT REPLICATION SLAVE,FILE,REPLICATION CLIENT ON *.* TO 'repluser'@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)

slave的配置

配置文件my.cnf内容与master一致,注意修改server-id,保持唯一。

创建docker实例:

$ docker run --name mysql3313 -p 3313:3306 --privileged=true -ti -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=order -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -v /home/mysql/docker-data/3313/conf:/etc/mysql/conf.d -v /home/mysql/docker-data/3313/data/:/var/lib/mysql -v /home/mysql/docker-data/3313/logs/:/var/log/mysql -d mysql:5.7

开启GTID同步:

mysql> change master to master_host='172.23.252.98',master_port=3310,master_user='repluser',master_password='123456',master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.02 sec)

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

查看状态:

mysql> show master status;
+------------------+----------+--------------+------------------+----------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000008 |      154 |              |                  | cd2eaa0a-7a59-11ec-b3b4-0242ac110002:1 |
+------------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.23.252.98
                  Master_User: repluser
                  Master_Port: 3312
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000006
          Read_Master_Log_Pos: 419
               Relay_Log_File: 5dfbef024732-relay-bin.000003
                Relay_Log_Pos: 632
        Relay_Master_Log_File: mysql-bin.000006
             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: 419
              Relay_Log_Space: 846
              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: 1403311
                  Master_UUID: cd2eaa0a-7a59-11ec-b3b4-0242ac110002
             Master_Info_File: /var/lib/mysql/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: cd2eaa0a-7a59-11ec-b3b4-0242ac110002:1
            Executed_Gtid_Set: cd2eaa0a-7a59-11ec-b3b4-0242ac110002:1
                Auto_Position: 1
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)

在master.order表插入数据:

mysql> insert into t_order values(4,"V");

发现数据已经同步至slave:

mysql> select * from order.t_order;
+------+------+
| id   | name |
+------+------+
|    4 | V    |
+------+------+
3 rows in set (0.00 sec)

先停止slave,再在master.order表插入数据:

mysql> insert into t_order values(5,"X");

然后再启动slave,发现数据已自动同步:

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

mysql> select * from order.t_order;
+------+------+
| id   | name |
+------+------+
|    4 | V    |
+------+------+
3 rows in set (0.00 sec)

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

mysql> select * from order.t_order;
+------+------+
| id   | name |
+------+------+
|    4 | V    |
|    5 | X    |
+------+------+
4 rows in set (0.00 sec)

遇到的问题

在slave服务器show slave status:

Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.

首先检查master和slave的server_id是否一致,如果一致去修改my.cnf文件中的server_id字段:

mysql> show variables like 'server_id';

然后排查master和slave的uuid是否一致:

mysql> show variables like '%uuid%';

如果uuid一致去修改data目录下的auto.cnf文件,拷贝整个data目录,把auto.cnf文件也拷贝过来了,里面记录了数据库的uuid,每个库的uuid应该是不一样的。

到此这篇关于MySQL复制之GTID复制的具体使用的文章就介绍到这了!


Tags in this post...

MySQL 相关文章推荐
MySQL Threads_running飙升与慢查询的相关问题解决
May 08 MySQL
my.ini优化mysql数据库性能的十个参数(推荐)
May 26 MySQL
MySQL中distinct与group by之间的性能进行比较
May 26 MySQL
MYSQL主从数据库同步备份配置的方法
May 26 MySQL
Mysql systemctl start mysqld报错的问题解决
Jun 03 MySQL
MySQL系列之一 MariaDB-server安装
Jul 02 MySQL
Mysql中where与on的区别及何时使用详析
Aug 04 MySQL
MySQL笔记 —SQL运算符
Jan 18 MySQL
MySQL高级进阶sql语句总结大全
Mar 16 MySQL
Pycharm远程调试和MySQL数据库授权问题
Mar 18 MySQL
提高系统的吞吐量解决数据库重复写入问题
Apr 23 MySQL
MySQL数据库实验之 触发器和存储过程
Jun 21 MySQL
单机多实例部署 MySQL8.0.20
May 15 #MySQL
MySQL中的全表扫描和索引树扫描
MySQL sql模式设置引起的问题
May 15 #MySQL
MySQL 逻辑备份 into outfile
May 15 #MySQL
Mysql开启外网访问
May 15 #MySQL
Mysql索引失效 数据库表中有索引还是查询很慢
MySQL查询日期时间
May 15 #MySQL
You might like
解决163/sohu/sina不能够收到PHP MAIL函数发出邮件的问题
2009/03/13 PHP
php fsockopen中多线程问题的解决办法[翻译]
2011/11/09 PHP
php自动加载方式集合
2016/04/04 PHP
PHP 应用容器化以及部署方法
2018/02/12 PHP
PHP中用Trait封装单例模式的实现
2019/12/18 PHP
免费空间广告万能消除代码
2006/09/04 Javascript
类似框架的js代码
2006/11/09 Javascript
js jquery做的图片连续滚动代码
2008/01/06 Javascript
复制本贴标题和地址的js代码
2008/07/01 Javascript
JQuery加载图片自适应固定大小的DIV
2013/09/12 Javascript
jquery 检测元素是否存在的实例代码
2013/11/19 Javascript
JQuery 给元素绑定click事件多次执行的解决方法
2014/09/09 Javascript
jQuery插件Slider Revolution实现响应动画滑动图片切换效果
2015/06/05 Javascript
js游戏人物上下左右跑步效果代码分享
2015/08/28 Javascript
浅谈JS中json数据的处理
2016/06/30 Javascript
js 获取本地文件及目录的方法(推荐)
2016/11/10 Javascript
Angularjs的$http异步删除数据详解及实例
2017/07/27 Javascript
JavaScript实现百度搜索框效果
2020/03/26 Javascript
JavaScript求一组数的最小公倍数和最大公约数常用算法详解【面向对象,回归迭代和循环】
2018/05/07 Javascript
vue模式history下在iis中配置流程
2019/04/17 Javascript
JavaScript setInterval()与setTimeout()计时器
2019/12/27 Javascript
使用Python3中的gettext模块翻译Python源码以支持多语言
2015/03/31 Python
Python3读取文件常用方法实例分析
2015/05/22 Python
详解python之配置日志的几种方式
2017/05/22 Python
Python基于pygame模块播放MP3的方法示例
2017/09/30 Python
Python tkinter和exe打包的方法
2020/02/05 Python
Django web自定义通用权限控制实现方法
2020/11/24 Python
寻找迷宫的一条出路,o通路;X:障碍
2016/07/10 面试题
C++程序员求职信范文
2014/04/14 职场文书
高中运动会广播稿
2014/09/16 职场文书
爱心助学感谢信
2015/01/21 职场文书
教师辞职书范文
2015/02/26 职场文书
管理失职检讨书范文
2015/05/05 职场文书
高二语文教学反思
2016/02/16 职场文书
Jupyter notebook 输出部分显示不全的解决方案
2021/04/24 Python
python前后端自定义分页器
2022/04/13 Python