導 讀
作者:高鵬(重慶八怪)
原文地址:
https://www.jianshu.com/p/caae9a019dbd
深入理解MySQL 5.7 GTID系列文章共十篇,本文為第四篇,
第一篇:深入理解MySQL 5.7 GTID系列(一)
第二篇:深入理解MySQL 5.7 GTID系列(二):GTID相關內部數據結構
第三篇:深入理解MySQL 5.7 GTID系列(三):GTID的生成時機
第四篇:
深入理解MySQL 5.7 GTID系列(四):mysql.gtid_executed&PREVIOUS GTID EVENT
第五篇:深入理解MySQL 5.7 GTID系列(五) gtid_executed>id_purged什麼時候更新
第六篇:深入理解MySQL 5.7 GTID系列(六):MySQL啟動初始化GTID模塊
第七篇:深入理解MySQL 5.7 GTID系列(七)binlog_gtid_simple_recovery參數的影響總結
該系列文章將陸續不定期更新~
依託前文的解析來講5.7中 GTID帶來的運維改變,我想理解應該是更加深刻,這節主要討論以下幾個部分:
如何跳過一個事務
mysqldump導出行為的改變
5.7中搭建基於GTID的主從
5.7中GTID的主從的切換
5.7中在線改變GTID模式
一、如何跳過一個事務和傳統基於位置的主從不同,如果從庫報錯我們需要獲得從庫執行的最後一個事務,方法有如下:
show slave status \G 中的 Executed_Gtid_Set。
show global variables like '%gtid%'; 中的 gtid_executed 。
show master status;中的Executed_Gtid_Set。
然後構建一個空事務如下:
stop slave ;set gtid_next='4a6f2a67-5d87-11e6-a6bd-000c29a879a3:34';begin;commit;set gtid_next='automatic';start slave ;
如果是多個如下:
stop slave ;set gtid_next='89dfa8a4-cb13-11e6-b504-000c29a879a3:3';begin;commit;set gtid_next='89dfa8a4-cb13-11e6-b504-000c29a879a3:4';begin;commit;set gtid_next='automatic';start slave ;
二、 mysqldump導出行為的改變使用mysqldump受到選項set-gtid-purged=AUTO的影響,假如我們在GTID開啟和關閉的情況下使用如下語句導出數據:
mysqldump --single-transaction --master-data=2 -R -E --triggers --all-databases
在GTID開啟的情況下會多如下設置:
SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;SET @@SESSION.SQL_LOG_BIN= 0;---- GTID state at the beginning of the backup --SET @@GLOBAL.GTID_PURGED='ec9bdd78-a593-11e7-9315-5254008138e4:1-105';
為什麼要這麼設置呢?因為如果做基於GTID的主從,是否生成BINLOG就意味著在導入數據的時候是否基於本地資料庫生成新的GTID事務,顯然這是不合理的,所以將SQL_LOG_BIN設置為0是必須的。接著GTID_PURGED被設置為備份時刻已經執行過的GTID事務,如前文第五節源碼剖析設置GTID_PURGED會設置三個地方的GTID如下:
mysql.gtid_executed表
gtid_purge變量
gtid_executed變量
看起來是合理的,但是如果這裡忽略了整個mysql.gtid_executed表是innodb表,導入過程中某些版本(已知percona 5.7.14,5.7.17)會重新刪除和建立,因此通過GTID_PURGED設置的mysql.gtid_executed表會重新改變,重啟資料庫後需要讀取mysql.gtid_executed表可能獲得錯誤Gtid集合導致複製錯誤。這也為我的故障案例埋下了伏筆,案例中在詳細描述。
當然也可以使用 --set-gtid-purged=OFF選項來告訴mysqldump不需要加入SQL_LOG_BIN= 0和GTID_PURGED,但是初始化搭建基於GTID的主從一定不要設置為OFF。下面是這個選項的含義。
--set-gtid-purged[=name] Add 'SET @@GLOBAL.GTID_PURGED' to the output. Possible values for this option are ON, OFF and AUTO. If ON is used and GTIDs are not enabled on the server, an error is generated. If OFF is used, this option does nothing. If AUTO is used and GTIDs are enabled on the server, 'SET @@GLOBAL.GTID_PURGED' is added to the output. If GTIDs are disabled, AUTO does nothing. If no value is supplied then the default (AUTO) value will be considered.
三、5.7中搭建基於GTID的主從這裡存在一個注意點,也是我案例中會提到的。我們還是直接說步驟
enforce_gtid_consistency = ON gtid_mode = ON server_id = 9910 binlog_format = row
同時主備庫都開啟binlog如果不設置級聯從庫,從庫不要設置log_slave_updates參數。
這是最合理的設置。
CREATE USER 'repl'@'%' IDENTIFIED BY 'test123';GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' ;
mysqldump --single-transaction --master-data=2 -R -E --triggers --all-databases > test.sql
reset master;
---- GTID state at the beginning of the backup --SET @@GLOBAL.GTID_PURGED='ec9bdd78-a593-11e7-9315-5254008138e4:1-21';
執行
SET @@GLOBAL.GTID_PURGED='ec9bdd78-a593-11e7-9315-5254008138e4:1-21';
語句即可,完成本部分mysql.gtid_executed表會重構。
change master to master_host='192.168.99.41',master_user='repl',master_password='test123',master_port=3310,MASTER_AUTO_POSITION = 1;
start slave
四、5.7中GTID的主從的切換切換中必須要確認從庫(新主庫)沒有做過本地的事務,如果做過,否則切換主庫(新從庫)需要拉取這一部分的GTID事務,如果這些binlog已經不存在了那麼勢必會報錯。這種情況下還是從建從庫吧。那麼我們來說正常的切換步驟。
stop slave;reset slave all;
change master to master_host='192.168.99.40',master_user='repl',master_password='test123',master_port=3310,MASTER_AUTO_POSITION = 1;start slave;
實際就這麼簡單,從庫(新主庫)會生成自己的GTID事務,新主庫接受到後執行即可。此時會出現如下有兩個server_uuid對應的GTID,如下的gtid_executed
總的說來如果要作為的切換的從庫,不要在從庫本地做任何事務。如果確實要做比如加索引等不影響數據的操作可以是使用如下:
mysql> set sql_log_bin=0;Query OK, 0 rows affected (0.00 sec)mysql> create index test_jjj on jjj(id);Query OK, 0 rows affected (0.42 sec)Records: 0 Duplicates: 0 Warnings: 0
這樣也是不會增加本地GTID的。
五、在線修改GTID模式這是5.7.6以後實現的功能其主要依賴了我們前面分析的 Previous gtid Event以及參數gtid_mode新加入的2個值。我們具體來看看gitd_mode各個值的含義:
OFF(0): Both new and replicated transactions must be anonymous.(生成的是匿名事務,slave也只能應用匿名事務)
OFF_PERMISSIVE:(1) New transactions are anonymous. Replicated transactions can be either
anonymous or GTID transactions.(生成的是匿名事務,slave可以應用匿名和GTID事務)
ON_PERMISSIVE(2): New transactions are GTID transactions. Replicated transactions can be either
anonymous or GTID transactions.(生成的是GTID事務,slave可以應用匿名和GTID事務)
ON(3): Both new and replicated transactions must be GTID transactions(生成的是GTID事務,slave也只能應用GTID事務)
注意每次修改值必然導致一次binlog的切換,如果發生binlog刪除也能夠依託 Previous gtid Event快速準確的找到gtid_purged(Gtid_state.lost_gtids)。
在線啟動SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN;
確定事務都支持GTID,不會在err log中出現警告如下:
2017-02-26T22:35:24.322055Z 55 [Warning] Statement violates GTID consistency: CREATE TABLE ... SELECT.
SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON;
SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
生成的是匿名事務,slave可以應用匿名和GTID事務
SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;
生成的是GTID事務,slave可以應用匿名和GTID事務
確定已經沒有匿名的事務
SHOW GLOBAL STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';
同時確認從庫
Retrieved_Gtid_Set
Executed_Gtid_Set
正常增長
到這一步實際上GTID事務已經開始使用了。
SET @@GLOBAL.GTID_MODE = ON;
stop slave;CHANGE MASTER TO MASTER_AUTO_POSITION = 1;start slave;
在線關閉stop slave;
記錄從庫執行狀態值
Exec_Master_Log_Pos: 7631438Relay_Master_Log_File: bin_log.000016
執行
CHANGE MASTER TO MASTER_AUTO_POSITION = 0,MASTER_LOG_FILE = 'bin_log.000016', MASTER_LOG_POS = 7631438start slave;
SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;
生成的是GTID事務,slave可以應用匿名和GTID事務
SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
生成的是匿名事務,slave可以應用匿名和GTID事務
等待從庫
Retrieved_Gtid_Set
Executed_Gtid_Set
不再變動。
完成這一步實際上GTID事務已經沒有生成和應用了
SET @@GLOBAL.GTID_MODE = OFF;
修改配置文件my.cnf,將參數的更改加入到配置文件
六、總結學習完本節至少能夠學習到:
如何跳過一個事務
mysqldump導出行為的改變
5.7中搭建基於GTID的主從
5.7中GTID的主從的切換
5.7中在線改變GTID 模式
關於其他運維可以參考官方文檔:
對本文有任何疑問可掃碼添加原文作者微信
知數堂
葉金榮與吳炳錫聯合打造
領跑IT精英培訓
行業資深專家強強聯合,傾心定製
MySQL實戰/MySQL優化 /大數據實戰/ Python/ SQL優化
數門精品課程
緊隨技術發展趨勢,定期優化培訓教案
融入大量生產案例,貼合企業一線需求
社群陪伴學習,一次報名,可學1年
DBA、開發工程師必修課
上千位學員已華麗轉身,薪資翻番,職位提升
改變已悄然發生,你還在等什麼?
掃碼下載知數堂精品課程試聽視頻
(MySQL 實戰/優化、大數據實戰、Python開發,及SQL優化等課程)
密碼:hg3h