MySQL的GTID复制怎么应用

60次阅读
没有评论

共计 7222 个字符,预计需要花费 19 分钟才能阅读完成。

这篇文章主要介绍“MySQL 的 GTID 复制怎么应用”的相关知识,丸趣 TV 小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“MySQL 的 GTID 复制怎么应用”文章能帮助大家解决问题。

从 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 复制怎么应用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注丸趣 TV 行业资讯频道,丸趣 TV 小编每天都会为大家更新不同的知识点。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-13发表,共计7222字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)