對於MySQL GTID來說,經過多年的磨鍊已經很穩定了,相關的知識點網上也很多,本次分享GTID技術點的彙總。

MySQL複製不管用那個方式,都離不開binlog方式進行的。GTID作為position方式的延伸,在如今使用環境中帶來了很多方便。下面一步一步的把gtid相關的知識點複習一下。

基礎

先了解複製的基本原理:

1. MySQL複製方式:

master使用者寫入資料,生成event記到binary log中。 slave接收master上傳來的binlog,然後按順序應用,重現master上的操作。

MySQL GTID技術點,看這一篇就夠了!

傳統的複製基於(file,pos),當主從發生宕機,切換的時候有問題

slave儲存的是原master上的(file,pos),無法直接指向新master上的(file,pos)

2. 日誌記錄上position方式和GTID方式區別。

直觀圖對比:

MySQL GTID技術點,看這一篇就夠了!

主從複製,預設是透過pos複製(postion)方式,將使用者進行的每一項操作都進行編號(pos),每一個event都有一個起始編號,一個終止編號。GTID就是類似於pos的一個作用,全域性通用並且日誌檔案裡事件的GTID值是一致的。 pos與GTID在日誌裡是一個識別符號,在slave 裡已不同的方式展現。

GTID的生成受gtid_next控制。 在Master上,gtid_next是預設的AUTOMATIC,即GTID在每次事務提交時自動生成。它從當前已執行的GTID集合(即gtid_executed)中,找一個大於0的未使用的最小值作為下個事務GTID。同時將GTID寫入到binlog(set gtid_next記錄),在實際的更新事務記錄之前。 在Slave上,從binlog先讀取到主庫的GTID(即set gtid_next記錄),而後執行的事務採用該GTID。

MySQL GTID技術點,看這一篇就夠了!

MySQL GTID技術點,看這一篇就夠了!

3. GTID優勢

更簡單的實現failover,不像傳統方式那樣在需要找log_file和log_Pos。

更簡單的搭建主從複製。

複製叢集有一個統一的方式識別複製位置,給叢集管理帶來了便利。

正常情況下,GTID是連續沒有空洞的,因此主從庫出現數據衝突時,可以用新增空事物的方式進行跳過。

MySQL5。7。6版本開始可以線上升級gtid模式

冷門功能:介面

這類介面MySQL初期是為了透過開發介面,解決執行狀態和複製延遲的跟蹤準備的。但現在基本不適用。

1. FUNCTION

MySQL GTID技術點,看這一篇就夠了!

GTID_SUBSET(set1,set2)

給定兩組全域性事務識別符號set1和set2,如果set1中的所有gtid也在set2中,則返回true。否則返回false。

MySQL GTID技術點,看這一篇就夠了!

GTID_SUBTRACT(set1,set2)

給定兩組全域性事務識別符號set1和set2,只返回set1中不屬於set2的gtid。

MySQL GTID技術點,看這一篇就夠了!

WAIT_FOR_EXECUTED_GTID_SET()

監視應用於伺服器上的所有gtid,包括從所有複製通道和使用者客戶機到達的事務。

如果指定了超時,並且在GTID集中的所有事務應用之前超時時間已經過去,則函式停止等待。超時是可選的,預設超時為0秒,在這種情況下,函式總是等待,直到應用了GTID集中的所有事務。

MySQL GTID技術點,看這一篇就夠了!

WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS(gtid_set[, timeout][,channel])

等待所有事務都已應用,或者等待超時時間過完。8。0。18棄用功能,暫不介紹。

參考:

https://

dev。mysql。com/doc/refma

n/5。7/en/gtid-functions。html

2. API

跟蹤gtid從庫接受的情況,返回值:成功的為零。發生錯誤時非零。

跟蹤器機制的一種用途是為MySQL聯結器和客戶端應用程式提供一種方法,能確保執行情況 ,已經有增強半同步這樣的機制,基本沒有,除非進行二次開發

mysql_session_track_get_first()

mysql_session_track_get_next()

網上分析案例:

DROP TABLE IF EXISTS test。t1;

CREATE TABLE test。t1 (i INT, f FLOAT);

——enable_session_track_info

SET @@SESSION。session_track_schema=ON;

SET @@SESSION。session_track_system_variables=‘*’;

SET @@SESSION。session_track_state_change=ON;

USE information_schema;

SET NAMES ‘utf8mb4’;

SET @@SESSION。session_track_transaction_info=‘CHARACTERISTICS’;

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

SET TRANSACTION READ WRITE;

START TRANSACTION;

SELECT 1;

INSERT INTO test。t1 () VALUES();

INSERT INTO test。t1 () VALUES(1, RAND());

COMMIT;

shell> mysqltest < testscript

DROP TABLE IF EXISTS test。t1;

CREATE TABLE test。t1 (i INT, f FLOAT);

SET @@SESSION。session_track_schema=ON;

SET @@SESSION。session_track_system_variables=‘*’;

—— Tracker : SESSION_TRACK_SYSTEM_VARIABLES

—— session_track_system_variables

—— *

SET @@SESSION。session_track_state_change=ON;

—— Tracker : SESSION_TRACK_SYSTEM_VARIABLES

—— session_track_state_change

—— ON

USE information_schema;

—— Tracker : SESSION_TRACK_SCHEMA

—— information_schema

—— Tracker : SESSION_TRACK_STATE_CHANGE

—— 1

SET NAMES ‘utf8mb4’;

—— Tracker : SESSION_TRACK_SYSTEM_VARIABLES

—— character_set_client

—— utf8mb4

—— character_set_connection

