

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 了解具有無效資料庫的自動清空行為
<a name="appendix.postgresql.commondbatasks.autovacuumbehavior"></a>

 系統會將新值 `-2` 引入 `pg_database` 目錄中的 `datconnlimit` 欄，以指出在 DROP DATABASE 操作中間中斷的資料庫無效。

 此新值可從下列 RDS for PostgreSQL 版本取得：
+ 15.4 版和所有更新版本
+ 14.9 和更新版本
+ 13.12 和更新版本
+ 12.16 和更新版本
+ 11.21 和更新版本

無效的資料庫不會影響自動清空凍結有效資料庫功能的能力。自動清空會忽略無效的資料庫。因此，定期清空操作將繼續對 PostgreSQL 環境中的所有有效資料庫正常運作且有效率地運作。

**Topics**
+ [監控交易 ID](#appendix.postgresql.commondbatasks.autovacuum.monitorxid)
+ [調整監控查詢](#appendix.postgresql.commondbatasks.autovacuum.monitoradjust)
+ [解決無效的資料庫問題](#appendix.postgresql.commondbatasks.autovacuum.connissue)

## 監控交易 ID
<a name="appendix.postgresql.commondbatasks.autovacuum.monitorxid"></a>

 `age(datfrozenxid)` 函數通常用於監控資料庫的交易 ID (XID) 存留期，以防止交易 ID 包圍。

 由於自動清空會排除無效的資料庫，因此其交易 ID (XID) 計數器可以達到 `2 billion` 的最大值、包裝至 `- 2 billion`，並無限期地繼續此週期。用於監控交易 ID 包圍的典型查詢可能如下所示：

```
SELECT max(age(datfrozenxid)) FROM pg_database;
```

不過，隨著引入 `datconnlimit` 的 -2 值，無效的資料庫可能會扭曲此查詢的結果。由於這些資料庫無效，且不應成為定期維護檢查的一部分，因此可能會導致誤報，造成您認為 `age(datfrozenxid)` 高於實際值。

## 調整監控查詢
<a name="appendix.postgresql.commondbatasks.autovacuum.monitoradjust"></a>

 為了確保準確的監控，您應該調整監控查詢以排除無效的資料庫。遵循以下建議的查詢：

```
SELECT
    max(age(datfrozenxid))
FROM
    pg_database
WHERE
    datconnlimit <> -2;
```

此查詢可確保 `age(datfrozenxid)` 計算中只會考慮有效的資料庫，以提供 PostgreSQL 環境中交易 ID 存留期的真實反映。

## 解決無效的資料庫問題
<a name="appendix.postgresql.commondbatasks.autovacuum.connissue"></a>

 嘗試連線至無效的資料庫時，您可能會遇到類似以下的錯誤訊息：

```
postgres=> \c db1
connection to server at "mydb.xxxxxxxxxx.us-west-2.rds.amazonaws.com" (xx.xx.xx.xxx), port xxxx failed: FATAL:  cannot connect to invalid database "db1"
HINT:  Use DROP DATABASE to drop invalid databases.
Previous connection kept
```

 此外，如果 `log_min_messages` 參數設定為 `DEBUG2` 或更高版本，您可能會注意到下列日誌項目，指出自動清空程序正在略過無效的資料庫：

```
       
2024-07-30 05:59:00 UTC::@:[32000]:DEBUG:  autovacuum: skipping invalid database "db6"
2024-07-30 05:59:00 UTC::@:[32000]:DEBUG:  autovacuum: skipping invalid database "db1"
```

若要解決問題，請遵循連線嘗試期間提供的 `HINT`。使用 RDS 主帳戶或具有 `rds_superuser` 角色的資料庫帳戶 (RDS 主帳戶) 連線到任何有效的資料庫，並捨棄無效的資料庫。

```
SELECT
    'DROP DATABASE ' || quote_ident(datname) || ';'
FROM
    pg_database
WHERE
    datconnlimit = -2 \gexec
```