
當我們嘗試還原 mysqldump 檔案時,我們已經多次遇到導致 MySQL 資料庫損壞的情況。我們已經使用相同的流程(透過批次腳本)好幾年了,沒有出現任何問題,直到最近幾個月才開始遇到這個問題。
我們正在運行 MySQL 伺服器版本:5.7.18-0ubuntu0.16.04.1 (Ubuntu 16.04.2 LTS),並正在恢復兩個包含約 350K 記錄(總計)的 MyISAM 表。
我們使用以下 cmd 腳本從內部備份表並還原到遠端資料庫伺服器:
"%mysql_path%\mysqldump.exe" --user=root --password="%PWD%" --host=%source% ourdbname --tables table1 table2 | "%mysql_path%\mysql.exe" -uroot --password="%PWD%" --host=%dbtarget% -C ourdbname
其中%%
變數作為較大批次腳本的一部分提供。基本上,我們將轉儲的輸出透過管道傳輸到 mysql.exe 以在遠端伺服器上復原。該腳本在 Windows 10 電腦上運行,但來源資料庫和目標資料庫都在 Linux 上。
復原部分是資料庫損壞的地方,這會導致資料庫伺服器 CPU 使用率飆升至每個核心 100%。我們發現解決此問題的唯一方法是終止 mysql 進程,刪除文件.frm, .MYD, .MYI
,然後啟動 mysql 並在本地恢復表(將 mysqldump 文件 scp 到伺服器並恢復)。
我們發現,只有當網站上有活躍流量時,資料庫才會損壞。因此,我們可以關閉該網站(透過 JDBC 連線執行 Java 的獨立伺服器),執行腳本,然後使網站恢復線上狀態,並且它 100% 都可以正常運作。顯然這並不理想,但這是我們現在能做到的唯一方法。
有什麼想法可能導致這種情況嗎?關於如何解決這個問題而不需要關閉前端伺服器的建議?
答案1
您似乎正在使用 MyISAM 作為您網站的資料庫引擎。我推薦使用InnoDB,它在很多方面都更好。
然而,這裡的主要問題是,您的 Web 應用程式很可能在將備份寫入資料庫的同時寫入資料庫。根據實際的表模式,這可能會導致各種不良影響。使用 MyISAM 只會讓它起作用,因為如果我沒記錯的話,MyISAM 中沒有行級鎖定。
因此,使用 InnoDB 可以幫助解決這個問題,但話又說回來,它可能不會。唯一安全的選擇可能是簡單地停止前端伺服器。另一種選擇是為遠端應用程式建立一個 API,它將傳入的資料安全地寫入資料庫。