—— utf8mb4

—— character_set_results

—— utf8mb4

—— Tracker : SESSION_TRACK_STATE_CHANGE

—— 1

SET @@SESSION。session_track_transaction_info=‘CHARACTERISTICS’;

—— Tracker : SESSION_TRACK_SYSTEM_VARIABLES

—— session_track_transaction_info

—— CHARACTERISTICS

—— Tracker : SESSION_TRACK_STATE_CHANGE

—— 1

—— Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS

——

—— Tracker : SESSION_TRACK_TRANSACTION_STATE

—— ________

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

—— Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS

—— SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

SET TRANSACTION READ WRITE;

—— Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS

—— SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET TRANSACTION READ WRITE;

START TRANSACTION;

—— Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS

—— SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; START TRANSACTION READ WRITE;

—— Tracker : SESSION_TRACK_TRANSACTION_STATE

—— T_______

SELECT 1;

1

1

—— Tracker : SESSION_TRACK_TRANSACTION_STATE

—— T_____S_

INSERT INTO test。t1 () VALUES();

—— Tracker : SESSION_TRACK_TRANSACTION_STATE

—— T___W_S_

INSERT INTO test。t1 () VALUES(1, RAND());

—— Tracker : SESSION_TRACK_TRANSACTION_STATE

—— T___WsS_

COMMIT;

—— Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS

——

—— Tracker : SESSION_TRACK_TRANSACTION_STATE

—— ________

ok

參考:

https://

dev。mysql。com/doc/refma

n/5。7/en/mysql-session-track-get-first。html

https://

dev。mysql。com/doc/refma

n/5。7/en/c-api-functions。html

判斷方式

1. 如何判斷複製方式GTID 還是 pos

Show slave status 檢視Auto_Position欄位。0是pos 方式, 1是gtid方式。

MySQL GTID技術點,看這一篇就夠了!

gtid變更為pos方式:

change master to master_auto_position=0;

2. 當前執行gtid資訊

mysql> SELECT @@GLOBAL。GTID_EXECUTED;

+————————————————————————+

| @@GLOBAL。GTID_EXECUTED |

+————————————————————————+

| 39d0a7f2-702c-11ea-92a0-000c29b9a76d:1-46534 |

+————————————————————————+

mysql> SELECT * FROM mysql。gtid_executed;

MySQL GTID技術點,看這一篇就夠了!

mysql。gtid_executed表是由MySQL伺服器提供給內部使用的。它允許副本在副本上禁用二進位制日誌記錄時使用GTIDs,並允許在二進位制日誌丟失時保留GTID狀態。RESET MASTER命令,gtid_executed表將被清除。

服務意外停止的情況下,當前二進位制日誌檔案中的gtid集不會儲存在gtid_executed表。在恢復期間,這些gtid將從二進位制日誌檔案新增到表中,以便可以繼續複製。

3. gtid_executed

若MySQL伺服器啟用了二進位制日誌,則表mysql。gtid_executed的更新僅在二進位制rotation時發生,因為發生重啟等情況依舊可以透過掃描二進位制日誌判斷得知當前執行的GTID位置。 簡單來說,該表會記錄當前執行的GTID

在MySQL 5。6中必須配置引數log_slave_updates的最重要原因在於當slave重啟後,無法得知當前slave已經執行到的GTID位置,因為變數gtid_executed是一個記憶體值:

MySQL 5。7將gtid_executed這個值給持久化。採用的技巧與MySQL 5。6處理SQL thread儲存位置的方式一樣,即將GTID值持久化儲存在一張InnoDB表中,並與使用者事務一起進行提交,從而實現資料的一致性。

觸發條件:

在binlog發生rotate(flush binary logs/達到max_binlog_size)或者關閉服務時,會把所有寫入到binlog中的Gtid資訊寫入到mysql。gtid_executed表。

從庫:如果沒有開啟log_bin或者沒有開啟log_slave_updates,從庫在應用relay-log中的每個事務會執行一個insert mysql。gtid_executed操作。

常用命令

1. gtid設定

gtid_mode=ON #必選

enforce-gtid-consistency=true #必選

log-bin=mysql #5。6必選 5。7。5和它之後可選,為了高可用,最好設定

server-id=1 #開啟log-bin的必須設定

log-slave-updates=ON # 5。6必選 5。7。5和它之後可選,為了高可用切換,最好設定ON

2. gtid跳過 gtid_next

stop slave;

set gtid_next=‘d74faa2d-5819-11e8-b248-ac853db70398:10603’;

begin;commit;

set gtid_next=‘automatic’;

start slave;

備註:該操作類似於sql_slave_skip_counter,只是跳過錯誤,不能保證資料一致性,需要人工介入,固強烈建議從機開啟read_only=1

3. gtid清除gtid_pureged

命令的實際意義:因沒有binlog資訊(expire_logs_days),不考慮這些gtid確認和回滾。 常用備份恢復,搭建從庫的時候使用。

自動觸發機制:flush,伺服器重新啟動

使用場景:

在副本上禁用二進位制日誌記錄提交的複製事務的GTIDs。

寫入二進位制日誌檔案的事務的GTIDs,該檔案現在已被清除。

透過語句set @@GLOBAL。gtid_purged顯式新增到集合中的gtid。

mysqldump ——set-gtid-purged=off/on 引數;

是否將GTID_PURGED’新增到輸出中

MySQL GTID技術點,看這一篇就夠了!

4. gtid升級

...

✨ 接下來內容請點選【原文】進行檢視~

更多資料庫相關內容,可訪問【墨天輪】進行瀏覽。

MySQL GTID技術點,看這一篇就夠了!