Mysql

如何優化大型數據庫的 mysqldump?

  • September 9, 2019

我有一個 symfony 應用程序,其 InnoDB 數據庫約為 2GB,有 57 個表。數據庫的大部分大小位於單個表中(~1.2GB)。我目前正在使用 mysqldump 每晚備份數據庫。

由於我的 comcast 連接,通常如果我手動執行轉儲,我與伺服器的連接將在轉儲完成之前超時,導致我不得不重新執行轉儲。

$$ I currently run a cron that does the dump nightly, this is just for dumps that I run manually. $$ 有沒有辦法加快連接超時問題的轉儲,但也可以限制伺服器被此程序佔用的時間?

順便說一句,我目前正在努力減少整個數據庫的大小以解決這個問題。

像這樣的轉儲中的主要瓶頸是驅動器 I/O。您正在讀取大量數據並再次寫入。您可以通過多種方式加快速度:

  • 確保您的輸出將發送到與儲存數據庫文件的驅動器不同的驅動器 - 這將與旋轉磁碟產生巨大差異,因為驅動器磁頭不會在讀取的位置之間不斷滑動以及被寫入的位置。
  • mysqldump 的輸出將是非常可壓縮的,因此如果您不能如上所述將輸出與輸入分開,請通過管道gzip或類似管道輸出。這將減少正在完成的寫入量(因此減少整體 IO 負載和磁頭移動量),但會花費一些 CPU 時間(無論如何,這些時間你可能有很多空閒時間)。
  • 此外,(以及或代替壓縮)通過管道實用程序(如pv )傳遞輸出,該實用程序支持大型寫入緩衝區以將寫入驅動器的塊更多地組合在一起,再次減少磁頭移動延遲的影響 - 這將使如果使用該--quick選項來減少備份大表對 RAM 的影響,則會有很大的不同)。
  • 僅當 IO 負載較低時才執行備份過程。

不過,您可能正在解決錯誤的問題:解決連接斷開問題可能更容易(儘管減少備份施加的 I/O 負載將有助於減少您對其他使用者的影響,因此無論如何都值得嘗試)。您可以通過screen(或類似的工具,如tmux)執行手動備份嗎?這樣,如果您與伺服器的連接斷開,您只需重新連接並重新連接到screen會話,而不會中斷任何程序。

如果您直接通過連接發送數據(即您在本地電腦上針對遠端數據庫執行 mysqldump,因此轉儲出現在本地)您最好先在伺服器上執行轉儲,根據需要進行壓縮,然後傳輸使用支持部分傳輸的工具(例如rsync)通過網路傳輸數據,因此如果連接中斷中斷傳輸,您可以恢復傳輸(而不是重新啟動)。

作為您“減少整個數據庫的大小以解決此問題”的一部分,我猜您的大部分數據不會改變。您可能可以將 1.2Gb 的一大塊從該主表移到另一個表中,並將其從mysqldump呼叫複制的那些中刪除。如果這些數據從不更改,則無需每次都備份此數據。以這種方式在表和數據庫之間拆分數據通常稱為數據分區,還可以讓您將數據和 I/O 負載分散到多個驅動器上。高端數據庫內置了對自動分區的支持,但在 mysql 中,您可能必須手動執行此操作並更改數據訪問層以解決此問題。

偏離本網站的主題(因此您可能應該向 ServerFault 或 SuperUser 詢問您是否需要更多詳細資訊):如果您似乎由於不活動而失去連接,請檢查您的 SSH 伺服器和 SSH 客戶端中的選項以進行確保啟用並經常發送保持活動數據包。如果即使連接處於活動狀態也看到丟包,您也可以嘗試使用 OpenVPN 或類似的東西來包裝連接 - 它應該處理短暫的丟包,如果您的整個連接中斷幾秒鐘,甚至是完全丟包,例如 SSH 客戶端和伺服器沒有註意到。

引用自:https://dba.stackexchange.com/questions/20