本節說明如何在已經上線且使用匿名交易的伺服器上啟用 GTID 交易,以及選擇性地自動定位。此程序不需要將伺服器離線,適用於生產環境。但是,如果您可以在啟用 GTID 交易時讓伺服器離線,該程序會比較簡單。
您可以設定複寫通道,將 GTID 指派給尚未有任何 GTID 的複寫交易。此功能可讓您從不使用基於 GTID 的複寫的來源伺服器,複寫到使用基於 GTID 的複本。如果可以在複寫來源伺服器上啟用 GTID(如本程序所述),請改用此方法。指派 GTID 的設計適用於無法啟用 GTID 的複寫來源伺服器。如需此選項的詳細資訊,請參閱第 19.1.3.6 節,〈從沒有 GTID 的來源複寫到有 GTID 的複本〉。
開始之前,請確保所有伺服器上的 gtid_mode
都是 OFF
。
下列程序可以隨時暫停,稍後在暫停的位置恢復,或透過跳至第 19.1.4.3 節,〈線上停用 GTID 交易〉中停用 GTID 的線上程序的對應步驟來還原。這使得此程序具有容錯能力,因為任何在程序中途可能出現的不相關問題都可以照常處理,然後在上次中斷的位置繼續程序。
若要啟用 GTID 交易,您必須先完成下列每個步驟,才能繼續下一個步驟。
在每台伺服器上,執行下列陳述式
SET @@GLOBAL.enforce_gtid_consistency = WARN;
讓伺服器在正常工作負載下執行一段時間,並監控日誌。如果此步驟在日誌中產生任何警告,請調整您的應用程式,使其僅使用與 GTID 相容的功能,且不會產生任何警告。
在每台伺服器上,執行此陳述式
SET @@GLOBAL.enforce_gtid_consistency = ON;
在每台伺服器上,執行下列陳述式
SET @@GLOBAL.gtid_mode = OFF_PERMISSIVE;
伺服器執行此陳述式的順序沒有差別,但所有伺服器都必須在開始下一個步驟之前執行。
在每台伺服器上,執行下列陳述式
SET @@GLOBAL.gtid_mode = ON_PERMISSIVE;
如同前一步驟,只要每個伺服器在繼續下一步驟之前執行過該語句,哪個伺服器先執行該語句都沒關係。
在每個伺服器上,等待直到
Ongoing_anonymous_transaction_count
為0
。您可以使用SHOW STATUS
語句來檢查其值,如下所示:mysql> SHOW STATUS LIKE 'Ongoing%'; +-------------------------------------+-------+ | Variable_name | Value | +-------------------------------------+-------+ | Ongoing_anonymous_transaction_count | 0 | +-------------------------------------+-------+ 1 row in set (0.00 sec)
在副本上,理論上它有可能先為
0
,然後又變為非零值。這不是問題,只要它至少出現過一次0
即可。等待所有在上一步驟之前產生的事務複製到所有伺服器。您可以不必停止更新來執行此操作;重要的是在繼續下一步驟之前,所有匿名事務都已複製。
請參閱第 19.1.4.4 節「驗證匿名事務的複製」,以瞭解檢查所有匿名事務是否已複製到所有伺服器的一種方法。
如果您將二進制日誌用於除複製之外的其他用途,例如時間點備份和還原,請等待直到您不再需要包含無 GTID 事務的舊二進制日誌。
例如,在所有事務都已複製後,您可以在執行備份的伺服器上執行
FLUSH LOGS
。然後明確地進行備份,或者等待您可能已設置的任何定期備份例程的下一次迭代。理想情況下,您應該等待伺服器清除在上一步驟完成時存在的所有二進制日誌,並等待之前進行的任何備份過期。
請記住,包含匿名事務(即,無 GTID 的事務)的二進制日誌,在下一步驟之後不能使用,在下一步驟之後,您必須確保任何伺服器上沒有未提交的無 GTID 事務。
在每台伺服器上,執行此陳述式
SET @@GLOBAL.GTID_MODE = ON;
在每個伺服器上,將
gtid-mode=ON
和enforce-gtid-consistency=ON
添加到my.cnf
。這可確保 GTID 用於所有尚未處理的事務。為了開始使用 GTID 協定以便您稍後可以執行自動故障轉移,請在每個副本上執行下一組語句。如果您使用多源複製,請為每個通道執行此操作,包括FOR CHANNEL
子句。channel
STOP REPLICA [FOR CHANNEL 'channel']; CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION = 1 [FOR CHANNEL 'channel']; START REPLICA [FOR CHANNEL 'channel'];