為什麼我的 Amazon RDS for MySQL 或 MariaDB 執行個體顯示為儲存空間已滿?

3 分的閱讀內容
0

我的 Amazon Relational Database Service (Amazon RDS) for MySQL 或 MariaDB 執行個體顯示為儲存空間已滿。為什麼會發生這種情況,如何查看我的資料庫執行個體中使用儲存空間的項目?

簡短描述

若要對儲存空間已滿問題進行疑難排解,您必須先分析資料庫執行個體所使用的總空間。資料庫執行個體上的空間用於下列項目:

  • 使用者建立的資料庫
  • 暫存資料表
  • 二進位日誌或 MySQL 待命執行個體轉送日誌 (如果您使用僅供讀取複本)
  • InnoDB 資料表空間
  • 一般日誌、慢速查詢日誌和錯誤日誌

在識別使用儲存空間的內容之後,您可以回收儲存空間。然後,監控 FreeStorageSpace 指標,以避免再次耗盡空間。

**注意:**如果可用儲存空間突然減少,請執行 SHOW FULL PROCESSLIST 命令來檢查資料庫執行個體層級正在進行的查詢。SHOW FULL PROCESSLIST 命令提供關於每個連線執行的所有作用中連線和查詢的資訊。若要檢閱長時間處於作用中的交易,請執行 INFORMATION_SCHEMA.INNODB_TRXSHOW ENGINE INNODB STATUS 命令。然後,檢閱輸出。

解決方法

分析資料庫執行個體上使用的總空間 (使用者建立的資料庫)

若要尋找每個使用者建立的資料庫的大小,請執行下列查詢:

mysql> SELECT table_schema, ROUND(SUM(data_length+index_length)/1024/1024/1024,2) "size in GB" FROM information_schema.tables GROUP BY 1 ORDER BY 2 DESC;

若要檢查特定資料庫 (在資料庫執行個體中) 的每個資料表的大小,請執行下列查詢:

mysql> SELECT table_schema "DB Name", table_name,(data_length + index_length)/1024/1024/1024 AS "TableSizeinGB" from information_schema.tables where table_schema='database_name';

若要在 MySQL 5.7 版或更高版本或 MySQL 8.0 及更高版本中獲得更準確的資料表大小,請使用下列查詢:
**注意:**information_schema.files 查詢不適用於 MariaDB 引擎。

mysql> SELECT file_name, ROUND(SUM(total_extents * extent_size)/1024/1024/1024,2) AS "TableSizeinGB" from information_schema.files where file_name like '%/database_name/%';

若要取得資料庫層級和資料表層級的完整儲存詳細資訊和大致的分段空間,請執行下列查詢:
注意: 此查詢不適用於位於共用資料表空間中的資料表。

mysql> SELECT table_schema AS "DB_NAME", SUM(size) "DB_SIZE", SUM(fragmented_space) APPROXIMATED_FRAGMENTED_SPACE_GB FROM (SELECT table_schema, table_name, ROUND((data_length+index_length+data_free)/1024/1024/1024,2) AS size, ROUND((data_length - (AVG_ROW_LENGTH*TABLE_ROWS))/1024/1024/1024,2)
    AS fragmented_space FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_schema NOT IN ('performance_schema', 'mysql', 'information_schema') ) AS TEMP GROUP BY DB_NAME ORDER BY APPROXIMATED_FRAGMENTED_SPACE_GB DESC;

mysql> SELECT table_schema DB_NAME, table_name TABLE_NAME, ROUND((data_length+index_length+data_free)/1024/1024/1024,2) SIZE_GB, ROUND((data_length - (AVG_ROW_LENGTH*TABLE_ROWS))/1024/1024/1024,2) APPROXIMATED_FRAGMENTED_SPACE_GB from information_schema.tables
    WHERE table_type='BASE TABLE' AND table_schema NOT IN ('performance_schema', 'mysql', 'information_schema') ORDER BY APPROXIMATED_FRAGMENTED_SPACE_GB DESC;

