您可以使用 --binlog-format=
來啟動 MySQL 伺服器,以明確選擇二進制日誌格式。 類型
類型
的支援值為:
STATEMENT
會導致以陳述式為基礎記錄。ROW
會導致以列為基礎記錄。這是預設值。MIXED
會導致使用混合格式記錄。
設定二進制日誌格式並不會為伺服器啟動二進制日誌。只有在伺服器上啟用二進制日誌時,設定才會生效,也就是當 log_bin
系統變數設定為 ON
時。在 MySQL 9.0 中,預設會啟用二進制日誌,只有當您使用 --skip-log-bin
或 --disable-log-bin
啟動伺服器時才會停用。
也可以在執行期間切換日誌格式,但請注意,在某些情況下您無法執行此操作,這將在本節稍後討論。設定 binlog_format
系統變數的全域值,以指定變更之後連線的用戶端的格式
mysql> SET GLOBAL binlog_format = 'STATEMENT';
mysql> SET GLOBAL binlog_format = 'ROW';
mysql> SET GLOBAL binlog_format = 'MIXED';
個別用戶端可以藉由設定 binlog_format
的會話值來控制其自身陳述式的日誌格式
mysql> SET SESSION binlog_format = 'STATEMENT';
mysql> SET SESSION binlog_format = 'ROW';
mysql> SET SESSION binlog_format = 'MIXED';
變更全域 binlog_format
值需要足夠的權限來設定全域系統變數。變更會話 binlog_format
值需要足夠的權限來設定受限制的會話系統變數。請參閱第 7.1.9.1 節:「系統變數權限」。
用戶端可能需要以每個會話為基礎設定二進制日誌格式有幾個原因
對資料庫進行許多小型變更的會話可能需要使用以列為基礎的記錄。
在
WHERE
子句中執行與許多列相符的更新的會話可能需要使用以陳述式為基礎的記錄,因為記錄少數陳述式比記錄許多列更有效率。某些陳述式在來源上需要大量的執行時間,但只會修改少數列。因此,使用以列為基礎的記錄來複製它們可能會很有益。
在執行期間無法切換複製格式時,會有例外情況
無法從儲存的函式或觸發器內變更複製格式。
如果已啟用
NDB
儲存引擎。如果會話有開啟的暫存表格,則無法變更會話的複製格式 (
SET @@SESSION.binlog_format
)。如果任何複製通道有開啟的暫存表格,則無法全域變更複製格式 (
SET @@GLOBAL.binlog_format
或SET @@PERSIST.binlog_format
)。如果任何複製通道套用程式執行緒目前正在執行,則無法全域變更複製格式 (
SET @@GLOBAL.binlog_format
或SET @@PERSIST.binlog_format
)。
在任何這些情況下嘗試切換複製格式(或嘗試設定目前的複製格式)都會導致錯誤。但是,您可以使用 PERSIST_ONLY
( SET @@PERSIST_ONLY.binlog_format
) 隨時變更複製格式,因為此操作不會修改執行時全域系統變數值,只會在伺服器重新啟動後生效。
當存在任何暫存表格時,不建議在執行時切換複製格式,因為暫存表格只有在使用基於語句的複製時才會記錄,而在基於列的複製和混合複製中,則不會記錄。
在複製正在進行時切換複製格式也可能會導致問題。每個 MySQL 伺服器都可以設定自己且僅限於自己的二進位日誌格式(無論是否使用全域或會話範圍設定 binlog_format
)。這表示在複製來源伺服器上變更日誌格式不會導致複本將其日誌格式變更為符合來源。當使用 STATEMENT
模式時,binlog_format
系統變數不會被複製。當使用 MIXED
或 ROW
日誌模式時,它會被複製,但會被複本忽略。
複本無法將以 ROW
日誌格式接收的二進位日誌項目轉換為 STATEMENT
格式,以供其自身的二進位日誌使用。因此,如果來源使用 ROW
或 MIXED
格式,複本也必須使用。當複製正在進行到使用 STATEMENT
格式的複本時,將來源的二進位日誌格式從 STATEMENT
變更為 ROW
或 MIXED
,可能會導致複製失敗,並出現例如 執行列事件時發生錯誤:'無法執行語句:由於語句是列格式且 BINLOG_FORMAT = STATEMENT,因此無法寫入二進位日誌。' 的錯誤。當來源仍在使用 MIXED
或 ROW
格式時,將複本的二進位日誌格式變更為 STATEMENT
格式也會導致相同類型的複製失敗。為了安全地變更格式,您必須停止複製,並確保在來源和複本上都進行相同的變更。
如果您正在使用 InnoDB
表格,且交易隔離層級為 READ COMMITTED
或 READ UNCOMMITTED
,則只能使用基於列的日誌記錄。將日誌格式變更為 STATEMENT
是 可能 的,但是在執行時執行此操作會很快導致錯誤,因為 InnoDB
將無法再執行插入。
當二進位日誌格式設定為 ROW
時,許多變更會使用基於列的格式寫入二進位日誌。但是,某些變更仍會使用基於語句的格式。範例包括所有 DDL(資料定義語言)語句,例如 CREATE TABLE
、ALTER TABLE
或 DROP TABLE
。
當使用基於列的二進位日誌記錄時,binlog_row_event_max_size
系統變數及其對應的啟動選項 --binlog-row-event-max-size
會設定列事件最大大小的軟限制。預設值為 8192 個位元組,且該值只能在伺服器啟動時變更。在可能的情況下,儲存在二進位日誌中的列會分組到大小不超過此設定值的事件中。如果無法分割事件,則可能會超過最大大小。
--binlog-row-event-max-size
選項適用於能夠進行基於列的複製的伺服器。列會以位元組大小不超過此選項值的區塊儲存在二進位日誌中。該值必須是 256 的倍數。預設值為 8192。
當使用 基於語句的日誌記錄 進行複製時,如果語句的設計方式使資料修改是非決定性的(也就是說,交由查詢最佳化工具決定),則來源和複本上的資料可能會變得不同。一般而言,即使在複製之外,這也不是一個好的做法。如需此問題的詳細說明,請參閱第 B.3.7 節,「MySQL 中的已知問題」。