啟用 GTID 一致性模式(ENFORCE_GTID_CONSISTENCY=ON)後,執行 CREATE TABLE ... SELECT 會報錯 ERROR 1786 (HY000)。本文解析原因、驗證參數狀態、給出修改配置重啟的標準修復流程。
CREATE TABLE lgmnr_bak SELECT * FROM lgmnr; ERROR 1786 (HY000): CREATE TABLE ... SELECT is forbidden when @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1
ENFORCE_GTID_CONSISTENCY 要求所有寫入操作必須是「事務安全」且「可被 Binlog 精確記錄」的。CREATE TABLE ... SELECT 屬於「DDL + DQL 混合」,在某些存儲引擎下不可回滾,Binlog 記錄格式(STATEMENT/ROW)可能導致主從不一致,故被禁止。CREATE TEMPORARY TABLE、事務中混用事務表與非事務表。SHOW VARIABLES LIKE 'ENFORCE_GTID_CONSISTENCY'; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | enforce_gtid_consistency | ON | +--------------------------+-------+
嘗試動態修改會報錯:
SET GLOBAL enforce_gtid_consistency = OFF; ERROR 1238 (HY000): Variable 'enforce_gtid_consistency' is a read only variable
結論:該參數為只讀,必須修改配置文件並重啟實例生效。
/etc/my.cnf,[mysqld] 區段:enforce_gtid_consistency = OFF(或註釋掉,默認 OFF)。mysqladmin -uroot -p shutdownmysqld_safe &SHOW VARIABLES LIKE 'ENFORCE_GTID_CONSISTENCY'; -- OFFCREATE TABLE ... SELECT 成功。CREATE TABLE ... SELECT,可暫時關閉 GTID 一致性,但**喪失 GTID 主從自動定位、故障轉移能力**。CREATE TABLE new_tbl LIKE old_tbl; INSERT INTO new_tbl SELECT * FROM old_tbl; 兩步分離,符合 GTID 規範。CREATE TABLE ... SELECT 及 CREATE TEMPORARY TABLE。| 參數 | 動態修改 | 默認值 | 作用 |
|---|---|---|---|
| enforce_gtid_consistency | 否(只讀) | OFF | 強制 GTID 一致性,禁止不安全語句 |
| gtid_mode | 是(ONLINE/OFFLINE 狀態機) | OFF | 啟用 GTID 複制模式 |
| log_bin | 否 | OFF | 開啟 Binlog,GTID 前置條件 |
| log_slave_updates | 否 | OFF | 從庫寫入自身 Binlog,鏈式複制必需 |
遇到 1786 錯誤,先確認業務是否真需要 GTID,再決定「改代碼」還是「改參數」。