共計(jì) 7222 個(gè)字符,預(yù)計(jì)需要花費(fèi) 19 分鐘才能閱讀完成。
這篇文章主要介紹“MySQL 的 GTID 復(fù)制怎么應(yīng)用”的相關(guān)知識(shí),丸趣 TV 小編通過實(shí)際案例向大家展示操作過程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“MySQL 的 GTID 復(fù)制怎么應(yīng)用”文章能幫助大家解決問題。
從 MySQL 5.6.5 開始新增了一種基于 GTID 的復(fù)制方式。通過 GTID 保證了每個(gè)在主庫(kù)上提交的事務(wù)在集群中有一個(gè)唯一的 ID。這種方式強(qiáng)化了數(shù)據(jù)庫(kù)的主備一致性,故障恢復(fù)以及容錯(cuò)能力。
GTID 是什么
GTID (Global Transaction ID) 是對(duì)于一個(gè)已提交事務(wù)的編號(hào),并且是一個(gè)全局唯一的編號(hào)。GTID 實(shí)際上是由 UUID+TID 組成的。其中 UUID 是一個(gè) MySQL 實(shí)例的唯一標(biāo)識(shí)。TID 代表了該實(shí)例上已經(jīng)提交的事務(wù)數(shù)量,并且隨著事務(wù)提交單調(diào)遞增。
下面是一個(gè) GTID 的具體形式:3E11FA47-71CA-11E1-9E33-C80AA9429562:23,冒號(hào)分割前邊為 uuid,后邊為 TID。
GTID 集合可以包含來自多個(gè) MySQL 實(shí)例的事務(wù),它們之間用逗號(hào)分隔。
如果來自同一 MySQL 實(shí)例的事務(wù)序號(hào)有多個(gè)范圍區(qū)間,各組范圍之間用冒號(hào)分隔。例如:e6954592-8dba-11e6-af0e-fa163e1cf111:1-5:11-18,e6954592-8dba-11e6-af0e-fa163e1cf3f2:1-27。
GTID 改進(jìn)有哪些
在原來基于二進(jìn)制日志的復(fù)制中,從庫(kù)需要告知主庫(kù)要從哪個(gè)偏移量進(jìn)行增量同步,如果指定錯(cuò)誤會(huì)造成數(shù)據(jù)的遺漏,從而造成數(shù)據(jù)的不一致。借助 GTID,在發(fā)生主備切換的情況下,MySQL 的其它從庫(kù)可以自動(dòng)在新主庫(kù)上找到正確的復(fù)制位置,這大大簡(jiǎn)化了復(fù)雜復(fù)制拓?fù)湎录旱木S護(hù),也減少了人為設(shè)置復(fù)制位置發(fā)生誤操作的風(fēng)險(xiǎn)。另外,基于 GTID 的復(fù)制可以忽略已經(jīng)執(zhí)行過的事務(wù),減少了數(shù)據(jù)發(fā)生不一致的風(fēng)險(xiǎn)。
主庫(kù)基于 gtid set 可以準(zhǔn)確的知道從庫(kù)缺少哪些數(shù)據(jù),不會(huì)多給從庫(kù)數(shù)據(jù),也不會(huì)少給,避免網(wǎng)絡(luò)帶寬浪費(fèi)。
mysql 主從結(jié)構(gòu)在一主一從情況下對(duì)于 GTID 來說就沒有優(yōu)勢(shì)了,而對(duì)于 2 臺(tái)主以上的結(jié)構(gòu)優(yōu)勢(shì)異常明顯,可以在數(shù)據(jù)不丟失的情況下切換新主。
注意:在構(gòu)建主從復(fù)制之前,在一臺(tái)將成為主的實(shí)例上進(jìn)行一些操作(如數(shù)據(jù)清理等),通過 GTID 復(fù)制,這些在主從成立之前的操作也會(huì)被復(fù)制到從服務(wù)器上,引起復(fù)制失敗。也就是說通過 GTID 復(fù)制都是從最先開始的事務(wù)日志開始,即使這些操作在復(fù)制之前執(zhí)行。比如在 server1 上執(zhí)行一些 drop、delete 的清理操作,接著在 server2 上執(zhí)行 change 的操作,會(huì)使得 server2 也進(jìn)行 server1 的清理操作。
GTID 的工作原理
當(dāng)一個(gè)事務(wù)在主庫(kù)端執(zhí)行并提交時(shí),產(chǎn)生 GTID,一同記錄到 binlog 日志中。
binlog 傳輸?shù)?slave,并存儲(chǔ)到 slave 的 relaylog 后,讀取這個(gè) GTID 的這個(gè)值設(shè)置 gtid_next 變量,即告訴 Slave,下一個(gè)要執(zhí)行的 GTID 值。
sql 線程從 relay log 中獲取 GTID,然后對(duì)比 slave 端的 binlog 是否有該 GTID。
如果有記錄,說明該 GTID 的事務(wù)已經(jīng)執(zhí)行,slave 會(huì)忽略。
如果沒有記錄,slave 就會(huì)執(zhí)行該 GTID 事務(wù),并記錄該 GTID 到自身的 binlog,在讀取執(zhí)行事務(wù)前會(huì)先檢查其他 session 持有該 GTID,確保不被重復(fù)執(zhí)行。
一主一從 GTID 復(fù)制的搭建
主機(jī)規(guī)劃:
master:docker,端口 3312
slave:docker,端口 3313
master 的配置
配置文件 my.cnf 內(nèi)容如下:
$ 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
創(chuàng)建 docker 實(shí)例:
$ 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
添加用于復(fù)制的用戶并授權(quán):
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 內(nèi)容與 master 一致,注意修改 server-id,保持唯一。
創(chuàng)建 docker 實(shí)例:
$ 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)
查看狀態(tài):
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 表插入數(shù)據(jù):
mysql insert into t_order values(4, V
發(fā)現(xiàn)數(shù)據(jù)已經(jīng)同步至 slave:
mysql select * from order.t_order;
+------+------+
| id | name |
+------+------+
| 4 | V |
+------+------+
3 rows in set (0.00 sec)
先停止 slave,再在 master.order 表插入數(shù)據(jù):
mysql insert into t_order values(5, X
然后再啟動(dòng) slave,發(fā)現(xiàn)數(shù)據(jù)已自動(dòng)同步:
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 服務(wù)器 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 文件,拷貝整個(gè) data 目錄,把 auto.cnf 文件也拷貝過來了,里面記錄了數(shù)據(jù)庫(kù)的 uuid,每個(gè)庫(kù)的 uuid 應(yīng)該是不一樣的。
關(guān)于“MySQL 的 GTID 復(fù)制怎么應(yīng)用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注丸趣 TV 行業(yè)資訊頻道,丸趣 TV 小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。