RDS MySQL實例的空間使用率是日常需要重點關注的監控項之一,如果實例的存儲空間不足,會導致嚴重后果,例如數據庫無法寫入、數據庫無法備份、存儲空間擴容任務耗時過長等。本文介紹查看空間使用情況的方式,以及各種空間問題的原因和解決方案。
查看空間使用情況
RDS MySQL實例存儲空間包含用戶數據庫數據、系統數據庫數據、各類日志和臨時表文件等,您可以通過RDS標準監控查看存儲空間使用情況。
解決方案概述
實例存儲空間不足的直接原因是實例內各類文件的堆積。您需要在查看實例存儲空間情況時,重點關注以下文件的空間使用量,根據不同的文件類型選擇不同的解決方案。
文件名稱 | 標準監控中對應參數名 | 空間分析中對應參數名 | 解決方案 |
臨時文件 |
|
| |
Binlog文件 |
|
| |
undo log文件 |
|
| |
general log文件 |
|
| |
用戶數據文件 |
|
|
除上述文件之外,您還需關注實例的空間碎片與數據庫索引:
空間碎片堆積也會造成可用存儲空間不足,詳情請參見空間碎片堆積導致空間不足。
當數據庫使用了不合理的索引策略時,會造成索引文件堆積,進而引發實例空間不足問題,詳情請參見索引文件堆積導致空間不足。
緊急情況下,建議您優先手動擴容磁盤,盡快解鎖實例,業務訪問恢復后再根據文件堆積情況清理存儲空間。一般情況下,實例會在磁盤擴容后五分鐘左右解鎖。
臨時文件堆積導致空間不足
MySQL實例可能會由于查詢語句的排序、分組、關聯表產生的臨時表文件,或者大事務未提交前產生的binlog cache文件,導致實例磁盤空間滿。為避免數據丟失,RDS會將實例鎖定,在鎖定之后,將無法進行寫入操作。
解決方案:詳情請參見RDS MySQL臨時文件堆積解決辦法。
MySQL 5.7及以下實例:建議您重啟實例,系統會自動刪除臨時文件。
MySQL 8.0實例:實例鎖定時會結束所有用戶會話并開始自動回滾,系統會在回滾結束后自動釋放臨時文件。
如果實例長時間未自動解鎖,您需要通過
show processlist
命令查看所有會話狀態,找到狀態為Copy to tmp table
、Sending data
等的會話,并使用kill
命令手動結束。
Binlog(本地日志)文件堆積導致空間不足
MySQL實例可能會由于大事務快速生成Binlog文件,導致實例空間滿,為避免數據丟失,會對實例進行自動鎖定,磁盤鎖定之后,將無法進行寫入操作。
解決方案:詳情請參見MySQL Binlog文件堆積解決辦法。
一鍵上傳Binlog:您可以使用RDS的一鍵上傳Binlog功能,將RDS實例存儲空間中的Binlog文件上傳至OSS中保存,上傳完成后RDS將自動刪除已上傳的Binlog文件。
修改本地日志保留策略:您可以在RDS控制臺的 中修改本地日志的保留時長、最大存儲空間占有率、可用存儲空間等參數。實例中本地日志存儲量達到設定閾值后,系統將按時間順序從最早的本地日志開始刪除,直到本地日志存儲量低于閾值。
空間碎片堆積導致空間不足
InnoDB是按頁(Page)管理表空間的。當使用delete
或update
語句刪除或更新數據時,該命令只會將記錄的位置或數據頁標記為“可復用”,而磁盤文件的大小并不會改變,即表空間不會直接回收。當原空間無法復用時,會形成實例空間碎片,占用實例存儲空間。
解決方案:詳情請參見MySQL空間碎片堆積解決辦法。
通過命令行整理空間碎片:您可以使用
optimize table
命令整理表空間碎片。通過DMS優化數據表:您可以登錄RDS MySQL實例,在DMS控制臺中右鍵單擊任意表名并選擇批量操作表,勾選需要空間碎片整理的表名,并選擇
。開啟空間碎片自動回收:您可以在RDS控制臺的空間碎片自動回收。
中單擊自治功能開關,開啟自治功能后,可以在優化和限流頁簽中開啟空間碎片自動回收功能,詳情請參見
系統文件堆積導致空間不足
系統文件過大主要是由于undo文件過大。當存在對InnoDB表長時間不結束的查詢語句,而且在查詢過程中表有大量的數據變化時,系統會生成大量的undo信息,占用大量存儲空間,導致存儲空間耗盡。為避免數據丟失,RDS會自動鎖定實例,實例運行狀態顯示為鎖定中。
解決方案:詳情請參見MySQL系統文件堆積解決辦法。
MySQL 8.0:系統會自動清理undo文件。
MySQL 5.7:
實例
innodb_undo_tablespaces
參數取值為2
時,表示實例允許使用獨立的undo表空間存儲undo數據,可以進行清理。當undo文件大小超過innodb_max_undo_log_size
參數值且其中的日志不再被任何活動的事務所需要時,系統會對undo文件進行truncate
操作,清理過大的文件并釋放空間。實例
innodb_undo_tablespaces
參數取值為0
時,表示不使用獨立的undo表空間,undo文件存儲在系統表空間ibdata1中,不可以進行清理。您可以新建實例并遷移數據或將數據庫版本升級至MySQL 8.0,詳情請參見升級數據庫版本。
MySQL 5.5、MySQL 5.6:不支持清理undo文件,建議將實例升級為MySQL 5.7版本的高可用系列實例或MySQL 8.0實例。
說明MySQL 5.7高可用系列實例的
innodb_undo_tablespaces
參數取值為2,允許使用獨立的undo表空間存儲undo數據,可以清理undo文件。
常規日志文件堆積導致空間不足
當RDS MySQL開啟了general log后,該文件記錄了用戶的所有操作,包括每條SQL語句的執行細節,無論是查詢、插入、更新還是刪除操作。當訪問量大或者長時間不清理general log文件時,會占用大量的存儲空間,導致存儲空間耗盡。
解決方案:詳情請參見MySQL general log文件堆積解決辦法。
關閉常規日志采集:關閉general log(運行參數值設為OFF),以防止產生新的日志。詳情請參見設置實例參數。
刪除常規日志文件:您可以登錄RDS實例并執行
TRUNCATE TABLE mysql.general_log;
命令刪除常規日志。建議只在調試或跟蹤問題時臨時開啟general log,使用完成之后請及時關閉general log。
用戶數據文件堆積導致空間不足
用戶數據文件長時間未整理或在表結構中使用blob
、text
和較長的varchar
字段會占用大量的實例存儲空間進而導致存儲空間滿的問題。為避免數據丟失,RDS MySQL會對實例進行自動鎖定,鎖定之后將無法進行寫入操作。
解決方案:詳情請參見RDS MySQL數據文件堆積解決辦法。
刪除無用數據:使用
drop
或truncate
命令清理無用數據。壓縮數據:對于一些大字段數據,您可以先進行數據壓縮,再傳入數據庫存儲,減少存儲空間使用量。
索引文件堆積導致空間不足
數據庫索引會以文件形式存儲在磁盤中,當您使用了不合理的索引策略或創建了大量的二級索引,會導致索引文件過大或堆積,造成實例存儲空間不足。
解決方案:
選擇合適的字段創建索引:除主鍵索引外,建議您選擇在被頻繁查詢、需要排序或經常用于表間連接的字段上創建索引。同時,建議您考慮創建聯合索引而非單列索引,節約磁盤空間。
刪除無用索引:對于長時間不使用的索引或無用索引,可以考慮刪除以節約磁盤空間。同時,也建議您優化數據結構,減少二級索引數量。