

# バキューム処理によるストレージ容量の再利用
<a name="limitless-vacuum"></a>

PostgreSQL のマルチバージョン同時実行制御 (MVCC) は、トランザクションがコミットまたはロールバックされるまで、更新または削除された行の内部コピーを保存することで、データの整合性を維持するのに役立ちます。これらのコピーは*タプル*とも呼ばれ、定期的にクリーンアップしないとテーブルが肥大化する原因となります。PostgreSQL インスタンスはトランザクション ID でトランザクションを順序付けます。PostgreSQL はトランザクション ID ベースの MVCC を使用してタプルの可視性を制御し、トランザクションを分離します。各トランザクションはデータのスナップショットを確立し、各タプルにはバージョンがあります。スナップショットとバージョンはどちらもトランザクション ID ベースです。

データをクリーンアップするために、`VACUUM` ユーティリティは PostgreSQL で 4 つの主な関数を実行します。
+ `VACUUM` – 期限切れの行バージョンを削除し、スペースを再利用できるようにします。
+ `VACUUM FULL` – デッド行バージョンを削除してテーブルを圧縮することで、完全なデフラグメンテーションを実現し、サイズを縮小して効率を向上させます。
+ `VACUUM FREEZE` – 古い行バージョンをフリーズとしてマークすることで、トランザクション ID の循環の問題から保護します。
+ `VACUUM ANALYZE` – デッド行バージョンを削除し、データベースのクエリ計画統計を更新します。これは、`VACUUM` 関数と `ANALYZE` 関数の組み合わせです。Aurora PostgreSQL Limitless Database での `ANALYZE` 処理の仕組みの詳細については、「[ANALYZE](limitless-reference.DML-limitations.md#limitless-reference.DML-limitations.ANALYZE)」を参照してください。

 MVCC と同様に、Aurora PostgreSQL でのバキューム処理はトランザクション ID ベースです。バキュームの開始時に進行中のトランザクションがある場合、そのトランザクションに表示されている行は削除されません。

`VACUUM` ユーティリティの詳細については、PostgreSQL ドキュメントの「[VACUUM](https://www.postgresql.org/docs/current/sql-vacuum.html)」を参照してください。Aurora PostgreSQL Limitless Database での `VACUUM` のサポートの詳細については、「[VACUUM](limitless-reference.DML-limitations.md#limitless-reference.DML-limitations.VACUUM)」を参照してください。

**Topics**
+ [AUTOVACUUM](#limitless-autovacuum)
+ [Aurora PostgreSQL Limitless Database での時間ベースのバキューム処理](#limitless-vacuum.time-based)
+ [データベース統計を使用したバキューム処理](#limitless-vacuum.stats)
+ [Aurora PostgreSQL と Aurora PostgreSQL Limitless Database のバキューム動作の違い](#limitless-vacuum-limitations)

## AUTOVACUUM
<a name="limitless-autovacuum"></a>

Aurora PostgreSQL は、`VACUUM` および `AUTOVACUUM` ユーティリティを使用して不要なタプルを削除します。`AUTOVACUUM` と手動 `VACUUM` の基盤となるメカニズムは同じです。唯一の違いは自動化です。

Aurora PostgreSQL および Aurora PostgreSQL Limitless Database の `AUTOVACUUM` は、`VACUUM` と `ANALYZE` ユーティリティの組み合わせです。`AUTOVACUUM` は、デッドタプルの割合や挿入数など、事前定義されたルールに従って、クリーンアップするデータベースとテーブルを決定します。

例えば、`AUTOVACUUM` は定期的に「ウェイクアップ」してクリーンアップを実行します。この間隔は、`autovacuum_naptime` パラメータで制御されます。デフォルト値は 1 分です。Aurora PostgreSQL Limitless Database の `AUTOVACUUM` および `VACUUM` 設定パラメータのデフォルト値は、Aurora PostgreSQL と同じです。

`AUTOVACUUM` デーモンが有効になっている場合、テーブルの内容が一定以上変更されるたびに自動的に `ANALYZE` コマンドを発行します。Aurora PostgreSQL Limitless Databaseでは、`AUTOVACUUM` はルーターとシャードの両方で `ANALYZE` を発行します。

`AUTOVACUUM` に関連付けられている`AUTOVACUUM` デーモンとテーブルストレージパラメータの詳細については、PostgreSQL ドキュメントの「[The autovacuum daemon](https://www.postgresql.org/docs/current/routine-vacuuming.html#AUTOVACUUM )」と「[Storage parameters](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html)」を参照してください。

## Aurora PostgreSQL Limitless Database での時間ベースのバキューム処理
<a name="limitless-vacuum.time-based"></a>

Aurora PostgreSQL Limitless Database は分散システムです。つまり、トランザクションに複数のインスタンスが関与する可能性があります。したがって、トランザクション ID ベースの可視性は適用されません。代わりに、Aurora PostgreSQL Limitless Database は*時間ベースの*可視性を使用します。トランザクション ID はインスタンス間で「統一」されませんが、時間はインスタンス間で「統一」できるからです。各トランザクションスナップショットと各タプルバージョンは、トランザクション ID ではなく時刻に従います。具体的には、トランザクションスナップショットにはスナップショットの開始時刻があり、タプルには作成時刻 (`INSERT` または `UPDATE` が発生した時刻) と削除時刻 (`DELETE` が発生した時刻) があります。

DB シャードグループ内のインスタンス間でデータ整合性を維持するために、Aurora PostgreSQL Limitless Database は、DB シャードグループ内のアクティブなトランザクションに表示されているタプルがバキューム処理によって削除されないようにする必要があります。したがって、Aurora PostgreSQL Limitless Database でのバキューム処理も時間ベースです。`VACUUM` のその他の側面は同じです。例えば、特定のテーブルで `VACUUM` を実行するには、ユーザーがそのテーブルにアクセスできる必要があります。

**注記**  
長時間トランザクションを開いたままにしないことを強くお勧めします。  
時間ベースのバキューム処理は、トランザクション ID ベースのバキューム処理よりも多くのメモリを消費します。

次の例は、時間ベースのバキューム処理の仕組みを示しています。

1. 顧客テーブルは 4 つのシャードに分散されています。

1. トランザクション 1 は繰り返し可能な読み取りで始まり、1 つのシャード (シャード 1) のみをターゲットとします。このトランザクションは開いたままです。

   トランザクション 1 は、その後に開始された他のトランザクションよりも古くなります。

1. トランザクション 2 が後で開始され、テーブルからすべてのタプルを削除してからコミットします。

1. `AUTOVACUUM` または手動 `VACUUM` がデッドタプルをクリーンアップしようとすると (トランザクション 2 によってデッド)、何も削除されません。

   これはシャード 1 だけでなく、シャード 2～4 にも当てはまります。トランザクション 1 が引き続きこれらのタプルにアクセスする必要がある可能性があるためです。MVCC のため、これらのタプルはトランザクション 1 に引き続き表示されます。

最後のステップは同期によって達成されます。これにより、トランザクション 1 はすべてのシャードに認識されますが、トランザクション 1 はすべてのシャードにアクセスするわけではありません。

## データベース統計を使用したバキューム処理
<a name="limitless-vacuum.stats"></a>

クリーンアップが必要なタプルに関する情報を取得するには、[pg\_stat\_all\_tables](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW) と同様に機能する [limitless\_stat\_all\_tables](limitless-monitoring-views.md#limitless_stat_all_tables) ビューを使用します。次の例では、ビューをクエリします。

```
SELECT * FROM rds_aurora.limitless_stat_all_tables WHERE relname LIKE '%customer%';
```

同様に、データベース統計には [pg\_stat\_database](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW) の代わりに [limitless\_stat\_database](limitless-monitoring-views.md#limitless_stat_database) を、[pg\_stat\_activity](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW) の代わりに [limitless\_stat\_activity](limitless-monitoring-views.md#limitless_stat_activity) を使用します。

テーブルのディスク使用量を確認するには、[pg\_relation\_size](https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT) と同様に機能する [limitless\_stat\_relation\_sizes](limitless-monitoring-functions.md#limitless_stat_relation_sizes) 関数を使用します。次の例では、関数をクエリします。

```
SELECT * FROM rds_aurora.limitless_stat_relation_sizes('public','customer');
```

Aurora PostgreSQL Limitless Database で `VACUUM` オペレーションの進行状況を追跡するには、[pg\_stat\_progress\_vacuum](https://www.postgresql.org/docs/15/progress-reporting.html#VACUUM-PROGRESS-REPORTING) の代わりに [limitless\_stat\_progress\_vacuum](limitless-monitoring-views.md#limitless_stat_progress_vacuum) ビューを使用します。次の例では、ビューをクエリします。

```
SELECT * FROM rds_aurora.limitless_stat_progress_vacuum;
```

詳細については、[Aurora PostgreSQL Limitless Database ビュー](limitless-monitoring-views.md)および[Aurora PostgreSQL Limitless Database 関数](limitless-monitoring-functions.md)を参照してください。

## Aurora PostgreSQL と Aurora PostgreSQL Limitless Database のバキューム動作の違い
<a name="limitless-vacuum-limitations"></a>

Aurora PostgreSQL と Aurora PostgreSQL Limitless Database のバキューム処理の動作には、他に以下のような違いがあります。
+ Aurora PostgreSQL は、最も古い進行中のトランザクションまでのトランザクション ID に対して `VACUUM` オペレーションを実行します。データベースに進行中のトランザクションがない場合、`VACUUM` は最後のトランザクションまでオペレーションを実行します。
+ Aurora PostgreSQL Limitless Database は、最も古い時間のスナップショットを 10 秒ごとに同期します。そのため、`VACUUM` は過去 10 秒以内に実行されたトランザクションに対してオペレーションを実行しない可能性があります。

Aurora PostgreSQL Limitless Database での `VACUUM` のサポートの詳細については、「[Aurora PostgreSQL Limitless Database リファレンスLimitless Database リファレンス](limitless-reference.md)」の「[VACUUM](limitless-reference.DML-limitations.md#limitless-reference.DML-limitations.VACUUM)」を参照してください。