簡介
GTID工作原理簡單介紹
1.master更新數據的時候,會在事務前產生GTID,一同記錄到binlog日志中。
2.slave端的io線程將binlog寫入到本地relay log中。
3.然後SQL線程從relay log中讀取GTID,設置gtid_next的值為該gtid,然後對比slave端的binlog是否有記錄
4.如果有記錄的話,說明該GTID的事務已經運行,slave會忽略
5.如果沒有記錄的話,slave就會執行該GTID對應的事務,並記錄到binlog中
GTID工作原理深入理解
gtid在master和slave上持久化保存,即使删除了日志,也會記錄到previous_gtid中。
1.binlog文件中記錄的格式是先記錄gtid,然後再記錄事務相關的操作。
2.gtid_next 是基於會話的,不同會話的gtid_next不同。
3.如果mysql是5.6版本,那麼主從必須開啟log_slave_updates參數,此時slave對比自己的binlog查看是否有記錄。如果mysql是5.7版本,那麼主從不需要開啟此參數(級聯主從除外),mysql5.7提供了gtid_excuted系統錶來記錄複制的信息,以此减少從庫的壓力。
GTID模式的主從配置介紹
主從服務同時開啟gtid模式
從MySQL 5.6.5 開始新增了一種基於 GTID 的複制方式。通過 GTID 保證了每個在主庫上提交的事務在集群中有一個唯一的ID。這種方式强化了數據庫的主備一致性,故障恢複以及容錯能力。
GTID (Global Transaction ID)是全局事務ID,當在主庫上提交事務或者被從庫應用時,可以定比特和追踪每一個事務,對DBA來說意義就很大了,我們可以適當的解放出來,不用手工去可以找偏移量的值了,而是通過CHANGE MASTER TO MASTER_HOST='xxx', MASTER_AUTO_POSITION=1的即可方便的搭建從庫,在故障修複中也可以采用MASTER_AUTO_POSITION=‘X’的方式。
可能大多數人第一次聽到GTID的時候會感覺有些突兀,但是從架構設計的角度,GTID是一種很好的分布式ID實踐方式,通常來說,分布式ID有兩個基本要求:
1)全局唯一性
2)趨勢遞增
這個ID因為是全局唯一,所以在分布式環境中很容易識別,因為趨勢遞增,所以ID是具有相應的趨勢規律,在必要的時候方便進行順序提取,行業內適用較多的是基於Twitter的ID生成算法snowflake,所以換一個角度來理解GTID,其實是一種優雅的分布式設計。
如何開啟GTID?
如何開啟GTID呢,我們先來說下基礎的內容,然後逐步深入,通常來說,需要在my.cnf中配置如下的幾個參數:
-
server_id=1
-
log-bin
-
gtid_mode=ON
-
enforce_gtid_consistency=1
部署
修改配置文件
主節點編輯配置文件,添加參數:
[[email protected] tmp]# vim /etc/my.cnf
[mysqld]
log_bin
server_id=1
gtid_mode=ON
enforce_gtid_consistency=1
[[email protected] tmp]# systemctl restart mysqld # 重啟mysql生效
從節點編輯配置文件,添加參數:
[[email protected] tmp]# vim /etc/my.cnf # 編輯配置文件
[mysqld]
# log_bin # 從服務器log_bin可開可不開,不影響複制功能
server_id=2 # 注意id的唯一性
gtid_mode=ON
enforce_gtid_consistency=1
[[email protected] tmp]# systemctl restart mysqld # 重啟mysql生效
配置用戶
主節點配置rep用戶:
grant replication slave,replication client on *.* to 'rep'@'%'; # mysql5和8的用戶創建命令不同,此處注意。
設置從服務器主從關系
從節點上進行操作:
#二進制文件比特置由master_auto_position=1參數自動確定
mysql> change master to master_host='192.168.137.100',master_user='rep',master_password='[email protected]',master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.137.100
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: localhost-bin.000003
Read_Master_Log_Pos: 154
Relay_Log_File: localhost-relay-bin.000002
Relay_Log_Pos: 375
Relay_Master_Log_File: localhost-bin.000003
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: 154
Relay_Log_Space: 586
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: 1
Master_UUID: d4194c0e-35e2-11eb-a021-000c291c0d9f
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:
Executed_Gtid_Set:
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
到此MySQL主從模式已經配置完成。
注意:
在從庫上執行 show slave status\G
顯示報錯:
Last_IO_Error: error connecting to master '[email protected]:3316' - retry-time: 60 retries: 2 message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
考慮到我的MySQL8 ,
查看主庫:
SELECT plugin FROM user
where user = 'rep';
原來是主庫rep的plugin是caching_sha2_password 導致連接不上,修改為mysql_native_password即可解决。
ALTER USER 'rep'@'%' IDENTIFIED WITH mysql_native_password BY 'root';