一、GTID相關(guān)概念
1.GTID 是什么?
關(guān)于gitd的介紹
- MySQL-5.6.5開始支持的,MySQL-5.6.10后開始完善;
- mysql數(shù)據(jù)庫從5.6.5開始新增一種基于GDIT的復(fù)制方式。通過GDIT保證每個主庫上提交的事務(wù)在集群中有一個唯一的ID.這種方式強化了數(shù)據(jù)庫的主備一致性,故障恢復(fù)以及容錯能力。
- GTID (Global Transaction ID) 在整個事務(wù)流程中每一個事務(wù) ID 是全局唯一的,且在整個主從復(fù)制架構(gòu)中該 ID 都不會相同。
- GTID 實際上 是由 UUID+TID 組成的。其中 UUID 是一個 MySQL 實例的唯一標(biāo)識。TID 代表了該實例上已經(jīng)提交的事務(wù)數(shù)量,并且隨著事務(wù)提交單調(diào)遞增。
- server_uuid:server_uuid 是在 Mysql 首次啟動過程中自動生成的一個uuid(128位) 隨機值,生成后會將該值存儲到數(shù)據(jù)目錄的auto.cnf 中。因為是隨機值,所以不同服務(wù)器的 Mysql 的server_uuid 都是不相同的。
- transaction_id(tid):代表了該實例上已經(jīng)提交的事務(wù)數(shù)量,是一個整數(shù),初始值是 1 ,每次提交事務(wù)的時候分配給這個事務(wù)并加1 。
- GTID是用來代替?zhèn)鹘y(tǒng)復(fù)制的方法,GTID復(fù)制與普通復(fù)制模式的最大不同就是不需要指定二進制文件名和位置。
2.GTID主從復(fù)制方式概念
- 基于 GTID 的主從復(fù)制方式的出現(xiàn),主要是用于替換傳統(tǒng)的日志點 復(fù)制方式。通過GTID 可以保證每個主庫提交的事務(wù)在集群中都有 唯一 的一個事務(wù) ID。
- 強化了數(shù)據(jù)庫主從的一致性和故障恢復(fù)數(shù)據(jù)的容錯能力,在主庫 宕機發(fā)生主從切換 的情況下,GTID 方式可以讓其他從庫自動找到新主庫復(fù)制的位置。
- 而且 GTID 可以忽略已經(jīng)執(zhí)行過的事務(wù),減少了數(shù)據(jù)發(fā)生錯誤的概率。
- 一個GTID在一個服務(wù)器上只執(zhí)行一次,避免重復(fù)執(zhí)行導(dǎo)致數(shù)據(jù)混亂或者主從不一致;
- GTID用來代替?zhèn)鹘y(tǒng)復(fù)制方法,不再使用MASTER_LOG_FILE+MASTER_LOG_POS開啟復(fù)制。而是使用MASTER_AUTO_POSTION=1的方式開始復(fù)制;
- 在GTID中【slave】端的binlog是必須開啟的,目的是記錄執(zhí)行過的GTID(強制)。
3.GTID的優(yōu)缺點
優(yōu)點:
- 根據(jù) GTID 可以快速的確定事務(wù)最初是在哪個實例上提交的。
- 更簡單的搭建主從復(fù)制,確保每個事務(wù)只會被執(zhí)行一次。
- 一個事務(wù)對應(yīng)一個唯一ID,一個GTID在一個服務(wù)器上只會執(zhí)行一次
- GTID是用來代替?zhèn)鹘y(tǒng)復(fù)制的方法,GTID復(fù)制與普通復(fù)制模式的最大不同就是不需要指定二進制文件名和位置
- 簡單的實現(xiàn) failover故障轉(zhuǎn)移,不用以前那樣在需要找 log_file 和 log_pos。
- 減少手工干預(yù)和降低服務(wù)故障時間,當(dāng)主機掛了之后通過軟件從眾多的備機中提升一臺備機為主機
缺點:
- 主從庫的表存儲引擎必須是一致的
- 主從庫的表存儲引擎不一致,就會導(dǎo)致數(shù)據(jù)不一致。如果主從庫的存儲引擎不一致,例如一個是事務(wù)存儲引擎,一個是非事務(wù)存儲引擎,則會導(dǎo)致事務(wù)和 GTID 之間一對一的關(guān)系被破壞,結(jié)果就會導(dǎo)致基于 GTID 的復(fù)制不能正確運行;
- master:對一個innodb表做一個多sql更新的事物,效果是產(chǎn)生一個GTID。
- slave:假設(shè)對應(yīng)的表是MYISAM引擎,執(zhí)行這個GTID的第一個語句后就會報錯,因為非事務(wù)引擎一個sql就是一個事務(wù)。
- 當(dāng)從庫報錯時簡單的stop slave; start slave;就能夠忽略錯誤。
- 但是這個時候主從的一致性已經(jīng)出現(xiàn)問題,需要手工的把slave差的數(shù)據(jù)補上,這里要將引擎調(diào)整為一樣的,slave也改為事務(wù)引擎。
- 不允許一個SQL同時更新一個事務(wù)引擎和非事務(wù)引擎的表
- 事務(wù)中混合多個存儲引擎,就會產(chǎn)生多個 GTID。當(dāng)使用 GTID 時,如果在同一個事務(wù)中,更新包括了非事務(wù)引擎(如 MyISAM)和事務(wù)引擎(如 InnoDB)表的操作,可能會導(dǎo)致產(chǎn)生多個 GTID、主從復(fù)制數(shù)據(jù)不一致、從庫復(fù)制中斷等情況
- 在一個復(fù)制組中,必須要求統(tǒng)一開啟GTID或是關(guān)閉GTID
- 不支持create table….select 語句復(fù)制(主庫直接報錯);
- create table xxx as select的語句,會被拆分為兩部分,create語句和insert語句,但是如果想一次搞定,MySQL會拋出如下的錯誤。
- ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE … SELECT.
- create table xxx as select 的方式可以拆分成兩部分,如下:
- create table xxxx like data_mgr;
- insert into xxxx select *from data_mgr;
二、GTID工作原理
- 當(dāng)一個事務(wù)在主庫端執(zhí)行并提交時,產(chǎn)生 GTID,一同記錄到 binlog 日志中。
- binlog 傳輸?shù)?slave,并存儲到 slave 的 relaylog 后,讀取這個 GTID 的這個值設(shè)置 gtid_next 變量,即告訴 Slave,下一個要執(zhí)行的 GTID 值。
- sql 線程從 relay log 中獲取 GTID,然后對比 slave 端的 binlog 是否有該 GTID。
- 如果有記錄,說明該 GTID 的事務(wù)已經(jīng)執(zhí)行,slave 會忽略。
- 如果沒有記錄,slave 就會執(zhí)行該 GTID 事務(wù),并記錄該 GTID 到自身的 binlog。
如何判斷復(fù)制方式GTID 還是 posShow slave status
查看Auto_Position字段:0是pos 方式, 1是gtid方式。
三、部署主從復(fù)制
架構(gòu)圖
1、準(zhǔn)備環(huán)境兩臺機器,關(guān)閉防火墻和selinux;兩臺機器環(huán)境必須一致;時間也得一致?。?!
192.168.221.136 mysql-master
192.168.221.138 mysql-slave
對時:
[root@localhost ~]# timedatectl set-timezone Asia/Shanghai
//查看和ntp server的時間差異(需要外網(wǎng)訪問,如果內(nèi)網(wǎng)有ntpd服務(wù)器,自行替換域名為該服務(wù)的地址)
[root@localhost ~]# yum -y install ntpdate
[root@localhost ~]# ntpdate -d cn.pool.ntp.org
//和 ntp 服務(wù)器同步時間
[root@localhost ~]# ntpdate cn.pool.ntp.org
?2、兩臺機器安裝mysql5.7(略)建議使用相同的安裝方式
注意:
對主庫已有的數(shù)據(jù)庫不會進行自動同步。
主從同步之前,主庫上已有數(shù)據(jù)庫備份,需要在從庫上手動導(dǎo)入同步。
開啟 GTID 后的導(dǎo)出導(dǎo)入數(shù)據(jù)的注意點
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don’t want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events
#意思是: 當(dāng)前數(shù)據(jù)庫實例中開啟了 GTID 功能, 在開啟有 GTID 功能的數(shù)據(jù)庫實例中, 導(dǎo)出其中任何一個庫, 如果沒有顯示地指定–set-gtid-purged參數(shù), 都會提示這一行信息。 意思是默認情況下, 導(dǎo)出的庫中含有 GTID 信息, 如果不想導(dǎo)出包含有 GTID 信息的數(shù)據(jù)庫, 需要顯示地添加–set-gtid-purged=OFF參數(shù)。mysqldump -uroot -p'' --set-gtid-purged=OFF --single-transaction --all-databases > /path/dbname.bak
mysqldump -uroot -p'' --set-gtid-purged=OFF --single-transaction -B 庫名1 庫名2 > /path/dbname.bak
在從庫上導(dǎo)入單個數(shù)據(jù)庫。mysql -uroot -p'' 庫名 < /path/dbname.bak
在從庫上導(dǎo)入多個數(shù)據(jù)庫。mysql -uroot -p'' < /path/dbname.bak
master操作:
[root@mysql-master ~]# vim /etc/my.cnf //在[mysqld]下添加如下內(nèi)容
server-id=1
log-bin = mylog //開啟binlog日志,不指定絕對路徑的話,yum安裝方式產(chǎn)生在/var/lib/mysql/,二進制安裝方式在/usr/local/mysql/data/
gtid_mode = on //在主從服務(wù)器上都打開gtid模式
enforce_gtid_consistency=1 //強制使用GTID一致性 consistency:一致性
sync_binlog = 1 //強制gtid
[root@mysql-master ~]# systemctl restart mysqld
主服務(wù)器創(chuàng)建賬戶:
mysql> grant replication slave,reload,super on *.* to 'slave'@'%' identified by 'JiannLt@123';
//注:生產(chǎn)環(huán)境中密碼采用高級別的密碼,實際生產(chǎn)環(huán)境中將'%'換成slave的ip
mysql> flush privileges;
?注意:如果不成功刪除以前的binlog日志
replication slave權(quán)限:這個權(quán)限用來給從服務(wù)器賬號授予復(fù)制權(quán)限,從服務(wù)器可以從主服務(wù)器中讀取二進制日志。
super權(quán)限:允許用戶使用修改全局變量的SET語句以及CHANGE MASTER語句
reload權(quán)限:必須擁有reload權(quán)限,才可以執(zhí)行flush [tables | logs | privileges]
slave操作:
[root@mysql-slave ~]# vim /etc/my.cnf //[mysqld]添加如下配置
server-id=2 //server-id每臺服務(wù)器都不能一樣,用于標(biāo)識不同的MySQL服務(wù)器實例
gtid_mode = ON //打開gtid
enforce_gtid_consistency=1 //強制使用GTID一致性
master-info-repository=TABLE //將主服務(wù)器信息保存在mysql.slave_master_info表中
relay-log-info-repository=TABLE //將中繼日志信息保存到mysql.slave_relay_log_info表中
[root@mysql-slave ~]# systemctl restart mysqld
[root@mysql-slave ~]# mysql -uroot -p'JiannLt@123' //登陸mysql
mysql> change master to #設(shè)置主從關(guān)系
master_host='192.168.221.136', #指定同步的主機
master_user='slave', #指定同步的賬號
master_password='JiannLt@123', #指定slave的密碼
master_auto_position=1; #開啟自動同步位置模式
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> start slave; #啟動slave角色
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G #查看狀態(tài),驗證sql和IO是不是yes。
說明同步成功
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
四、測試同步
1.主庫上新建數(shù)據(jù)庫
#查看本機IP
mysql> select substring_index(host,':',1) as ip , count(*) from information_schema.processlist group by ip;
+----------------+----------+
| ip | count(*) |
+----------------+----------+
| 192.168.221.136| 1 |
| localhost | 1 |
+----------------+----------+
2 rows in set (0.00 sec)
?
mysql> create database testdb;
Query OK, 1 row affected (0.00 sec)
?
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
5 rows in set (0.00 sec)
2.從庫上查看是否同步成功
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
5 rows in set (0.00 sec)
五、重設(shè)從庫
#全在從庫執(zhí)行
mysql> stop slave;
mysql> reset slave;
mysql> reset master;
?
#從庫的binlog已經(jīng)無效了,所以要執(zhí)行這個命令清空binlog
mysql> change master to
master_host='192.168.221.136',
master_port=3306,
master_user='slave',
master_password='JiannLt@123',
master_auto_position=1;
?#master_auto_position=1;表示是否自動獲取主庫的binary log坐標(biāo)點,設(shè)置為1表示是。
?
mysql> start slave; #啟動slave角色
Query OK, 0 rows affected (0.00 sec)
?
mysql> show slave status\G #查看狀態(tài),驗證sql和IO是不是yes。
六、常見故障
常見故障1:
Slave has more GTIDs than the master has,using the master’s SERVER_UUID
該問題代表從庫獲取到的GTID超過了主庫,比如主庫在未指定binlog文件名的同時修改了系統(tǒng)主機名,導(dǎo)致binlog全部被修改,從庫就會判斷失??;
解決方法如下:
#重設(shè)從庫
mysql> stop slave;
mysql> reset slave;
mysql> reset master;
mysql> change master to
master_host='192.168.221.136',
master_port=3306,
master_user='slave',
master_password='JiannLt@123',
master_auto_position=1;
mysql> start slave;
?常見故障2
如果從庫未指定relaylog的同時修改了系統(tǒng)主機名,只需要在從庫重新執(zhí)行一次同步
mysql> stop slave;
mysql> reset slave;
mysql> change master to
master_host='192.168.221.136',
master_port=3306,
master_user='slave',
master_password='JiannLt@123',
master_auto_position=1;
mysql> start slave;
?常見故障3
Master_has_purged_require_gtids
主庫提前刪除了還未同步完成的binlog
解決方法如下:
#在主庫上查看master信息
mysql> show master status\G;
*************************** 1. row ***************************
File: mylog.000001
Position: 605
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: cc9a32c5-4bc7-11ee-bdae-000c295e8b83:1-2
1 row in set (0.00 sec)
#在從庫上手動指定二進制日志文件master_log_file和位置master_log_pos與master上的一致
mysql > stop slave;
mysql > change master to
master_host='192.168.221.136',
master_user='slave',
master_password='JiannLt@123',
master_log_file='mylog.000001',
master_log_pos=605,
master_auto_position=0;
mysql > start slave;
七、故障切換
mysql主從,主機故障或者宕機,如何進行切換?
1)在salve執(zhí)行:
mysql> stop slave;
mysql> reset master;
2)查看是否只讀模式,如果是只讀需要將只讀關(guān)閉:show variables like 'read_only';
只讀模式需要修改my.cnf文件,注釋read-only=1并重啟mysql服務(wù)。
或者不重啟使用命令關(guān)閉只讀,但下次重啟后失效:set global read_only=off;
3)查看
show slave status \G
show master status \G
4)在程序中將原來主庫IP地址改為現(xiàn)在的從庫IP地址,測試應(yīng)用連接是否正常
八、GTID的一些疑問
1.為什么基于GTID的同步也要打開bin-log?
疑問:為什么基于gtid的主從復(fù)制也需要將bin-log日志打開,不是基于gtid的復(fù)制么?怎么還需要打開bin-log呢?
在 MySQL 中,全局事務(wù) ID(GTID)確實用于主從復(fù)制,以確保主服務(wù)器(master)上的每個事務(wù)在所有從服務(wù)器(slave)上只被執(zhí)行一次。然而,GTID 并不是日志記錄本身,而是一個在主服務(wù)器上為每個事務(wù)生成的唯一標(biāo)識符。
即使在使用 GTID 的情況下,我們也需要二進制日志(binlog)。下面是主要的原因:
- GTID本身并不保存binlog事件的具體內(nèi)容,它只記錄了每個event的全局唯一標(biāo)識編號。這些修改內(nèi)容還是記錄在二進制日志中的。
- 主庫也需要打開binlog,因為GTID信息是存放在binlog中的。如果主庫關(guān)閉了binlog,就不能記錄GTID,從而無法進行基于GTID的復(fù)制。
- GTID只是增加了一個全局事務(wù)ID,本質(zhì)上還是基于二進制日志日志進行位置(基于日志偏移量)的復(fù)制。
- 從庫想要真正進行同步復(fù)制,還需要根據(jù)GTID從主機拉取對應(yīng)的binlog事件。
- 所以主庫上binlog日志的記錄和傳遞是基于GTID復(fù)制的基礎(chǔ)。master需要將binlog寫入磁盤,并通過binlog協(xié)議傳遞給slave。
- 基于GTID的優(yōu)勢在于,即使binlog日志被清理,也能通過GTID標(biāo)識從任意位置恢復(fù)同步。
- 一些用來恢復(fù)容災(zāi)的操作,如從機POS(position),也需要在binlog中定位恰當(dāng)?shù)奈恢谩?/li>
- 某些數(shù)據(jù)庫操作如切換讀寫節(jié)點,也需要基于binlog中實際事件來完成數(shù)據(jù)一致性。
因此,即使在使用基于 GTID 的主從復(fù)制的情況下,也需要開啟二進制日志,以便記錄和復(fù)制數(shù)據(jù)更改,支持故障恢復(fù),以及存儲 GTID 信息。
2.GTID和Bin-log的方式對比
MySQL的二進制日志(binlog)和全局事務(wù)標(biāo)識符(GTID)是MySQL復(fù)制中的兩種不同機制,它們具有不同的特點和適用場景:
記錄方式不同:
- binlog 通過 log file + log pos 來定位數(shù)據(jù)事件。
- GTID 使用全局唯一的事務(wù)ID來標(biāo)識事件。
分配方式不同:
- binlog 是順序分配的。
- GTID 可以隨機分配,不依賴服務(wù)啟動順序。
故障恢復(fù)不同:
- binlog 需要使用備份+重放所有日志的方式進行恢復(fù)。
- GTID 可以只重放丟失的事務(wù)段的日志。
引用關(guān)系不同:
- binlog 無法判斷事件順序和依賴關(guān)系。
- GTID 可以明確事件順序和事務(wù)之間的依賴。
重復(fù)數(shù)據(jù)處理不同:
- binlog 可能會重放重復(fù)數(shù)據(jù)。
- GTID 可以識別重復(fù)數(shù)據(jù)并自動跳過。
使用場景:文章來源:http://www.zghlxwxcb.cn/news/detail-726557.html
- Binlog 支持所有版本MySQL,更加兼容,適合常規(guī)的主從復(fù)制。
- GTID 可以更方便地進行故障恢復(fù),分庫分表也更簡單,適合對數(shù)據(jù)一致性要求更高的場景。
綜上,GTID 在事務(wù)管理上更強大,但需要MySQL 5.6以上版本。二者可以配合使用,發(fā)揮各自優(yōu)勢。文章來源地址http://www.zghlxwxcb.cn/news/detail-726557.html
到了這里,關(guān)于MySQL主從復(fù)制(基于GTID--事務(wù)ID方式)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!