每個二進位記錄格式都有其優點和缺點。對於大多數使用者來說,混合複製格式應該提供資料完整性和效能的最佳組合。但是,如果您想在執行某些任務時利用特定於基於語句或基於列的複製格式的功能,您可以使用本節中的資訊,其中提供了它們相對優點和缺點的摘要,以判斷哪種最適合您的需求。
基於語句的複製的優點
經過驗證的技術。
寫入日誌檔的資料較少。當更新或刪除影響多個列時,這會導致日誌檔所需的儲存空間少得多。這也意味著可以更快地完成備份和從備份還原。
日誌檔包含所有進行變更的陳述式,因此可用於稽核資料庫。
基於語句的複製的缺點
對於 SBR 不安全的陳述式。 並非所有修改資料的陳述式(例如
INSERT
DELETE
、UPDATE
和REPLACE
陳述式)都可以使用基於語句的複製進行複製。使用基於語句的複製時,任何非決定性行為都難以複製。此類資料修改語言 (DML) 陳述式的範例包括以下內容如果陳述式依賴於非決定性的可載入函式或預存程式,則該陳述式也是非決定性的,因為此類函式或預存程式傳回的值,取決於提供給它的參數以外的因素。(但是,基於列的複寫僅僅複製函式或預存程式傳回的值,因此其對表格列和資料的影響在來源和複本上是相同的。) 有關更多資訊,請參閱第 19.5.1.16 節,「呼叫功能的複寫」。
使用
LIMIT
子句但沒有ORDER BY
子句的DELETE
和UPDATE
陳述式是非決定性的。請參閱第 19.5.1.19 節,「複寫和 LIMIT」。使用
NOWAIT
或SKIP LOCKED
選項的鎖定讀取陳述式 (SELECT ... FOR UPDATE
和SELECT ... FOR SHARE
)。請參閱「使用 NOWAIT 和 SKIP LOCKED 的鎖定讀取並行」。決定性的可載入函式必須在複本上應用。
使用下列任何函式的陳述式無法使用基於陳述式的複寫正確複寫
但是,所有其他函式都可以使用基於陳述式的複寫正確複寫,包括
NOW()
等等。有關更多資訊,請參閱第 19.5.1.14 節,「複寫和系統函式」。
無法使用基於陳述式的複寫正確複寫的陳述式會記錄類似於此處顯示的警告
[Warning] Statement is not safe to log in statement format.
在這種情況下,也會向用戶端發出類似的警告。用戶端可以使用
SHOW WARNINGS
顯示它。INSERT ... SELECT
需要比使用基於列的複寫更多的列級鎖定。需要表格掃描 (因為在
WHERE
子句中未使用索引) 的UPDATE
陳述式必須鎖定比使用基於列的複寫更多的列。對於
InnoDB
:使用AUTO_INCREMENT
的INSERT
陳述式會封鎖其他非衝突的INSERT
陳述式。對於複雜的陳述式,必須在更新或插入列之前在複本上評估和執行該陳述式。使用基於列的複寫,複本只需要修改受影響的列,而無需執行完整的陳述式。
如果複本上的評估發生錯誤,尤其是在執行複雜的陳述式時,基於陳述式的複寫可能會隨著時間的推移,慢慢地增加受影響列的誤差幅度。請參閱第 19.5.1.30 節,「複寫期間的複本錯誤」。
預存函式使用與呼叫陳述式相同的
NOW()
值執行。但是,預存程序則不然。決定性的可載入函式必須在複本上應用。
表格定義在來源和複本上必須(幾乎)相同。有關更多資訊,請參閱第 19.5.1.9 節,「在來源和複本上使用不同的表格定義進行複寫」。
從 MySQL 授權表格 (透過聯結清單或子查詢) 讀取資料但不修改它們的 DML 操作,會在 MySQL 授權表格上執行為非鎖定讀取,因此對於基於陳述式的複寫來說是不安全的。有關更多資訊,請參閱「授權表格並行」。
基於列的複寫的優點
可以複寫所有變更。這是最安全的複寫形式。
注意更新
mysql
系統綱要中資訊的陳述式,例如GRANT
、REVOKE
以及對觸發程序、預存常式(包括預存程序)和檢視的操控,都會使用基於陳述式的複寫複寫到複本。對於諸如
CREATE TABLE ... SELECT
之類的陳述式,會從表格定義產生CREATE
陳述式,並使用基於陳述式的格式進行複寫,而列插入則使用基於列的格式進行複寫。在來源上需要較少的列鎖定,因此對於下列類型的陳述式可以實現更高的並行性
具有
AUTO_INCREMENT
的INSERT
陳述式
基於列的複寫的缺點
RBR 可能會產生更多必須記錄的資料。若要複寫 DML 陳述式 (例如
UPDATE
或DELETE
陳述式),基於陳述式的複寫只會將陳述式寫入二進位日誌。相反,基於列的複寫會將每個變更的列寫入二進位日誌。如果陳述式變更許多列,基於列的複寫可能會將顯著更多的資料寫入二進位日誌;即使對於回滾的陳述式也是如此。這也意味著進行和還原備份可能需要更多時間。此外,二進位日誌會被鎖定更長的時間來寫入資料,這可能會導致並行問題。使用binlog_row_image=minimal
來大幅減少缺點。產生大型
BLOB
值的決定性可載入函式,使用基於列的複寫比使用基於陳述式的複寫需要更長的時間來複寫。這是因為會記錄BLOB
資料行值,而不是產生資料的陳述式。您無法在複本上看到從來源接收和執行的陳述式。但是,您可以使用帶有
--base64-output=DECODE-ROWS
和--verbose
選項的 mysqlbinlog 查看變更的資料。或者,使用
binlog_rows_query_log_events
變數,如果啟用,則在使用-vv
選項時,會將包含陳述式的Rows_query
事件新增至 mysqlbinlog 輸出。對於使用
MyISAM
儲存引擎的表格,當將其作為基於列的事件套用至二進位日誌時,在複本上對INSERT
陳述式需要比將它們作為陳述式套用時更強大的鎖定。這表示當使用基於列的複寫時,不支援在MyISAM
表格上同時插入。