1. 程式人生 > >MySQl新特性 GTID

MySQl新特性 GTID

推薦 pen efm my.cnf 混合 二進制日誌 ppr mat p s

GTID簡介

概念

全局事務標識符(GTID)是創建的唯一標識符,並與在源(主)服務器上提交的每個事務相關聯。此標識符不但是唯一的,而且在給定復制設置中的所有服務器上都是唯一的。所有交易和所有GTID之間都有一對一的映射關系。
GTID由source_id和transaction_id組成

GTID = source_id:transaction_id

server_uuid一般為source_id

GTID集合

GTID總是保存在主從之間。這意味著您可以通過檢查二進制日誌來確定應用於任何從屬設備的任何事務的來源。另外,一旦給定GTID的事務在給定的服務器上被提交,任何具有相同GTID的後續事務都被該服務器忽略。因此,在主站上提交的事務只在從站上應用一次,這有助於保證一致性。

GTID的生成和生命周期:
1,事務在主服務器上執行並提交。使用主服務器的UUID和此服務器上尚未使用的最小非零事務序列號為該事務分配一個GTID; GTID被寫入到master的二進制日誌中
2,在將二進制日誌數據發送到從站並存儲在從站的中繼日誌中,從站讀取GTID並設置gtid_next這告訴slave,下一個事務必須使用這個GTID記錄。
3,從服務器驗證這個GTID是否應用此事務。
4,因為gtid_next不是空的,把git_next也就是從主機中獲得的GTID寫入到二進制日誌中。

mysql.gtid_executed

  • 該mysql.gtid_executed表使從機能夠在從機上禁用二進制日誌記錄時使用GTID,並且可以在二進制日誌丟失時保留GTID歷史記錄。
  • 若將mysql.gtid_executed表復位,執行RESET MASTER
  • 表格提供會周期性的壓縮 當數量達到executed_gtid_compression_period值或者日誌輪轉時候mysql壓縮儲存,值默認為1000,壓縮線程thread/sql/compress_gtid_table
mysql> SELECT * FROM performance_schema.threads WHERE NAME LIKE ‘%gtid%‘\G
*************************** 1. row ***************************
          THREAD_ID: 26
               NAME: thread/sql/compress_gtid_table
               TYPE: FOREGROUND
     PROCESSLIST_ID: 1
   PROCESSLIST_USER: NULL
   PROCESSLIST_HOST: NULL
     PROCESSLIST_DB: NULL
PROCESSLIST_COMMAND: Daemon
   PROCESSLIST_TIME: 1509
  PROCESSLIST_STATE: Suspending
   PROCESSLIST_INFO: NULL
   PARENT_THREAD_ID: 1
               ROLE: NULL
       INSTRUMENTED: YES
            HISTORY: YES
    CONNECTION_TYPE: NULL
       THREAD_OS_ID: 18677

實踐

兩臺機器
172.16.10.53
172.16.10.54

步驟

1,將master 設置read-only,使slave趕上master更新速度
mysql >set global read-only
註:read-only 設置時候super用戶可寫,普通用戶不可寫。
2,停止兩臺機器

>mysqladmin  -uroot -p shutdown

3,修改配置,啟用GTID功能,要啟用基於GTID的復制,必須通過將gtid_mode變量 設置為啟用GTID模式啟動每個服務器 ON,並enforce_gtid_consistency 啟用變量以確保只記錄對基於GTID的復制安全的語句。在slave機器啟動之前,使用--skip-slave-start禁用slave的復制進程。
由於在MySQL 5.7.5中增加了mysql.gtid_executed,所以不需要slave機器啟用二進制日誌記錄來使用GTID 。這意味著您可以使用GTID但沒有二進制日誌記錄的從服務器。為了能夠復制,主設備必須始終啟用二進制日誌記錄。而slave,只需要配置這些變量:

gtid_mode=ON
enforce-gtid-consistency=true

不過為了高可用的切換,推薦選擇如下配置

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

4, 配置slave使用GTID來進行同步數據,當然需要在master給slave開通權限

grant  replication slave on *.*  to repl@"172.16.10.53" identified by "password";

設置GTID同步模式

change master to master_host=‘172.16.10.53‘,master_user=‘repl‘,master_port=3306,master_password="password",master_auto_position=1;

註意:非端口號需要加上引號
5,做一個新的備份,啟用GTID之前創建的現有備份現在不能再在這些服務器上使用,因為您啟用了GTID。在這一點上做一個新的備份,這樣你就不會沒有可用的備份。
比如說物理備份。

6,啟動slave的同步進程

mysql> start slave

問題

在啟動slave同步進程時候,查看日誌出現如下問題

2018-01-17T09:48:18.116983Z 1 [Warning] Slave SQL for channel ‘‘: If a crash happens this configuration does not guarantee that the relay log info will be consistent, Error_code: 0

