type
status
date
slug
summary
tags
category
icon
password
前言
在 MySQL 文檔中描述 replication filter 和 binlog-do(ignore)-db 的判斷方式是接近的,但經過實測發現在未指定 database 的 statement 語句行為的處理方式不一致,本文基於 MySQL 8.0.21 紀錄。
MySQL 如何評估過濾規則
以下節錄自 MySQL 8.0 官方文檔
官方文檔說明
- 是否有任何 binlog-do-db 或 binlog-ignore-db 選項?
- YES:繼續下一個步驟2。
- NO:紀錄語句並退出。
- 是否有 default database (透過 USE 選擇 database)
- YES:繼續下一個步驟3。
- NO:
忽略語句並退出。 (實測發現應該是紀錄語句並退出,可參照實測)
- 是否有任何 binlog-do-db 選項?
- YES:defatult database 是否有符合 binlog-do-db 指定的 database 呢?
- YES:紀錄語句並退出。
- NO:忽略語句並退出。
- NO:繼續下一個步驟4。
- defatult database 是否有符合 binlog-ignore-db 指定的 database 呢?
- YES:忽略語句並退出。
- NO:紀錄語句並退出。
需留意狀況
因為這部分過濾也受 binlog_format 的影響,因此需要留意以下狀況:
- STATEMENT 格式:以 default database 為判斷 (USE database)。
ROW 格式:以實際被異動的 database 為判斷。
- DDL 語句無論如何都是用 STATEMENT 格式紀錄,所以在使用 DDL 語句前加上 USE database 才能在 filter 這邊做符合期望的判斷。
- STATEMENT 格式有一個例外是 CREATE DATABASE,ALTER DATABASE 和 DRP DATABASE,在執行這些操作之前預設 database 會自動切換成對象 DATABASES。
- 使用 routine (SP、function) 時,會隱式的 USE routine 所在的 DATABASE (routine 結束後會撤銷),並且在 routine 內不能使用 USE DATABASE 語句,因此如果 routine 內包含 DDL 語句,會以 routine 所在 DATABASE 做判斷,需要特別注意。
- 當語句同時涉及兩張表,其中一個表符合 DO 條件,另一個表符合 IGNORE 條件時,則: 當 binlog format = Statement 時,該語句不會執行,兩張表都不進行更新。 當 binlog format = Row 時,更新符合 DO 條件的表,並忽略更新符合 IGNORE 條件的表。
實測
經過實測可以發現不論是 do 還是 ignore,對於沒有指定預設 database 的 DDL 語句是都會紀錄的,這部分和文檔描述並不一致。
測試紀錄如下
以下整理對於沒有指定預設 database 的 DDL 語句,binlog filter 和 replication filter 區別如下:
- binlog filter:不論是 binlog-do-db、binlog-ignore-db 都會進行紀錄。
- replication filter:不符合 replicate-do-db 不執行,不符合 replicate-ignore-db 不忽略。
使用建議
需要謹慎評估是否真的需要使用 binlog_do_db、binlog_ignore_db 這兩種選項,原因如下:
- 此選項作用於 primary,這將導致 primary binlog 不完整,後續無法基於 binlog 進行數據復原。
- 相較之下作用於 replica 的 replication filter 能符合大部分的需求也更加安全。
在官方存檔中也明確建議補不應該使用 binlog_do_db、binlog_ignore_db 這兩種選項,而是使用 replication filter 做為替代。
You should not use these options(--binlog-do-db and --binlog-ignore-db) to control which databases and tables are replicated. Instead, use filtering on the replica to control the events that are executed on the replica.
binlog_do_db、binlog_ignore_db 不適合做為一個通用的方案使用,除非可以接受數據丟失或是有其他精心設計的特殊方案,否則都不建議使用。