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 官方文檔

官方文檔說明

  1. 是否有任何 binlog-do-db 或 binlog-ignore-db 選項?
      • YES:繼續下一個步驟2。
      • NO:紀錄語句並退出。
  1. 是否有 default database (透過 USE 選擇 database)
      • YES:繼續下一個步驟3。
      • NO:忽略語句並退出。 (實測發現應該是紀錄語句並退出,可參照實測)
  1. 是否有任何 binlog-do-db 選項?
      • YES:defatult database 是否有符合 binlog-do-db 指定的 database 呢?
        • YES:紀錄語句並退出。
        • NO:忽略語句並退出。
      • NO:繼續下一個步驟4。
  1. defatult database 是否有符合 binlog-ignore-db 指定的 database 呢?
      • YES:忽略語句並退出。
      • NO:紀錄語句並退出。

需留意狀況

因為這部分過濾也受 binlog_format 的影響,因此需要留意以下狀況:
  1. STATEMENT 格式:以 default database 為判斷 (USE database)。
    1. ROW 格式:以實際被異動的 database 為判斷。
  1. DDL 語句無論如何都是用 STATEMENT 格式紀錄,所以在使用 DDL 語句前加上 USE database 才能在 filter 這邊做符合期望的判斷。
  1. STATEMENT 格式有一個例外是 CREATE DATABASE,ALTER DATABASE 和 DRP DATABASE,在執行這些操作之前預設 database 會自動切換成對象 DATABASES。
  1. 使用 routine (SP、function) 時,會隱式的 USE routine 所在的 DATABASE (routine 結束後會撤銷),並且在 routine 內不能使用 USE DATABASE 語句,因此如果 routine 內包含 DDL 語句,會以 routine 所在 DATABASE 做判斷,需要特別注意。
  1. 當語句同時涉及兩張表,其中一個表符合 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.
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 不適合做為一個通用的方案使用,除非可以接受數據丟失或是有其他精心設計的特殊方案,否則都不建議使用。

參考