天天看點

MySQL 複制過濾詳解

如果有這樣的一個需求:master 有3個庫a,b,c ,d,由于某種原因,現在需要将其中2個庫b,c單獨拆分出來,單獨一個執行個體。 如果是你,打算怎麼做呢? 常見的做法就是,單獨搭建一個隻有b,c庫的執行個體,然後隻複制master的b,c庫,過濾掉a,d庫。那麼複制過濾就應運而生了,replicate-*-do-db/table 等。

為了搭建這一套環境(隻複制master的b,c庫),部分人會在my.cnf中這樣配置:

當然,按照大家的慣性思維,認為這樣是沒有錯的。不幸的是,災難已經來臨。

官方文檔:

mysql 會認為<code>b,c</code> 為一個庫名,而不是2個庫。

然而,這裡不僅僅有一個複制過濾參數,一共包括:

這裡面可以随意組合,且不同組合有不同的含義,為了徹底搞清楚他們直接的關系,下面我們一起來一窺究竟。

注意1:庫級别的規則,隻針對binlog_format='statement or mixed‘ 注意2:如果是binlog_format=‘row’,不受庫級别規則限制,隻受表級别規則限制。
MySQL 複制過濾詳解
MySQL 複制過濾詳解
注意: 以下測試和結論,前提都是row_format='mixed'

在db level 中,當binlog-format=statement 時,過濾以use db為主(不允許跨庫)。為rows模式是:不以use db為主(允許跨庫)

不管binlog格式是statement,還是rows模式,table level的判斷都是 不以use db為主(可以跨庫的)

總的流程走向:先判斷db-level,如果db-level 判斷完成後需要exit,則退出。如果db-level判斷完成後,沒有exit,則再判斷table-level

在db-level中,如果有replicate-do-db,則判斷replicate-do-db,将不會走到replicate-ignore-db這層。 如果判斷replicate-do-db符合條件,則判斷table-level。 如果不符合,則exit

在db-level中,如果沒有replicate-do-db,但是有replicate-ignore-db。 流程則是:符合replicate-ignore-db規則,則exit,不符合,則走到table-level層繼續判斷

在table-level中,判斷邏輯順序自上而下為:replicate-do-table -&gt; replicate-ignore-table -&gt; replicate-wild-do-table -&gt; replicate-wild-ignore-table

在table-level中, 從第一個階段(replicate-do-table)開始,如果符合replicate-do-table判斷規則,則exit。如果不符合,則跳到下一層(replicate-ignore-table)。 然後以此内推,直到最後一層(replicate-wild-ignore-table)都不符合,則最後判斷是否有(replicate-do-table or replicate-wild-do-table),如果有,則ignore &amp; exit。如果沒有,則execute &amp; exit

說明:以下測試,均以statement格式為例。 rows模式參見原理同樣可以證明,這裡就不解釋。

第一種情況:設定replicate_do_db=a,b

do-db

ignoare-db

do-db &amp; ignore-db

do-table

ignore-table

wild-do-table

wild-ignore-table

do-table &amp; ignore-table

do-table &amp; wild-ignore-table

wild-do-table &amp; wild-ignore-table

do-db &amp; do-table

do-db &amp; wild-do-table

do-db &amp; ignore-table

do-db &amp; wild-ignore-table

最常見場景: db-db &amp; do-ignore-db &amp; wild-do-table &amp; wild-ignore-table

實戰: wild-do-table &amp; ignore-table &amp; wild-ignore-table

由于組合太多,就不一一列舉。

以上情況,還可以衍生出各種場景群組合,隻要弄懂了原理,基本都沒有問題。

繼續閱讀