故障分析 | MySQL 備份文件靜默損壞一例分析

作者:付祥

現居珠海,主要負責 Oracle、MySQL、mongoDB 和 Redis 維護工作。

本文來源:原創投稿

* 愛可生開源社區出品,原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。


背景

線上一套 MySQL 計劃升級到 8.0 ,通過備份還原搭建一個測試環境,用於升級測試。數據庫採用 xtrabackup 每天進行全備,壓縮備份文件約 300G ,解壓到一半就報錯了:

gzip: stdin: invalid compressed data--format violated
tar: Unexpected EOF in archive
tar: Unexpected EOF in archive
tar: Error is not recoverable: exiting now
剛開始以爲只是這個備份文件不完整,又找了前一天備份文件,解壓過程中也報了同樣的錯誤,備份文件比較大,無疑增加了排障時間。

故障分析

備份腳本通過 crontab 每天凌晨執行,線上都是同一套備份腳本,不同項目時常做備份數據還原,還是頭一次遇到備份文件解壓失敗現象,查看了腳本,每個關鍵階段都做了狀態碼判斷是否成功,若失敗就告警,同時對 xtrabackup 備份日誌最後一行是否包含 completed OK 關鍵詞也做了判斷,關鍵備份腳本如下:

xtrabackup xxx --stream=tar  --no-timestamp $bkdir 2> xxx.log | gzip - > xxx.tar.gz

近期也沒收到失敗告警,說明備份腳本是執行成功了的,感覺太奇怪了,查看定時任務日誌,發現同一任務同一時間點竟然啓了2次:

[root@localhost backup]# grep backup /var/log/cron
Mar 6 00:00:01 localhost CROND[6212]: (root) CMD (sh xxx/mysql_ftp_backup.sh || echo 1 > xxx/err.log)
Mar 6 00:00:01 localhost CROND[6229]: (root) CMD (sh xxx/mysql_ftp_backup.sh || echo 1 > xxx/err.log)
Mar 7 00:00:01 localhost CROND[5387]: (root) CMD (sh xxx/mysql_ftp_backup.sh || echo 1 > xxx/err.log)
Mar 7 00:00:01 localhost CROND[5420]: (root) CMD (sh xxx/mysql_ftp_backup.sh || echo 1 > xxx/err.log)

crond 服務每次同時拉起2個進程執行備份,併發的往同一個壓縮文件 xxx.tar.gz 寫數據,備份數據相互覆蓋,導致備份文件損壞,每天看似備份成功的任務,其實備份都是無效的,這也說明了定期備份恢復演練的重要性。爲何定時任務同一時間點會啓動2次?查看 crond 進程:

[root@localhost backup]# ps -ef|grep crond |grep -v grep
root 2883 1 0 2018 ? 01:42:46 crond
root 17293 1 0 2022 ? 00:43:22 crond

原來是因爲系統啓動了2個 crond 進程,kill crond 進程後重啓,再次查看只有一個 crond 進程:

[root@localhost backup]# service crond stop
Stopping crond: [ OK ]

[root@localhost backup]# ps -ef|grep crond
root 2883 1 0 2018 ? 01:42:46 crond
root 31486 31856 0 10:59 pts/2 00:00:00 grep crond

[root@localhost backup]# kill 2883
[root@localhost backup]# ps -ef|grep crond
root 31572 31856 0 10:59 pts/2 00:00:00 grep crond

[root@localhost backup]# service crond start
Starting crond: [ OK ]
[root@localhost backup]# ps -ef|grep crond
root 31632 1 0 10:59 ? 00:00:00 crond
root 31639 31856 0 11:00 pts/2 00:00:00 grep crond

總結

爲了確保備份有效,需要做如下改進:

1、flock給腳本執行加互斥鎖,確保一個時間點只有1個進程運行。

2、定期做備份恢復演練。

3、增加crond進程監控,不等於1告警。

本文關鍵字:#備份失敗# #定時任務#


文章推薦:

MySQL 相同 SQL 不同環境執行時間不一樣案例分析

MySQL 從機故障重啓後主從同步報錯案例分析

mysql 5.6 升級到 8.0 失敗一例處理

關於SQLE

愛可生開源社區的 SQLE 是一款面向數據庫使用者和管理者,支持多場景審覈,支持標準化上線流程,原生支持 MySQL 審覈且數據庫類型可擴展的 SQL 審覈工具。

SQLE 獲取

類型 地址
版本庫 https://github.com/actiontech/sqle
文檔 https://actiontech.github.io/sqle-docs-cn/
發佈信息 https://github.com/actiontech/sqle/releases
數據審覈插件開發文檔 https://actiontech.github.io/sqle-docs-cn/3.modules/3.7_auditplugin/auditplugin_development.html
更多關於 SQLE 的信息和交流,請加入官方QQ交流羣:637150065...

本文分享自微信公衆號 - 愛可生開源社區(ActiontechOSS)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章