什麽!!not consistent,絕對不能忍
在網上查了下添加如下配置就好了
在my.cnf中設置,

relay_log_info_repository = TABLE 
master_info_repository = TABLE 
relay_log_recovery = on 

報錯原因:
MySQL5.6版本號開始支持把master.info和relay-log.info的內容寫入到mysql庫的表中。

master.info--> mysql.slave_master_info
relay-log.info--> mysql. slave_relay_log_info

同一時候在MySQL5.6版本號中,添加了 Slave crash-safe replication功能,為了保證mysql的replication可以crash-safe。slave_master_info和slave_relay_log_info表必須使用事務型的存儲引擎(InnoDB),不要嘗試去手動改動這兩張表的內容。
同一時候,Slave還要開啟relay_log_recovery功能。
解決方法:
設置master_info_repository和relay_log_info_repository的值為TABLE。同一時候開啟relay_log_recovery功能。

GTID的故障處理和恢復。

1,簡單的復制,在新服務器上重現所有標識符和事務的最簡單方法是將新服務器變為具有全部執行歷史記錄的主服務器的從服務器,並在兩臺服務器上啟用全局事務標識符,缺點是較慢,且需要master保持所有的bin-log
2,使用mysqldump的方式,設置新slave機器(較快)
首先使用mysqldump命令備份

mysqldump --single-transaction --set-gtid-purged=OFF  --triggers --routines --events  -uroot -p >all.sql

此時會出現提示

mysqldump: [Warning] Using a password on the command line interface can be insecure.
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don‘t want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events.

若不需要進行GTID的恢復和從庫設置,則可以添加--set-gtid-purged=OFF 關閉(默認為ON)
若需要進行GTID的主從設置則--set-gtid-purged=ON 既可

mysqldump --single-transaction --set-gtid-purged=ON  --triggers --routines --events  -uroot -p >all.sql

查看sql文件中會出現以下語句,設置GTID_PURGED來跳過一些事務。

--
-- GTID state at the beginning of the backup 
--
SET @@GLOBAL.GTID_PURGED=‘7abe211e-fb4f-11e7-b16e-000c29ba88ca:1-69726‘;

然後在slave機器上進行恢復(需要slave開啟GTID功能),在恢復時候可能需要下面問題。

[root@localhost ~]# mysql -uroot -pMysql3200$%^ test < /tmp/all.sql   
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.

解決辦法:登錄執行reset master 清空 GTID_EXECUTED

[root@localhost ~]# mysql -uroot -p                    
mysql> reset master;
Query OK, 0 rows affected (0.02 sec)

導入binlog後,再start slave既可。

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.16.10.53
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql.000005
          Read_Master_Log_Pos: 777138
               Relay_Log_File: localhost-relay-bin.000018
                Relay_Log_Pos: 88658
        Relay_Master_Log_File: mysql.000005
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

3,使用空事務處理故障
情況1:
主鍵重復

                   Last_Error: Could not execute Write_rows event on table test.a; Duplicate entry ‘500‘ for key ‘PRIMARY‘, Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event‘s master log mysql.000005, end_log_pos 651107

方法1:
註入空事務

      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 7abe211e-fb4f-11e7-b16e-000c29ba88ca:66253-68381:69091-70362
            Executed_Gtid_Set: 7abe211e-fb4f-11e7-b16e-000c29ba88ca:1-70362,
9a455b69-fb4f-11e7-b993-000c29e8a43c:1

(root@Slave)[tempdb]>stop slave sql_thread;

(root@Slave)[tempdb]>set gtid_next=‘7abe211e-fb4f-11e7-b16e-000c29ba88ca:70363‘;

(root@Slave)[tempdb]>begin;commit;

(root@Slave)[tempdb]>set gtid_next=‘AUTOMATIC‘;

(root@Slave)[tempdb]>start slave sql_thread;

(root@Slave)[tempdb]>show slave status \G

方法2:
刪除沖突行

使用GTID的限制

  • 涉及非事務性存儲引擎的更新。對使用非事務性存儲引擎的表進行的更新與在同一事務中使用事務性存儲引擎的表的更新混合在一起會導致將多個GTID分配給同一事務。
  • CREATE TABLE ... SELECT語句。在使用基於行的復制時,該語句實際上被記錄為兩個單獨的事件 - 一個用於創建表,另一個用於將源表中的行插入剛剛創建的新表中。當這個語句在一個事務中被執行時,這些事件在某些情況下可能會被接收到相同的事務標識符,這意味著包含插入事務的事務被從機跳過。
  • 創建臨時表。
  • GTID模式和mysql_upgrade,當服務器在啟用全局事務標識符(GTID)時候,不要用mysql_upgrade --write-binlog啟用二進制日誌記錄。

參考鏈接:
http://www.cnblogs.com/gcczhongduan/p/4869525.html
https://dev.mysql.com/doc/refman/5.7/en/replication-gtids-failover.html

MySQl新特性 GTID