基於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的概念

  1. 全局事務標識:global transaction identifiers
  2. GTID是一個事務一一對應,並且全局唯一ID。
  3. 一個GTID在一個服務器上只執行一次,避免重複執行導致數據混亂或者主從不一致。
  4. GTID用來代替傳統複製方法,不再使用MASTER_LOG_FILE+MASTER_LOG_POS開啓。
  5. 而是使用MASTER_AUTO_POSTION=1的方式開始複製。
  6. 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,後面的23transaction_id

四、GTID的優勢

  1. 更簡單的實現failover,不用以前那樣在需要找log_file和log_pos。
  2. 更簡單的搭建主從複製。
  3. 比傳統的複製更加安全。
  4. GTID是連續的沒有空洞的,保證數據的一致性,零丟失
  5. 藉助GTID,在發生主備切換的情況下,MySQL的其它Slave可以自動在新主上找到正確的複製位置,這大大簡化了複雜複製拓撲下集羣的維護,也減少了人爲設置複製位置發生誤操作的風險。另外,基於GTID的複製可以忽略已經執行過的事務,減少了數據發生不一致的風險。

五、GTID的工作原理

  1. 當一個事務在主庫端執行並提交時,產生GTID,一同記錄到binlog日誌中。
  2. binlog傳輸到slave,並存儲到slave的relaylog後,讀取這個GTID的這個值設置gtid_next變量,即告訴Slave,下一個要執行的GTID值。
  3. sql線程從relay log中獲取GTID,然後對比slave端的binlog是否有該GTID。
  4. 如果有記錄,說明該GTID的事務已經執行,slave會忽略。
  5. 如果沒有記錄,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的主從複製搭建成功

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章