記錄從這兩個查詢取得的資料庫大小,並將它們與 Amazon RDS 中的 Amazon CloudWatch 指標進行比較。然後,您可以確認是否因資料使用而造成儲存空間充滿。

暫存資料表

InnoDB 使用者建立的暫存資料表和磁碟內部暫存資料表在名為 ibtmp1 的暫存資料表空間文件中建立。有時,暫存資料表空間檔案甚至可以擴展到 MySQL 資料目錄中的 ibtmp2

**提示:**如果暫存資料表 (ibtmp1) 使用過多的儲存空間,請重新啟動資料庫執行個體以釋放空間。

線上 DDL 操作使用暫存日誌檔來執行下列操作:

  • 記錄並行 DML
  • 建立索引時建立暫存排序檔
  • 重建資料表時建立暫存中間資料表檔案 (以便暫存資料表可以佔用儲存空間)

**注意:**InnoDB 資料表空間的檔案大小只能使用 MySQL 5.7 版或更高版本或 MySQL 8.0 及更高版本查詢。

若要尋找 InnoDB 暫存資料表空間,請執行下列查詢:

mysql> SELECT file_name, tablespace_name, table_name, engine, index_length, total_extents, extent_size from information_schema.files WHERE file_name LIKE '%ibtmp%';

若要回收全域暫存資料表空間資料檔案所佔用的磁碟空間,請重新啟動 MySQL 伺服器或重新啟動資料庫執行個體。如需詳細資訊,請參閱 MySQL 網站上的暫存資料表空間

InnoDB 資料表空間

有時 MySQL 會建立因查詢正在介入而無法移除的內部暫存資料表。這些暫存資料表不是 information_schema 內名為 "tables" 的資料表的一部分。如需詳細資訊,請參閱 MySQL 網站上的 MySQL 中的內部暫存資料資料表使用

執行下列查詢以尋找這些內部暫存資料資料表:

mysql> SELECT * FROM information_schema.innodb_sys_tables WHERE name LIKE '%#%';

InnoDB 系統資料表空間InnoDB 資料字典的儲存區域。除了資料字典之外,InnoDB 系統資料表空間中也存在雙寫緩衝區、變更緩衝區和復原日誌。此外,如果在系統資料表空間中建立資料表 (而不是 file-per-table 或一般資料表空間),則資料表空間可能包含索引和資料表資料。

執行下列查詢以尋找 InnoDB 系統資料表空間:

mysql> SELECT file_name, tablespace_name, table_name, engine, index_length, total_extents, extent_size from information_schema.files WHERE file_name LIKE '%ibdata%';

**注意:**此查詢在 MySQL 5.7 版及更高版本或 MySQL 8.0 及更高版本上執行。

系統資料表空間的大小增加後,無法縮小。但是,您可以轉換所有 InnoDB 表並將資料表匯入新的 MySQL 資料庫執行個體中。為避免大型系統資料表空間,請考慮使用 file-per-table 資料表空間。如需詳細資訊,請參閱 MySQL 網站上的 file-per-table 資料表空間

如果您啟用 Innodb_file_per_table,則每個資料表將資料和索引儲存在自己的資料表空間檔案中。您可以透過在該資料表上執行 OPTIMIZE TABLE 來回收空間 (從資料庫和資料表上的片段)。OPTIMIZE TABLE 命令會建立資料表的全新空白副本。然後,舊資料表中的資料會逐列複製到新資料表中。在此過程中,新的 .ibd 資料表空間會建立,且空間回收。如需有關此程序的詳細資訊,請參閱 MySQL 網站上的 OPTIMIZE TABLE 陳述式

**重要:**OPTIMIZE TABLE 命令使用 COPY 演算法來建立與原始資料表相同大小的暫存資料表。在執行此命令之前,請確認您有足夠的可用磁碟空間。

若要最佳化資料表,請執行下列命令語法:

mysql> OPTIMIZE TABLE <tablename>;

或者,您也可以執行下列命令來重新建置資料表:

mysql> ALTER TABLE <table_name> ENGINE=INNODB;

