本文介紹了由於記錄檔過多導致儲存空間被佔滿的問題描述、解決方案以及後續維護等內容。
問題描述
PolarDB MySQL版叢集由於Binlog檔案、Redo日誌或者Undo日誌過多,佔用了太多儲存空間,且在空間分析中確認日誌空間使用量較高。如下圖所示:

引發該問題的原因可能是由於大事務在快速產生Binlog檔案、Redo檔案或Undo檔案時,佔用了太多的叢集儲存空間。
解決方案
清理Binlog檔案、Undo檔案或Redo檔案時,介面更新有延遲,請耐心等待。
由於DML等操作(比如涉及大欄位的DML操作)會快速產生Binlog檔案、Undo檔案或Redo檔案,在這種情況下,建議您考慮升級擴充儲存空間,並且排查快速產生Binlog檔案、Undo檔案或Redo檔案的原因。
若根據以下方案仍不能通過清理記錄檔釋放足夠的儲存空間,您可以清理其他類型的資料檔案來降低儲存空間使用率。詳情請參見由於資料檔案過多導致叢集儲存空間被佔滿的解決辦法。
Binlog日誌
儲存策略
Binlog檔案有如下兩種儲存策略:
開啟Binlog後,檔案預設儲存3天,超過3天的Binlog檔案會被自動刪除。
說明在2023年11月23日前購買的PolarDB MySQL版叢集,其Binlog檔案預設儲存兩周(14天)。
在2024年1月17日前購買的PolarDB MySQL版叢集,其Binlog檔案預設儲存一周(7天)。
關閉Binlog後,已有的Binlog檔案會一直保留,不會自動刪除。
修改儲存時間長度
修改Binlog儲存時間長度不會造成串連閃斷,也不需要重啟叢集。
但如果修改儲存時間長度導致大量Binlog檔案需要被清除(如10 TB),則在清除時可能會造成短時間的資料庫寫入異常。因此,在Binlog檔案較大的情況下,建議在業務低峰期進行操作,並分多次縮短Binlog的儲存時間長度,每次清除一部分Binlog資料。
已被清除的Binlog檔案被刪除後無法進行恢複。
若您的叢集已開啟Binlog,您可以通過如下兩種方式修改Binlog檔案儲存時間長度:
若叢集版本為PolarDB MySQL版5.6,您可以通過修改loose_expire_logs_hours(取值範圍為0~2376,單位為小時,預設值為72)的參數值來設定Binlog的儲存時間長度。0表示不自動刪除Binlog檔案。參數詳細設定請參見修改參數值。
若叢集版本為PolarDB MySQL版5.7或8.0,您可以通過修改binlog_expire_logs_seconds(取值範圍為0~4294967295,單位為秒,預設值為259200)的參數值來設定Binlog的儲存時間長度。0表示不自動刪除Binlog檔案。參數詳細設定請參見修改參數值。
重要通過修改這兩個參數的參數值來設定Binlog的儲存時間長度後,叢集中歷史Binlog檔案不會被立即自動清除。此時若您需要清除歷史Binlog檔案,可以通過如下三種方法之一:
當叢集中最後一個Binlog檔案達到
max_binlog_size,切換到新的Binlog檔案後,這些歷史Binlog檔案將會被自動清除。使用高許可權帳號執行flush binary logs命令可以立即觸發Binlog檔案切換並清除到期的Binlog檔案。
您也可重啟叢集。叢集重啟後將自動清除歷史Binlog檔案。
若您的叢集未開啟Binlog,此時如需刪除Binlog檔案,您可以重新開啟Binlog,將上述Binlog的儲存時間長度參數(loose_expire_logs_hours或binlog_expire_logs_seconds)設定為一個較小的值,等檔案超過儲存時間長度自動刪除後再關閉Binlog。
Redo日誌
PolarDB MySQL版叢集使用Redo日誌替代Binlog日誌,以實現主節點與唯讀節點之間的資料同步。
在不考慮記錄備份的情況下,本地Redo日誌會佔用範圍為2 GB至11 GB的儲存空間,最高可達11 GB。其中包括緩衝池中的8個Redo日誌(佔用8 GB)、正在寫入的Redo日誌(佔用1 GB)、提前建立的Redo日誌(佔用1 GB)以及最後一個Redo日誌(佔用1 GB)。
在考慮記錄備份的情況下,本地Redo日誌會在備份完成後保留約一個小時。如果寫入速度較快(例如超過35 MB/s),則可能導致本地Redo日誌的暫時性堆積。
清理規則
Redo日誌不支援手動清理,通常在記錄備份完成後會自動進行清理,無需手動幹預。
您可以在PolarDB控制台調整叢集的記錄備份策略(預設為7天)。
Undo日誌
檢查是否有未提交的舊事務,PolarDB中的Undo log承擔MVCC的歷史版本作用,因此當有未提交事務持有舊的Read View時會阻塞Undo log的清理,造成空間積累。您可以使用以下命令查看是否存在大事務:
SELECT * FROM INFORMATION_SCHEMA.innodb_trx;PolarDB的唯讀節點與讀寫節點共用儲存,唯讀節點上的未提交的大事務同樣會影響Undo log的清理,在kill掉事務對應的線程後,Undo會停止繼續擴大。如果需要回收Undo檔案,您可以通過如下步驟確定Undo history推進情況後,再進行Undo檔案的空間清理。
當寫入壓力大時,確定是否將Undo清理滯後,PolarDB的策略會優先保證當前的寫入效能,可能會導致Undo log的清理滯後。您可以通過如下命令查看當前Undo history的長度:
SELECT COUNT FROM INFORMATION_SCHEMA.innodb_metrics WHERE name = 'trx_rseg_history_len';如果該值大於100萬,或者幾分鐘的時間內,該值還在不斷地上升,並且當前壓力確實比較大,可以通過如下步驟調整:
將參數
innodb_purge_batch_size的值調大,該操作不會重啟叢集。將參數
innodb_purge_threads的值調大,建議跟叢集規格中的核心數一致,該操作會重啟叢集,建議在業務低峰期操作,等待Undo history長度降低以後,Undo空間會停止增長,如果需要回收Undo空間,可以開啟Undo truncate開關進行清理。
將
innodb_undo_log_truncate參數的值設定為ON,來開啟Undo truncate開關。由於Undo truncate功能會在叢集切換或重啟時帶來額外的開銷,建議在空間回收後立即關閉該功能,尤其是發起小版本升級等任務之前先關閉。需要的時候再開啟。PolarDB維護8個Undo檔案,當單個檔案超過innodb_max_undo_log_size後,就會觸發Undo truncate。innodb_max_undo_log_size預設為8 GB,因此如果長時間超過8 GB,寫入壓力較小,並且叢集版本比較老,可以嘗試做小版本升級來升級到最新版本。說明一些歷史版本存在Undo truncate相關缺陷,關閉了修改
innodb_undo_log_truncate的許可權,導致在參數修改介面找不到該參數。此時需要通過小版本升級操作將目前的版本升級到最新的版本。
後續維護
擴充儲存空間,PolarDB MySQL版採用儲存與計算分離的架構,您可以選擇手動擴容/縮容儲存空間來擴充當前的儲存空間容量。