基於GTID的 Mysql 主從數據庫的複製
一、主從複製存在的問題以及解決辦法
問題:
主庫宕機之後,數據可能會丟失
從庫只有一個sql Thread,主庫寫壓力大,複製很可能延時
解決方法:
半同步複製--解決數據丟失的問題
並行複製--解決從庫複製延時的問題
1.數據庫同步是怎樣進行的?
master用戶寫入數據,生成event記到binary log中.
slave接收master上傳來的binlog,然後按順序應用,重現master上的用戶操作。
2.數據庫是靠什麼同步的?
主從複製,默認是通過pos複製(postion),就是說在日誌文檔裏,將用戶進行的每一項操作都進行編號(pos),每一個event都有一個起始編號,一個終止編號,我們在配置主從複製時從節點時,要輸入master的log_pos值就是這個原因,要求它從哪個pos開始同步數據庫裏的數據,這也是傳統複製技術, MySQL5.6增加了GTID複製,GTID就是類似於pos的一個作用,不過它是整個mysql複製架構全局通用的,就是說在這整個mysql冗餘架構中,它們的日誌文件裏事件的GTID值是一致的.
3.從節點怎麼知道要從哪塊進行同步?
上面也說了,一開始是自己設置的從節點從主節點的日誌文件裏的pos開始複製,以後就自己去讀取上一次同步到哪一塊,接着同步.
4:pos與GTID有什麼區別?
兩者都是日誌文件裏事件的一個標誌,如果將整個mysql集羣看作一個整體,pos就是局部的,GTID就是全局的。
二、GTID的概念
- 全局事務標識:
global transaction identifiers
。 - GTID是一個事務一一對應,並且全局唯一ID。
- 一個GTID在一個服務器上只執行一次,避免重複執行導致數據混亂或者主從不一致。
- GTID用來代替傳統複製方法,不再使用MASTER_LOG_FILE+MASTER_LOG_POS開啓。
- 而是使用MASTER_AUTO_POSTION=1的方式開始複製。
- MySQL-5.6.5開始支持的,MySQL-5.6.10後開始完善。
三、GTID的組成
GTID = source_id:transaction_id
source_id
,用於鑑別原服務器,即mysql服務器唯一的的server_uuid,由於GTID會傳遞到slave,所以也可以理解爲源ID。transaction_id
,爲當前服務器上已提交事務的一個序列號,通常從1開始自增長的序列,一個數值對應一個事務。
#示例:
3E11FA47-71CA-11E1-9E33-C80AA9429562:23
前面的一串爲服務器的server_uuid
,即3E11FA47-71CA-11E1-9E33-C80AA9429562
,後面的23
爲transaction_id
四、GTID的優勢
- 更簡單的實現failover,不用以前那樣在需要找log_file和log_pos。
- 更簡單的搭建主從複製。
- 比傳統的複製更加安全。
- GTID是連續的沒有空洞的,保證數據的一致性,零丟失
- 藉助GTID,在發生主備切換的情況下,MySQL的其它Slave可以自動在新主上找到正確的複製位置,這大大簡化了複雜複製拓撲下集羣的維護,也減少了人爲設置複製位置發生誤操作的風險。另外,基於GTID的複製可以忽略已經執行過的事務,減少了數據發生不一致的風險。
五、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的 Mysql 主從數據庫的複製
配置server1(主庫)
1.修改配置文件(/etc/my.cnf)並重啓mysql
[root@server1 mysql]# vim /etc/my.cnf
在最後寫入:
log-bin=mysql-bin #啓動mysql二進制日誌,即數據同步語句,從數據庫會一條一條的執行這些語句
server-id=1 #服務器唯一標識
gtid_mode=ON #開啓gtid模式
enforce-gtid-consistency=true #強制gtid一致性,開啓後對於特定create table不被支持
修改完配置文件之後,重啓mysqld服務
[root@server1 mysql]# systemctl restart mysqld
2.查看主庫狀態
[root@server1 mysql]# mysql -uroot -pWestos+001
mysql> show master status;
配置server2(從庫)
1.修改配置文件(/etc/my.cnf)並重啓mysql
[root@server2 mysql]# vim /etc/my.cnf
在最後寫入:
gtid_mode=ON #開啓gtid模塊
enforce-gtid-consistency=true #強制gtid一致性,開啓後對於特定create table不被支持
server-id=2 #服務器唯一標識
修改完配置文件之後,重啓mysqld服務
[root@server2 mysql]# systemctl restart mysqld
2.設定從庫,將主庫與從庫連接起來,並開啓從庫
登錄server2(從庫)自己的數據庫進行設置
[root@server2 mysql]# mysql -uroot -pWestos+001
mysql> stop slave; #先關閉slave(在change之前要關閉slave)
Query OK, 0 rows affected (0.03 sec)
mysql> change master to
-> master_host='172.25.63.1',
-> master_user='repl',
-> master_password='Westos+001',
-> master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.17 sec)
mysql> start slave;
Query OK, 0 rows affected (0.06 sec)
查看從庫狀態:
如果Slave_IO_Running和Slave_SQL_Running都爲yes,則表示正常
下圖記錄了gtid的變化
測試:
1.在主庫端的數據庫westos下的表usertb中,插入信息
mysql> insert into usertb values ('user2','456');
Query OK, 1 row affected (0.04 sec)
mysql> insert into usertb values ('user3','789');
Query OK, 1 row affected (0.08 sec)
在主庫上查看gtid號的改變
mysql> show master status;
2.從庫端查看是否存在在主庫中添加的內容
此時可以在從庫上查看gtid號碼的改變。
結論:
從庫看到的數據和主庫看到的數據是一致的,代表基於gtid的主從複製搭建成功