轉原文地址: http://www.javashuo.com/article/p-kzwodwps-bu.htmlhtml
之前備份binlog時,都是先在本地進行備份壓縮,而後發送到遠程服務器中。可是這其中仍是有必定風險的,由於日誌的備份都是週期性的,若是在某個週期中,服務器宕機了,硬盤損壞了,就可能致使這段時間的binlog就丟失了。mysql
並且,之前用腳本對遠程服務器進行備份的方式,有個缺點:沒法對MySQL服務器當前正在寫的二進制日誌文件進行備份。因此,只能等到MySQL服務器所有寫完才能進行備份。而寫完一個binlog的時間並不固定,這就致使備份週期的不肯定。sql
從MySQL5.6開始,mysqlbinlog支持將遠程服務器上的binlog實時複製到本地服務器上。服務器
mysqlbinlog的實時二進制複製功能並不是簡單的將遠程服務器的日誌複製過來,它是經過MySQL 5.6公佈的Replication API實時獲取二進制事件。本質上,就至關於MySQL的從服務器。與普通服務器相似,主服務器發生事件後,通常都會在0.5~1秒內進行備份。post
備份命令url
mysqlbinlog --read-from-remote-server --raw --host=192.168.244.145 --port=3306 --user=repl --password=repl --stop-never mysql-bin.000001
解釋以下:spa
--read-from-remote-server:用於備份遠程服務器的binlog。若是不指定該選項,則會查找本地的binlog。日誌
--raw:binlog日誌會以二進制格式存儲在磁盤中,若是不指定該選項,則會以文本形式保存。code
--user:複製的MySQL用戶,只須要授予REPLICATION SLAVE權限。server
--stop-never:mysqlbinlog能夠只從遠程服務器獲取指定的幾個binlog,也可將不斷生成的binlog保存到本地。指定此選項,表明只要遠程服務器不關閉或者鏈接未斷開,mysqlbinlog就會不斷的複製遠程服務器上的binlog。
mysql-bin.000001:表明從哪一個binlog開始複製。
除了以上選項外,還有如下幾個選項須要注意:
--stop-never-slave-server-id:在備份遠程服務器的binlog時,mysqlbinlog本質上就至關於一個從服務器,該選項就是用來指定從服務器的server-id的。默認爲-1。
--to-last-log:表明mysqlbinlog不只可以獲取指定的binlog,還能獲取其後生成的binlog,獲取完了,才終止。若是指定了--stop-never選項則會隱式打開--to-last-log選項。
--result-file:用於設置遠程服務器的binlog,保存到本地的前綴。譬如對於mysql-bin.000001,若是指定--result-file=/test/backup-,則保存到本地後的文件名爲/test/backup-mysql-bin.000001。注意:若是將--result-file設置爲目錄,則必定要帶上目錄分隔符「/」。譬如--result-file=/test/,而不是--result-file=/test,否則保存到本地的文件名爲/testmysql-bin.000001。
不足:
這個方式有個問題,對於常規的主從複製來講,若是主從直接的鏈接斷開了,則從會自動再次鏈接,而對於mysqlbinlog,若是斷開了,並不會自動鏈接。
解決方案:
可經過腳原本彌補上述不足。
#!/bin/sh BACKUP_BIN=/usr/bin/mysqlbinlog LOCAL_BACKUP_DIR=/backup/binlog/ BACKUP_LOG=/backup/binlog/backuplog REMOTE_HOST=192.168.244.145 REMOTE_PORT=3306 REMOTE_USER=repl REMOTE_PASS=repl FIRST_BINLOG=mysql-bin.000001 #time to wait before reconnecting after failure SLEEP_SECONDS=10 ##create local_backup_dir if necessary mkdir -p ${LOCAL_BACKUP_DIR} cd ${LOCAL_BACKUP_DIR} ## 運行while循環,鏈接斷開後等待指定時間,從新鏈接 while : do if [ `ls -A "${LOCAL_BACKUP_DIR}" |wc -l` -eq 0 ];then LAST_FILE=${FIRST_BINLOG} else LAST_FILE=`ls -l ${LOCAL_BACKUP_DIR} | grep -v backuplog |tail -n 1 |awk '{print $9}'` fi ${BACKUP_BIN} --raw --read-from-remote-server --stop-never --host=${REMOTE_HOST} --port=${REMOTE_PORT} --user=${REMOTE_USER} --password=${REMOTE_PASS} ${LAST_FILE} echo "`date +"%Y/%m/%d %H:%M:%S"` mysqlbinlog中止,返回代碼:$?" | tee -a ${BACKUP_LOG} echo "${SLEEP_SECONDS}秒後再次鏈接並繼續備份" | tee -a ${BACKUP_LOG} sleep ${SLEEP_SECONDS} done
腳本解讀:
1. 實際上定義了一個死循環,若是備份失敗,則10s後從新鏈接。
2. 第一次運行時需指定FIRST_BINLOG的值,指從哪一個binlog開始複製,通常爲mysql-bin.000001。後續執行的時候就直接獲取備份目錄下最新的binlog,從最新的binlog開始複製。
總結:
1. 若是指定了--raw,mysqlbinlog獲取事件後,並不會實時落盤,而是先保存在本地服務器的內存中,每4K刷盤一次。這也就減小了頻繁的日誌寫操做。若是此時mysqlbinlog和主服務器之間的鏈接斷開了,則內存中的binlog會立刻刷新到磁盤中。
2. 儘管mysqlbinlog相似於從服務器,但從服務器上的relaylog倒是實時存盤的,即從服務器獲取主服務器產生的事件後,會實時寫入到relaylog中。
3. 若是不指定--raw,這個時候會以文本格式存盤,此時,--result-file=/test/不能指定爲目錄,必須明確寫上文件名,譬如--result-file=/test/1.sql,此時,mysqlbinlog獲取事件後,是實時落盤的,不會每4K刷盤一次。