Help us improve the AWS re:Post Knowledge Center by sharing your feedback in a brief survey. Your input can influence how we create and update our content to better support your AWS journey.
為什麼我在 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; -
從先前命令的輸出來比較資料庫的使用和實際大小。如果差異很大,則孤立檔案可能正在使用儲存空間。
相關資訊
相關內容
- 已提問 8 個月前
- 已提問 3 年前

