在 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.39 節,「複製和變數」。
在 MySQL 8.0 之前的版本中,當使用混合二進制日誌格式時,如果一個陳述式按列記錄,並且執行該陳述式的工作階段有任何暫存表格,則所有後續陳述式都被視為不安全,並以基於列的格式記錄,直到該工作階段使用的所有暫存表格都被捨棄。在 MySQL 8.4 中,對暫存表格的操作不會以混合二進制日誌格式記錄,並且工作階段中暫存表格的存在對每個陳述式使用的日誌模式沒有影響。
如果您嘗試使用基於語句的日誌記錄來執行應使用基於列的日誌記錄來寫入的語句,則會產生警告。該警告會顯示在用戶端(在 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
設定為顯示警告,則複本會將訊息列印到錯誤日誌,以提供其狀態的相關資訊,例如其開始工作的二進位日誌和中繼日誌座標、何時切換到另一個中繼日誌、在斷線後重新連線的時間、不適用於基於語句的日誌記錄的語句等等。