文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 參考手冊  /  ...  /  二進位日誌中安全與不安全語句的判斷

19.2.1.3 二進位日誌中安全與不安全語句的判斷

MySQL 複寫中陳述式的「安全」是指該陳述式及其效果是否可以使用基於陳述式的格式正確複寫。如果陳述式是這樣,我們將該陳述式稱為安全;否則,我們將其稱為不安全

一般而言,如果陳述式具有決定性,則為安全,如果不具決定性,則為不安全。但是,某些不具決定性的函式被視為不安全(請參閱本節稍後的不被視為不安全的不具決定性函式)。此外,使用來自浮點數學函式(與硬體相關)的結果的陳述式一律被視為不安全(請參閱第 19.5.1.12 節「複寫和浮點數值」)。

安全與不安全陳述式的處理方式。陳述式的處理方式不同,取決於該陳述式是否被視為安全,以及二進位日誌格式(也就是說,binlog_format 的目前值)。

  • 使用基於列的記錄時,不會區分安全與不安全陳述式的處理方式。

  • 使用混合格式記錄時,標示為不安全的陳述式會使用基於列的格式記錄;視為安全的陳述式會使用基於陳述式的格式記錄。

  • 使用基於陳述式的記錄時,標示為不安全的陳述式會產生此效果的警告。安全的陳述式會正常記錄。

每個被標記為不安全的語句都會產生警告。如果在來源端執行大量此類語句,可能會導致錯誤日誌檔案過大。為了防止這種情況,MySQL 具有警告抑制機制。如果在任何 50 秒的時間段內,最近的 50 個 ER_BINLOG_UNSAFE_STATEMENT 警告被產生超過 50 次,則會啟用警告抑制。啟用後,此類警告不會寫入錯誤日誌;相反地,每 50 個此類警告,會將一個註釋 The last warning was repeated N times in last S seconds 寫入錯誤日誌。只要最近的 50 個此類警告是在 50 秒或更短的時間內發出,此機制就會持續運作;一旦速率降低到此閾值以下,警告將再次正常記錄。警告抑制不會影響基於語句記錄方式的語句安全性判斷,也不會影響警告傳送到用戶端的方式。MySQL 用戶端仍然會針對每個此類語句收到一個警告。

更多資訊,請參閱第 19.2.1 節,「複製格式」

被視為不安全的語句。 具有以下特徵的語句被視為不安全:

  • 包含系統函數的語句,這些函數在副本上可能傳回不同的值。 這些函數包括 FOUND_ROWS()GET_LOCK()IS_FREE_LOCK()IS_USED_LOCK()LOAD_FILE()RAND()RELEASE_LOCK()ROW_COUNT()SESSION_USER()SLEEP()SOURCE_POS_WAIT()SYSDATE()SYSTEM_USER()USER()UUID()UUID_SHORT()

    不被視為不確定的函數。 雖然這些函數不是確定性的,但為了記錄和複製的目的,它們被視為安全:CONNECTION_ID()CURDATE()CURRENT_DATE()CURRENT_TIME()CURRENT_TIMESTAMP()CURTIME()LAST_INSERT_ID()LOCALTIME()LOCALTIMESTAMP()NOW()UNIX_TIMESTAMP()UTC_DATE()UTC_TIME()UTC_TIMESTAMP()

    更多資訊,請參閱第 19.5.1.14 節,「複製與系統函數」

  • 對系統變數的參照。 大多數系統變數無法使用基於語句的格式正確複製。請參閱第 19.5.1.39 節,「複製與變數」。關於例外情況,請參閱第 7.4.4.3 節,「混合二進位日誌格式」

  • 可載入函數。 由於我們無法控制可載入函數的行為,我們必須假設它正在執行不安全的語句。

  • 全文搜尋外掛程式。 此外掛程式在不同的 MySQL 伺服器上可能表現不同;因此,依賴它的語句可能會產生不同的結果。因此,在 MySQL 中,所有依賴全文搜尋外掛程式的語句都被視為不安全。

  • 觸發程序或儲存程序更新具有 AUTO_INCREMENT 欄位的資料表。 由於在來源端和副本上更新資料列的順序可能不同,因此這是不安全的。

    此外,若 INSERT 插入的資料表其複合主鍵包含一個 AUTO_INCREMENT 欄位,且該欄位不是此複合主鍵的第一個欄位,則該操作是不安全的。

    更多資訊,請參閱第 19.5.1.1 節,「複製與 AUTO_INCREMENT」

  • 在具有多個主鍵或唯一鍵的資料表上執行 INSERT ... ON DUPLICATE KEY UPDATE 語句。 當針對包含多個主鍵或唯一鍵的資料表執行時,此語句被視為不安全,因為它對儲存引擎檢查鍵的順序很敏感,而這是不確定的,MySQL 伺服器所選擇更新的資料列也取決於此。

    針對具有多個唯一鍵或主鍵的資料表執行的 INSERT ... ON DUPLICATE KEY UPDATE 語句,會被標記為不安全,不適用於基於語句的複製。(Bug #11765650, Bug #58637)

  • 使用 LIMIT 的更新。 由於擷取資料列的順序未指定,因此被認為是不安全。請參閱第 19.5.1.18 節,「複製與 LIMIT」

  • 存取或參照日誌資料表。 來源端和副本端的系統日誌資料表內容可能不同。

  • 交易操作之後的非交易操作。 在交易中,允許任何非交易讀取或寫入在任何交易讀取或寫入之後執行,都被視為不安全。

    更多資訊,請參閱第 19.5.1.35 節,「複製與交易」

  • 存取或參照自我記錄資料表。 對自我記錄資料表的所有讀取和寫入都被視為不安全。在交易中,任何在讀取或寫入自我記錄資料表之後的語句也被視為不安全。

  • LOAD DATA 語句。 LOAD DATA 被視為不安全,當 binlog_format=MIXED 時,該語句會以基於列的格式記錄。當 binlog_format=STATEMENT 時,LOAD DATA 不會產生警告,這與其他不安全語句不同。

  • XA 交易。 如果在來源端平行提交的兩個 XA 交易,在副本上以相反的順序準備,則可能發生鎖定相依性,而基於語句的複製無法安全解決此問題,而且複製有可能在副本上因死鎖而失敗。當設定 binlog_format=STATEMENT 時,XA 交易內的 DML 語句會被標記為不安全並產生警告。當設定 binlog_format=MIXEDbinlog_format=ROW 時,XA 交易內的 DML 語句會使用基於列的複製記錄,因此不存在潛在的問題。

  • 參照非確定性函數的 DEFAULT 子句。 如果表達式預設值參照非確定性函數,則任何導致評估該表達式的語句對於基於語句的複製都是不安全的。這包括諸如 INSERTUPDATEALTER TABLE 等語句。與大多數其他不安全語句不同,此類語句無法以基於列的格式安全地複製。當 binlog_format 設定為 STATEMENT 時,該語句會被記錄並執行,但會將警告訊息寫入錯誤日誌。當 binlog_format 設定為 MIXEDROW 時,該語句不會被執行,並將錯誤訊息寫入錯誤日誌。有關明確預設值處理的更多資訊,請參閱明確預設值處理

更多資訊,請參閱第 19.5.1 節,「複製功能與問題」