閱讀548 返回首頁    go 小米 go 小米6


從一個案例看mysqldump的複製選項

寫在前麵

 背景其實出現在兩周前了,當時隻是簡單地排查了下原因就草草了事,今天再次仔細研究了下官方文檔,發現還是有些嚼頭的,多半是自己之前沒有去刻意的思考,其實一點點小特性,有時候還是可以讓我們的工作簡化很多的。

奇怪的小案例

 這個小案例可能對於某些人來說並不陌生,當時的情境是給一個客戶執行一個dump文件,就這麼一個小小的操作,後來盡然讓客戶發現了蹊蹺:導入的數據備庫上沒有。
 同事告知給我的情況,我也是覺得蠻不可思議,立馬與客戶配合客戶再次確認,發現確實是操作沒有同步過去,馬上檢查了主備複製狀況,一切正常。
 同事懷著僥幸的心理打開dump文件,發現了如下一個明顯的SET指令:

SET @@SESSION.SQL_LOG_BIN= 0;

 這個指令大家一看便知,就是在會話級臨時禁掉binlog的產生,看來這個蹊蹺的問題就是由它所致。那麼為什麼mysqldump的導出文件會出現這個set指令呢?

 馬上就在官方文檔上找到了答案。

The --set-gtid-purged option has the following effect on binary logging when the dump file is reloaded:
● --set-gtid-purged=OFF: SET @@SESSION.SQL_
LOG_BIN=0; is not added to the output.
● --set-gtid-purged=ON: SET @@SESSION.SQL_LOG_BIN=0; is added to the output.
● --set-gtid-purged=AUTO: SET @@SESSION.SQL_LOG_BIN=0; is added to the output if GTIDs are enabled on the server you are backing up (that is, if AUTO evaluates to ON).
This option was added in MySQL 5.6.9.

 那麼再來概述一下事情的原由。這個導出文件的源數據庫開啟了gtid mode,因此默認的dump選項導致了dump文件中添加指令'SET @@SESSION.SQL_LOG_BIN= 0;',然後在客戶的另一個主備環境進行導入,由於主庫導入的操作沒有產生任何binlog,因此備庫上沒有主庫新導入的數據。
 人工補完數據後,告知客戶可以通過--set-gtid-purged這個參數來控製導入操作是否被複製。
 故事卒。

mysqldump的複製支持選項

 案例過後,除了詫異,便是對mysqldump的複製選項重新研究了一番,稍微總結了下,發現還是有點收獲。接下來簡單歸類,聊一下基於mysqldump的特性,如何簡單的做複製架構搭建。

1.主從結構

 這種場景最簡單,就是從一個生產庫通過mysqldump來複製出一個從庫的需求,結構如下
clipboard1

1)非gtid mode

master-data選項:
If the option value is 2, the CHANGE MASTER TO statement is written as an SQL comment, and thus is informative only; it has no effect when the dump file is reloaded. If the option value is 1, the statement is not written as a comment and takes effect when the dump file is reloaded.

 從這裏可以看到,在非gtid模式下,通過--master-data選項,可以將主庫dump時的binlog file以及position記錄下來,那麼change master就會變得很簡單,甚至在innodb引擎下,在線添加從庫根本不需要對主庫形成任何阻塞。
 如下,
 # mysqldump -h127.0.0.1 -uroot -p -P3301 --single-transaction --master-data=2 test t1
1

2)gtid mode

set-gtid-purged選項
This option enables control over global transaction ID (GTID) information written to the dump file, by indicating whether to add a SET @@global.gtid_purged statement to the output. This option may also cause a statement to be written to the output that disables binary logging while the dump file is being reloaded.

 而在gtid模式下,這個操作變得更加簡單,設置這個參數為ON(或者默認值),我們甚至不需要關心從庫執行到了哪個主庫上的transaction id,因為dump命令執行時的gtid被記錄下來,並且直接用來設置從庫的gtid_purged參數,這個就是為什麼gtid模式下在線添加從庫如此簡單的原因。
 如下,
 # mysqldump -h127.0.0.1 -uroot -p -P3301 --single-transaction --set-gtid-purged=ON test t1
2

2.主主結構

 即從一個生產庫通過mysqldump複製出一個從庫,並且與當前實例互為主備,結構如下。
clipboard2
 這裏不討論非gtid模式了,和前麵所說的使用方式一致。
 而在討論gtid模式下的這種場景之前,這裏先回歸到這個案例,為什麼mysql默認會有這個舉動,自動禁掉導入操作的binlog生成?先回顧下gtid特性的使用方式,一個實例的全局事務id,不管在哪個實例上被使用,標識方式都是server_uuid:tran_id,其中server_uuid標識角色,tran_id標識執行的事務,而gtid_purge參數標識已經執行過的某個實例上的事務。因此,dump文件導入意味著從實例執行了主庫上id為m--n的事務,而這些更新默認不被認為是從實例上的行為,這種思維是很科學的,因為複製,即代表接受某個實例對數據的變更。
 而主庫隻需要做一個簡單的change master指令就夠了,因為新添加的從庫並沒有任何更新操作。或許有些人曾經有過困惑,在線做這麼奇葩的事情,本來很緊張,然後莫名其妙的很簡單就搞定了。。
3

3.一主多從結構

 這種場景也是我們平時工作中比較常見的,即需要在線新增一個從庫。結構如下
clipboard3

--dump-slave
This option is similar to --master-data except that it is used to dump a replication slave server to produce a dump file that can be used to set up another server as a slave that has the same master as the dumped server. It causes the dump output to include a CHANGE MASTER TO statement that indicates the binary log coordinates (file name and position) of the dumped slave's master.

--include-master-host-port
For the CHANGE MASTER TO statement in a slave dump produced with the --dump-slave option, add MASTER_HOST and MASTER_PORT options for the host name and TCP/IP port number of the slave's master.

 從這裏可以看到,這兩個選項可以讓你從一個從庫上複製實例的時候,即獲取到一個數據副本,同時收獲需要做的change master語句,輕鬆地從A→B複製出一個A→C。也就是從當前從庫,複製出一個新的從庫,兩個從庫同時指向一個主庫。這樣不管是否為gtid模式,都能夠在完全不影響主庫的前提下擴展從庫。

 gtid模式如下,
 # mysqldump -h127.0.0.1 -uroot -p -P3302 --single-transaction --set-gtid-purged=ON --dump-slave=2 --include-master-host-port liu testb
4

 非gtid模式如下,
 # mysqldump -h127.0.0.1 -uroot -p -P3302 --single-transaction --set-gtid-purged=OFF --dump-slave=2 --include-master-host-port liu testb
5

結語

 雖然隻是一個小小的案例,卻能帶來很多思考,看來真正理解一款產品,對於平時的運維工作還是十分重要的。

最後更新:2017-07-04 09:32:38

  上一篇:go  對安卓係統的功能性升級來說,安全補丁更重要!
  下一篇:go  CentOS7 1611 運行Docker 使用systemctl start httpd.service報錯的解決過程