Knowledge Center Monthly Newsletter - March 2025
Stay up to date with the latest from the Knowledge Center. See all new and updated Knowledge Center articles published in the last month and re:Post’s top contributors.
為什麼我在 Amazon RDS for PostgreSQL 上收到「裝置上沒有剩餘空間」或「DiskFull」錯誤?
我擁有適用於 PostgreSQL 資料庫的 Amazon Relational Database Service (Amazon RDS)。資料庫執行個體的可用儲存空間正在減少,我收到下列錯誤: 「錯誤訊息: PG::DiskFull: 錯誤:無法延伸檔案 "base/16394/5139755": 裝置上沒有剩餘空間。提示: 檢查可用的磁碟空間。」
解決方法
**注意:**當您的工作負載可預測時,接著啟用執行個體的儲存空間自動擴展功能。透過儲存體自動擴展功能,Amazon RDS 可在可用資料庫空間不足時自動擴展儲存空間。
若要監控儲存空間,請檢查 FreeStorageSpace Amazon CloudWatch 指標。為可用儲存空間設定 CloudWatch 警示後,您會在空間開始減少時收到通知。如果收到警示,請檢查下列使用 Amazon RDS 資料庫執行個體儲存空間的資源:
- 由 PostgreSQL 交易建立的暫存資料表或檔案
- 資料檔案
- 預先寫入日誌 (WAL)
- 複寫插槽
- 保留時間過長的資料庫日誌 (例如錯誤檔案)
- 支援 RDS 資料庫執行個體一致狀態的其他資料庫或 Linux 檔案
如果您的資料庫執行個體消耗的儲存空間超過預期,請執行下列疑難排解動作。
檢查資料庫日誌檔案的大小
依預設,Amazon RDS for PostgreSQL 錯誤日誌的保留值為 4,320 分鐘 (三天)。由於大型日誌的工作負載較高或日誌過多,因此所以可能會使用更多空間。若要變更系統日誌保留期,請使用與資料庫執行個體相關聯的資料庫參數群組中的 rds.log_retention_period 參數。例如,如果您將值設定為 1,440,Amazon RDS 會保留日誌一天。如需詳細資訊,請參閱 RDS for PostgreSQL 資料庫日誌檔案。
若要減少過多的日誌,請變更資料庫參數群組中的錯誤報告和日誌參數。此動作會導致日誌檔案大小縮小。如需詳細資訊,請參閱 PostgreSQL 網站上的 19.8 錯誤報告和日誌記錄。
檢查暫存檔案
暫存檔案是 Amazon RDS 儲存在每個後端或工作階段連線中的檔案。Amazon RDS 使用這些檔案作為資源集區。若要檢閱暫存檔案統計資料,請執行下列命令:
psql=> SELECT datname, temp_files AS "Temporary files",temp_bytes AS "Size of temporary files" FROM pg_stat_database ;
**重要:**在 pg_stat_database 檢視收集彙整統計資料中的 temp_files 及 temp_bytes 資料欄。Amazon RDS 僅在立即關機、伺服器當機或時間點復原 (PITR) 後才會重設這些計數器。因此,最佳實務是監控這些檔案的數量和大小變化,而不是僅檢視輸出。
Amazon RDS 會為排序、雜湊和暫存查詢結果建立暫時檔案。若要追蹤暫存資料表或檔案的建立作業,請在自訂參數群組中,將 log_temp_files 設定為 0 以記錄所有暫存檔案資訊。log_temp_files 預設會設定為 -1,因此 Amazon RDS 不會記錄暫存檔案。如果將 log_temp_files 設定為正值,則 Amazon RDS 只會記錄等於或大於該千位元組數的檔案。
在查詢中使用 EXPLAIN ANALYZE 來檢閱磁碟排序。在日誌輸出中,檢查查詢建立的暫存檔案的大小。如需詳細資訊,請參閱使用 work_mem 調整 PostgreSQL 中的排序操作。
檢查交易日誌磁碟使用量是否持續增加
檢查TransactionLogsDiskUsage 指標以檢視交易 WAL 所使用的磁碟空間。交易日誌磁碟使用量可能會因下列原因而增加:
- 產生額外的 WAL 的寫入和更新作業的較高資料庫負載
- 相同 AWS 區域中的複本之串流讀取複本延遲,或讀取複本處於儲存空間已滿狀態
- 複寫插槽
AWS Database Migration Service (AWS DMS) 會將複寫插槽建立為邏輯解碼的一部分。對於邏輯複寫,插槽參數 rds.logical_replication 會設為 1。複寫插槽會保留 WAL 檔案,直到外部取用者消耗檔案為止。範例取用者包括 pg_recvlogic、擷取、轉換和載入 (ETL) 工作,以及 AWS DMS。
如果您將 rds.logical_replication 參數值設為 1,則 Amazon RDS 會設定wal_level、max_wal_senders、max_replication_slots 和 max_connections 參數。這些參數變更可能會增加 WAL 的產生。最佳實務為僅在使用邏輯插槽時才設定 rds.logical_replication 參數。如果沒有保留的 WAL 檔案的取用者,則交易日誌磁碟使用量會增加,而可用的儲存空間會持續減少。
若要檢查複寫插槽的顯示狀態和大小,請執行下列查詢:
-
PostgreSQL 第 9 版:
psql=> SELECT slot_name, pg_size_pretty(pg_xlog_location_diff(pg_current_xlog_location(),restart_lsn)) AS replicationSlotLag, active FROM pg_replication_slots ;
-
PostgreSQL 第 10 版及更新版本:
psql=> SELECT slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(),restart_lsn)) AS replicationSlotLag, active FROM pg_replication_slots ;
範例輸出結果:
slot_name | replicationslotlag | active---------------------------------------------------------------+--------------------+-------- xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d | 129 GB | f 7pajuy7htthd7sqn_00013322_a27bcebf_7d0f_4124_b336_92d0fb9f5130 | 704 MB | t zp2tkfo4ejw3dtlw_00013322_03e77862_689d_41c5_99ba_021c8a3f851a | 624 MB | t
將作用中狀態設定為 f (false) 的複寫插槽不會被耗用。在此範例中,xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d 顯示具有 f 作用中的狀態。此插槽不會主動被使用,而是使用 129 GB 的交易檔案。
若要捨棄未使用的插槽,請執行下列查詢:
psql=> SELECT pg_drop_replication_slot('YOUR_SLOTNAME');
**注意:**使用插槽名稱取代 YOUR_SLOTNAME。
範例輸出結果:
psql=> SELECT pg_drop_replication_slot('xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d');
如果 AWS DMS 任務是取用者且不再需要該任務,則請刪除該任務並手動捨棄複寫插槽。
檢查跨區域或相同區域讀取複本的狀態
**注意:**只有在 PostgreSQL 14.1 或更新版本上執行相同區域讀取複本時,才能使用下列解決方案。
當您使用跨區域或相同區域讀取複寫時,Amazon RDS 會在主要執行個體上建立實體複寫插槽。讀取複本失敗可能會影響主要資料庫執行個體上的儲存空間。當 WAL 檔案未在讀取複本中複製時,就會發生這種情況。檢查 OldestReplicationSlotLag 及 TransactionLogsDiskUsage 指標以確定延遲最多的複本落後於進度的程度。您還可以查看 WAL 資料使用了多少的儲存空間。
若要檢查讀取複本的狀態,請執行下列查詢:
psql=> SELECT * FROM pg_replication_slots;
如需有關 pg_replication_slots 的詳細資訊,請參閱 PostgreSQL 網站上的 52.19 pg_replication_slots。如果輸出具有設為 f 的作用中狀態,則插槽不會用於複寫。
您也可以在來源執行個體上使用 pg_stat_replication 以檢查複寫的統計資料。如需詳細資訊,請參閱 PostgreSQL 網站上的資料表 27.14. pg_stat_replication 檢視。
檢查無效資料列膨脹或不當去除的情形
在標準 PostgreSQL 作業中,PostgreSQL 不會移除使用者刪除的或 UPDATE 從其資料表中停用的無效資料列 (元組)。對於 Multi-Version Concurrency Control (MVCC),當執行 DELETE 作業時,資料列不會立即從資料檔案中移除。反之,PostgreSQL 在標頭中設定 xmax 欄位,以將該資料列標記為已刪除。更新首先標記要刪除的資料列,然後執行插入作業。這可讓您在不同的交易之間以最小鎖定並行。因此,PostgreSQL 會在 MVCC 流程中保留不同的資料列版本。
未清除的無效資料列會保留在資料檔案中,但對交易仍不可見。這些資料列可能會導致磁碟空間問題。如果資料表有許多 DELETE 和 UPDATE 作業,則無效元組可能會使用大量磁碟空間 (膨脹)。
使用 VACUUM 作業可釋放無效元組所使用的儲存空間。請注意,VACUUM 不會將可用儲存空間釋放到檔案系統。若要將儲存空間釋放到檔案系統,請使用 VACUUM FULL。請注意,當您執行 VACUUM FULL 時,PostgreSQL 會將存取專用鎖定套用至資料表。因為 VACUUM FULL 會寫入資料表的新副本,並且不會在作業完成之前釋放現有副本,所以此方法需要額外的磁碟空間。最佳實務為當您必須從資料表回收大量空間時,才會使用 VACUUM FULL。在經常更新的資料表上執行定期 VACUUM 或 AUTOVACUUM 作業,同樣屬於最佳實務。如需詳細資訊,請參閱 PostgreSQL 網站上的 VACUUM。
若要檢查預估的無效元組數量,請使用 pg_stat_all_tables 檢視。如需詳細資訊,請參閱 PostgreSQL 網站上的 資料表 27.29. pg_stat_all_tables 檢視。在下列範例資料表中,n_dead_tup 記錄中有 1,999,952 個無效元組:
psql => SELECT * FROM pg_stat_all_tables WHERE relname='test'; -[ RECORD 1 ]-------+------------------------------ relid | 16395 schemaname | public relname | test seq_scan | 3 seq_tup_read | 5280041 idx_scan | idx_tup_fetch | n_tup_ins | 2000000 n_tup_upd | 0 n_tup_del | 3639911 n_tup_hot_upd | 0 n_live_tup | 1635941 n_dead_tup | 1999952 n_mod_since_analyze | 3999952 last_vacuum | last_autovacuum | 2024-08-16 04:49:52.399546+00 last_analyze | 2024-08-09 09:44:56.208889+00 last_autoanalyze | 2024-08-16 04:50:22.581935+00 vacuum_count | 0 autovacuum_count | 1 analyze_count | 1 autoanalyze_count | 1 psql => VACUUM TEST;
檢查孤立檔案
當沒有物件指向資料庫目錄中存在的檔案時,可能會產生孤立檔案。如果您的執行個體儲存空間不足,或者在 ALTER TABLE、VACUUM FULL 或 CLUSTER 等作業期間發生引擎當機,即可能會發生這種情況。若要檢查是否有孤立檔案,請完成下列步驟:
-
登入每個資料庫中的 PostgreSQL。
-
若要取得資料庫使用的大小,請執行下列查詢:
psql=> SELECT pg_size_pretty(pg_database_size('DATABASE_NAME'));
**注意:**使用您的資料庫名稱取代 DATABASE_NAME。
-
若要取得資料庫的實際大小,請執行下列查詢:
psql=> SELECT pg_size_pretty(SUM(pg_relation_size(oid))) FROM pg_class;
-
從先前命令的輸出來比較資料庫的使用和實際大小。如果差異很大,則孤立檔案可能正在使用儲存空間。
相關資訊

相關內容
- 已提問 1 年前lg...
- 已提問 2 年前lg...
- AWS 官方已更新 3 年前
- AWS 官方已更新 3 個月前