二進位日誌

如果您在 Amazon RDS 執行個體上啟用自動備份,則資料庫執行個體上也會自動啟動二進位日誌。這些二進位日誌儲存在磁碟上,會消耗儲存空間,但在每個二進位日誌保留組態時都會清除。執行個體的預設資料庫保留值也設定為 "Null",這意味著檔案會立即移除。

為避免儲存空間不足的問題,請在 Amazon RDS for MySQL 中設定適當的二進位日誌保留期間。您可以使用 mysql.rds_show_configuration 命令語法查看二進位日誌保留的小時數:

CALL mysql.rds_show_configuration;

您也可以減少此值以保留日誌更短時間,以便減少日誌使用的空間量。值為 NULL 表示日誌會盡快清除。如果作用中執行個體有待命執行個體,請監控待命執行個體上的 ReplicaLag 指標。ReplicaLag 指標表示在作用中執行個體上進行二進位日誌處理期間發生的任何延遲或待命執行個體上的轉送日誌。

如果作用中執行個體有待命執行個體,請監控待命執行個體上的 ReplicaLag 指標。ReplicaLag 指標表示作用中執行個體上的二進位日誌清除期間的任何延遲,以及待命執行個體上的轉送日誌。如果出現清除或複製問題,則這些二進位日誌可能會隨著時間的推移而積累,消耗額外的磁碟空間。若要檢查執行個體上的二進位日誌數和檔案大小,請使用 SHOW BINARY LOGS 命令。如需詳細資訊,請參閱 MySQL 網站上的 SHOW BINARY LOGS 陳述式

如果資料庫執行個體作為複本待命執行個體,請使用下列命令檢查轉送日誌 (Relay_Log_Space) 值的大小:

SHOW SLAVE STATUS\G

MySQL 日誌 (一般日誌、慢速查詢日誌和錯誤日誌)

Amazon RDS for MySQL 提供日誌 (例如一般日誌、慢速查詢日誌和錯誤日誌),可用於監控您的資料庫。依預設,錯誤日誌處於作用中狀態。但是,可以使用 RDS 執行個體上的自訂參數群組來啟用一般日誌和慢速查詢日誌。慢速查詢日誌和一般日誌在啟用後,會自動儲存在 MySQL 資料庫內的 slow_loggeneral_log 資料表中。若要檢查任何慢速查詢、一般日誌 ("FILE" 類型) 和錯誤日誌的大小,請檢視並列出資料庫日誌檔案

如果慢速查詢日誌和一般日誌資料表使用過多的儲存空間,請手動旋轉日誌資料表來管理資料表型 MySQL 日誌。若要完全移除舊資料並回收磁碟空間,請連續呼叫下列命令兩次:

mysql> CALL mysql.rds_rotate_slow_log;
mysql> CALL mysql.rds_rotate_general_log;

**注意:**資料表不提供日誌的準確檔案大小。修改參數,使 slow_loggeneral_loglog_output 值為「檔案」而非「資料表」。

使用 Amazon CloudWatch 監控 Amazon RDS 資料庫執行個體也是最佳實務。您可以在 FreeStorageSpace 指標上設定 CloudWatch 警示,以在儲存空間低於特定臨界值時接收提醒。最後,設定 CloudWatch 警示來監控 FreeStorageSpace 指標,以在資料庫執行個體空間不足時接收通知。如需詳細資訊,請請參閱如何建立 CloudWatch 警示來監控 Amazon RDS 可用的儲存空間,並防止儲存空間已滿的問題?

此外,您也可以使用 Amazon RDS 儲存自動擴展功能來自動管理容量。使用儲存自動擴展功能,您無需手動向上擴展資料庫儲存空間。如需有關 Amazon RDS 儲存自動擴展的詳細資訊,請參閱使用 Amazon RDS 資料庫執行個體的儲存空間


相關資訊

如何解決使用比預期更多儲存空間的 Amazon RDS for MySQL DB 資料庫執行個體的問題?

AWS 官方
AWS 官方已更新 2 年前