天天看點

MySQL GTID使用介紹

GTID定義:

定義: GTID即全局事務ID(global transaction  identifier),一個事物對應一個GTID
引入: MySQL-5.6.5開始支援,MySQL-5.6.10後開始完善
組成: GTID = server_uuid :transaction_id
server_uuid 首次啟動時 MySQL 會自動生成一個 server_uuid,并且儲存到 auto.cnf 檔案,一個執行個體對應一個server_uuid
transaction_id 從 1 開始的自增計數,表示在這個主庫上執行的第 n 個事務

開啟GTID:

[mysqld] 配置
#GTID
gtid_mode=on    開啟GTID
enforce-gtid-consistency  = on 啟用強一緻性檢查,避免create table...select操作
log-slave-updates=1 允許下端接入slave
#binlog
log-bin=mysql-bin 開啟binlog
binlog_format=row binlog格式為row模式

GTID優缺點:優點:

  • slave在做同步複制時,無須找到binlog日志和POS點,直接change master to master_auto_position=1即可,自動找點同步;
  • 搭建主從複制簡單。

缺點:

  • GTID同步複制是基于事務。是以Myisam表不支援,這可能導緻多個GTID配置設定給同一個事務;
  • CREATE TABLE ...SELECT語句不支援。因為該語句會被拆分成createtable 和insert兩個事務,并且這個兩個事務被配置設定了同一個GTID,這會導緻insert被備庫忽略掉;
  • 不支援CREATE TEMPORARY TABLE、DROP TEMPORARYTABLE 臨時表操作;
  • Errant transaction問題:即從庫不能進行任何事物型操作,會引入新的GTID,當binlog被清除後,再進行主從切換,會導緻其他從庫找不到此GTID,進而挂載不上。

GTID原理:GTID的最大特性就是它的Failover能力,如下架構,當主庫A cresh時,需要進行主從切換,将B或C其中一台提升為主,傳統模式我們無法确認哪台資料較新,由于同一個事務在每台機器上所在的binlog名字和位置都不一樣,那麼怎麼找到C目前同步停止點,對應B的master_log_file和master_log_pos,需要通過程式對比或者借助MHA等工具。

MySQL GTID使用介紹

GTID出現後,這個問題就顯得非常簡單。由于同一事務的GTID在所有節點上的值一緻,那麼根據

C

目前停止點的GTID就能唯一定位到

B

上的GTID。甚至由于

MASTER_AUTO_POSITION

 功能的出現,我們都不需要知道GTID的具體值,直接使用

CHANGE MASTER TO MASTER_HOST='xxx', MASTER_AUTO_POSITION=1

指令就可以直接完成failover的工作。

GTID主要參數說明:

show global variables like '%gtid%';      
gtid_next session級别,指定下一個GTID擷取的方式,預設AUTOMATIC 使用下一個自動産生的GTID,slave解析binlog,将GTID賦給gtid_next并于下一個事務使用此GTID;
gtid_executed 執行個體已執行的所有GTID集合 slave使用GTID前先做檢查,確定其沒被使用過;reset master會将其重置為空;
gtid_owned 隻讀變量,分别描述session和global目前擁有的gtid集合 確定沒有被其他session正在使用,多個用戶端不可并發運作同一個事務;
gtid_purged 已清除的binlog中包含的GTID集合 伺服器啟動時,讀取最舊binlog的previous_gtid_log_event并将其指派;每purge一個binlog,則重置一次;reset master會将其重置為空

GTID複制錯誤修複:

一、手動跳過錯誤事物(在從庫上)

  1. STOP SLAVE;
  2. RESET MASTER; 
  3. SET @@GLOBAL.GTID_PURGED = 'f2b6c829-9c87-11e4-84e8-deadeb54b599:1-32';
  4. START SLAVE;

上面這些指令的用意是,忽略 f2b6c829-9c87-11e4-84e8-deadeb54b599:32 這個GTID事務,下一次事務接着從 33 這個GTID開始,即可跳過上述錯誤。注:無論是否開啟了GTID,都可以使用percona  的 pt-slave-restart工具去跳過錯誤。

二、Errant transaction問題修複:

此問題主要是采用GTID複制的情況下,在slave上進行了事物操作,此時這台slave就多出來一個或多個其他slave節點和master節點沒有的事務。我們知道Binlog預設保留7天,7天後這些事物産生的binlog會被删除,當發生failover的時,這個slave被提升為主,由于其他從庫已經找不到新主庫事物所産生的binlog,此時其他從庫會挂載不上,造成資料庫單點,十分危險。

步驟
1 create table t1(id int);從庫執行一個事物
2

show global variables like  '%gtid%';

| gtid_executed |984f9b33-2118-11e8-b4d2-8a5337dcf960:1-6 |

| gtid_executed | 9831a0f8-2118-11e8-b585-96f5258290c0:1,

984f9b33-2118-11e8-b4d2-8a5337dcf960:1-6

此時從庫已經多了一個GTID

3 stop slave;
4 reset master;
5 set @@GLOBAL.GTID_PURGED = '984f9b33-2118-11e8-b4d2-8a5337dcf960:1-6';
6 start slave;
7 此時gtid_executed已經和主庫一緻
  • 傳統解決方案:通過在主庫手動設定下一次事物GTID,執行一條空事物,實作跟從庫一緻
show global variables like  '%gtid%';| gtid_executed |984f9b33-2118-11e8-b4d2-8a5337dcf960:1-6 | show global variables like  '%gtid%';| gtid_executed | 9831a0f8-2118-11e8-b585-96f5258290c0:1,984f9b33-2118-11e8-b4d2-8a5337dcf960:1-6此時從庫已經多了一個GTID
set  gtid_next='9831a0f8-2118-11e8-b585-96f5258290c0:1';在session級别,指定此GTID給下一個事物
begin;
commit;
set gtid_next='automatic';
show global variables like  '%gtid%';| gtid_executed | 9831a0f8-2118-11e8-b585-96f5258290c0:1,984f9b33-2118-11e8-b4d2-8a5337dcf960:1-6此時跟從庫已經一緻
  • 通過類似一種“欺騙”方(優先選擇此方式,無需操作主庫)
  • mysqlslavetrx優雅處理方式