當以 MIXED
日誌格式執行時,伺服器會在下列情況下自動從基於陳述式的記錄切換為基於列的記錄
當函數包含
UUID()
時。當更新一個或多個具有
AUTO_INCREMENT
欄位的資料表,且叫用觸發程序或儲存函數時。與所有其他不安全的陳述式一樣,如果binlog_format = STATEMENT
,這會產生警告。如需詳細資訊,請參閱第 19.5.1.1 節「複寫和 AUTO_INCREMENT」。
當檢視表的主體需要基於列的複寫時,建立檢視表的陳述式也會使用它。例如,當建立檢視表的陳述式使用
UUID()
函數時,就會發生這種情況。當涉及對可載入函數的呼叫時。
當使用
FOUND_ROWS()
或ROW_COUNT()
時。(錯誤 #12092,錯誤 #30244)當使用
USER()
、CURRENT_USER()
或CURRENT_USER
時。(錯誤 #28086)當其中一個涉及的資料表是
mysql
資料庫中的日誌資料表時。當使用
LOAD_FILE()
函數時。(錯誤 #39701)當陳述式參考一個或多個系統變數時。(錯誤 #31168)
例外狀況。下列系統變數在搭配工作階段範圍(僅限)使用時,不會導致記錄格式切換
如需判斷系統變數範圍的資訊,請參閱第 7.1.9 節「使用系統變數」。
如需有關複寫如何處理
sql_mode
的資訊,請參閱第 19.5.1.40 節「複寫和變數」。
在 MySQL 8.0 之前的版本中,當使用混合式二進位日誌格式時,如果陳述式依列記錄,且執行陳述式的工作階段有任何暫時資料表,則所有後續陳述式都會被視為不安全,並以基於列的格式記錄,直到該工作階段使用的所有暫時資料表都被捨棄為止。在 MySQL 9.0 中,暫時資料表上的作業不會以混合式二進位日誌格式記錄,且工作階段中存在暫時資料表不會影響每個陳述式使用的記錄模式。
如果您嘗試使用基於陳述式的記錄執行應使用基於列的記錄寫入的陳述式,則會產生警告。警告會顯示在用戶端中(在 SHOW WARNINGS
的輸出中)和透過 mysqld 錯誤日誌顯示。每次執行此類陳述式時,都會在 SHOW WARNINGS
資料表中新增警告。但是,為了防止日誌氾濫,只有每個用戶端工作階段產生警告的第一個陳述式會寫入錯誤日誌。
除了上述決定外,個別引擎也可以決定更新資料表中的資訊時所使用的記錄格式。個別引擎的記錄功能可以定義如下
如果引擎支援以列為基礎的記錄,則該引擎被稱為具備列記錄能力。
如果引擎支援以語句為基礎的記錄,則該引擎被稱為具備語句記錄能力。
一個特定的儲存引擎可以支援其中一種或兩種記錄格式。下表列出每個引擎支援的格式。
儲存引擎 | 支援列記錄 | 支援語句記錄 |
---|---|---|
ARCHIVE |
是 | 是 |
BLACKHOLE |
是 | 是 |
CSV |
是 | 是 |
EXAMPLE |
是 | 否 |
FEDERATED |
是 | 是 |
HEAP |
是 | 是 |
InnoDB |
是 | 當交易隔離等級為 REPEATABLE READ 或 SERIALIZABLE 時為「是」;否則為「否」。 |
MyISAM |
是 | 是 |
MERGE |
是 | 是 |
NDB |
是 | 否 |
是否要記錄語句以及要使用的記錄模式,取決於語句的類型(安全、不安全或二進位注入)、二進位記錄格式(STATEMENT
、ROW
或 MIXED
)以及儲存引擎的記錄能力(具備語句能力、具備列能力、兩者皆具備或兩者皆不具備)。(二進位注入是指必須使用 ROW
格式記錄的變更。)
語句可以記錄,也可以不記錄警告;失敗的語句不會記錄,但會在日誌中產生錯誤。這顯示在以下的決策表中。類型、binlog_format、SLC 和 RLC 欄概述條件,而 錯誤/警告 和 記錄為 欄代表相應的動作。SLC 代表 「具備語句記錄能力」,而 RLC 代表 「具備列記錄能力」。
類型 | binlog_format |
SLC | RLC | 錯誤/警告 | 記錄為 |
---|---|---|---|---|---|
* | * |
否 | 否 | 錯誤:無法執行語句:由於至少有一個引擎既不具備列記錄能力也不具備語句記錄能力,因此無法進行二進位記錄。 | - |
安全 | STATEMENT |
是 | 否 | - | STATEMENT |
安全 | MIXED |
是 | 否 | - | STATEMENT |
安全 | ROW |
是 | 否 | 錯誤:無法執行語句:由於 BINLOG_FORMAT = ROW 且至少有一個表格使用不具備以列為基礎的記錄能力的儲存引擎,因此無法進行二進位記錄。 |
- |
不安全 | STATEMENT |
是 | 否 | 警告:不安全語句以語句格式記錄到二進位日誌,因為 BINLOG_FORMAT = STATEMENT |
STATEMENT |
不安全 | MIXED |
是 | 否 | 錯誤:無法執行語句:當儲存引擎僅限於以語句為基礎的記錄時,即使 BINLOG_FORMAT = MIXED ,也無法對不安全語句進行二進位記錄。 |
- |
不安全 | ROW |
是 | 否 | 錯誤:無法執行語句:由於 BINLOG_FORMAT = ROW 且至少有一個表格使用不具備以列為基礎的記錄能力的儲存引擎,因此無法進行二進位記錄。 |
- |
列注入 | STATEMENT |
是 | 否 | 錯誤:無法執行列注入:由於至少有一個表格使用不具備以列為基礎的記錄能力的儲存引擎,因此無法進行二進位記錄。 | - |
列注入 | MIXED |
是 | 否 | 錯誤:無法執行列注入:由於至少有一個表格使用不具備以列為基礎的記錄能力的儲存引擎,因此無法進行二進位記錄。 | - |
列注入 | ROW |
是 | 否 | 錯誤:無法執行列注入:由於至少有一個表格使用不具備以列為基礎的記錄能力的儲存引擎,因此無法進行二進位記錄。 | - |
安全 | STATEMENT |
否 | 是 | 錯誤:無法執行語句:由於 BINLOG_FORMAT = STATEMENT 且至少有一個表格使用不具備以語句為基礎的記錄能力的儲存引擎,因此無法進行二進位記錄。 |
- |
安全 | MIXED |
否 | 是 | - | ROW |
安全 | ROW |
否 | 是 | - | ROW |
不安全 | STATEMENT |
否 | 是 | 錯誤:無法執行語句:由於 BINLOG_FORMAT = STATEMENT 且至少有一個表格使用不具備以語句為基礎的記錄能力的儲存引擎,因此無法進行二進位記錄。 |
- |
不安全 | MIXED |
否 | 是 | - | ROW |
不安全 | ROW |
否 | 是 | - | ROW |
列注入 | STATEMENT |
否 | 是 | 錯誤:無法執行列注入:由於 BINLOG_FORMAT = STATEMENT ,因此無法進行二進位記錄。 |
- |
列注入 | MIXED |
否 | 是 | - | ROW |
列注入 | ROW |
否 | 是 | - | ROW |
安全 | STATEMENT |
是 | 是 | - | STATEMENT |
安全 | MIXED |
是 | 是 | - | STATEMENT |
安全 | ROW |
是 | 是 | - | ROW |
不安全 | STATEMENT |
是 | 是 | 警告:不安全語句以語句格式記錄到二進位日誌,因為 BINLOG_FORMAT = STATEMENT 。 |
STATEMENT |
不安全 | MIXED |
是 | 是 | - | ROW |
不安全 | ROW |
是 | 是 | - | ROW |
列注入 | STATEMENT |
是 | 是 | 錯誤:無法執行列注入:由於 BINLOG_FORMAT = STATEMENT ,因此無法進行二進位記錄。 |
- |
列注入 | MIXED |
是 | 是 | - | ROW |
列注入 | ROW |
是 | 是 | - | ROW |
當判斷產生警告時,會產生標準的 MySQL 警告(可以使用 SHOW WARNINGS
檢視)。該資訊也會寫入 mysqld 錯誤日誌。每個客戶端連線的每個錯誤實例只記錄一個錯誤,以防止日誌氾濫。日誌訊息包含嘗試執行的 SQL 語句。
如果複本的 log_error_verbosity
設定為顯示警告,複本會將訊息列印到錯誤日誌中,以提供其狀態的資訊,例如它開始工作的二進位日誌和中繼日誌座標、何時切換到另一個中繼日誌、中斷連線後重新連線時、不適合以語句為基礎的記錄的不安全語句等等。