

# Amazon RDS for PostgreSQL の一般的な DBA タスク
<a name="Appendix.PostgreSQL.CommonDBATasks"></a>

Amazon RDS for PostgreSQL DB インスタンスを管理するときに、データベース管理者 (DBA) は、さまざまなタスクを実行します。すでに PostgreSQL に精通している DBA の場合は、ハードウェア上で PostgreSQL を実行することと RDS for PostgreSQL との重要な違いのいくつかに注意する必要があります。例えば、マネージドサービスであるため、Amazon RDS では DB インスタンスへのシェルアクセスができません。つまり、`pg_hba.conf` および他の設定ファイルに直接アクセスすることはできません。RDS for PostgreSQL の場合、オンプレミスインスタンスの PostgreSQL 設定ファイルに通常加えられる変更は、RDS for PostgreSQL DB インスタンスに関連付けられたカスタム DB パラメータグループに対して行われます。詳細については、「[Amazon RDS のパラメータグループ](USER_WorkingWithParamGroups.md)」を参照してください。

また、オンプレミスの PostgreSQL インスタンスと同じ方法では、ログファイルにアクセスできません。ログ記録の詳細については、「[ RDS for PostgreSQL データベースログファイル](USER_LogAccess.Concepts.PostgreSQL.md)」を参照してください。

別の例としては、PostgreSQL `superuser` アカウントにアクセスできなくなります。RDS for PostgreSQL では、`rds_superuser` ロールが最も高い権限を持つロールであり、設定時に `postgres` に付与されます。オンプレミスで PostgreSQL を使い慣れている場合でも、RDS for PostgreSQL を初めて使用する場合でも、`rds_superuser` ロールについて、およびロール、ユーザー、グループ、アクセス権限の操作方法を理解することをお勧めします。詳細については、「[PostgreSQL のロールとアクセス権限について](Appendix.PostgreSQL.CommonDBATasks.Roles.md)」を参照してください。

RDS for PostgreSQL の一般的な DBA タスクの一部を次に示します。

**Topics**
+ [

# RDS for PostgreSQL でサポートされる照合。
](PostgreSQL-Collations.md)
+ [

# PostgreSQL のロールとアクセス権限について
](Appendix.PostgreSQL.CommonDBATasks.Roles.md)
+ [

# PostgreSQL でのデッド接続の処理
](Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.md)
+ [

# Amazon RDS for PostgreSQL での PostgreSQL 自動バキュームの使用
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md)
+ [

# Amazon RDS for PostgreSQL での高いオブジェクト数の管理
](PostgreSQL.HighObjectCount.md)
+ [

# Amazon RDS for PostgreSQL での TOAST OID 競合の管理
](Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.md)
+ [

## RDS for PostgreSQL でサポートされているログ記録メカニズムの使用
](#Appendix.PostgreSQL.CommonDBATasks.Auditing)
+ [

# PostgreSQL による一時ファイルの管理
](PostgreSQL.ManagingTempFiles.md)
+ [

## pgBadger を使用した PostgreSQL でのログ分析
](#Appendix.PostgreSQL.CommonDBATasks.Badger)
+ [

## PostgreSQL をモニタリングするために PGSnapper を使用する
](#Appendix.PostgreSQL.CommonDBATasks.Snapper)
+ [

# RDS for PostgreSQL でのカスタムキャストの管理
](PostgreSQL.CustomCasts.md)
+ [

# RDS for PostgreSQL での並列クエリのベストプラクティス
](PostgreSQL.ParallelQueries.md)
+ [

# RDS for PostgreSQL DB インスタンスでのパラメータの使用
](Appendix.PostgreSQL.CommonDBATasks.Parameters.md)

# RDS for PostgreSQL でサポートされる照合。
<a name="PostgreSQL-Collations"></a>

照合は、データベースに保存されている文字列をソートして比較する方法を決定する一連のルールです。照合は、コンピュータシステムにおいて基本的な役割を果たし、オペレーティングシステムの一部として組み込まれています。照合は、言語に新しい文字が追加されたり、順序規則が変更されたりすると、時間の経過とともに変化します。

照合ライブラリは、照合の特定のルールとアルゴリズムを定義します。PostgreSQL で使用される最も一般的な照合ライブラリは GNU C (glibc) と Unicode 用の国際化コンポーネント (ICU) です。デフォルトでは、RDS for PostgreSQL は、マルチバイト文字シーケンスの Unicode 文字ソート順序を含む glibc 照合を使用します。

新しい RDS for PostgreSQL の DB インスタンスを作成すると、オペレーティングシステムで使用可能な照合がチェックされます。`CREATE DATABASE` コマンド `LC_COLLATE` および `LC_CTYPE` の PostgreSQL パラメーターは、照合順序を指定するために使用され、そのデータベースのデフォルトの照合となります。または、`CREATE DATABASE` で `LOCALE` パラメータを使用して、これらのパラメータを設定することもできます。これにより、データベース内の文字列のデフォルトの照合と、文字を文字、数字、または記号として分類する規則が決まります。列、インデックス、またはクエリで使用する照合を選択することもできます。

RDS for PostgreSQL は、照合をサポートするためにオペレーティングシステムの glibc ライブラリに依存しています。RDS for PostgreSQL インスタンスは、オペレーティングシステムの最新バージョンで定期的に更新されます。これらのアップデートには glibc ライブラリの新しいバージョンが含まれることがあります。ごくまれに、新しいバージョンの glibc で一部の文字のソート順序や照合順序が変更されるため、データのソート方法が変わったり、無効なインデックスエントリが生成されることがあります。更新中に照合のソート順序の問題が見つかった場合は、インデックスの再構築が必要になることがあります。

glibc の更新による影響を減らすために、RDS for PostgreSQL に独立したデフォルトの照合ライブラリが含まれるようになりました。この照合ライブラリは、RDS for PostgreSQL 14.6、13.9、12.13、11.18、10.23、およびそれ以降のマイナーバージョンリリースで利用できます。glibc 2.26-59.amzn2 と互換性があり、誤ったクエリ結果を防ぐためにソート順序が安定しています。

# PostgreSQL のロールとアクセス権限について
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles"></a>

AWS マネジメントコンソール を使用して RDS for PostgreSQL DB インスタンスを作成すると、管理者アカウントが同時に作成されます。次のスクリーンショットに示すように、デフォルトでは `postgres` という名前になります。

![\[「データベースを作成」ページの認証情報のデフォルトのログイン ID は postgres です。\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/images/default-login-identity-apg-rpg.png)


デフォルト設定 (`postgres`) を受け入れるのではなく、別の名前を選択することもできます。この場合、選択する名前はアルファベットで始まり、1 文字以上 16 文字以下の英数字である必要があります。このガイドでは、わかりやすくするために、このメインユーザーアカウントをデフォルトの値 (`postgres`) で表記しています。

AWS マネジメントコンソール ではなく、`create-db-instance` AWS CLI を使用する場合は、コマンドの `master-username` パラメータと一緒に渡すことで名前を作成します。詳細については、 を参照してください。[Amazon RDS DB インスタンスの作成](USER_CreateDBInstance.md)

AWS マネジメントコンソール、AWS CLI、または Amazon RDS API のいずれを使用する場合でも、またデフォルトの `postgres` 名を使用するか、別の名前を選択するかにかかわらず、この最初のデータベースユーザーアカウントは `rds_superuser` グループのメンバーであり、`rds_superuser` 権限を持つことになります。

**Topics**
+ [

# rds\$1superuser ロールを理解する
](Appendix.PostgreSQL.CommonDBATasks.Roles.rds_superuser.md)
+ [

# PostgreSQL データベースへのユーザーアクセスのコントロール
](Appendix.PostgreSQL.CommonDBATasks.Access.md)
+ [

# ユーザーパスワード管理の委任と制御
](Appendix.PostgreSQL.CommonDBATasks.RestrictPasswordMgmt.md)
+ [

# PostgreSQL のパスワード暗号化に SCRAM を使用する
](PostgreSQL_Password_Encryption_configuration.md)

# rds\$1superuser ロールを理解する
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles.rds_superuser"></a>

PostgreSQL では、*ロール*はデータベース内のさまざまなオブジェクトに対して、ユーザー、グループ、またはグループやユーザーに与えられた特定のアクセス権限を定義することができます。`CREATE USER` と `CREATE GROUP` に対する PostgreSQL コマンドは、データベースユーザーを区別するために、より一般的な、特定のプロパティを持つ `CREATE ROLE` に置き換えられました。データベースユーザーは、LOGIN 権限を持つロールと考えることができます。

**注記**  
`CREATE USER` および `CREATE GROUP` コマンドは引き続き使用できます。詳細については、PostgreSQL のドキュメントの「[データベースロール](https://www.postgresql.org/docs/current/user-manag.html)」セクションを参照してください。

`postgres` ユーザーは、 RDS for PostgreSQL DB インスタンス で最も権限があるデータベースユーザーです。ユーザーには、次の `CREATE ROLE` ステートメントで定義される特性があります。

```
CREATE ROLE postgres WITH LOGIN NOSUPERUSER INHERIT CREATEDB CREATEROLE NOREPLICATION VALID UNTIL 'infinity'
```

特に指定がない限り、プロパティ `NOSUPERUSER`、`NOREPLICATION`、`INHERIT`、および `VALID UNTIL 'infinity'` が CREATE ROLE のデフォルトオプションです。

デフォルトでは、`postgres` には `rds_superuser` ロールに付与された権限と、ロールとデータベースを作成するアクセス許可があります。`rds_superuser` ロールでは、`postgres` ユーザーによる次の操作を許可します。
+ Amazon RDS で使用できる拡張機能の追加 詳細については、「[Amazon RDS for PostgreSQL でサポートされている PostgreSQL の機能を使用する](PostgreSQL.Concepts.General.FeatureSupport.md) 
+ ユーザーのロールを作成し、ユーザーに権限を付与します。詳細については、PostgreSQL のドキュメントの「[CREATE ROLE](https://www.postgresql.org/docs/current/sql-createrole.html)」および「[GRANT](https://www.postgresql.org/docs/14/sql-grant.html)」セクションを参照してください。
+ データベースの作成 詳細については、PostgreSQL のドキュメントの「[CREATE DATABASE](https://www.postgresql.org/docs/14/sql-createdatabase.html)」を参照してください。
+ これらの権限を持たないユーザーロールに対する `rds_superuser` 権限を付与し、必要に応じてそれらの権限を取り消します。このロールは、スーパーユーザータスクを実行するユーザーにのみ付与することをお勧めします。つまり、データベース管理者 (DBA) またはシステム管理者にこのロールを付与できます。
+ `rds_superuser` ロールを持たないデータベースユーザーに `rds_replication` ロールを付与 (または取り消し) します。
+ `rds_superuser` ロールを持たないデータベースユーザーに `rds_password` ロールを付与 (または取り消し) します。
+ `pg_stat_activity` ビューを使用して、すべてのデータベース接続に関するステータス情報を取得します。必要に応じて、`rds_superuser` で `pg_terminate_backend` または `pg_cancel_backend` を使用して接続を停止できます。

`CREATE ROLE postgres...` ステートメントで、`postgres` ユーザーロールは PostgreSQL の `superuser` アクセス許可を特に禁止することがわかります。RDS for PostgreSQL はマネージドサービスのため、ホスト OS へのアクセスや、PostgreSQL `superuser` アカウントを使用した接続はできません。スタンドアロンの PostgreSQL で `superuser` のアクセスが必要な作業の多くは、Amazon RDS で自動的に管理されます。

権限の付与に関する詳細については、PostgreSQL のドキュメントの「[GRANT](http://www.postgresql.org/docs/current/sql-grant.html)」を参照してください。

`rds_superuser` ロールは、におけるいくつかの*事前定義済み*ロールの 1 つです。RDS for PostgreSQL DB インスタンス。

**注記**  
PostgreSQL 13 以前のリリースでは、*定義済み*ロールは*デフォルト*ロールと呼ばれていました。

次のリストに、新しい のために自動的に作成される他の定義済みロールの一部を示します。RDS for PostgreSQL DB インスタンス。定義済みロールとその権限は変更できません。これらの定義済みロールに対して削除、名前の変更、変更を行うことはできません。それらの操作を試みると、エラーが発生します。
+ **rds\$1password** - データベースユーザーのパスワードを変更し、パスワード制約を設定できるロールです。`rds_superuser` ロールにはデフォルトでこのロールが付与され、データベースユーザーにロールを付与できます。詳細については、「[PostgreSQL データベースへのユーザーアクセスのコントロールPostgreSQL へのユーザーアクセスのコントロール](Appendix.PostgreSQL.CommonDBATasks.Access.md)」を参照してください。
  + 14 より前のバージョンの RDS for PostgreSQL の場合、`rds_password` ロールはパスワードを変更し、データベースユーザーと `rds_superuser` ロールを持つユーザーのパスワード制約を設定できます。RDS for PostgreSQL 14 以降のバージョンでは、`rds_password` ロールがユーザーのパスワードを変更し、パスワード制約を設定できるのは、データベースユーザーに対してのみです。`rds_superuser` ロールを持つユーザーのみが、`rds_superuser` ロールを持つ他のユーザーに対して上記のアクションを実行できます。
+ **rdsadmin** - `superuser` 権限を持つ管理者がスタンドアロンの PostgreSQL データベースで行う管理タスクの多くを処理するために作成されるロールです。このロールは、RDS for PostgreSQL によって多くの管理タスクのために内部的に使用されます。
+ **rdstopmgr** - マルチ AZ 配置をサポートするために Amazon RDS によって内部的に使用されるロールです。
+ **rds\$1reserved** – データベース接続を予約するために Amazon RDS によって内部的に使用されるロール。

# ロールとその権限の表示
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles.View"></a>

PostgreSQL バージョン別に異なるコマンドを使用して、RDS for PostgreSQL DB インスタンスで事前定義されたロールとその権限を表示できます。事前定義されたロールをすべて表示するには、RDS for PostgreSQL DB インスタンスに接続し、`psql` を使用して以下のコマンドを実行します。

**`psql` バージョン 15 以前の場合**

RDS for PostgreSQL DB インスタンスに接続し、psql で `\du` コマンドを使用します。

```
postgres=> \du
                                                               List of roles
    Role name    |                         Attributes                         |                          Member of
-----------------+------------------------------------------------------------+------------------------------------------------------
 postgres        | Create role, Create DB                                    +| {rds_superuser}
                 | Password valid until infinity                              |
 rds_ad          | Cannot login                                               | {}
 rds_iam         | Cannot login                                               | {}
 rds_password    | Cannot login                                               | {}
 rds_replication | Cannot login                                               | {}
 rds_superuser   | Cannot login                                               | {pg_monitor,pg_signal_backend,rds_password,rds_replication}
 rdsadmin        | Superuser, Create role, Create DB, Replication, Bypass RLS+| {}
                 | Password valid until infinity                              |
```

**`psql` バージョン 16 以降の場合**

```
postgres=> \drg+
                             List of role grants
   Role name   |          Member of          |       Options       | Grantor
---------------+-----------------------------+---------------------+----------
 postgres      | rds_superuser               | INHERIT, SET        | rdsadmin
 rds_superuser | pg_checkpoint               | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_monitor                  | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_signal_backend           | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_use_reserved_connections | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | rds_password                | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | rds_replication             | ADMIN, INHERIT, SET | rdsadmin
```

バージョンに関係なくロールのメンバーシップを確認するには、次の SQL クエリを使用できます。

```
SELECT m.rolname AS "Role name", r.rolname AS "Member of"
FROM pg_catalog.pg_roles m
JOIN pg_catalog.pg_auth_members pam ON (pam.member = m.oid)
LEFT JOIN pg_catalog.pg_roles r ON (pam.roleid = r.oid)
LEFT JOIN pg_catalog.pg_roles g ON (pam.grantor = g.oid)
WHERE m.rolname !~ '^pg_'
ORDER BY 1, 2;
```

出力では、`rds_superuser` がデータベースユーザーロールではない (ログインできない) が、他の多くのロールの特権を持っていることがわかります。また、そのデータベースユーザー `postgres` は `rds_superuser` ロールのメンバーであることも確認できます。前述のように、`postgres` が Amazon RDS コンソールの **[Create database]** (データベースを作成) ページのデフォルト値です。別の名前を選択した場合、代わりにその名前がロールのリストに表示されます。

# PostgreSQL データベースへのユーザーアクセスのコントロール
<a name="Appendix.PostgreSQL.CommonDBATasks.Access"></a>

PostgreSQL の新しいデータベースは、常にデータベースの `public` スキーマに、すべてのデータベースユーザーとロールがオブジェクトを作成できるようなデフォルトの権限セットで作成されます。これらの権限により、例えば、データベースユーザーがデータベースに接続し、接続しながら一時テーブルを作成することができます。

 RDS for PostgreSQL DB インスタンスに作成するデータベースインスタンスへのユーザーアクセスをよりよく制御するために、これらのデフォルトの `public` 権限を取り消すことを推奨します。その後、次の手順で示すように、データベースのユーザーに特定の権限をより詳細に付与します。

**新しいデータベースインスタンスのロールと権限を設定するには**

全員がデータベースへの読み取り/書き込みアクセスを必要とする複数の研究者が使用するために、新しく作成された RDS for PostgreSQL DB インスタンス上にデータベースをセットアップしているとします。

1. `psql` (または pgAdmin) を使用して、 RDS for PostgreSQL DB インスタンスに接続します。

   ```
   psql --host=your-db-instance.666666666666.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

   プロンプトが表示されたら、パスワードを入力します。`psql` クライアントが接続し、プロンプトとしてデフォルトの管理用接続データベースである `postgres=>` を表示します。

1. データベースユーザーが `public` スキーマでオブジェクトを作成できないようにするには、次の操作を行います。

   ```
   postgres=> REVOKE CREATE ON SCHEMA public FROM PUBLIC;
   REVOKE
   ```

1. 次に、新しいデータベースインスタンスを作成します。

   ```
   postgres=> CREATE DATABASE lab_db;
   CREATE DATABASE
   ```

1. この新しいデータベースの `PUBLIC` スキーマからすべての権限を取り消します。

   ```
   postgres=> REVOKE ALL ON DATABASE lab_db FROM public;
   REVOKE
   ```

1. データベースユーザーのロールを作成します。

   ```
   postgres=> CREATE ROLE lab_tech;
   CREATE ROLE
   ```

1. このロールを持つデータベースユーザーに、データベースに接続する機能を付与します。

   ```
   postgres=> GRANT CONNECT ON DATABASE lab_db TO lab_tech;
   GRANT
   ```

1. `lab_tech` ロールを持つすべてのユーザーに、このデータベースのすべての権限を付与します。

   ```
   postgres=> GRANT ALL PRIVILEGES ON DATABASE lab_db TO lab_tech;
   GRANT
   ```

1. 次のように、データベースユーザーを作成します。

   ```
   postgres=> CREATE ROLE lab_user1 LOGIN PASSWORD 'change_me';
   CREATE ROLE
   postgres=> CREATE ROLE lab_user2 LOGIN PASSWORD 'change_me';
   CREATE ROLE
   ```

1. これら 2 人のユーザーに lab\$1tech ロールに関連付けられた権限を付与します。

   ```
   postgres=> GRANT lab_tech TO lab_user1;
   GRANT ROLE
   postgres=> GRANT lab_tech TO lab_user2;
   GRANT ROLE
   ```

この時点で、`lab_user1` と `lab_user2` は `lab_db` データベースに接続できます。この例は、複数のデータベースインスタンスの作成、異なるスキーマの作成、制限されたアクセス許可の付与などを含む、エンタープライズで使用するためのベストプラクティスに従ったものではありません。詳細な情報と追加のシナリオについては、「[PostgreSQL ユーザーとロールの管理](https://aws.amazon.com/blogs//database/managing-postgresql-users-and-roles/)」を参照してください。

PostgreSQL データベースでの権限の詳細については、PostgreSQL のドキュメントの [GRANT](https://www.postgresql.org/docs/current/static/sql-grant.html) コマンドを参照してください。

# ユーザーパスワード管理の委任と制御
<a name="Appendix.PostgreSQL.CommonDBATasks.RestrictPasswordMgmt"></a>

DBA は、ユーザーパスワードの管理を委任する場合があります。または、データベースユーザーがパスワードを変更したり、パスワードの有効期間などのパスワード制約を再設定したりしないようにする場合もあります。選択したデータベースユーザーのみがパスワード設定を変更できるようにするには、制限されたパスワード管理の機能をオンにします。この機能をアクティブにすると、`rds_password` ロールを付与されたデータベースユーザーのみがパスワードを管理できます。

**注記**  
制限されたパスワード管理を使用するには、RDS for PostgreSQL DB インスタンス PostgreSQL 10.6 以上を実行している必要があります。

次に示すように、デフォルトではこの機能は `off` になっています。

```
postgres=> SHOW rds.restrict_password_commands;
  rds.restrict_password_commands
--------------------------------
 off
(1 row)
```

この機能をオンにするには、カスタムパラメータグループを使用して、`rds.restrict_password_commands` の設定を 1 に変更します。設定を有効にするには、 RDS for PostgreSQL DB インスタンスを必ず再起動してください。

この機能をアクティブにすると、次の SQL コマンドには `rds_password` 権限が必要になります。

```
CREATE ROLE myrole WITH PASSWORD 'mypassword';
CREATE ROLE myrole WITH PASSWORD 'mypassword' VALID UNTIL '2023-01-01';
ALTER ROLE myrole WITH PASSWORD 'mypassword' VALID UNTIL '2023-01-01';
ALTER ROLE myrole WITH PASSWORD 'mypassword';
ALTER ROLE myrole VALID UNTIL '2023-01-01';
ALTER ROLE myrole RENAME TO myrole2;
```

ロールの名前の変更 (`ALTER ROLE myrole RENAME TO newname`) は、パスワードが MD5 ハッシュアルゴリズムを使用する場合にも制限されます。

この機能が有効な場合、`rds_password` ロールのアクセス許可なしでこれらの SQL コマンドの実行を試みると、次のエラーが発生します。

```
ERROR: must be a member of rds_password to alter passwords
```

`rds_password` は、パスワード管理専用の少数のロールにのみ付与することをお勧めします。`rds_superuser` 権限を持たないデータベースユーザーに `rds_password` 権限を付与する場合は、`CREATEROLE` 属性も付与する必要があります。

パスワード要件 (クライアント側の有効期限や必要な複雑さなど) を確認してください。パスワード関連の変更に独自のクライアント側ユーティリティを使用する場合、そのユーティリティは `rds_password` のメンバーであり、`CREATE ROLE` 権限を持つ必要があります。

# PostgreSQL のパスワード暗号化に SCRAM を使用する
<a name="PostgreSQL_Password_Encryption_configuration"></a>

*SCRAM (Salted Challenge Response Authentication Mechanism)* は、パスワードを暗号化するための PostgreSQL のデフォルトのメッセージダイジェスト (MD5) アルゴリズムの代替手段です。SCRAM 認証メカニズムは MD5 よりも安全であると見なされます。これら 2 つの異なるパスワードを保護する方法の詳細については、PostgreSQL のドキュメントの「[パスワード認証](https://www.postgresql.org/docs/14/auth-password.html)」を参照してください。

に対しては、パスワード暗号化方式として MD5 ではなく SCRAM を使用することをお勧めします。RDS for PostgreSQL DB インスタンス。これは、パスワード認証と暗号化のために scram-sha-256 アルゴリズムを使用する暗号化チャレンジレスポンスのメカニズムです。

SCRAM をサポートするために、クライアントアプリケーションのライブラリを更新する必要があります。例えば、42.2.0 より前の JDBC バージョンで SCRAM はサポートされていません。詳細については、PostgreSQL JDBC ドライバーのドキュメントの「[PostgreSQL JDBC ドライバー](https://jdbc.postgresql.org/changelogs/2018-01-17-42.2.0-release/)」を参照してください。その他の PostgreSQL ドライバーおよび SCRAM サポートの一覧については、PostgreSQL のドキュメントの「[ドライバーの一覧](https://wiki.postgresql.org/wiki/List_of_drivers)」を参照してください。

RDS for PostgreSQL 13.1 以降のバージョンは scram-sha-256 をサポートします。これらのバージョンでは、次の手順で説明するように、DB インスタンスに SCRAM を要求するように設定することもできます。

## SCRAM を要求するために RDS for PostgreSQL DB インスタンスを設定する
<a name="PostgreSQL_Password_Encryption_configuration.preliminary"></a>

では、scram-sha-256 アルゴリズムを使用するパスワードのみを受け入れるために、に RDS for PostgreSQL DB インスタンスを要求できます。

**重要**  
PostgreSQL データベースを使用する既存の RDS プロキシでは、`SCRAM` のみを使用するようにデータベース認証を変更すると、プロキシは最大 60 秒間使用できなくなります。この問題を回避するには、以下のいずれかの方法で対応します。  
データベースが `SCRAM` と `MD5` 認証の両方を許可していることを確認します。
`SCRAM` 認証のみを使用するには、新しいプロキシを作成し、アプリケーショントラフィックを新しいプロキシに移行してから、以前にデータベースに関連付けられていたプロキシを削除します。

システムに変更を加える前に、次の完全なプロセスを理解していることを確認してください。
+ すべてのデータベースユーザーのすべてのロールとパスワードの暗号化に関する情報を取得します。
+ パスワードの暗号化を制御するパラメータを指定するために、 RDS for PostgreSQL DB インスタンスのパラメータ設定を再確認してください。
+  RDS for PostgreSQL DB インスタンスでデフォルトのパラメータグループを使用する場合は、カスタムの DB パラメータグループを作成して、それを RDS for PostgreSQL DB インスタンスに適用し、必要なときにパラメータを変更できるようにする必要があります。 RDS for PostgreSQL DB インスタンスがカスタムパラメータグループを使用している場合、必要に応じて、プロセスの後で必要なパラメータを変更できます。
+ `password_encryption` パラメータを `scram-sha-256` に変更します。
+ パスワードを更新する必要があることをすべてのデータベースユーザーに通知します。`postgres` アカウントに同じ操作を行います。新しいパスワードは暗号化され、scram-sha-256 アルゴリズムを使用して保存されます。
+ 暗号化の種類を使用して、すべてのパスワードが暗号化されていることを確認します。
+ すべてのパスワードで scram-sha-256 が使用されている場合、`rds.accepted_password_auth_method` パラメータを `md5+scram` から `scram-sha-256` に変更できます。

**警告**  
`rds.accepted_password_auth_method` を scram-sha-256 のみに変更した後、`md5` で暗号化されたパスワードを持つすべてのユーザー (ロール) は接続できなくなります。

### RDS for PostgreSQL DB インスタンスに SCRAM を要求する準備
<a name="PostgreSQL_Password_Encryption_configuration.getting-ready"></a>

お使いの 、RDS for PostgreSQL DB インスタンスに変更を加える前に、既存のデータベースユーザーアカウントをすべて確認します。また、パスワードに使用されている暗号化の種類を確認してください。確認するためには、`rds_tools` 拡張機能を使用します。`rds_tools` をサポートする PostgreSQL バージョンを確認するには、「[Extension versions for Amazon RDS for PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html)」を参照してください。

**データベースユーザー (ロール) とパスワードの暗号化方法のリストを取得するには**

1. 次のように、`psql` を使用して を RDS for PostgreSQL DB インスタンスに接続します。

   ```
   psql --host=db-name.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. `rds_tools` 拡張機能をインストールします。

   ```
   postgres=> CREATE EXTENSION rds_tools;
   CREATE EXTENSION
   ```

1. ロールと暗号化のリストを取得します。

   ```
   postgres=> SELECT * FROM 
         rds_tools.role_password_encryption_type();
   ```

   以下のような出力結果が表示されます。

   ```
          rolname        | encryption_type
   ----------------------+-----------------
    pg_monitor           |
    pg_read_all_settings |
    pg_read_all_stats    |
    pg_stat_scan_tables  |
    pg_signal_backend    |
    lab_tester           | md5
    user_465             | md5
    postgres             | md5
   (8 rows)
   ```

### カスタム DB パラメータグループの作成
<a name="PostgreSQL_Password_Encryption_configuration.custom-parameter-group"></a>

**注記**  
 RDS for PostgreSQL DB インスタンスで既にカスタムパラメータグループを使用している場合、新しいパラメータグループを作成する必要はありません。

Amazon RDS のパラメータグループの概要については、「[RDS for PostgreSQL DB インスタンスでのパラメータの使用](Appendix.PostgreSQL.CommonDBATasks.Parameters.md)」を参照してください。

パスワードに使用されるパスワード暗号化タイプは、1 つのパラメータ `password_encryption` で設定します。 RDS for PostgreSQL DB インスタンスで許可される暗号化は、別のパラメータ `rds.accepted_password_auth_method` で設定されます。これらのいずれかをデフォルト値から変更するには、カスタム DB パラメータグループを作成して、 インスタンスに適用する必要があります。

また、AWS マネジメントコンソール または RDS API を使用して、カスタムの DB パラメータグループを作成することもできます。詳細については、「」を参照してください。

これで、カスタムパラメータグループを DB インスタンスに関連付けることができます。

**カスタム DB パラメータグループを作成するには**

1. `[create-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/create-db-parameter-group.html) ` CLI コマンドを使用して、カスタムの DB パラメータグループを作成します。この例では `postgres13` をこのカスタムパラメータグループのソースとして使用します。

   Linux、macOS、Unix の場合:

   ```
   aws rds create-db-parameter-group --db-parameter-group-name 'docs-lab-scram-passwords' \
     --db-parameter-group-family postgres13  --description 'Custom parameter group for SCRAM'
   ```

   Windows の場合:

   ```
   aws rds create-db-parameter-group --db-parameter-group-name "docs-lab-scram-passwords" ^
     --db-parameter-group-family postgres13  --description "Custom DB parameter group for SCRAM"
   ```

1. `[modify-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-instance.html)` CLI コマンドを使用して、このカスタムパラメータグループを RDS for PostgreSQL DB クラスターに適用します。

   Linux、macOS、Unix の場合:

   ```
   aws rds modify-db-instance --db-instance-identifier 'your-instance-name' \
           --db-parameter-group-name "docs-lab-scram-passwords
   ```

   Windows の場合:

   ```
   aws rds modify-db-instance --db-instance-identifier "your-instance-name" ^
           --db-parameter-group-name "docs-lab-scram-passwords
   ```

   PostgreSQL DB インスタンスとカスタム DB クラスターパラメータグループと再同期するには、プライマリインスタンスとクラスターの他のすべてのインスタンスを再起動する必要があります。ユーザーへの影響を最小限に抑えるため、定期的なメンテナンス期間中に実施するように計画してください。

### SCRAM を使用するためのパスワード暗号化の設定
<a name="PostgreSQL_Password_Encryption_configuration.configure-password-encryption"></a>

 RDS for PostgreSQL DB インスタンスで使用されるパスワード暗号化メカニズムは、`password_encryption` パラメータの DB パラメータグループに設定されています。指定できる値は、未設定、`md5` または `scram-sha-256` です。デフォルト値は、次のように RDS for PostgreSQL のバージョンによって異なります。
+ RDS for PostgreSQL 14 以上 – デフォルトは `scram-sha-256`
+ RDS for PostgreSQL 13 – デフォルトは `md5`

 RDS for PostgreSQL DB インスタンスにアタッチされているカスタム DB パラメータグループでは、パスワード暗号化パラメータの値を変更できます。

![\[次では、RDS コンソールには、RDS for PostgreSQL の password_encryption パラメータのデフォルト値が表示されます。\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/images/rpg-pwd-encryption-md5-scram-1.png)


**パスワード暗号化の設定を scram-sha-256 に変更するには**
+ 次のように、パスワード暗号化の値を scram-sha-256 に設定します。パラメータが動的であるため、変更をすぐに適用できます。そのため、変更を有効にするために再起動は不要です。

  Linux、macOS、Unix の場合:

  ```
  aws rds modify-db-parameter-group --db-parameter-group-name \
    'docs-lab-scram-passwords' --parameters 'ParameterName=password_encryption,ParameterValue=scram-sha-256,ApplyMethod=immediate'
  ```

  Windows の場合:

  ```
  aws rds modify-db-parameter-group --db-parameter-group-name ^
    "docs-lab-scram-passwords" --parameters "ParameterName=password_encryption,ParameterValue=scram-sha-256,ApplyMethod=immediate"
  ```

### ユーザーロールのパスワードを SCRAM に移行する
<a name="PostgreSQL_Password_Encryption_configuration.migrating-users"></a>

以下に説明するように、ユーザーロールのパスワードを SCRAM に移行できます。

**データベースユーザー (ロール) のパスワードを MD5 から SCRAM に移行するには**

1. 次のように、管理者ユーザーとしてログインします (デフォルトのユーザー名、`postgres`)。

   ```
   psql --host=db-name.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. 次のコマンドを使って、RDS for PostgreSQL DB インスタンスの `password_encryption` パラメータの設定を確認します。

   ```
   postgres=> SHOW password_encryption;
    password_encryption
   ---------------------
    md5
    (1 row)
   ```

1. このパラメータの値を scram-sha-256 に変更します。詳細については、「[SCRAM を使用するためのパスワード暗号化の設定](#PostgreSQL_Password_Encryption_configuration.configure-password-encryption)」を参照してください。

1.  値をもう一度チェックして、次のように `scram-sha-256` に設定されていることを確認します。

   ```
   postgres=> SHOW password_encryption;
    password_encryption
   ---------------------
    scram-sha-256
    (1 row)
   ```

1. パスワードの変更をすべてのデータベースユーザーに通知します。アカウント `postgres` (`rds_superuser` 権限を持つデータベースユーザー) のパスワードも必ず変更してください。

   ```
   labdb=> ALTER ROLE postgres WITH LOGIN PASSWORD 'change_me';
   ALTER ROLE
   ```

1. のすべてのデータベースに対してこの処理を繰り返します。RDS for PostgreSQL DB インスタンス。

### SCRAM を要求するようにパラメータを変更する
<a name="PostgreSQL_Password_Encryption_configuration.require-scram"></a>

これがプロセスの最後のステップです。次の手順で変更した後、パスワードに引き続き `md5` 暗号化を使用するユーザーアカウント (ロール) は にログインできません。RDS for PostgreSQL DB インスタンス。

`rds.accepted_password_auth_method` は、ログインプロセス中に RDS for PostgreSQL DB インスタンスがユーザーパスワードに対して受け入れる暗号化方式を指定します。デフォルト値は `md5+scram` です。つまり、どちらの方法も受け入れられます。次の画像では、このパラメータのデフォルト設定が表示されています。

![\[rds.accepted_password_auth_method パラメータに対してデフォルト値と許可された値が表示されている RDS コンソール。\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/images/pwd-encryption-md5-scram-2.png)


このパラメータに指定できる値は、`md5+scram` または `scram` のみです。このパラメータの値を `scram` に変更すると、これが要件となります。

**パスワードの SCRAM 認証を要求するようにパラメータ値を変更するには**

1.  RDS for PostgreSQL DB インスタンスの上のすべてのデータベースに対するすべてのデータベースユーザーパスワードが、パスワード暗号化に `scram-sha-256` を使用していることを確認します。そのためには、`rds_tools` にロール (ユーザー) と暗号化タイプについて、次のようにクエリします。

   ```
   postgres=> SELECT * FROM rds_tools.role_password_encryption_type();
     rolname        | encryption_type
     ----------------------+-----------------
     pg_monitor           |
     pg_read_all_settings |
     pg_read_all_stats    |
     pg_stat_scan_tables  |
     pg_signal_backend    |
     lab_tester           | scram-sha-256
     user_465             | scram-sha-256
     postgres             | scram-sha-256
     ( rows)
   ```

1. のすべての DB インスタンスでクエリを繰り返します。RDS for PostgreSQL DB インスタンス。

   すべてのパスワードで scram-sha-256 が使用されている場合は続行できます。

1. 次のように、受け入れたパスワード認証の値を scram-sha-256 に設定します。

   Linux、macOS、Unix の場合:

   ```
   aws rds modify-db-parameter-group --db-parameter-group-name 'docs-lab-scram-passwords' \
     --parameters 'ParameterName=rds.accepted_password_auth_method,ParameterValue=scram,ApplyMethod=immediate'
   ```

   Windows の場合:

   ```
   aws rds modify-db-parameter-group --db-parameter-group-name "docs-lab-scram-passwords" ^
     --parameters "ParameterName=rds.accepted_password_auth_method,ParameterValue=scram,ApplyMethod=immediate"
   ```

# PostgreSQL でのデッド接続の処理
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling"></a>

デッド接続は、クライアントアプリケーションが終了または異常終了したにもかかわらず、データベースセッションがサーバー上でアクティブのままである場合に発生します。この状況は通常、データベース接続を適切に閉じたり、進行中のリクエストをキャンセルしたりせずに、クライアントプロセスがクラッシュまたは予期せず終了した場合に発生します。

PostgreSQL は、サーバープロセスがアイドル状態のとき、またはクライアントにデータを送信しようとしたときに、デッド接続を効率的に識別してクリーンアップします。ただし、アイドル状態のセッション、クライアント入力を待っているセッション、またはクエリがアクティブに実行されているセッションでは、検出は困難です。これらのシナリオを処理するために、PostgreSQL は `tcp_keepalives_*`、`tcp_user_timeout`、および `client_connection_check_interval` パラメータを提供します。

**Topics**
+ [

## TCP キープアライブを理解する
](#Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.Understanding)
+ [

## RDS for PostgreSQL の主要な TCP キープアライブパラメータ
](#Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.Parameters)
+ [

## TCP キープアライブ設定のユースケース
](#Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.UseCases)
+ [

## ベストプラクティス
](#Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.BestPractices)

## TCP キープアライブを理解する
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.Understanding"></a>

TCP キープアライブは、接続の整合性の維持と検証に役立つプロトコルレベルのメカニズムです。各 TCP 接続は、キープアライブ動作を管理するカーネルレベルの設定を維持します。キープアライブタイマーの有効期限が切れると、システムは以下を実行します。
+ データがなく、ACK フラグが設定されているプローブパケットを送信します。
+ TCP/IP 仕様に従ってリモートエンドポイントからのレスポンスを待ちます。
+ 応答の有無に基づいて接続状態を管理します。

## RDS for PostgreSQL の主要な TCP キープアライブパラメータ
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.Parameters"></a>


| パラメータ | 説明 | デフォルト値 | 
| --- |--- |--- |
| tcp\$1keepalives\$1idle | Specifies number of seconds of inactivity before sending keepalive message. | 300 | 
| tcp\$1keepalives\$1interval | Specifies number of seconds between retransmissions of unacknowledged keepalive messages. | 30 | 
| tcp\$1keepalives\$1count | Maximum lost keepalive messages before declaring connection dead | 2 | 
| tcp\$1user\$1timeout | Specifies how long (in Milliseconds) unacknowledged data can remain before forcibly closing the connection. | 0 | 
| client\$1connection\$1check\$1interval | Sets the interval (in Milliseconds) for checking client connection status during long-running queries. This ensures quicker detection of closed connections. | 0 | 

## TCP キープアライブ設定のユースケース
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.UseCases"></a>

### アイドルセッションを存続させる
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.UseCases.KeepingAlive"></a>

アイドル状態が原因でファイアウォールまたはルーターによってアイドル状態の接続が終了されないようにするには
+ キープアライブパケットを定期的に送信するように `tcp_keepalives_idle` を設定します。

### デッド接続の検出
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.UseCases.DetectingDead"></a>

デッド接続を迅速に検出するには
+ `tcp_keepalives_idle`、`tcp_keepalives_interval`、および `tcp_keepalives_count` を調整します。例えば、Aurora PostgreSQL のデフォルトでは、デッド接続を検出するのに約 1 分 (2 プローブ × 30 秒) かかります。これらの値を小さくすると、検出を速めることができます。
+ `tcp_user_timeout` を使用して、確認の最大待機時間を指定します。

TCP キープアライブ設定は、カーネルがデッド接続を検出するのに役立ちますが、PostgreSQL はソケットが使用されるまで動作しない場合があります。セッションが長いクエリを実行している場合、デッド接続はクエリの完了後にのみ検出される可能性があります。PostgreSQL 14 以降のバージョンでは、`client_connection_check_interval` はクエリの実行中にソケットを定期的にポーリングすることで、デッド接続の検出を迅速化できます。

## ベストプラクティス
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.BestPractices"></a>
+ **妥当なキープアライブ間隔を設定する:** `tcp_user_timeout`、`tcp_keepalives_idle`、`tcp_keepalives_count`、および `tcp_keepalives_interval` を調整して、検出速度とリソースの使用のバランスを取ります。
+ **環境に合わせて最適化する:** 設定をネットワーク動作、ファイアウォールポリシー、およびセッションのニーズに合わせます。
+ **PostgreSQL の機能を活用する:** PostgreSQL 14 以降のバージョンで `client_connection_check_interval` を使用して、効率的な接続チェックを行います。

# Amazon RDS for PostgreSQL での PostgreSQL 自動バキュームの使用
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum"></a>

autovacuum 機能を使用して、PostgreSQL DB インスタンスの状態を維持することを強くお勧めします。autovacuum は、VACUUM コマンドと ANALYZE コマンドのスタートを自動化します。自動バキュームが、多数のタプルが挿入、更新、または削除されたテーブルを確認します。確認後、自動バキュームは PostgreSQL データベースから古いデータやタプルを削除することで、ストレージを再利用します。

デフォルトの PostgreSQL DB パラメータグループのいずれかを使用して作成した RDS for PostgreSQL DB インスタンスでは、デフォルトで自動バキュームがオンになっています。autovacuum 機能に関連するその他の設定パラメータもデフォルトで設定されます。これらのデフォルト値は汎用的であるため、特定のワークロードに対して、autovacuum 機能に関連付けられているパラメータの一部をチューニングすることには利点があります。

次に、autovacuum の詳細と、RDS for PostgreSQL DB インスタンスでそのパラメータの一部をチューニングする方法について説明します。概要については、「[PostgreSQL を使用するためのベストプラクティス](CHAP_BestPractices.md#CHAP_BestPractices.PostgreSQL)」を参照してください。

**Topics**
+ [

## autovacuum のメモリを割り当てる
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.WorkMemory)
+ [

## トランザクション ID の循環の可能性を減らす
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming)
+ [

# データベース内のテーブルにバキューム処理が必要かどうかの判別
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.NeedVacuuming.md)
+ [

# 現在 autovacuum の対象となっているテーブルの判別
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.EligibleTables.md)
+ [

# Autovacuum が現在実行されているかどうかと実行されている時間の判別
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AutovacuumRunning.md)
+ [

# 手動バキュームフリーズの実行
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md)
+ [

# autovacuum の実行中にテーブルのインデックスを再作成する
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Reindexing.md)
+ [

# 大きなインデックスを使った autovacuum の管理
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.md)
+ [

# autovacuum に影響を与えるその他のパラメータ
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.OtherParms.md)
+ [

# テーブルレベルの autovacuum パラメータを設定する
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.TableParameters.md)
+ [

# 自動バキュームおよびバキュームアクティビティのログ記録
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Logging.md)
+ [

# 無効なデータベースでの自動バキュームの動作を理解する
](appendix.postgresql.commondbatasks.autovacuumbehavior.md)
+ [

# RDS for PostgreSQL で積極的なバキュームのブロック要因を特定して解決する
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.md)

## autovacuum のメモリを割り当てる
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.WorkMemory"></a>

autovacuum のパフォーマンスに影響を与える最も重要なパラメータの 1 つは、[https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM) パラメータです。RDS for PostgreSQL バージョン 14 以前では、`autovacuum_work_mem` パラメータは -1 に設定されており、`maintenance_work_mem` の設定が代わりに使用されていることを示します。他のすべてのバージョンでは、`autovacuum_work_mem` は GREATEST(\$1DBInstanceClassMemory/32768\$1, 65536) によって決定されます。

手動バキュームオペレーションは常に `maintenance_work_mem` 設定を使用し、デフォルト設定は GREATEST(\$1DBInstanceClassMemory/63963136\$11024\$1, 65536) です。また、より的を絞った手動 `VACUUM` オペレーションを実現するために、`SET` のコマンドを使用してセッションレベルで調整することもできます。

`autovacuum_work_mem` は、インデックスをバキュームするためのデッドタプル (`pg_stat_all_tables.n_dead_tup`) の識別子を保持するため、autovacuum のメモリを決定します。

計算を実行して `autovacuum_work_mem` パラメータの値を決定するときは、次の点に注意してください。
+ パラメータの設定値が低すぎると、バキューム処理が完了するまでにテーブルを複数回スキャンすることが必要になる場合があります。このような複数のスキャンは、パフォーマンスに悪影響を及ぼすことがあります。より大きなインスタンスでは、`maintenance_work_mem` または `autovacuum_work_mem` を少なくとも 1 GB に設定することで、デッドタプル数が多いテーブルをバキュームするためのパフォーマンスが向上します。ただし、PostgreSQL バージョン 16 以前では、バキュームのメモリ使用量は 1 GB に制限されています。これは、1 回のパスで約 1 億 7,900 万個のデッドタプルを処理するのに十分な量です。テーブルのデッドタプルがこれよりも多い場合、バキュームはテーブルのインデックスを複数回通過させる必要があり、所要時間が大幅に増加します。PostgreSQL バージョン 17 以降、1 GB の制限はなく、自動バキュームは基数ツリーを使用して 1 億 7,900 万を超えるタプルを処理できます。

  タプル識別子のサイズは 6 バイトです。テーブルのインデックスのバキュームに必要なメモリを推定するには、`pg_stat_all_tables.n_dead_tup` をクエリしてデッドタプル数を求め、この数に 6 を掛けて、1 回のパスでインデックスをバキュームするのに必要なメモリを決定します。以下のクエリを使用できます。

  ```
  SELECT
      relname AS table_name,
      n_dead_tup,
      pg_size_pretty(n_dead_tup * 6) AS estimated_memory
  FROM
      pg_stat_all_tables
  WHERE
      relname = 'name_of_the_table';
  ```
+ `autovacuum_work_mem` パラメータは、`autovacuum_max_workers` パラメータと連動して機能します。`autovacuum_max_workers` 間の各ワーカーは、割り当てたメモリを使用できます。小さいテーブルが多数ある場合、`autovacuum_max_workers` の割り当てを増やして `autovacuum_work_mem` の割り当てを減らします。大きなテーブル (100 GB 以上) がある場合は、メモリの割り当てを増やしてワーカープロセス数を減らします。最も大きいテーブルを正常に処理するには、十分なメモリを割り当てる必要があります。したがって、ワーカープロセスとメモリの組み合わせが、割り当てるメモリの合計と等しくなることを確認してください。

## トランザクション ID の循環の可能性を減らす
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming"></a>

autovacuum に関連するパラメータグループの設定は、トランザクション ID の循環を防ぐほどは排除率が高くない場合があります。この問題に対処するために、RDS for PostgreSQL には autovacuum パラメータ値を自動的に適応させるメカニズムが用意されています。*適応型 autovacuum* は、RDS for PostgreSQL の機能です。[トランザクション ID の循環](https://www.postgresql.org/docs/current/static/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND)に関する詳しい説明については、PostgreSQL ドキュメントを参照してください。

適応型 autovacuum は、動的パラメータ `rds.adaptive_autovacuum` が ON に設定されている RDS for PostgreSQL インスタンスでは、デフォルトでオンになります。この設定をオンにしておくことを強くお勧めします。ただし、autovacuum パラメータのアダプティブチューニングをオフにする場合は、`rds.adaptive_autovacuum` パラメータを 0 または OFF に設定します。

トランザクション ID の循環は、Amazon RDS で autovacuum パラメータをチューニングした後でも発生する場合があります。トランザクション ID の循環に対して Amazon CloudWatch アラームを実装することをお勧めします。詳細については、AWS データベースブログの記事「[Implement an early warning system for transaction ID wraparound in RDS for PostgreSQL](https://aws.amazon.com/blogs/database/implement-an-early-warning-system-for-transaction-id-wraparound-in-amazon-rds-for-postgresql/)」(RDS for PostgreSQL でトランザクション ID の循環に早期警告システムを実装する) を参照してください。

自動バキュームパラメータのアダプティブチューニングをオンにすると、CloudWatch メトリクス `MaximumUsedTransactionIDs` が `autovacuum_freeze_max_age` パラメータの値または 500,000,000 のいずれか大きいほうに達したときに、Amazon RDS で自動バキュームパラメータの調整が開始されます。

テーブルでトランザクション ID の循環の傾向が続く場合、Amazon RDS では自動バキュームパラメータの調整が続行されます。続行される調整ごとに、循環を避けるために autovacuum に割り当てられる専用のリソースが増えます。Amazon RDS は、以下の autovacuum 関連のパラメータを更新します。
+ [autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)
+ [ autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)
+  [https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM) 
+  [autovacuum\$1naptime](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-NAPTIME) 

これらのパラメータが RDS で変更されるのは、新しい値で autovacuum による排除率が高くなる場合に限られます。パラメータは、DB インスタンスのメモリで変更されます。パラメータグループの値は変更されません。現在のメモリ内の設定を確認するには、PostgreSQL の [SHOW](https://www.postgresql.org/docs/current/sql-show.html) SQL コマンドを使用します。

これらの自動バキュームパラメータのいずれかが Amazon RDS で変更されると、影響を受ける DB インスタンスでイベントが生成されます。このイベントは、AWS マネジメントコンソール や Amazon RDS API を介して表示できます。CloudWatch メトリクス `MaximumUsedTransactionIDs` がしきい値より低い値に戻ると、Amazon RDS はメモリ内の自動バキューム関連のパラメータをリセットして、パラメータグループで指定されている値に戻します。次に、この変更に対応する別のイベントが生成されます。

# データベース内のテーブルにバキューム処理が必要かどうかの判別
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.NeedVacuuming"></a>

次のクエリを使用して、データベース内のフリーズしていないトランザクションの数を表示できます。データベースの `datfrozenxid` 行の `pg_database` 列は、そのデータベースに表示されている正常なトランザクション ID の下限です。この列は、データベース内のテーブルあたりの `relfrozenxid` 値の最小数です。

```
SELECT datname, age(datfrozenxid) FROM pg_database ORDER BY age(datfrozenxid) desc limit 20;
```

例えば、前述のクエリの実行結果は以下のようになります。

```
datname    | age
mydb       | 1771757888
template0  | 1721757888
template1  | 1721757888
rdsadmin   | 1694008527
postgres   | 1693881061
(5 rows)
```

データベースのトランザクション ID 数が 20 億に達すると、トランザクション ID (XID) の循環が発生し、データベースは読み取り専用になります。このクエリを使用してメトリクスを生成し、1 日に数回実行できます。デフォルトでは、autovacuum は保持するトランザクション数が 200,000,000 以下になるように設定されます ()。[https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE)

サンプルモニタリング戦略は次のようになります。
+ `autovacuum_freeze_max_age` の値を 2 億トランザクションに設定します。
+ テーブルのフリーズしていないトランザクション数が 5 億に達すると、重要度が低いアラームがトリガーされます。これは無効な値ではありませんが、autovacuum が遅れていることを示している場合があります。
+ テーブルのトランザクション数が 10 億に達した場合は、対処を要するアラームとして扱う必要があります。一般的に、パフォーマンス上の理由から、トランザクション数は `autovacuum_freeze_max_age` に近い値にしてください。以下の推奨事項を使用して調査することをお勧めします。
+ テーブルのバキューム処理されていないトランザクション数が 15 億に達すると、重要度が高いアラームがトリガーされます。データベースでトランザクション ID をどれだけ速く使用するかによりますが、このアラームは、システムに autovacuum を実行する時間がないことを示している場合があります。この場合は、この問題を早急に解決することをお勧めします。

テーブルのサイズがこれらのしきい値を頻繁に超える場合は、自動バキュームパラメータをさらに変更します。デフォルトでは、手動で VACUUM (コストベースの遅延が無効) を使用するほうが、デフォルトの autovacuum を使用するより排除率が高くなりますが、システム全体に与える負担が増えます。

次の構成を推奨します。
+ この場合、最も古いトランザクションの経過時間を認識できるように、モニタリングメカニズムをオンにしてください。

  トランザクション ID の循還について警告するプロセスを作成する方法については、AWS のデータベースブログの記事「[Amazon RDS for PostgreSQL でトランザクション ID の循環に早期警告システムを実装する](https://aws.amazon.com/blogs/database/implement-an-early-warning-system-for-transaction-id-wraparound-in-amazon-rds-for-postgresql/)」を参照してください。
+ 処理の多いテーブルでは、autovacuum の使用に加えて、メンテナンスウィンドウ中に手動でバキュームフリーズを定期的に実行してください。手動バキュームフリーズの実行については、「[手動バキュームフリーズの実行](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md)」を参照してください。

# 現在 autovacuum の対象となっているテーブルの判別
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.EligibleTables"></a>

多くの場合、1 つ以上のテーブルにバキューム処理が必要です。`relfrozenxid` の値が `autovacuum_freeze_max_age` のトランザクション数を超えているテーブルは、常に autovacuum の処理対象となります。それ以外の場合、前回の VACUUM 以降「古い」とされたタプルの数が「バキュームしきい値」を超えると、テーブルがバキューム処理されます。

[autovacuum しきい値](https://www.postgresql.org/docs/current/static/routine-vacuuming.html#AUTOVACUUM)は、次のように定義されます。

```
Vacuum-threshold = vacuum-base-threshold + vacuum-scale-factor * number-of-tuples
```

ここで、`vacuum base threshold` は `autovacuum_vacuum_threshold`、`vacuum scale factor` は `autovacuum_vacuum_scale_factor`、`number of tuples` は `pg_class.reltuples` です。

データベースに接続しているときに、次のクエリを実行し、自動バキュームがバキューム処理の対象と見なしているテーブルのリストを表示します。

```
WITH vbt AS (SELECT setting AS autovacuum_vacuum_threshold FROM 
pg_settings WHERE name = 'autovacuum_vacuum_threshold'),
vsf AS (SELECT setting AS autovacuum_vacuum_scale_factor FROM 
pg_settings WHERE name = 'autovacuum_vacuum_scale_factor'), 
fma AS (SELECT setting AS autovacuum_freeze_max_age FROM pg_settings WHERE name = 'autovacuum_freeze_max_age'),
sto AS (select opt_oid, split_part(setting, '=', 1) as param,
split_part(setting, '=', 2) as value from (select oid opt_oid, unnest(reloptions) setting from pg_class) opt)
SELECT '"'||ns.nspname||'"."'||c.relname||'"' as relation,
pg_size_pretty(pg_table_size(c.oid)) as table_size,
age(relfrozenxid) as xid_age,
coalesce(cfma.value::float, autovacuum_freeze_max_age::float) autovacuum_freeze_max_age,
(coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) +
coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples)
AS autovacuum_vacuum_tuples, n_dead_tup as dead_tuples FROM
pg_class c join pg_namespace ns on ns.oid = c.relnamespace 
join pg_stat_all_tables stat on stat.relid = c.oid join vbt on (1=1) join vsf on (1=1) join fma on (1=1)
left join sto cvbt on cvbt.param = 'autovacuum_vacuum_threshold' and c.oid = cvbt.opt_oid 
left join sto cvsf on cvsf.param = 'autovacuum_vacuum_scale_factor' and c.oid = cvsf.opt_oid
left join sto cfma on cfma.param = 'autovacuum_freeze_max_age' and c.oid = cfma.opt_oid
WHERE c.relkind = 'r' and nspname <> 'pg_catalog'
AND (age(relfrozenxid) >= coalesce(cfma.value::float, autovacuum_freeze_max_age::float)
OR coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + 
coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * 
c.reltuples <= n_dead_tup)
ORDER BY age(relfrozenxid) DESC LIMIT 50;
```

# Autovacuum が現在実行されているかどうかと実行されている時間の判別
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AutovacuumRunning"></a>

テーブルを手動でバキューム処理する必要がある場合、必ず自動バキュームが現在実行されているかどうか判別してください。実行されている場合、さらに効率的に実行されるようにパラメータを調整するか、自動バキュームを一時的にオフに切り替えて VACUUM を手動で実行できるようにする必要がある場合があります。

次のクエリを使用して、autovacuum が実行中か、どのくらいの時間実行中か、また別のセッションの待機中かを判別します。

```
SELECT datname, usename, pid, state, wait_event, current_timestamp - xact_start AS xact_runtime, query
FROM pg_stat_activity 
WHERE upper(query) LIKE '%VACUUM%' 
ORDER BY xact_start;
```

クエリが実行されると、次のような出力が表示されます。

```
 datname | usename  |  pid  | state  | wait_event |      xact_runtime       | query  
 --------+----------+-------+--------+------------+-------------------------+--------------------------------------------------------------------------------------------------------
 mydb    | rdsadmin | 16473 | active |            | 33 days 16:32:11.600656 | autovacuum: VACUUM ANALYZE public.mytable1 (to prevent wraparound)
 mydb    | rdsadmin | 22553 | active |            | 14 days 09:15:34.073141 | autovacuum: VACUUM ANALYZE public.mytable2 (to prevent wraparound)
 mydb    | rdsadmin | 41909 | active |            | 3 days 02:43:54.203349  | autovacuum: VACUUM ANALYZE public.mytable3
 mydb    | rdsadmin |   618 | active |            | 00:00:00                | SELECT datname, usename, pid, state, wait_event, current_timestamp - xact_start AS xact_runtime, query+
         |          |       |        |            |                         | FROM pg_stat_activity                                                                                 +
         |          |       |        |            |                         | WHERE query like '%VACUUM%'                                                                           +
         |          |       |        |            |                         | ORDER BY xact_start;                                                                                  +
```

いくつかの問題が原因で autovacuum セッションの実行が長期間 (複数日) に渡る場合があります。最もよくある問題は、[https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) パラメータ値で設定されたテーブルのサイズまたは更新速度が小さすぎることです。

次の計算式を使用して、`maintenance_work_mem` パラメータ値を設定することをお勧めします。

```
GREATEST({DBInstanceClassMemory/63963136*1024},65536)
```

実行時間が短い autovacuum セッションは、以下の問題を示している可能性もあります。
+ ワークロード用の `autovacuum_max_workers` が十分ではないことを示している場合があります。この場合は、ワーカーの数を指定する必要があります。
+ インデックスの破損を示している場合があります (自動バキュームがクラッシュし、同じリレーションで再起動されますが進行はありません)。この場合は、手動 `vacuum freeze verbose table` を実行して正確な原因を確認します。

# 手動バキュームフリーズの実行
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze"></a>

バキュームプロセスが既に実行されているテーブルで、手動バキュームを実行できます。これは、トランザクション数が 20 億に近づいている (または、モニタリングしているしきい値を上回った) テーブルに気付いた場合に役立ちます。

次の手順はガイドラインであり、プロセスにはいくつかのバリエーションがあります。例えば、テスト時に、[https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) パラメータの設定値が小さすぎて、テーブルに早急な対処が必要であることに気づいたとします。ただし、今はインスタンスをバウンスしたくない場合があります。前のセクションのクエリを使用することで、問題のあるテーブルを判別し、長時間実行されている autovacuum セッションを確認できます。`maintenance_work_mem` パラメータ設定の変更が必要であることがわかっていても、すぐに対処して問題のテーブルにバキューム処理を実行する必要があります。このような場合、次の手順で対応します。

**バキュームフリーズを手動で実行するには**

1. バキュームを実行するテーブルを含むデータベースへのセッションを 2 つ開きます。2 番目のセッションで、接続が中断された場合にセッションを維持する「screen」または他のユーティリティを使用します。

1. セッション 1 で、テーブルで実行されている自動バキュームセッションのプロセス ID (PID) を取得します。

   次のクエリを実行し、autovacuum セッションの PID を取得します。

   ```
   SELECT datname, usename, pid, current_timestamp - xact_start 
   AS xact_runtime, query
   FROM pg_stat_activity WHERE upper(query) LIKE '%VACUUM%' ORDER BY 
   xact_start;
   ```

1. セッション 2 で、このオペレーションに必要なメモリの量を計算します。この例では、このオペレーションに最大 2GB のメモリを使用できると決めたため、現在のセッションの [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) を 2GB に設定します。

   ```
   SET maintenance_work_mem='2 GB';
   SET
   ```

1. セッション 2 で、テーブルに対して `vacuum freeze verbose` コマンドを発行します。現在のところ PostgreSQL には進行状況レポートがないため、verbose 設定はアクティビティを確認するのに役立ちます。

   ```
   \timing on
   Timing is on.
   vacuum freeze verbose pgbench_branches;
   ```

   ```
   INFO:  vacuuming "public.pgbench_branches"
   INFO:  index "pgbench_branches_pkey" now contains 50 row versions in 2 pages
   DETAIL:  0 index row versions were removed.
   0 index pages have been deleted, 0 are currently reusable.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   INFO:  index "pgbench_branches_test_index" now contains 50 row versions in 2 pages
   DETAIL:  0 index row versions were removed.
   0 index pages have been deleted, 0 are currently reusable.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   INFO:  "pgbench_branches": found 0 removable, 50 nonremovable row versions 
        in 43 out of 43 pages
   DETAIL:  0 dead row versions cannot be removed yet.
   There were 9347 unused item pointers.
   0 pages are entirely empty.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   VACUUM
   Time: 2.765 ms
   ```

1. セッション 1 で、自動バキュームがバキュームセッションをブロックしていた場合、`pg_stat_activity` は、バキュームセッションを待機中であること (`T`) を示します。この場合は、次のように自動バキュームプロセスを終了します。

   ```
   SELECT pg_terminate_backend('the_pid'); 
   ```
**注記**  
Amazon RDS の一部の下位バージョンでは、前述のコマンドを使用して自動バキュームプロセスを終了できず、次のエラーで失敗します: `ERROR: 42501: must be a superuser to terminate superuser process LOCATION: pg_terminate_backend, signalfuncs.c:227`。

   この時点で、セッションがスタートされます。このテーブルは作業リストの一番上にあると思われるため、自動バキュームは即座に再開します。

1. セッション 2 で `vacuum freeze verbose` コマンドを開始し、セッション 1 で自動バキュームプロセスを終了します。

# autovacuum の実行中にテーブルのインデックスを再作成する
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Reindexing"></a>

インデックスが破損した場合、autovacuum はテーブルの処理を続けますが失敗します。この状況で手動バキュームを試みると、次のようなエラーメッセージが表示されます。

```
postgres=>  vacuum freeze pgbench_branches;
ERROR: index "pgbench_branches_test_index" contains unexpected 
   zero page at block 30521
HINT: Please REINDEX it.
```

インデックスが破損しているときに、自動バキュームをテーブルで実行しようとすると、既に実行中の自動バキュームセッションと競合します。「[REINDEX](https://www.postgresql.org/docs/current/static/sql-reindex.html)」コマンドを発行する場合は、テーブルに対する排他ロックを取り除きます。書き込みオペレーションがブロックされ、この特定のインデックスを使用する読み込みオペレーションもブロックされます。

**autovacuum がテーブルに対して実行されているときにテーブルのインデックスを再作成するには**

1. バキュームを実行するテーブルを含むデータベースへのセッションを 2 つ開きます。2 番目のセッションで、接続が中断された場合にセッションを維持する「screen」または他のユーティリティを使用します。

1. セッション 1 で、テーブルを実行している autovacuum セッションの PID を取得します。

   次のクエリを実行し、autovacuum セッションの PID を取得します。

   ```
   SELECT datname, usename, pid, current_timestamp - xact_start 
   AS xact_runtime, query
   FROM pg_stat_activity WHERE upper(query) like '%VACUUM%' ORDER BY 
   xact_start;
   ```

1. セッション 2 で、reindex コマンドを発行します。

   ```
   \timing on
   Timing is on.
   reindex index pgbench_branches_test_index;
   REINDEX
     Time: 9.966 ms
   ```

1. セッション 1 で、自動バキュームがプロセスをブロックしていた場合、`pg_stat_activity` で、バキュームセッションの [waiting] (待機) が「T」であることを確認できます。この場合、自動バキュームプロセスを終了します。

   ```
   SELECT pg_terminate_backend('the_pid');
   ```

   この時点で、セッションがスタートされます。このテーブルは作業リストの一番上にあると思われるため、autovacuum が即座に再開される点に注意することが重要です。

1. セッション 2 で コマンドを開始し、セッション 1 で自動バキュームプロセスを終了します。

# 大きなインデックスを使った autovacuum の管理
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes"></a>

操作の一環として、*autovacuum* はテーブル上で実行している間にいくつかの[バキュームフェーズ](https://www.postgresql.org/docs/current/progress-reporting.html#VACUUM-PHASES)を実行します。テーブルをクリーンアップする前に、まずすべてのインデックスがバキューム処理されます。複数の大きなインデックスを削除する場合、このフェーズではかなりの時間とリソースを消費します。したがって、ベストプラクティスとして、テーブル上のインデックスの数を制御し、未使用のインデックスを削除してください。

このプロセスでは、まずインデックス全体のサイズを確認します。次に、次の例に示すように、削除できるインデックスがあるかどうかを確認します。

**テーブルとそのインデックスのサイズを確認するには**

```
postgres=> select pg_size_pretty(pg_relation_size('pgbench_accounts'));
pg_size_pretty
6404 MB
(1 row)
```

```
postgres=> select pg_size_pretty(pg_indexes_size('pgbench_accounts'));
pg_size_pretty
11 GB
(1 row)
```

この例では、インデックスのサイズはテーブルよりも大きくなっています。この違いにより、インデックスが肥大化したり使用されなかったりするため、パフォーマンスの問題が発生し、自動バキュームや挿入オペレーションに影響する可能性があります。

**未使用のインデックスを確認するには**

[https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-INDEXES-VIEW](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-INDEXES-VIEW) ビューを使用すると、`idx_scan` 列でインデックスがどのくらいの頻度で使用されているかを確認できます。次の例では、未使用のインデックスに `0` の `idx_scan` 値があります

```
postgres=> select * from pg_stat_user_indexes where relname = 'pgbench_accounts' order by idx_scan desc;
    
relid  | indexrelid | schemaname | relname          | indexrelname          | idx_scan | idx_tup_read | idx_tup_fetch
-------+------------+------------+------------------+-----------------------+----------+--------------+---------------
16433  | 16454      | public     | pgbench_accounts | index_f               | 6        | 6            | 0
16433  | 16450      | public     | pgbench_accounts | index_b               | 3        | 199999       | 0
16433  | 16447      | public     | pgbench_accounts | pgbench_accounts_pkey | 0        | 0            | 0
16433  | 16452      | public     | pgbench_accounts | index_d               | 0        | 0            | 0
16433  | 16453      | public     | pgbench_accounts | index_e               | 0        | 0            | 0
16433  | 16451      | public     | pgbench_accounts | index_c               | 0        | 0            | 0
16433  | 16449      | public     | pgbench_accounts | index_a               | 0        | 0            | 0
(7 rows)
```

```
postgres=> select schemaname, relname, indexrelname, idx_scan from pg_stat_user_indexes where relname = 'pgbench_accounts' order by idx_scan desc;
    
schemaname  | relname          | indexrelname          | idx_scan
------------+------------------+-----------------------+----------
public      | pgbench_accounts | index_f               | 6
public      | pgbench_accounts | index_b               | 3
public      | pgbench_accounts | pgbench_accounts_pkey | 0
public      | pgbench_accounts | index_d               | 0
public      | pgbench_accounts | index_e               | 0
public      | pgbench_accounts | index_c               | 0
public      | pgbench_accounts | index_a               | 0
(7 rows)
```

**注記**  
これらの統計情報は、統計がリセットされた時点から増加します。例えば、あるビジネス四半期末にのみ使用される、または特定のレポートにのみ使用されるインデックスがあるとします。統計がリセットされてから、このインデックスが使用されていない可能性があります。詳細については、「[統計関数](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-STATS-FUNCTIONS)」を参照してください。一意性を保証するために使用されるインデックスはスキャンされないため、未使用のインデックスとして識別しないでください。未使用のインデックスを特定するには、アプリケーションとそのクエリに関する深い知識が必要です。

データベースの統計が最後にリセットされた日時を確認するには、[ https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW]( https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW) を使用してください。

```
postgres=> select datname, stats_reset from pg_stat_database where datname = 'postgres';
    
datname   | stats_reset
----------+-------------------------------
postgres  | 2022-11-17 08:58:11.427224+00
(1 row)
```

## テーブルをできるだけ早くバキューム処理する
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.Executing"></a>

**RDS for PostgreSQL 12 以上**

大きなテーブルにインデックスが多すぎる場合、DB インスタンスがトランザクション ID ラップアラウンド (XID) に近づいている可能性があります。これは XID カウンターが 0 にラップアラウンドするタイミングです。チェックを外したままにすると、この状況では、データが失われる可能性があります。ただし、インデックスをクリーンアップせずにテーブルをすばやくバキューム処理できます。RDS for PostgreSQL 12 以上では、[https://www.postgresql.org/docs/current/sql-vacuum.html](https://www.postgresql.org/docs/current/sql-vacuum.html) 句で VACUUM を使用することができます。

```
postgres=> VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) pgbench_accounts;
        
INFO: vacuuming "public.pgbench_accounts"
INFO: table "pgbench_accounts": found 0 removable, 8 nonremovable row versions in 1 out of 819673 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 7517
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.01 s, system: 0.00 s, elapsed: 0.01 s.
```

自動バキュームセッションが既に実行されている場合、手動 VACUUM を開始するにはセッションを終了する必要があります。手動バキュームフリーズの実行については、「[手動バキュームフリーズの実行](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md)」を参照してください。

**注記**  
インデックスのクリーンアップを定期的にスキップすると、インデックスが肥大化し、スキャンのパフォーマンスが低下します。インデックスはデッド行を保持し、テーブルはデッドラインポインタを保持します。その結果、`pg_stat_all_tables.n_dead_tup` は autovacuum またはインデックスクリーンアップを含む手動 VACUUM が実行されるまで増加します。ベストプラクティスとして、この手順は、トランザクション ID の循環を防ぐためにのみ使用してください。

**RDS for PostgreSQL 11 以降**

ただし、RDS for PostgreSQL 11 以前のバージョンでは、バキューム処理をより速く完了させる唯一の方法は、テーブルのインデックス数を減らすことです。インデックスを削除すると、クエリプランに影響する可能性があります。未使用のインデックスを最初に削除し、XID の循環が間近になったらインデックスを削除することをお勧めします。バキューム処理が完了したら、これらのインデックスを再作成できます。

# autovacuum に影響を与えるその他のパラメータ
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.OtherParms"></a>

次のクエリは、autovacuum とその動作に直接影響を与えるパラメータのいくつかについて値を表示します。[autovacuum パラメータ](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html)の詳細については、PostgreSQL のドキュメントを参照してください。

```
SELECT name, setting, unit, short_desc
FROM pg_settings
WHERE name IN (
'autovacuum_max_workers',
'autovacuum_analyze_scale_factor',
'autovacuum_naptime',
'autovacuum_analyze_threshold',
'autovacuum_analyze_scale_factor',
'autovacuum_vacuum_threshold',
'autovacuum_vacuum_scale_factor',
'autovacuum_vacuum_threshold',
'autovacuum_vacuum_cost_delay',
'autovacuum_vacuum_cost_limit',
'vacuum_cost_limit',
'autovacuum_freeze_max_age',
'maintenance_work_mem',
'vacuum_freeze_min_age');
```

これらはすべて autovacuum に影響を与えますが、最も重要なものは以下のとおりです。
+ [maintenance\$1work\$1mem](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE_WORK_MEM)
+ [autovacuum\$1freeze\$1max\$1age](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE)
+ [autovacuum\$1max\$1workers](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS)
+ [autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)
+ [ autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)

# テーブルレベルの autovacuum パラメータを設定する
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.TableParameters"></a>

自動バキューム関連の[ストレージパラメータ](https://www.postgresql.org/docs/current/static/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS)をテーブルレベルで設定できます。これは、データベース全体の動作を変更するより適切である場合があります。大きなテーブルでは、極端な設定にする必要が生じる場合がありますが、autovacuum がすべてのテーブルに対してそのように動作するわけではありません。

次のクエリは、現在テーブルレベルのオプションが設定されているテーブルを表示します。

```
SELECT relname, reloptions
FROM pg_class
WHERE reloptions IS NOT null;
```

これが役立つ可能性がある例として、残りのテーブルよりかなり大きいテーブルがあります。1 個の 300 GB のテーブルと、他の 30 個の 1 GB 未満のテーブルがあるとします。この場合、システム全体の動作を変更しないで、大きなテーブルのいくつかの特定のパラメータを設定できます。

```
ALTER TABLE mytable set (autovacuum_vacuum_cost_delay=0);
```

これを行うと、このテーブルでコストベースの自動バキューム遅延がなくなりますが、システムでのリソース使用量が多くなります。通常、自動バキュームは `autovacuum_cost_limit` に達するたびに `autovacuum_vacuum_cost_delay` で一時停止します。詳細については、「PostgreSQL ドキュメント」の「[cost-based vacuuming](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST)」(コストベースのバキューム処理) を参照してください。

# 自動バキュームおよびバキュームアクティビティのログ記録
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Logging"></a>

自動バキュームアクティビティに関する情報は、`rds.force_autovacuum_logging_level`パラメータで指定したレベルに基づいて `postgresql.log` に送信されます。このパラメータで指定できる値、およびその値がデフォルトで設定されている PostgreSQL バージョンは次のとおりです。
+ `disabled` (PostgreSQL 10、PostgreSQL 9.6)
+ `debug5`, `debug4`, `debug3`, `debug2`, `debug1`
+ `info` (PostgreSQL 12、PostgreSQL 11)
+ `notice`
+ `warning` (PostgreSQL 13 以降)
+ `error`、ログ、`fatal`、`panic`

`rds.force_autovacuum_logging_level` では `log_autovacuum_min_duration` パラメータが使用されます。`log_autovacuum_min_duration` パラメータの値はしきい値 (ミリ秒単位) です。このしきい値を超過すると、自動バキュームアクションがログに記録されます。`-1` に設定するとログに何も記録されませんが、0 に設定するとすべてのアクションが記録されます。`rds.force_autovacuum_logging_level` と同様に、`log_autovacuum_min_duration` のデフォルト値はバージョンによって次のように異なります。
+ `10000 ms` – PostgreSQL 14、PostgreSQL 13、PostgreSQL 12、および PostgreSQL 11 
+ `(empty)` – PostgreSQL 10 と PostgreSQL 9.6 の場合、デフォルト値はありません

`rds.force_autovacuum_logging_level` を `WARNING` に設定することをお勧めします。`log_autovacuum_min_duration` についても 1,000～5,000 の値に設定することをお勧めします。5,000 に設定すると、5,000 ミリ秒を超える長さのアクティビティがログに記録されます。-1 以外の設定では、ロックの競合または同時に削除されたリレーションが原因で自動バキュームアクションがスキップされた場合にも、メッセージがログに記録されます。詳細については、「PostgreSQL のドキュメント」の「[Automatic Vacuuming](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html)」(自動バキューム処理) を参照してください。

問題のトラブルシューティングを行うために、`rds.force_autovacuum_logging_level` パラメータを `debug1` から `debug5` までのデバッグレベルの 1 つに変更し、最も詳しい情報を取得します。デバッグ設定は、短期間かつトラブルシューティングの目的でのみ使用することをお勧めします。詳細については、「PostgreSQL のドキュメント」の「[When to log](https://www.postgresql.org/docs/current/static/runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHEN)」(ログ記録のタイミング) を参照してください。

**注記**  
PostgreSQL では、`rds_superuser` アカウントが `pg_stat_activity` 内の autovacuum セッションを表示できます。例えば、コマンドの実行をブロックしている autovacuum セッション、あるいは手動で発行される vacuum コマンドよりも実行スピードが遅い autovacuum セッションを特定して終了することもできます。

# 無効なデータベースでの自動バキュームの動作を理解する
<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 のラップアラウンドを防ぐため、データベースのトランザクション ID (XID) の経過時間をモニタリングするために使用されます。

 無効なデータベースは自動バキュームから除外されるため、そのトランザクション 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` ロールを持つデータベースアカウントを使用して有効なデータベースに接続し、無効なデータベースを削除します。

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

# RDS for PostgreSQL で積極的なバキュームのブロック要因を特定して解決する
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring"></a>

PostgreSQL でデータベースの正常な状態を維持するためにはバキューム処理が不可欠です。バキューム処理によって、ストレージの再利用が可能になり、[トランザクション ID の循環](https://www.postgresql.org/docs/current/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND)に関する問題を回避できます。しかし、バキューム処理が目的どおりに動作しなくなることもあります。これにより、パフォーマンスの低下やストレージの肥大化が生じ、トランザクション ID の循環によって DB インスタンスの可用性にも影響する場合があります。したがって、データベースのパフォーマンスと可用性を最適化するには、これらの問題を特定して解決することが不可欠です。「[Understanding autovacuum in Amazon RDS for PostgreSQL environments](https://aws.amazon.com/blogs/database/understanding-autovacuum-in-amazon-rds-for-postgresql-environments/)」で自動バキュームの詳細について確認してください。

`postgres_get_av_diag()` 関数は、積極的なバキュームの進行を妨げたり遅らせたりしている問題を特定するのに役立ちます。推奨事項が提示され、問題が特定可能な場合はそれを解決するためのコマンドが、問題を特定できない場合は詳細な診断のためのガイダンスが得られます。積極的なバキュームのブロック要因は、経過時間が RDS の[適応型自動バキューム](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming)のしきい値である 5 億トランザクション ID を超えた場合に報告されます。

**トランザクション ID の経過時間とは**

トランザクション ID の `age()` 関数は、データベース (`pg_database.datfrozenxid`) またはテーブル (`pg_class.relfrozenxid`) の最も古いフリーズしていないトランザクション ID 以降に発生したトランザクションの数を計算します。この値は、前回の積極的なバキューム操作以降のデータベースアクティビティを示し、今後の VACUUM プロセスのワークロードについての見通しを示します。

**積極的なバキュームとは**

積極的な VACUUM 操作では、通常の VACUUM で省略されるページも含め、テーブル内のすべてのページが包括的にスキャンされます。この徹底的なスキャンは、最大経過時間に近づいているトランザクション ID を「フリーズ」することを目指しており、[トランザクション ID の循環](https://www.postgresql.org/docs/current/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND)と呼ばれる状況を効果的に防止します。

`postgres_get_av_diag()` で報告されるブロック要因は、5 億トランザクション以上古いものとなります。

**Topics**
+ [

# RDS for PostgreSQL に自動バキュームのモニタリングツールと診断ツールをインストールする
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation.md)
+ [

# RDS for PostgreSQL の postgres\$1get\$1av\$1diag() の関数
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Functions.md)
+ [

# RDS for PostgreSQL での識別可能なバキュームブロック要因の解決
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md)
+ [

# RDS for PostgreSQL での識別不能なバキュームブロック要因の解決
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Unidentifiable_blockers.md)
+ [

# RDS for PostgreSQL でバキュームのパフォーマンスに関する問題を解決する
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance.md)
+ [

# RDS for PostgreSQL の NOTICE メッセージの説明
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md)

# RDS for PostgreSQL に自動バキュームのモニタリングツールと診断ツールをインストールする
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation"></a>

`postgres_get_av_diag()` 関数は現在、次の RDS for PostgreSQL バージョンで使用できます。
+ 17.2 以降の 17 バージョン
+ 16.7 以降の 16 バージョン
+ 15.11 以降の 15 バージョン
+ 14.16 以降の 14 バージョン
+ 13.19 以降の 13 バージョン

 `postgres_get_av_diag()` を使用するには、`rds_tools` 拡張機能を作成します。

```
postgres=> CREATE EXTENSION rds_tools ;
CREATE EXTENSION
```

拡張機能がインストールされていることを確認します。

```
postgres=> \dx rds_tools
             List of installed extensions
   Name    | Version |  Schema   |                    Description
 ----------+---------+-----------+----------------------------------------------------------
 rds_tools |   1.8   | rds_tools | miscellaneous administrative functions for RDS PostgreSQL
 1 row
```

関数が作成されていることを確認します。

```
postgres=> SELECT
    proname function_name,
    pronamespace::regnamespace function_schema,
    proowner::regrole function_owner
FROM
    pg_proc
WHERE
    proname = 'postgres_get_av_diag';
    function_name     | function_schema | function_owner
----------------------+-----------------+----------------
 postgres_get_av_diag | rds_tools       | rds_superuser
(1 row)
```

# RDS for PostgreSQL の postgres\$1get\$1av\$1diag() の関数
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Functions"></a>

`postgres_get_av_diag()` 関数は、RDS for PostgreSQL データベースで妨害または遅延が生じている自動バキュームプロセスに関する診断情報を取得します。正確な結果を得るには、最も古いトランザクション ID を持つデータベースでクエリを実行する必要があります。最も古いトランザクション ID を持つデータベースを使用する方法の詳細については、「[トランザクション ID の経過時間が最も古いデータベースに接続していない](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md)」を参照してください。

```
SELECT
    blocker,
    DATABASE,
    blocker_identifier,
    wait_event,
    TO_CHAR(autovacuum_lagging_by, 'FM9,999,999,999') AS autovacuum_lagging_by,
    suggestion,
    suggested_action
FROM (
    SELECT
        *
    FROM
        rds_tools.postgres_get_av_diag ()
    ORDER BY
        autovacuum_lagging_by DESC) q;
```

`postgres_get_av_diag()` 関数は次の情報を含むテーブルを返します。

**blocker**  
バキュームをブロックしているデータベースアクティビティのカテゴリを指定します。  
+ [アクティブなステートメント](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement)
+ [トランザクションでのアイドル状態](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction)
+ [準備済みトランザクション](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction)
+ [論理レプリケーションスロット](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot)
+ [物理レプリケーションスロットを使用するリードレプリカ](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [ストリーミングレプリケーションを使用するリードレプリカ](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [一時テーブル](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables)

**database**  
該当しサポートされている場合にデータベースの名前を指定します。これは、アクティビティが進行中で、自動バキュームをブロックしている、またはこれからブロックするデータベースです。これは、接続してアクションを実行する必要があるデータベースです。

**blocker\$1identifier**  
自動バキュームをブロックしている、またはこれからブロックするアクティビティの識別子を指定します。識別子は、プロセス ID に SQL ステートメント、準備済みトランザクション、リードレプリカの IP アドレス、および論理または物理レプリケーションスロットの名前を加えたものとなります。

**wait\$1event**  
ブロックしているセッションの[待機イベント](PostgreSQL.Tuning.md)を指定し、次のブロック要因に適用されます。  
+ アクティブなステートメント
+ トランザクションでのアイドル状態

**autovacum\$1lagging\$1by**  
バックログ作業で自動バキュームが停滞しているトランザクションの数をカテゴリごとに指定します。

**suggestion**  
ブロック要因を解決するための推奨事項を指定します。これらの手順には、アクティビティが存在するデータベースの名前 (該当する場合)、セッションのプロセス ID (PID)(該当する場合)、および実行するアクションが含まれます。

**suggested\$1action**  
ブロック要因を解決するために実行する必要があるアクションを提案します。

# RDS for PostgreSQL での識別可能なバキュームブロック要因の解決
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers"></a>

自動バキュームは積極的なバキュームを実行し、トランザクション ID の経過時間が RDS インスタンスの `autovacuum_freeze_max_age` パラメータで指定されたしきい値に達しないようにします。この経過時間は、Amazon CloudWatch メトリクス `MaximumUsedTransactionIDs` を使用して追跡できます。

Amazon RDS インスタンスの `autovacuum_freeze_max_age` の設定 (デフォルトは 2 億トランザクション ID) を確認するには、次のクエリを使用します。

```
SELECT
    TO_CHAR(setting::bigint, 'FM9,999,999,999') autovacuum_freeze_max_age
FROM
    pg_settings
WHERE
    name = 'autovacuum_freeze_max_age';
```

`postgres_get_av_diag()` では、経過時間が Amazon RDS の[適応型自動バキューム](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming)のしきい値である 5 億トランザクション ID を超えた場合にのみ、積極的なバキュームのブロック要因をチェックすることに注意してください。`postgres_get_av_diag()` で検出されるブロック要因は、5 億トランザクション以上古いものとなります。

`postgres_get_av_diag()` 関数は、次のタイプのブロック要因を識別します。

**Topics**
+ [

## アクティブなステートメント
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement)
+ [

## トランザクションでのアイドル状態
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction)
+ [

## 準備済みトランザクション
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction)
+ [

## 論理レプリケーションスロット
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot)
+ [

## リードレプリカ
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [

## 一時テーブル
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables)

## アクティブなステートメント
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement"></a>

PostgreSQL において、アクティブなステートメントとは、データベースによって現在実行されている SQL ステートメントです。これには、クエリ、トランザクション、または進行中のすべてのオペレーションが含まれます。`pg_stat_activity` を使ってモニタリングする場合、状態列には、対応する PID を持つプロセスがアクティブであることが示されます。

`postgres_get_av_diag()` 関数がアクティブなステートメントであるステートメントを識別すると、次のような出力を表示します。

```
blocker               | Active statement
database              | my_database
blocker_identifier    | SELECT pg_sleep(20000);
wait_event            | Timeout:PgSleep
autovacuum_lagging_by | 568,600,871
suggestion            | Connect to database "my_database", review carefully and you may consider terminating the process using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_terminate_backend (29621);"}
```

**推奨されるアクション**

`suggestion` 列のガイダンスに従って、ユーザーはアクティブなステートメントが存在するデータベースに接続できます。`suggested_action` 列で指定されているように、セッションを終了するオプションを慎重に検討することが推奨されます。終了しても安全な場合は、`pg_terminate_backend()` 関数を使用してセッションを終了できます。このアクションは、管理者 (RDS マスターアカウントなど) または必要な `pg_terminate_backend()` 権限を持つユーザーが実行できます。

**警告**  
終了したセッションは、行われた変更を元に戻します (`ROLLBACK`)。要件に応じて、ステートメントを再度実行できます。ただし、自動バキュームプロセスが積極的なバキューム操作を完了した後にのみ実行することをお勧めします。

## トランザクションでのアイドル状態
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction"></a>

トランザクションステートメントのアイドル状態とは、明示的なトランザクションを開き (`BEGIN` ステートメントの発行など)、何らかの作業を実行したセッションで、クライアントがさらに作業を渡すか、`COMMIT`、`ROLLBACK`、`END` (暗黙的な `COMMIT` になります) を発行してトランザクションの終了を通知するのを待っているセッションを指します。

`postgres_get_av_diag()` 関数が `idle in transaction` ステートメントをブロック要因として識別すると、次のような出力を表示します。

```
blocker               | idle in transaction
database              | my_database
blocker_identifier    | INSERT INTO tt SELECT * FROM tt;
wait_event            | Client:ClientRead
autovacuum_lagging_by | 1,237,201,759
suggestion            | Connect to database "my_database", review carefully and you may consider terminating the process using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_terminate_backend (28438);"}
```

**推奨されるアクション**

`suggestion` 列に示されているように、トランザクションセッションでのアイドル状態が存在するデータベースに接続し、`pg_terminate_backend()` 関数を使用してセッションを終了できます。ユーザーは、管理者 (RDS マスターアカウント) ユーザーでも、 `pg_terminate_backend()` 権限を持つユーザーでもかまいません。

**警告**  
終了したセッションは、行われた変更を元に戻します (`ROLLBACK`)。要件に応じて、ステートメントを再度実行できます。ただし、自動バキュームプロセスが積極的なバキューム操作を完了した後にのみ実行することをお勧めします。

## 準備済みトランザクション
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction"></a>

PostgreSQL では、[準備済みトランザクション](https://www.postgresql.org/docs/current/sql-prepare-transaction.html)と呼ばれる 2 相コミット戦略の一部であるトランザクションを使用できます。これらは、`max_prepared_transactions` パラメータをゼロ以外の値に設定することで有効になります。準備済みトランザクションは、データベースのクラッシュ、再起動、またはクライアントの切断後も、トランザクションが持続し、引き続き使用できるように設計されています。通常のトランザクションと同様に、トランザクション ID が割り当てられ、自動バキュームに影響を与える場合があります。準備状態のままにすると、自動バキュームはフリーズを実行できず、トランザクション ID の循環につながる可能性があります。

トランザクションマネージャによって解決されることなく無期限に準備状態となったトランザクションは、孤立した準備済みトランザクションになります。これを修正する唯一の方法は、`COMMIT PREPARED` コマンドまたは `ROLLBACK PREPARED` コマンドを使用してトランザクションをコミットするかロールバックすることです。

**注記**  
準備済みトランザクションで作成されたバックアップには、復元後もそのトランザクションが含まれることに注意してください。このようなトランザクションを見つけて閉じる方法については、以下の情報を参照してください。

`postgres_get_av_diag()` 関数が準備済みトランザクションをブロック要因として識別すると、次の出力を表示します。

```
blocker               | Prepared transaction
database              | my_database
blocker_identifier    | myptx
wait_event            | Not applicable
autovacuum_lagging_by | 1,805,802,632
suggestion            | Connect to database "my_database" and consider either COMMIT or ROLLBACK the prepared transaction using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"COMMIT PREPARED 'myptx';",[OR],"ROLLBACK PREPARED 'myptx';"}
```

**推奨されるアクション**

suggestion 列で説明されているように、準備済みトランザクションがあるデータベースに接続します。`suggested_action` 列に基づいて、`COMMIT` と `ROLLBACK` のどちらを実行するかを慎重に検討し、適切なアクションを選択します。

準備済みトランザクション全般をモニタリングするために、PostgreSQL には `pg_prepared_xacts` というカタログビューが用意されています。次のクエリを使用して、準備済みトランザクションを検索できます。

```
SELECT
    gid,
    prepared,
    owner,
    database,
    transaction AS oldest_xmin
FROM
    pg_prepared_xacts
ORDER BY
    age(transaction) DESC;
```

## 論理レプリケーションスロット
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot"></a>

レプリケーションスロットの目的は、ターゲットサーバーにレプリケートされるまで、未使用の変更を保持することです。詳細については、PostgreSQL の「[Logical replication](https://www.postgresql.org/docs/current/logical-replication.html)」を参照してください。

論理レプリケーションスロットには 2 つのタイプがあります。

**非アクティブな論理レプリケーションスロット**

レプリケーションが終了すると、未使用のトランザクションログは削除されず、レプリケーションスロットは非アクティブになります。非アクティブな論理レプリケーションスロットは、現在、サブスクライバーによって使用されていませんが、サーバーには残るため、WAL ファイルが保持され、古いトランザクションログが削除されなくなります。システムは LSN 情報が上書きされないよう保持する必要があるため、ディスク使用量が増加し、具体的には、自動バキュームで内部カタログテーブルをクリーンアップできなくなる可能性があります。放置するとカタログの肥大化とパフォーマンスの低下を招き、循環バキュームのリスクが増大して、トランザクションのダウンタイムが発生する可能性があります。

**アクティブだが遅い論理レプリケーションスロット**

論理レプリケーションのパフォーマンスの低下により、カタログのデッドタプルの削除が遅れることがあります。このレプリケーションの遅延により、`catalog_xmin` の更新が遅れ、カタログの肥大化や循環バキュームが発生する可能性があります。

`postgres_get_av_diag()` 関数が論理レプリケーションスロットをブロック要因として検出すると、次のような出力を表示します。

```
blocker               | Logical replication slot
database              | my_database
blocker_identifier    | slot1
wait_event            | Not applicable
autovacuum_lagging_by | 1,940,103,068
suggestion            | Ensure replication is active and resolve any lag for the slot if active. If inactive, consider dropping it using the command in suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_drop_replication_slot('slot1') FROM pg_replication_slots WHERE active = 'f';"}
```

**推奨されるアクション**

この問題を解決するには、レプリケーション設定で、適用プロセスを終了している可能性のあるターゲットスキーマまたはデータの問題を確認します。最も一般的な理由を次に示します。
+ 列の欠落
+ 互換性のないデータ型
+ データの不一致
+ データの欠落

問題がインフラストラクチャの問題に関連している場合
+ ネットワークの問題 - [互換性のないネットワーク状態にある Amazon RDS DB の問題を解決するにはどうすればよいですか?](https://repost.aws/knowledge-center/rds-incompatible-network)
+ データベースまたは DB インスタンスが、次の理由により使用できない
  + レプリカインスタンスのストレージが不足している - 「[Amazon RDS DB インスタンスのストレージが不足したときに発生する問題を解決する方法を教えてください](https://repost.aws/knowledge-center/rds-out-of-storage)」を参照して、ストレージの追加について確認してください。
  + 互換性のないパラメータ - 「[互換性のないパラメータステータスのままになっている Amazon RDS DB インスタンスを修正するにはどうすればよいですか?](https://repost.aws/knowledge-center/rds-incompatible-parameters)」を参照して、問題を解決する方法の詳細を確認してください。

インスタンスが AWS ネットワーク外または AWS EC2 上にある場合は、可用性またはインフラストラクチャ関連の問題の解決方法について管理者に問い合わせてください。

**非アクティブなスロットの削除**

**警告**  
注意: レプリケーションスロットを削除する前に、レプリケーションが進行中ではないこと、レプリケーションスロットが非アクティブで回復不可能な状態であることを慎重に確認してください。スロットを途中で削除すると、レプリケーションが中断されたり、データが失われたりする可能性があります。

レプリケーションスロットが不要になったことを確認したら、削除して自動バキュームを続行できるようにします。条件 `active = 'f'` を指定することで、非アクティブなスロットのみが削除されます。

```
SELECT pg_drop_replication_slot('slot1') WHERE active ='f'
```

## リードレプリカ
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas"></a>

[Amazon RDS リードレプリカ](USER_PostgreSQL.Replication.ReadReplicas.md)で `hot_standby_feedback` 設定が有効になっている場合、リードレプリカで実行されているクエリで引き続き必要になる可能性のあるデッド行は、プライマリデータベースの自動バキュームで削除されません。これは、レプリケーションスロットを使用して管理されているかどうかにかかわらず、すべてのタイプの物理リードレプリカに影響します。スタンバイレプリカで実行されているクエリでは、[クエリの競合](https://www.postgresql.org/docs/current/hot-standby.html#HOT-STANDBY-CONFLICT)やキャンセルを防ぐために、これらの行をプライマリで利用できる状態に保つ必要があるため、こうした動作が必要になります。

**物理レプリケーションスロットを使用するリードレプリカ**  
物理レプリケーションスロットを使用するリードレプリカでは、RDS for PostgreSQL でのレプリケーションの信頼性と安定性が大幅に強化されます。これらのスロットにより、プライマリデータベースはレプリカが処理するまで重要なログ先行書き込みファイルを保持し、ネットワークの中断中もデータ整合性を維持できます。

RDS for PostgreSQL バージョン 14 以降、すべてのレプリカでレプリケーションスロットが使用されます。以前のバージョンでは、クロスリージョンレプリカのみでレプリケーションスロットが使用されていました。

`postgres_get_av_diag()` 関数が物理レプリケーションスロットを使用するリードレプリカをブロック要因として検出すると、次のような出力を表示します。

```
blocker               | Read replica with physical replication slot
database              |
blocker_identifier    | rds_us_west_2_db_xxxxxxxxxxxxxxxxxxxxx
wait_event            | Not applicable
autovacuum_lagging_by | 554,080,689
suggestion            | Run the following query on the replica "rds_us_west_2_db_xxxxxxxxxxxxxxxxxxxx" to find the long running query:                           
                      | SELECT * FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 757989377;                                                       
                      | Review carefully and you may consdier terminating the query on read replica using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.                                 +                      |
suggested_action      | {"SELECT pg_terminate_backend(pid) FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 757989377;","                                                                                 +
                      | [OR]                                                                                                                                                                                                 +
                      | ","Disable hot_standby_feedback","                                                                                                                                                                   +
                      | [OR]                                                                                                                                                                                                 +
                      | ","Delete the read replica if not needed"}
```

**ストリーミングレプリケーションを使用するリードレプリカ**  
Amazon RDS では、バージョン 13 までの古いバージョンで、物理レプリケーションスロットを使用せずにリードレプリカを設定できます。このアプローチでは、プライマリが WAL ファイルをより積極的にリサイクルできるようにすることでオーバーヘッドを軽減します。これは、ディスク容量が制限された環境においてメリットがあり、ときどき発生するレプリケーションの遅延も許容できます。ただし、スロットを使用しない場合、WAL ファイルが欠落しないように、スタンバイは同期したままにする必要があります。Amazon RDS は、レプリカが遅れをとった場合にアーカイブされた WAL ファイルを使用して遅れを解消しますが、このプロセスには慎重なモニタリングが必要となり、時間がかかることがあります。

`postgres_get_av_diag()` 関数がストリーミングリードレプリカをブロック要因として検出すると、次のような出力を表示します。

```
blocker               | Read replica with streaming replication slot
database              | Not applicable
blocker_identifier    | xx.x.x.xxx/xx
wait_event            | Not applicable
autovacuum_lagging_by | 610,146,760
suggestion            | Run the following query on the replica "xx.x.x.xxx" to find the long running query:                                                                                                                                                         +
                      | SELECT * FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 348319343;                                                                                                                                                     +
                      | Review carefully and you may consdier terminating the query on read replica using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.                                       +
                      |
suggested_action      | {"SELECT pg_terminate_backend(pid) FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 348319343;","                                                                                                                        +
                      | [OR]                                                                                                                                                                                                                                        +
                      | ","Disable hot_standby_feedback","                                                                                                                                                                                                          +
                      | [OR]                                                                                                                                                                                                                                        +
                      | ","Delete the read replica if not needed"}
```

**推奨されるアクション**

`suggested_action` 列で推奨されているように、以下のオプションを慎重に検討して自動バキュームのブロックを解除します。
+ **クエリを終了する** – suggestion 列のガイダンスに従って、suggested\$1action 列で指定されているようにリードレプリカに接続できます。セッションを終了するオプションは慎重に検討することをお勧めします。終了しても安全であると判断した場合は、`pg_terminate_backend()` 関数を使用してセッションを終了できます。このアクションは、管理者 (RDS マスターアカウントなど) または必要な pg\$1terminate\$1backend() 権限を持つユーザーが実行できます。

  リードレプリカで次の SQL コマンドを実行すると、プライマリのバキュームによる古い行のクリーンアップを妨げているクエリを終了できます。`backend_xmin` の値は、関数の出力で報告されます。

  ```
  SELECT
      pg_terminate_backend(pid)
  FROM
      pg_catalog.pg_stat_activity
  WHERE
      backend_xmin::text::bigint = backend_xmin;
  ```
+ **ホットスタンバイフィードバックを無効にする** – `hot_standby_feedback` パラメータがバキュームの大幅な遅延の原因となっている場合は、これを無効にすることを検討します。

  `hot_standby_feedback` パラメータを使用すると、リードレプリカはクエリアクティビティについてプライマリに通知し、プライマリがスタンバイで使用されているテーブルや行をバキューム処理できないようにします。これによりスタンバイでのクエリの安定性が確保されますが、プライマリでのバキューム処理が大幅に遅延する可能性があります。この機能を無効にすると、プライマリはスタンバイが追いつくのを待たずにバキューム処理を進めることができます。ただし、プライマリによってバキューム処理された行にアクセスしようとすると、スタンバイでクエリのキャンセルや失敗が発生する可能性があります。
+ **不要になったリードレプリカを削除する** – リードレプリカが不要になった場合は、削除できます。これにより、関連するレプリケーションオーバーヘッドが解消され、プライマリがレプリカによって妨げられることなくトランザクションログをリサイクルできるようになります。

## 一時テーブル
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables"></a>

`TEMPORARY` キーワードを使用して作成された[一時テーブル](https://www.postgresql.org/docs/current/sql-createtable.html)は、pg\$1temp\$1xxx などの一時スキーマにあり、それらを作成したセッションのみがアクセスできます。一時テーブルは、セッションが終了すると削除されます。ただし、このようなテーブルは PostgreSQL の自動バキュームプロセスには表示されず、テーブルを作成したセッションによって手動でバキューム処理する必要があります。別のセッションから一時テーブルのバキューム処理を試みても効果はありません。

異常な状況下では、テーブルを所有するアクティブなセッションがない状態で一時テーブルが存在します。致命的なクラッシュ、ネットワークの問題、または同様のイベントが原因でテーブルを所有するセッションが予期せず終了した場合、一時テーブルはクリーンアップされず、「孤立した」テーブルとして残される可能性があります。PostgreSQL 自動バキュームプロセスで孤立した一時テーブルが検出されると、次のメッセージがログに記録されます。

```
LOG: autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"
```

`postgres_get_av_diag()` 関数が一時テーブルをブロック要因として識別すると、次のような出力を表示します。この関数で一時テーブルに関連する出力を正しく表示するには、それらのテーブルが存在するのと同じデータベース内で関数を実行する必要があります。

```
blocker               | Temporary table
database              | my_database
blocker_identifier    | pg_temp_14.ttemp
wait_event            | Not applicable
autovacuum_lagging_by | 1,805,802,632
suggestion            | Connect to database "my_database". Review carefully, you may consider dropping temporary table using command in suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"DROP TABLE ttemp;"}
```

**推奨されるアクション**

出力の `suggestion` 列に示されている手順に従って、自動バキュームの実行を妨げている一時テーブルを特定して削除します。次のコマンドを使用して、`postgres_get_av_diag()` で報告された一時テーブルを削除します。`postgres_get_av_diag()` 関数で提示された出力に基づいてテーブル名を置き換えます。

```
DROP TABLE my_temp_schema.my_temp_table;
```

次のクエリを使用して、一時テーブルを識別できます。

```
SELECT
    oid,
    relname,
    relnamespace::regnamespace,
    age(relfrozenxid)
FROM
    pg_class
WHERE
relpersistence = 't'
ORDER BY
    age(relfrozenxid) DESC;
```

# RDS for PostgreSQL での識別不能なバキュームブロック要因の解決
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Unidentifiable_blockers"></a>

このセクションでは、バキューム処理の進行を妨げる可能性のあるその他の理由について説明します。以下の問題は、現在、`postgres_get_av_diag()` 関数によって直接識別できません。

**Topics**
+ [

## 無効なページ
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages)
+ [

## インデックスの不整合
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Index_inconsistency)
+ [

## トランザクションレートが極めて高い
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.High_transaction_rate)

## 無効なページ
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages"></a>

無効なページエラーは、PostgreSQL がページへのアクセス中にページのチェックサムの不一致を検出した場合に発生します。コンテンツが読み取れないため、自動バキュームでタプルがフリーズされません。これにより、クリーンアッププロセスが実質的に停止します。次のエラーが PostgreSQL の ログに書き込まれます。

```
WARNING:  page verification failed, calculated checksum YYYYY but expected XXXX
ERROR:  invalid page in block ZZZZZ of relation base/XXXXX/XXXXX
CONTEXT:  automatic vacuum of table myschema.mytable
```

**オブジェクトタイプを判断する**

```
ERROR: invalid page in block 4305910 of relation base/16403/186752608 
WARNING: page verification failed, calculated checksum 50065 but expected 60033
```

エラーメッセージのパス `base/16403/186752608` は、次の情報を提供しています。
+ 「base」は PostgreSQL データディレクトリのディレクトリ名です。
+ 「16403」はデータベース OID であり、`pg_database` システムカタログで検索できます。
+ 「186752608」は `relfilenode` であり、`pg_class` システムカタログでスキーマとオブジェクト名を検索するために使用できます。

影響を受けるデータベースで次のクエリの出力をチェックすることで、オブジェクトタイプを判断できます。次のクエリは、oid: 186752608 のオブジェクト情報を取得します。OID を、発生したエラーに関連する OID に置き換えます。

```
SELECT
    relname AS object_name,
    relkind AS object_type,
    nspname AS schema_name
FROM
    pg_class c
    JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE
    c.oid = 186752608;
```

詳細については、PostgreSQL のドキュメント「[https://www.postgresql.org/docs/current/catalog-pg-class.html](https://www.postgresql.org/docs/current/catalog-pg-class.html)」で、`pg_class` の `relkind` 列で示されるサポート対象のすべてのオブジェクトタイプを参照してください。

**ガイダンス**

この問題の最も効果的な解決策は、特定の Amazon RDS インスタンスの設定と、整合性のないページの影響を受けるデータの種類によって異なります。

**オブジェクトタイプがインデックスの場合**

インデックスを再構築することをお勧めします。
+ **`CONCURRENTLY` オプションの使用** – PostgreSQL バージョン 12 より前のバージョンでは、インデックスを再構築するには、排他的テーブルロックによってテーブルへのアクセスを制限する必要がありました。PostgreSQL バージョン 12 以降のバージョンでは、`CONCURRENTLY` オプションにより行レベルのロックが可能になり、テーブルの可用性が大幅に向上しています。コマンドは以下のとおりです。

  ```
  REINDEX INDEX ix_name CONCURRENTLY;
  ```

  `CONCURRENTLY` はそれほど破壊的ではありませんが、ビジー状態のテーブルでは時間がかかる場合があります。可能であれば、トラフィックが少ない時間帯にインデックスを構築することを検討してください。

  詳細については、PostgreSQL ドキュメントの「[REINDEX](https://www.postgresql.org/docs/current/sql-reindex.html)」を参照してください。
+ **`INDEX_CLEANUP FALSE` オプションの使用** – インデックスが大きく、完了までにかなりの時間がかかると予想される場合は、インデックスを除外しながら手動 `VACUUM FREEZE` を実行して自動バキュームのブロックを解除できます。この機能は PostgreSQL バージョン 12 以降で使用できます。

  インデックスを無視すると、整合性のないインデックスのバキュームプロセスを省略して、循環の問題を軽減できます。ただし、無効なページの根本的な問題は解決されません。無効なページの問題に完全に対処し、これを解決するには、インデックスを再構築する必要があります。

**オブジェクトタイプがマテリアライズドビューの場合**

マテリアライズドビューで無効なページエラーが発生した場合は、影響を受けるデータベースにログインし、更新して無効なページを解決します。

マテリアライズドビューを更新します。

```
REFRESH MATERIALIZED VIEW schema_name.materialized_view_name;
```

更新に失敗した場合は、再作成を試みます。

```
DROP MATERIALIZED VIEW schema_name.materialized_view_name;
CREATE MATERIALIZED VIEW schema_name.materialized_view_name AS query;
```

マテリアライズドビューを更新または再作成すると、基盤となるテーブルデータに影響を与えずにマテリアライズドビューが復元されます。

**他のすべてのオブジェクトタイプの場合**

他のすべてのオブジェクトタイプについては、AWS サポートに問い合わせてください。

## インデックスの不整合
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Index_inconsistency"></a>

論理的に整合性のないインデックスによって、自動バキュームの進行が妨げられる場合があります。次のエラーまたは同様のエラーは、インデックスのバキュームフェーズ中、または SQL ステートメントによってインデックスがアクセスされるときにログに記録されます。

```
ERROR: right sibling's left-link doesn't match:block 5 links to 10 instead of expected 2 in index ix_name
```

```
ERROR: failed to re-find parent key in index "XXXXXXXXXX" for deletion target page XXX
CONTEXT:  while vacuuming index index_name of relation schema.table
```

**ガイダンス**

手動 `VACUUM FREEZE` で `INDEX_CLEANUP` を使用してインデックスを再構築するか、インデックスを省略します。インデックスを再構築する方法の詳細については、「[オブジェクトタイプがインデックスの場合](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages)」を参照してください。
+ **CONCURRENTLY オプションの使用** – PostgreSQL バージョン 12 より前のバージョンでは、インデックスを再構築するには、排他的テーブルロックによってテーブルへのアクセスを制限する必要がありました。PostgreSQL バージョン 12 以降のバージョンでは、CONCURRENTLY オプションにより行レベルのロックが可能になり、テーブルの可用性が大幅に向上しています。コマンドは以下のとおりです。

  ```
  REINDEX INDEX ix_name CONCURRENTLY;
  ```

  CONCURRENTLY はそれほど破壊的ではありませんが、ビジー状態のテーブルでは時間がかかる場合があります。可能であれば、トラフィックが少ない時間帯にインデックスを構築することを検討してください。詳細については、*PostgreSQL* ドキュメントの「[REINDEX](https://www.postgresql.org/docs/current/sql-reindex.html)」を参照してください。
+ **INDEX\$1CLEANUP FALSE オプションの使用** – インデックスが大きく、完了までにかなりの時間がかかると予想される場合は、インデックスを除外しながら手動 VACUUM FREEZE を実行して自動バキュームのブロックを解除できます。この機能は PostgreSQL バージョン 12 以降で使用できます。

  インデックスを無視すると、整合性のないインデックスのバキュームプロセスを省略して、循環の問題を軽減できます。ただし、無効なページの根本的な問題は解決されません。無効なページの問題に完全に対処し、これを解決するには、インデックスを再構築する必要があります。

## トランザクションレートが極めて高い
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.High_transaction_rate"></a>

PostgreSQL では、トランザクションレートが高いと自動バキュームのパフォーマンスに大きな影響を与え、デッドタプルのクリーンアップが遅くなり、トランザクション ID の循環のリスクが高まります。トランザクションレートは、2 つの期間 (通常は 1 秒ごと) の `max(age(datfrozenxid))` の差を測定することでモニタリングできます。さらに、RDS Performance Insights の次のカウンターメトリクスを使用して、トランザクションの合計数であるトランザクションレート (xact\$1commit と xact\$1rollback の合計) を測定できます。


|  Counter  |  タイプ  |  単位  |  メトリクス  | 
| --- | --- | --- | --- | 
|  xact\$1commit  |  トランザクション  |  1 秒あたりのコミット数  |  db.Transactions.xact\$1commit  | 
|  xact\$1rollback  |  トランザクション  |  1 秒あたりのロールバック数  |  db.Transactions.xact\$1rollback  | 

急激な増加は、トランザクション負荷が高いことを示しており、自動バキュームが過負荷になり、肥大化、ロック競合、および潜在的なパフォーマンスの問題が発生する可能性があります。これにより、以下のような点で自動バキュームプロセスに悪影響が及ぶ可能性があります。
+ **テーブルアクティビティ:** バキューム処理されている特定のテーブルで大量のトランザクションが発生し、遅延が発生する可能性があります。
+ **システムリソース:** システム全体が過負荷になっている可能性があるため、自動バキュームが効率的に機能するために必要なリソースにアクセスすることが困難になります。

自動バキュームをより効果的に動作させ、遅延なくタスクに対処するために、次の戦略を検討してください。

1. 可能であれば、トランザクションレートを下げます。可能な場合は、類似したトランザクションをバッチ処理またはグループ化することを検討してください。

1. オフピークの時間帯は、毎晩、毎週、または隔週の手動 `VACUUM FREEZE` オペレーションで頻繁に更新されるテーブルをターゲットにします。

1. インスタンスクラスをスケールアップして、大量のトランザクションと自動バキュームを処理するためにより多くのシステムリソースを割り当てることを検討してください。

# RDS for PostgreSQL でバキュームのパフォーマンスに関する問題を解決する
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance"></a>

このセクションでは、バキュームのパフォーマンスの低下を招く要因と、それらの問題に対処する方法について説明します。

**Topics**
+ [

## 大規模なインデックスのバキューム処理
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Large_indexes)
+ [

## バキューム処理対象のテーブルまたはデータベースが多すぎる
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Multiple_tables)
+ [

## (循環を防ぐための) 積極的なバキューム処理が実行されている
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum)

## 大規模なインデックスのバキューム処理
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Large_indexes"></a>

VACUUM は、初期化、ヒープスキャン、インデックスとヒープバキューム、インデックスクリーンアップ、ヒープ切り捨て、最終クリーンアップのシーケンシャルフェーズで動作します。ヒープスキャン中、プロセスはページを除外し、デフラグしてフリーズします。ヒープスキャンが完了すると、VACUUM はインデックスをクリーンアップし、空のページがオペレーティングシステムに返されて、空き領域マップのバキューム処理や統計の更新などの最終的なクリーンアップタスクを実行します。

`maintenance_work_mem` (または `autovacuum_work_mem`) がインデックスの処理に不十分な場合は、インデックスのバキューム処理に複数のパスが必要になることがあります。PostgreSQL 16 以前では、デッドタプル ID を保存するために 1 GB のメモリ制限があり、大きなインデックスでは、多くの場合複数のパスが必要となっていました。PostgreSQL 17 では、単一の割り当て配列を使用する代わりにメモリを動的に割り当てる `TidStore` が導入されています。これにより、1 GB の制約がなくなり、メモリをより効率的に使用でき、インデックスごとに複数のインデックススキャンを行う必要が軽減されます。

使用可能なメモリがインデックス処理全体を一度に処理できない場合、大きなインデックスには PostgreSQL 17 で複数のパスが必要になることがあります。通常、大きなインデックスには、複数のパスを必要とするデッドタプルが多く含まれます。

**低速バキュームオペレーションの検出**

`postgres_get_av_diag()` 関数は、メモリ不足が原因でバキューム操作の実行が遅いタイミングを検出できます。この関数の詳細については、「[RDS for PostgreSQL に自動バキュームのモニタリングツールと診断ツールをインストールする](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation.md)」を参照してください。

この `postgres_get_av_diag()` 関数は、使用可能なメモリが 1 回のパスでインデックスのバキューム処理を完了するのに十分でない場合、次の通知を発行します。

**`rds_tools` 1.8**

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
```

```
NOTICE: The current setting of autovacuum_work_mem is "XXX" and might not be sufficient. Consider increasing the setting, and if necessary, scaling up the Amazon RDS instance class for more memory. 
        Additionally, review the possibility of manual vacuum with exclusion of indexes using (VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) table_name;).
```

**`rds_tools` 1.9**

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
```

```
NOTICE: The current setting of autovacuum_work_mem is XX might not be sufficient. Consider increasing the setting to XXX, and if necessary, scaling up the RDS instance class for more 
        memory. The suggested value is an estimate based on the current number of dead tuples for the table being vacuumed, which might not fully reflect the latest state. Additionally, review the possibility of manual 
        vacuum with exclusion of indexes using (VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) table_name;). For more information, see 
        [Working with PostgreSQL autovacuum in the Amazon Amazon RDS User Guide](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html)
        .
```

**注記**  
`postgres_get_av_diag()` 関数では、`pg_stat_all_tables.n_dead_tup` を使用してインデックスのバキューム処理に必要なメモリ量を推定します。

`postgres_get_av_diag()` 関数が、`autovacuum_work_mem` が不十分なために複数のインデックススキャンを必要とするスローバキュームオペレーションを特定すると、次のメッセージが生成されます。

```
NOTICE: Your vacuum is performing multiple index scans due to insufficient autovacuum_work_mem:XXX for index vacuuming. 
        For more information, see [Working with PostgreSQL autovacuum in the Amazon Amazon RDS User Guide](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html).
```

**ガイダンス**

手動 `VACUUM FREEZE` を使用して次の回避策を適用し、テーブルのフリーズにかかる時間を短縮できます。

**バキューム処理のためのメモリを増やす**

`postgres_get_av_diag()` 関数で提案されているように、インスタンスレベルで潜在的なメモリの制約に対応するために、`autovacuum_work_mem` パラメータを増やすことをお勧めします。`autovacuum_work_mem` は動的パラメータですが、新しいメモリ設定を有効にするには、自動バキュームデーモンがワーカーを再起動する必要があることに注意してください。これを行うには、以下の手順を使用します。

1. 新しい設定が指定されていることを確認します。

1. 自動バキュームを現在実行しているプロセスを終了します。

このアプローチにより、調整されたメモリ割り当てが新しい自動バキューム操作に適用されます。

より迅速な結果を得るには、セッション内で `maintenance_work_mem` 設定を増やし、手動で `VACUUM FREEZE` 操作を実行することを検討してください。

```
SET maintenance_work_mem TO '1GB';
VACUUM FREEZE VERBOSE table_name;
```

Amazon RDS を使用していて、`maintenance_work_mem` または `autovacuum_work_mem` のより高い値をサポートするために追加のメモリが必要であると判断した場合は、より多くのメモリを持つインスタンスクラスにアップグレードすることを検討してください。これにより、手動バキューム操作と自動バキューム操作の両方を強化するために必要なリソースが提供され、バキューム処理とデータベースの全体的なパフォーマンスが向上します。

**INDEX\$1CLEANUP を無効にする**

PostgreSQL バージョン 12 以降の手動 `VACUUM` ではインデックスのクリーンアップフェーズを省略できますが、PostgreSQL バージョン 14 以降の緊急自動バキュームでは、[https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-VACUUM-FAILSAFE-AGE](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-VACUUM-FAILSAFE-AGE) パラメータに基づいてこのフェーズが自動的に行われます。

**警告**  
インデックスのクリーンアップを省略すると、インデックスが肥大化し、クエリのパフォーマンスに悪影響を及ぼす可能性があります。これを軽減するには、メンテナンスウィンドウで、影響を受けるインデックスに対してインデックスの再作成またはバキューム処理を行うことを検討してください。

大きなインデックスの処理に関するその他のガイダンスについては、「[大きなインデックスを使った autovacuum の管理](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.md)」のドキュメントを参照してください。

**インデックスの並列バキューム処理**

PostgreSQL 13 以降では、手動 `VACUUM` を使用して、各インデックスに 1 つのバキュームワーカープロセスを割り当て、デフォルトで複数のインデックスのバキューム処理とクリーンアップを並列して行うことができます。ただし、バキューム操作が並列実行の対象となるかどうかを PostgreSQL が判断するには、特定の基準を満たす必要があります。
+ 少なくとも 2 つのインデックスが必要です。
+ `max_parallel_maintenance_workers` パラメータを 2 以上に設定する必要があります。
+ インデックスサイズが `min_parallel_index_scan_size` の制限 (デフォルトは 512KB) を超えている必要があります。

Amazon RDS インスタンスで使用可能な vCPU の数とテーブルのインデックスの数に基づいて `max_parallel_maintenance_workers` 設定を調整し、バキューム処理のターンアラウンド時間を最適化できます。

詳細については、「[Parallel vacuuming in Amazon RDS for PostgreSQL and Amazon Aurora PostgreSQL](https://aws.amazon.com/blogs/database/parallel-vacuuming-in-amazon-rds-for-postgresql-and-amazon-aurora-postgresql/)」を参照してください。

## バキューム処理対象のテーブルまたはデータベースが多すぎる
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Multiple_tables"></a>

PostgreSQL の「[The Autovacuum Daemon](https://www.postgresql.org/docs/current/routine-vacuuming.html#AUTOVACUUM')」ドキュメントで説明されているように、自動バキュームデーモンは複数のプロセスで動作します。このプロセスには、システム内の各データベースの自動バキュームワーカープロセスを開始する、永続的な自動バキュームランチャーが含まれます。ランチャーは、データベースあたり約 `autovacuum_naptime` 秒ごとにこれらのワーカーを開始するようにスケジュールします。

N 個のデータベースでは、新しいワーカーはおおよそ [`autovacuum_naptime`/N 秒] ごとに開始されます。ただし、同時ワーカーの合計数は `autovacuum_max_workers` 設定によって制限されます。バキューム処理を必要とするデータベースまたはテーブルの数がこの制限を超えると、ワーカーが利用可能になり次第すぐに次のデータベースまたはテーブルが処理されます。

多数の大きなテーブルやデータベースで同時にバキューム処理が必要な場合、使用可能なすべての自動バキュームワーカーが長時間占有され、他のテーブルやデータベースのメンテナンスに遅延が生じる可能性があります。トランザクションレートが高い環境では、このボトルネックがすぐに増大し、Amazon RDS インスタンス内で循環バキュームの問題が発生する可能性があります。

`postgres_get_av_diag()` が多数のテーブルまたはデータベースを検出すると、次の推奨事項が提示されます。

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
```

```
NOTICE: The current setting of autovacuum_max_workers:3 might not be sufficient. Consider increasing the setting and, if necessary, consider scaling up the Amazon RDS instance class for more workers.
```

**ガイダンス**

**autovacuum\$1max\$1workers を増やす**

バキューム処理を迅速化するために、`autovacuum_max_workers` パラメータを調整して同時実行の自動バキュームワーカーを増やすことをお勧めします。パフォーマンスのボトルネックが続く場合は、Amazon RDS インスタンスをより多くの vCPU を持つクラスにスケールアップすることを検討してください。これにより、並列処理機能をさらに向上させることができます。

## (循環を防ぐための) 積極的なバキューム処理が実行されている
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum"></a>

PostgreSQL のデータベースの経過時間 (MaximumUsedTransactionIDs) は、(循環を防ぐための) 積極的なバキューム処理が正常に完了した場合にのみ減少します。このバキューム処理が終了するまで、トランザクションレートに応じて経過時間は増加し続けます。

`postgres_get_av_diag()` 関数が積極的なバキュームを検出すると、次の `NOTICE` を生成します。ただし、この出力は、バキュームが少なくとも 2 分間アクティブになった後にのみトリガーされます。

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound, monitor autovacuum performance.
```

積極的なバキュームの詳細については、「[When an aggressive vacuum is already running](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md)」を参照してください。

次のクエリを使用して、積極的なバキュームが進行中かどうかを確認できます。

```
SELECT
    a.xact_start AS start_time,
    v.datname "database",
    a.query,
    a.wait_event,
    v.pid,
    v.phase,
    v.relid::regclass,
    pg_size_pretty(pg_relation_size(v.relid)) AS heap_size,
    (
        SELECT
            string_agg(pg_size_pretty(pg_relation_size(i.indexrelid)) || ':' || i.indexrelid::regclass || chr(10), ', ')
        FROM
            pg_index i
        WHERE
            i.indrelid = v.relid
    ) AS index_sizes,
    trunc(v.heap_blks_scanned * 100 / NULLIF(v.heap_blks_total, 0)) AS step1_scan_pct,
    v.index_vacuum_count || '/' || (
        SELECT
            count(*)
        FROM
            pg_index i
        WHERE
            i.indrelid = v.relid
    ) AS step2_vacuum_indexes,
    trunc(v.heap_blks_vacuumed * 100 / NULLIF(v.heap_blks_total, 0)) AS step3_vacuum_pct,
    age(CURRENT_TIMESTAMP, a.xact_start) AS total_time_spent_sofar
FROM
    pg_stat_activity a
    INNER JOIN pg_stat_progress_vacuum v ON v.pid = a.pid;
```

出力の query 列をチェックすることで、(循環を防ぐための) 積極的なバキュームであるかどうかを判断できます。「to prevent wraparound」という語句は、それが積極的なバキュームであることを示しています。

```
query                  | autovacuum: VACUUM public.t3 (to prevent wraparound)
```

例えば、トランザクション経過時間が 10 億の時点でブロック要因があり、同じトランザクション経過時間での循環を防ぐために積極的なバキューム処理を必要とするテーブルがあるとします。さらに、トランザクション経過時間が 7 億 5,000 万の時点で別のブロック要因もあります。トランザクション経過時間 10 億でのブロック要因をクリアしても、トランザクション経過時間はすぐに 7 億 5,000 万には低下しません。積極的なバキューム処理を必要とするテーブル、または経過時間が 7 億 5,000 万を超えるトランザクションが完了するまで、高いままとなります。この間、PostgreSQL クラスターのトランザクション経過時間は増加し続けます。バキューム処理が完了すると、トランザクションの経過時間は 7 億 5,000 万に低下しますが、さらにバキューム処理が完了するまで再び増加し始めます。このサイクルは、最終的にトランザクション経過時間が `autovacuum_freeze_max_age` で指定された Amazon RDS インスタンスの設定レベルに低下するまで、これらの条件が存続する限り続きます。

# RDS for PostgreSQL の NOTICE メッセージの説明
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE"></a>

 `postgres_get_av_diag()` 関数は、次の NOTICE メッセージを提供します。

**経過時間がまだモニタリングしきい値に達していない場合**  
ブロック要因を識別するための `postgres_get_av_diag()` のモニタリングしきい値は、デフォルトで 5 億トランザクションです。`postgres_get_av_diag()` で次の NOTICE が生成された場合は、トランザクション経過時間がまだこのしきい値に達していないことを示します。  

```
NOTICE: postgres_get_av_diag() checks for blockers that prevent aggressive vacuums only, it does so only after exceeding dvb_threshold which is 500,000,000 and age of this PostgreSQL cluster is currently at 2.
```

**トランザクション ID の経過時間が最も古いデータベースに接続していない**  
`postgres_get_av_diag()` 関数は、トランザクション ID の経過時間が最も古いデータベースに接続したときに、最も正確な出力を提供します。`postgres_get_av_diag()` によって報告されたトランザクション ID の経過時間が最も古いデータベースが、「my\$1database」とは異なる場合があります。正しいデータベースに接続していない場合、次の NOTICE が生成されます。  

```
NOTICE: You are not connected to the database with the age of oldest transaction ID. Connect to my_database database and run postgres_get_av_diag() for accurate reporting.
```
トランザクション経過時間が最も古いデータベースに接続することは、次の理由で重要です。  
+ **一時テーブルのブロック要因の識別:** 一時テーブルのメタデータは各データベースに固有のため、通常、一時テーブルは作成されたデータベースにあります。ただし、一時テーブルが上位のブロック要因となり、最も古いトランザクションを持つデータベースに存在する状況では、誤解が生じる可能性があります。適切なデータベースに接続することで、一時テーブルのブロック要因を正確に識別できます。
+ **遅いバキュームの診断:** インデックスメタデータとテーブル数の情報はデータベース固有であり、バキュームが遅い問題の診断に必要です。

**トランザクションの経過時間が最も古いデータベースが、rdsadmin または template0 データベースにある**  
場合によっては、`rdsadmin` または `template0` データベースが、トランザクション ID の経過時間が最も古いデータベースとして識別される場合があります。このような場合、`postgres_get_av_diag()` で次の NOTICE が発行されます。  

```
NOTICE: The database with the age of oldest transaction ID is rdsadmin or template0, reach out to support if the reported blocker is in rdsadmin or template0.
```
リストされたブロック要因がこれら 2 つのデータベースのいずれからも発生していないことを確認します。ブロック要因が `rdsadmin` または `template0` のいずれかに存在すると報告された場合は、サポートに問い合わせてください。ユーザーはこれらのデータベースにはアクセスできず、サポートが必要です。  
`rdsadmin` と `template0` データベースのいずれかに上位のブロック要因が含まれている可能性はほとんどありません。

**積極的なバキュームがすでに実行されている場合**  
`postgres_get_av_diag()` 関数は、積極的なバキューム処理が実行されているときに報告を行うように設計されていますが、この出力はバキュームが少なくとも 1 分間アクティブになった後にのみトリガーされます。この意図的な遅延によって、誤検出の可能性が低くなります。待機することで、有効で重要なバキュームのみが報告され、バキュームアクティビティのより正確で信頼性の高いモニタリングが可能になります。  
`postgres_get_av_diag()` 関数は、進行中の 1 つ以上の積極的なバキュームを検出すると、次の NOTICE を生成します。  

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound, monitor autovacuum performance.
```
NOTICE に示されているように、バキュームのパフォーマンスを引き続きモニタリングします。積極的なバキュームの詳細については、「[(循環を防ぐための) 積極的なバキューム処理が実行されている](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum)」を参照してください。

**自動バキュームがオフの場合**  
データベースインスタンスで自動バキュームが無効になっている場合、`postgres_get_av_diag()` 関数は次の NOTICE を生成します。  

```
NOTICE: Autovacuum is OFF, we strongly recommend to enable it, no restart is necessary.
```
自動バキュームは、RDS for PostgreSQL DB インスタンスの重要な機能であり、スムーズなデータベース操作を実現します。古い行バージョンを自動的に削除し、ストレージ領域を再利用して、テーブルの肥大化を防止することで、テーブルとインデックスの効率が維持され、パフォーマンスが最適化されます。さらに、Amazon RDS インスタンスのトランザクションを停止する可能性のある、トランザクション ID の循環も防止します。自動バキュームを無効にすると、データベースのパフォーマンスと安定性が長期的に低下する可能性があるため、常に有効にしておくことをお勧めします。詳細については、「[Understanding autovacuum in RDS for PostgreSQL environments](https://aws.amazon.com/blogs/database/understanding-autovacuum-in-amazon-rds-for-postgresql-environments/)」を参照してください。  
自動バキュームをオフにしても、積極的なバキュームは停止しません。積極的なバキュームは、テーブルが `autovacuum_freeze_max_age` しきい値に達すると実行されます。

**残っているトランザクションの数が非常に少ない**  
`postgres_get_av_diag()` 関数は、循環バキュームが差し迫った場合に次の NOTICE を生成します。この NOTICE は、Amazon RDS インスタンスが新しいトランザクションを拒否するまであと 1 億トランザクションに差し迫った場合に発行されます。  

```
WARNING: Number of transactions remaining is critically low, resolve issues with autovacuum or perform manual VACUUM FREEZE before your instance stops accepting transactions.
```
データベースのダウンタイムを回避するために、直ちにアクションが必要です。バキューム操作を注意深くモニタリングし、トランザクションの失敗を防ぐために、影響を受けるデータベースで `VACUUM FREEZE` を手動で開始することを検討する必要があります。

# Amazon RDS for PostgreSQL での高いオブジェクト数の管理
<a name="PostgreSQL.HighObjectCount"></a>

PostgreSQL の制限は理論上のものですが、データベース内のオブジェクト数が非常に多いと、さまざまなオペレーションにおいてパフォーマンスに顕著な影響が及びます。このドキュメントでは、合計数が多い場合にさまざまな影響を及ぼす可能性のある、いくつかの一般的なオブジェクトタイプについて説明します。

次の表は、オブジェクトタイプとその潜在的な影響の概要を示しています。


**オブジェクトタイプと潜在的な影響**  

| オブジェクトのタイプ | autovacuum | 論理レプリケーション | メジャーバージョンアップグレード | pg\$1dump / pg\$1restore | 全般的なパフォーマンス | インスタンスの再起動 | 
| --- | --- | --- | --- | --- | --- | --- | 
| [リレーション](#PostgreSQL.HighObjectCount.Relations) | x |  | x | x | x |  | 
| [一時テーブル](#PostgreSQL.HighObjectCount.TempTables)。 | x |  |  |  | x |  | 
| [ログに記録されないテーブル](#PostgreSQL.HighObjectCount.UnloggedTables) |  | x |  |  |  | x | 
| [パーティション](#PostgreSQL.HighObjectCount.Partitions) |  |  |  |  | x |  | 
| [一時ファイル](#PostgreSQL.HighObjectCount.TempFiles) |  |  |  |  | x |  | 
| [シーケンス](#PostgreSQL.HighObjectCount.Sequences) |  | x |  |  |  |  | 
| [ラージオブジェクト](#PostgreSQL.HighObjectCount.LargeObjects) |  | x | x |  |  |  | 

## リレーション
<a name="PostgreSQL.HighObjectCount.Relations"></a>

PostgreSQL データベース内のテーブル数に特定のハード制限はありません。理論上の制限は非常に高いですが、データベース設計時に留意する必要がある実用的な制限が他にもあります。

**影響: autovacuum が遅れる**  
autovacuum は、作業量と比較してワーカーが不足しているため、トランザクション ID の増加やテーブルの肥大化に対応しきれない可能性があります。  
**推奨されるアクション:** autovacuum をチューニングして、特定の数のテーブルと特定のワークロードに適切に対応させるには、いくつかの要素を考慮する必要があります。適切な autovacuum 設定を決定する方法については、「[PostgreSQL autovacuum を使用するためのベストプラクティス](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html)」を参照してください。[postgres\$1get\$1av\$1diag ユーティリティ](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Functions.html)を使用して、トランザクション ID の増加に関する問題をモニタリングします。

**影響: メジャーバージョンのアップグレード/pg\$1dump と復元**  
Amazon RDS は、pg\$1upgrade の実行中に「--link」オプションを使用して、データファイルのコピーを作成する必要がないようにしますが、スキーマメタデータは新しいバージョンのデータベースに復元する必要があります。並列 pg\$1restore を使用しても、リレーションの数が多いとダウンタイムが増加します。

**影響: 一般的なパフォーマンスの低下**  
カタログサイズによる一般的なパフォーマンスの低下。各テーブルとそれに関連する列は、`pg_attribute`、`pg_class`、および通常のデータベースオペレーションで頻繁に使用される `pg_depend` テーブルに追加されます。特定の待機イベントは表示されませんが、共有バッファの効率に影響します。  
**推奨されるアクション:** これらの特定のテーブルに対してテーブルの肥大化を定期的にチェックし、必要に応じてこれらの特定のテーブルに `VACUUM FULL` を実行します。カタログテーブルの `VACUUM FULL` では `ACCESS EXCLUSIVE` ロックが必要です。これは、オペレーションが完了するまで他のクエリがそれらにアクセスできないことを意味します。

**影響: ファイル記述子の枯渇**  
エラー: 「ファイル記述子不足: システムで開いているファイルが多すぎます。ファイルを解放して再試行してください」。PostgreSQL のパラメータ `max_files_per_process` は、各プロセスが開くことができるファイルの数を決定します。多数のテーブルを結合する接続の数が多い場合、この制限に達する可能性があります。  
**推奨されるアクション:**  
+ パラメータ `max_files_per_process` の値を下げると、このエラーを軽減できる可能性があります。各プロセスとサブプロセス (並列クエリなど) は、この数のファイルを開くことができ、クエリが複数のテーブルを結合している場合は、この制限を超える可能性があります。
+ 接続の総数を減らし、[Amazon RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) などの接続プーラー、または PgBouncer などの他のソリューションを使用します。詳細については、[PGBouncer](https://www.pgbouncer.org/) のウェブサイトを参照してください。

**影響: Inode の枯渇**  
エラー: 「デバイスに空き容量がありません」。ストレージの空き領域が大量にある場合にこれが観察された場合は、inode が不足していることが原因です。[Amazon RDS 拡張モニタリング](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Monitoring.OS.html)は、使用中の inode とホストで使用できる最大数を可視化します。

**概算しきい値:** [数百万](#PostgreSQL.HighObjectCount.Note)

## 一時テーブル
<a name="PostgreSQL.HighObjectCount.TempTables"></a>

一時テーブルの使用は、テストデータまたは中間結果に役立ち、多くのデータベースエンジンで見られる一般的なパターンです。PostgreSQL での大量使用の影響を理解して、いくつかの落とし穴を回避する必要があります。一時テーブルの作成と削除ごとに、システムカタログテーブルに行が追加され、肥大化すると、一般的なパフォーマンスの問題が発生します。

**影響: autovacuum が遅れる**  
一時テーブルは autovacuum によってバキューム処理されませんが、存在中はトランザクション ID を保持し、削除しないと循環が発生する可能性があります。  
**推奨されるアクション:** 一時テーブルは、それらを作成したセッション期間中存続するか、手動で削除できます。ベストプラクティスとして、一時テーブルを使用する際に長時間実行されるトランザクションを避けることで、これらのテーブルが使用済みトランザクション ID の最大値の増加に寄与するのを防ぐことができます。

**影響: 一般的なパフォーマンスの低下**  
カタログサイズによる一般的なパフォーマンスの低下。セッションが継続的に一時テーブルを作成および削除すると、通常のデータベースオペレーションで頻繁に使用される `pg_attribute`、`pg_class`、`pg_depend` テーブルにテーブルが追加されます。特定の待機イベントは表示されませんが、共有バッファの効率に影響します。  
**推奨されるアクション:**  
+ これらの特定のテーブルに対してテーブルの肥大化を定期的にチェックし、必要に応じてこれらの特定のテーブルに `VACUUM FULL` を実行します。カタログテーブルの `VACUUM FULL` では `ACCESS EXCLUSIVE` ロックが必要です。これは、オペレーションが完了するまで他のクエリがそれらにアクセスできないことを意味します。
+ 一時テーブルが頻繁に使用される場合は、メジャーバージョンアップグレードの前に、ダウンタイムを短縮するために、これらの特定のカタログテーブルの `VACUUM FULL` を強くお勧めします。

**一般的なベストプラクティス:**
+ 共通テーブル式を使用して中間結果を生成することで、一時テーブルの使用を減らします。これらは、必要なクエリを複雑にすることがありますが、上記の影響を排除できます。
+ `TRUNCATE` コマンドを使用して一時テーブルを再利用し、ドロップ/作成ステップを実行する代わりに内容をクリアします。これにより、一時テーブルによるトランザクション ID の増加の問題も排除されます。

**概算しきい値:** [数万](#PostgreSQL.HighObjectCount.Note)

## ログに記録されないテーブル
<a name="PostgreSQL.HighObjectCount.UnloggedTables"></a>

ログに記録されないテーブルは、WAL 情報を生成しないため、パフォーマンスを向上させることができます。これらはデータベースのクラッシュ回復中に切り捨てられるため、耐久性がなく、慎重に使用する必要があります。これは PostgreSQL ではコストの高いオペレーションであり、ログに記録されていない各テーブルは順次切り捨てられます。このオペレーションはログに記録されないテーブルの数が少ない場合は高速ですが、数千のテーブルの数になると、起動中に顕著な遅延が発生し始める可能性があります。

**影響: 論理レプリケーション**  
論理レプリケーションでは WAL を利用して変更をキャプチャおよび転送するため、ログに記録されないテーブルは通常、[ブルー/グリーンデプロイ](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html)を含む論理レプリケーションに含まれません。

  


**影響: 復旧中のダウンタイムが長引く**  
フェイルオーバーによるマルチ AZ 再起動、Amazon RDS ポイントインタイムリカバリ、Amazon RDS メジャーバージョンアップグレードなどのデータベースのクラッシュ回復を含むデータベース状態においては、ログに記録されないテーブルを切り捨てるシリアル化されたオペレーションが発生します。これにより、予想よりもはるかに高いダウンタイムが発生する可能性があります。  
**推奨されるアクション:**  
+ ログに記録されないテーブルの使用は、データベースのクラッシュ回復オペレーション中に失われても許容できるデータのみに限定するようにしてください。
+ シリアル切り捨ての現在の動作により、データベースの起動にかなりの時間がかかる可能性があるため、ログに記録されないテーブルの使用は最小限に抑えてください。

**一般的なベストプラクティス:**
+ ログに記録されないテーブルはクラッシュ時に安全性が確保されません。クラッシュ回復を伴うポイントインタイムリカバリの開始は、各テーブルを切り捨てるシリアルプロセスであるため、PostgreSQL ではかなりの時間がかかります。

**概算しきい値:** [数千](#PostgreSQL.HighObjectCount.Note)

## パーティション
<a name="PostgreSQL.HighObjectCount.Partitions"></a>

パーティション分割により、クエリのパフォーマンスが向上し、データの論理的な整理が可能になります。理想的なシナリオでは、パーティション分割は、クエリの計画と実行時にパーティションプルーニングを使用できるように構成されます。パーティションが多すぎると、クエリのパフォーマンスとデータベースのメンテナンスに悪影響を及ぼす可能性があります。クエリの計画と実行のパフォーマンスは、不十分な設計によって悪影響を受ける可能性があるため、テーブルを分割する方法の選択は慎重に行う必要があります。パーティション分割の詳細については、[PostgreSQL のドキュメント](https://www.postgresql.org/docs/current/ddl-partitioning.html)を参照してください。

**影響: 一般的なパフォーマンスの低下**  
場合によっては、計画時間のオーバーヘッドが増加し、クエリの実行計画がより複雑になり、チューニングの機会を特定することが難しくなる場合があります。18 より前の PostgreSQL バージョンでは、ワークロードの高いパーティションが多いと、`LWLock:LockManager` 待機につながる可能性があります。  
**推奨されるアクション:** データの整理を完了させると同時に、クエリの実行パフォーマンスも向上させるために必要な最小限のパーティション数を決定します。

**影響: メンテナンスの複雑さ**  
パーティションの数が非常に多いと、事前作成や削除などのメンテナンスの問題が発生します。autovacuum はパーティションを通常のリレーションとして扱い、定期的なクリーンアップを実行する必要があるため、タスクを完了するのに十分なワーカーが必要です。  
**推奨されるアクション:**  
+ 新しいパーティションが必要になったとき (月単位のパーティションなど) や古いパーティションがロールオフされたときにワークロードがブロックされないように、パーティションを事前に作成してください。
+ すべてのパーティションの通常のクリーンアップメンテナンスを実行するのに十分な autovacuum ワーカーがあることを確認します。

**概算しきい値:** [数百](#PostgreSQL.HighObjectCount.Note)

## 一時ファイル
<a name="PostgreSQL.HighObjectCount.TempFiles"></a>

上記の一時テーブルとは異なり、一時ファイルは、複雑なクエリが複数のソート操作またはハッシュ操作を同時に実行する可能性がある場合に PostgreSQL によって作成されます。各オペレーションは、インスタンスメモリを使用して `work_mem` パラメータで指定された値までの結果を保存します。インスタンスメモリが不足すると、結果を保存する一時ファイルが作成されます。一時ファイルの詳細については、「[一時ファイルの管理](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.ManagingTempFiles.html)」を参照してください。ワークロードがこれらのファイルを大量に生成する場合、いくつかの影響が生じる可能性があります。

  


**影響: ファイル記述子の枯渇**  
エラー: 「ファイル記述子不足: システムで開いているファイルが多すぎます。ファイルを解放して再試行してください」。PostgreSQL のパラメータ `max_files_per_process` は、各プロセスが開くことができるファイルの数を決定します。多数のテーブルを結合する接続の数が多い場合、この制限に達する可能性があります。  
**推奨されるアクション:**  
+ パラメータ `max_files_per_process` の値を下げると、このエラーを軽減できる可能性があります。各プロセスとサブプロセス (並列クエリなど) は、この数のファイルを開くことができ、クエリが複数のテーブルを結合している場合は、この制限を超える可能性があります。
+ 接続の総数を減らし、[Amazon RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) などの接続プーラーや PgBouncer などの他のソリューションを使用します。詳細については、[PGBouncer](https://www.pgbouncer.org/) のウェブサイトを参照してください。

**影響: Inode の枯渇**  
エラー: 「デバイスに空き容量がありません」。ストレージの空き領域が大量にある場合にこれが観察された場合は、inode が不足していることが原因です。[Amazon RDS 拡張モニタリング](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Monitoring.OS.html)は、使用中の inode とホストで使用できる最大数を可視化します。

**一般的なベストプラクティス:**
+ [Performance Insights](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PerfInsights.html) を使用して一時ファイルの使用状況をモニタリングします。
+ 大量の一時ファイルを生成しているクエリを調整して、一時ファイルの合計数を減らすことができるかどうかを確認します。

**概算しきい値:** [数千](#PostgreSQL.HighObjectCount.Note)

## シーケンス
<a name="PostgreSQL.HighObjectCount.Sequences"></a>

シーケンスは、PostgreSQL の列の自動増分に使用される基盤となるオブジェクトであり、データの一意性とキーを提供します。これらは、論理レプリケーションを 1 つ例外として、通常のオペレーション中に特に影響を与えることなく、個々のテーブルで使用できます。

PostgreSQL では、論理レプリケーションは現在、シーケンスの現在の値をサブスクライバーにレプリケートしません。詳細については、[PostgreSQL のドキュメントの制約事項ページ](https://www.postgresql.org/docs/current/logical-replication-restrictions.html)を参照してください。

**影響: スイッチオーバー時間の延長**  
任意のタイプの設定変更またはアップグレードに、[Amazon RDS ブルー/グリーンデプロイ](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html)を使用する予定がある場合は、多数のシーケンスがスイッチオーバーに与える影響を理解することが重要です。スイッチオーバーの最後のフェーズの 1 つとして、シーケンスの現在の値を同期させる処理が行われますが、その数が数千に及ぶ場合、スイッチオーバー全体の所要時間が長くなります。  
**推奨されるアクション:** データベースワークロードがテーブルごとのシーケンスアプローチではなく共有 UUID の使用を許可する場合、スイッチオーバー中に同期ステップを削減できます。

**概算しきい値:** [数千](#PostgreSQL.HighObjectCount.Note)

## ラージオブジェクト
<a name="PostgreSQL.HighObjectCount.LargeObjects"></a>

ラージオブジェクトは pg\$1largeobject という名前の単一のシステムテーブルに保存されます。各ラージオブジェクトには、システムテーブル pg\$1largeobject\$1metadata にもエントリがあります。これらのオブジェクトは、標準リレーションとは大幅に異なる方法で作成、変更、クリーンアップされます。ラージオブジェクトは autovacuum では処理されないため、vacuumlo と呼ばれる別のプロセスで定期的にクリーンアップする必要があります。ラージオブジェクトの管理の例については、「lo モジュールを使用したラージオブジェクトの管理」を参照してください。

**影響: 論理レプリケーション**  
現在、PostgreSQL では論理レプリケーション時にラージオブジェクトはレプリケートされません。詳細については、[PostgreSQL のドキュメントの制約事項ページ](https://www.postgresql.org/docs/current/logical-replication-restrictions.html)を参照してください。[ブルー/グリーン](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html)設定では、ブルー環境内のラージオブジェクトはグリーン環境にレプリケートされません。

**影響: メジャーバージョンアップグレード**  
数百万のラージオブジェクトがあり、アップグレード中にインスタンスがそれらを処理できない場合、アップグレードはメモリ不足になり、失敗する可能性があります。PostgreSQL メジャーバージョンのアップグレードプロセスは、大きく分けて 2 つのフェーズで構成されます。pg\$1dump によるスキーマダンプと、pg\$1restore による復元です。データベースに数百万のラージオブジェクトがある場合は、アップグレード中に pg\$1dump と pg\$1restore を処理するために十分なメモリがインスタンスにあることを確認し、より大きなインスタンスタイプにスケールする必要があります。

**一般的なベストプラクティス:**
+ vacuumlo ユーティリティを定期的に使用して、孤立したラージオブジェクトを削除します。
+ ラージオブジェクトをデータベースに保存する場合は、BYTEA データ型を使用することを検討してください。

**概算しきい値:** [数百万](#PostgreSQL.HighObjectCount.Note)

## 概算しきい値
<a name="PostgreSQL.HighObjectCount.Note"></a>

このトピックで説明されている概算しきい値は、特定のリソースがスケールできる範囲を推定するためにのみ使用されます。これらは、説明されている影響が発生する可能性が高くなる一般的な範囲を示していますが、実際の動作は、特定のワークロード、インスタンスサイズ、および設定によって異なります。これらの予測を超える可能性はあるものの、記載されている影響を避けるためには、適切な管理とメンテナンスを遵守する必要があります。

# Amazon RDS for PostgreSQL での TOAST OID 競合の管理
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID"></a>

TOAST (オーバーサイズ属性ストレージ技術) は、一般的な 8KB のデータベースブロックサイズを超える大きなデータ値を処理するように設計された PostgreSQL 機能です。PostgreSQL では、物理的な行が複数のブロックにまたがることは許可されません。ブロックサイズは、行サイズの上限として機能します。TOAST は、大きなフィールド値を小さなチャンクに分割することで、この制限を克服します。メインテーブルにリンクされた専用の TOAST テーブルに個別に保存されます。詳細については、「[PostgreSQL TOAST storage mechanism and implementation documentation](https://www.postgresql.org/docs/current/storage-toast.html)」を参照してください。

**Topics**
+ [

## TOAST オペレーションについて
](#Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.HowWorks)
+ [

## パフォーマンスの課題を特定する
](#Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.PerformanceChallenges)
+ [

## 推奨事項
](#Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.Recommendations)
+ [

## モニタリング
](#Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.Monitoring)

## TOAST オペレーションについて
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.HowWorks"></a>

TOAST は圧縮を実行し、大きなフィールド値を行外に保存します。TOAST は、TOAST テーブルに保存されているオーバーサイズのデータの各チャンクに一意の OID (オブジェクト識別子) を割り当てます。メインテーブルは TOAST 値 ID とリレーション ID をページに保存し、TOAST テーブルの対応する行を参照します。これにより、PostgreSQL はこれらの TOAST チャンクを効率的に見つけて管理できます。ただし、TOAST テーブルが大きくなると、システムは使用可能な OID を使い果たすリスクがあり、OID の枯渇によりパフォーマンスが低下し、ダウンタイムが発生する可能性があります。

### TOAST のオブジェクト識別子
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.ObjectIdentifiers"></a>

オブジェクト識別子 (OID) は、PostgreSQL がテーブル、インデックス、関数などのデータベースオブジェクトを参照するために使用するシステム全体の一意の識別子です。これらの識別子は PostgreSQL の内部オペレーションで重要な役割を果たし、データベースがオブジェクトを効率的に見つけて管理できるようにします。

トーストの対象となるデータセットを持つテーブルの場合、PostgreSQL は OID を割り当てて、関連付けられた TOAST テーブルに保存されているオーバーサイズデータの各チャンクを一意に識別します。システムは各チャンクを `chunk_id` に関連付けます。これにより、PostgreSQL はこれらのチャンクを TOAST テーブル内で効率的に整理して見つけることができます。

## パフォーマンスの課題を特定する
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.PerformanceChallenges"></a>

PostgreSQL の OID 管理は、グローバル 32 ビットカウンターに依存しているため、40 億の一意の値を生成した後は最初に戻ります。データベースクラスターがこのカウンターを共有する間、OID 割り当てには TOAST オペレーション中の 2 つのステップが含まれます。
+ **割り当てのグローバルカウンター** – グローバルカウンターは、クラスター全体に新しい OID を割り当てます。
+ **競合のローカル検索** – TOAST テーブルは、新しい OID がその特定のテーブルで既に使用されている既存の OID と競合しないようにします。

パフォーマンスの低下は、次の場合に発生する可能性があります。
+ TOAST テーブルはフラグメント化または密な OID 使用率が高く、OID の割り当てが遅れます。
+ データチャーンが高い環境や TOAST を多用する幅の広いテーブルがある環境では、システムは OID を頻繁に割り当てて再利用します。

詳細については、「[PostgreSQL TOAST table size limits and OID allocation documentation](https://wiki.postgresql.org/wiki/TOAST#Total_table_size_limit)」を参照してください。

グローバルカウンターは OID を生成し、40 億個の値ごとに最初に戻るため、システムは時折、既に使用されている値を再生成します。PostgreSQL はそれを検出し、次の OID で再試行します。TOAST テーブル内で、使用済み OID 値が非常に長く連続し、ギャップがない場合、INSERT が遅くなる可能性があります。これらの課題は、OID スペースがいっぱいになるとより顕著になり、挿入と更新が遅くなります。

### 問題の特定
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.IdentifyingProblem"></a>
+ 単純な `INSERT` ステートメントは、一貫性のないランダムな方法で、通常よりも大幅に時間がかかります。
+ 遅延は、TOAST オペレーションを含む `INSERT` および `UPDATE` ステートメントに対してのみ発生します。
+ システムが TOAST テーブルで使用可能な OID を見つけられない場合、次のログエントリが PostgreSQL ログに表示されます。

  ```
  LOG: still searching for an unused OID in relation "pg_toast_20815"
  DETAIL: OID candidates have been checked 1000000 times, but no unused OID has been found yet.
  ```
+ Performance Insights は、`LWLock:buffer_io` および `LWLock:OidGenLock` 待機イベントに関連付けられた平均アクティブセッション (AAS) の数が多いことを示します。

  次の SQL クエリを実行して、長時間実行される INSERT トランザクションを待機イベントで識別できます。

  ```
  SELECT
      datname AS database_name,
      usename AS database_user,
      pid,
      now() - pg_stat_activity.xact_start AS transaction_duration,
      concat(wait_event_type, ':', wait_event) AS wait_event,
      substr(query, 1, 30) AS TRANSACTION,
      state
  FROM
      pg_stat_activity
  WHERE (now() - pg_stat_activity.xact_start) > INTERVAL '60 seconds'
      AND state IN ('active', 'idle in transaction', 'idle in transaction (aborted)', 'fastpath function call', 'disabled')
      AND pid <> pg_backend_pid()
  AND lower(query) LIKE '%insert%'
  ORDER BY
      transaction_duration DESC;
  ```

  待機時間が長い INSERT オペレーションを表示するクエリ結果の例。

  ```
   database_name |  database_user  |  pid  | transaction_duration |     wait_event      |          transaction           | state
  ---------------+-----------------+-------+----------------------+---------------------+--------------------------------+--------
   postgres       | db_admin_user| 70965 | 00:10:19.484061      | LWLock:buffer_io    | INSERT INTO "products" (......... | active
   postgres       | db_admin_user| 69878 | 00:06:14.976037      | LWLock:buffer_io    | INSERT INTO "products" (......... | active
   postgres       | db_admin_user| 68937 | 00:05:13.942847      | :                   | INSERT INTO "products" (......... | active
  ```

### 問題の分離
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.IsolatingProblem"></a>
+ **小さな挿入をテストする** – `toast_tuple_target` しきい値より小さいレコードを挿入します。TOAST ストレージの前に圧縮が適用されることに注意してください。これがパフォーマンスの問題なく動作する場合、問題は TOAST オペレーションに関連しています。
+ **新しいテーブルをテストする** – 同じ構造で新しいテーブルを作成し、`toast_tuple_target` より大きいレコードを挿入します。問題なく動作する場合、問題は元のテーブルの OID 割り当てに限定されます。

## 推奨事項
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.Recommendations"></a>

以下のアプローチは、TOAST OID 競合の問題を解決するのに役立ちます。
+ **データのクリーンアップとアーカイブ** – 廃止されたデータや不要なデータを確認して削除し、将来の使用のために OID を解放するか、データをアーカイブします。次の制限事項を考慮してください。
  + 将来のクリーンアップが常に可能とは限らないため、スケーラビリティが制限されます。
  + 長時間実行される VACUUM オペレーションで、生成されたデッドタプルを削除できます。
+ **新しいテーブルに書き込む** – 将来の挿入用に新しいテーブルを作成し、`UNION ALL` ビューを使用してクエリの古いデータと新しいデータを結合します。このビューは、古いテーブルと新しいテーブルの両方から組み合わされたデータを表示し、クエリが単一のテーブルとしてそれらにアクセスできるようにします。次の制限事項を考慮してください。
  + 古いテーブルを更新すると、OID が枯渇する可能性があります。
+ **パーティションまたはシャード** – テーブルまたはシャードデータをパーティション化して、スケーラビリティとパフォーマンスを向上させます。次の制限事項を考慮してください。
  + クエリロジックとメンテナンスの複雑さが増し、パーティション化されたデータを正しく処理するためにアプリケーションの変更が必要になる可能性があります。

## モニタリング
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.Monitoring"></a>

### システムテーブルの使用
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.SystemTables"></a>

PostgreSQL のシステムテーブルを使用して、OID 使用量の増加をモニタリングできます。

**警告**  
TOAST テーブルの OID の数によっては、完了までに時間がかかる場合があります。影響を最小限に抑えるために、営業時間外にモニタリングをスケジュールすることをお勧めします。

次の匿名ブロックは、各 TOAST テーブルで使用される個別の OID の数をカウントし、親テーブル情報を表示します。

```
DO $$
DECLARE
    r record;
    o bigint;
    parent_table text;
    parent_schema text;
BEGIN
    SET LOCAL client_min_messages TO notice;
    FOR r IN
    SELECT
        c.oid,
        c.oid::regclass AS toast_table
    FROM
        pg_class c
    WHERE
        c.relkind = 't'
        AND c.relowner != 10 LOOP
            -- Fetch the number of distinct used OIDs (chunk IDs) from the TOAST table
            EXECUTE 'SELECT COUNT(DISTINCT chunk_id) FROM ' || r.toast_table INTO o;
            -- If there are used OIDs, find the associated parent table and its schema
            IF o <> 0 THEN
                SELECT
                    n.nspname,
                    c.relname INTO parent_schema,
                    parent_table
                FROM
                    pg_class c
                    JOIN pg_namespace n ON c.relnamespace = n.oid
                WHERE
                    c.reltoastrelid = r.oid;
                -- Raise a concise NOTICE message
                RAISE NOTICE 'Parent schema: % | Parent table: % | Toast table: % | Number of used OIDs: %', parent_schema, parent_table, r.toast_table, TO_CHAR(o, 'FM9,999,999,999,999');
            END IF;
        END LOOP;
END
$$;
```

TOAST テーブル別に OID 使用状況統計を表示する出力例。

```
NOTICE:  Parent schema: public | Parent table: my_table | Toast table: pg_toast.pg_toast_16559 | Number of used OIDs: 45,623,317
NOTICE:  Parent schema: public | Parent table: my_table1 | Toast table: pg_toast.pg_toast_45639925 | Number of used OIDs: 10,000
NOTICE:  Parent schema: public | Parent table: my_table2 | Toast table: pg_toast.pg_toast_45649931 | Number of used OIDs: 1,000,000
DO
```

次の匿名ブロックは、空でない TOAST テーブルごとに割り当てられた最大 OID を取得します。

```
DO $$
DECLARE
    r record;
    o bigint;
    parent_table text;
    parent_schema text;
BEGIN
    SET LOCAL client_min_messages TO notice;
    FOR r IN
    SELECT
        c.oid,
        c.oid::regclass AS toast_table
    FROM
        pg_class c
    WHERE
        c.relkind = 't'
        AND c.relowner != 10 LOOP
            -- Fetch the max(chunk_id) from the TOAST table
            EXECUTE 'SELECT max(chunk_id) FROM ' || r.toast_table INTO o;
            -- If there's at least one TOASTed chunk, find the associated parent table and its schema
            IF o IS NOT NULL THEN
                SELECT
                    n.nspname,
                    c.relname INTO parent_schema,
                    parent_table
                FROM
                    pg_class c
                    JOIN pg_namespace n ON c.relnamespace = n.oid
                WHERE
                    c.reltoastrelid = r.oid;
                -- Raise a concise NOTICE message
                RAISE NOTICE 'Parent schema: % | Parent table: % | Toast table: % | Max chunk_id: %', parent_schema, parent_table, r.toast_table, TO_CHAR(o, 'FM9,999,999,999,999');
            END IF;
        END LOOP;
END
$$;
```

TOAST テーブルの最大チャンク ID を表示する出力例。

```
NOTICE:  Parent schema: public | Parent table: my_table | Toast table: pg_toast.pg_toast_16559 | Max chunk_id: 45,639,907
NOTICE:  Parent schema: public | Parent table: my_table1 | Toast table: pg_toast.pg_toast_45639925 | Max chunk_id: 45,649,929
NOTICE:  Parent schema: public | Parent table: my_table2 | Toast table: pg_toast.pg_toast_45649931 | Max chunk_id: 46,649,935
DO
```

### Performance Insights の使用
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.PerformanceInsights"></a>

待機イベント `LWLock:buffer_io` と `LWLock:OidGenLock` は、新しいオブジェクト識別子 (OID) の割り当てを必要とするオペレーション中に Performance Insights に表示されます。これらのイベントの高平均アクティブセッション (AAS) は、通常、OID の割り当てとリソース管理中に競合を示します。これは、データチャーンが高い環境、大規模なデータが頻繁に使用される、またはオブジェクトが頻繁に作成される環境で特に一般的です。

#### LWLock:buffer\$1io
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.LWLockBufferIO"></a>

`LWLock:buffer_io` は、PostgreSQL セッションが共有バッファの I/O オペレーションの完了を待機しているときに発生する待機イベントです。これは通常、データベースがディスクからメモリにデータを読み取り、変更されたページをメモリからディスクに書き込むときに発生します。`BufferIO` 待機イベントは、I/O オペレーションの進行中に複数のプロセスが同じバッファにアクセスまたは変更されないようにすることで、一貫性を確保します。この待機イベントの発生率が高い場合は、データベースワークロードのディスクのボトルネックまたは過剰な I/O アクティビティを示している可能性があります。

TOAST オペレーション中。
+ PostgreSQL は大きなオブジェクト OID を割り当て、TOAST テーブルのインデックスをスキャンしてその一意性を確保します。
+ 大きな TOAST インデックスでは、OID の一意性を検証するために複数のページにアクセスする必要がある場合があります。これにより、特にバッファプールが必要なすべてのページをキャッシュできない場合に、ディスク I/O が増加します。

インデックスのサイズは、これらのオペレーション中にアクセスする必要があるバッファページの数に直接影響します。インデックスが肥大化していない場合でも、特に高同時実行または高チャーン環境では、膨大なサイズによってバッファ I/O が増加する可能性があります。詳細については、「[LWLock:BufferIO 待機イベントのトラブルシューティングガイド](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/apg-waits.lwlockbufferio.html)」を参照してください。

#### Lwlock:OidGenLock
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.LWLockOidGenLock"></a>

`OidGenLock` は、PostgreSQL セッションが新しいオブジェクト識別子 (OID) の割り当てを待機しているときに発生する待機イベントです。このロックにより、OID が順番に安全に生成され、一度に 1 つのプロセスのみが OID を生成できます。

TOAST オペレーション中。
+ **TOAST テーブルのチャンクの OID 割り当て** – PostgreSQL は、大きなデータレコードを管理するときに、TOAST テーブルのチャンクに OID を割り当てます。システムカタログの競合を防ぐために、各 OID は一意である必要があります。
+ **高い同時実行性** – OID ジェネレーターへのアクセスはシーケンシャルであるため、複数のセッションが同時に OID を必要とするオブジェクトを作成している場合、`OidGenLock` の競合が発生する可能性があります。これにより、OID 割り当てが完了するまでセッションが待機する可能性が高まります。
+ **システムカタログアクセスの依存関係** – OID を割り当てるには、`pg_class` や `pg_type` などの共有システムカタログテーブルを更新する必要があります。これらのテーブルで大量のアクティビティが発生した場合 (DDL オペレーションが頻繁に発生するため)、`OidGenLock` のロック競合が増加する可能性があります。
+ **高い OID 割り当ての需要** – 大量のデータレコードを持つ TOAST 負荷の高いワークロードには、一定の OID 割り当てが必要で、競合が増大します。

OID の競合を増やすその他の要因。
+ **頻繁なオブジェクトの作成** – 一時テーブルなどのオブジェクトを頻繁に作成および削除するワークロードは、グローバル OID カウンターでの競合を増幅します。
+ **グローバルカウンターロック** – グローバル OID カウンターは一意性を確保するために連続してアクセスされ、同時実行性の高い環境で単一の競合ポイントを作成します。

## RDS for PostgreSQL でサポートされているログ記録メカニズムの使用
<a name="Appendix.PostgreSQL.CommonDBATasks.Auditing"></a>

いくつかのパラメータ、エクステンション、その他の設定可能な項目を設定して、PostgreSQL DB インスタンスで発生するアクティビティのログを作成できます。これには以下が含まれます。
+ `log_statement` パラメータは PostgreSQL データベースのユーザー操作のログを作成するのに使用できます。RDS for PostgreSQL のログ記録とログのモニタリング方法の詳細については、「[ RDS for PostgreSQL データベースログファイル](USER_LogAccess.Concepts.PostgreSQL.md)」を参照してください。
+ `rds.force_admin_logging_level` パラメータにより、DB インスタンス上のデータベースでの Amazon RDS 内部ユーザー (rdsadmin) によるアクションをログに記録されます。出力が PostgreSQL エラーログに書き込まれます。指定可能な値は、`disabled`、`debug5`、`debug4`、`debug3`、`debug2`、`debug1`、`info`、`notice`、`warning`、`error`、log、`fatal`、および `panic` です。デフォルト値は `disabled` です。
+ `rds.force_autovacuum_logging_level` パラメータを設定して、PostgreSQL エラーログにさまざまな自動バキュームオペレーションをキャプチャすることができます。詳細については、「[自動バキュームおよびバキュームアクティビティのログ記録](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Logging.md)」を参照してください。
+ PostgreSQL Audit (pgAudit) 拡張は、セッションレベルまたはオブジェクトレベルでアクティビティをキャプチャするようにインストールおよび設定できます。詳細については、「[pgAudit を使用してデータベースのアクティビティを記録する](Appendix.PostgreSQL.CommonDBATasks.pgaudit.md)」を参照してください。
+ `log_fdw` 拡張を使用すると、SQL を使用してデータベースエンジンのログにアクセスすることができます。詳細については、「[SQL を使用した DB ログのアクセスのための log\$1fdw 拡張機能の使用](CHAP_PostgreSQL.Extensions.log_fdw.md)」を参照してください。
+ `pg_stat_statements` ライブラリは、PostgreSQL バージョン 10 以降の RDS で、`shared_preload_libraries` パラメータのデフォルトとして指定されています。実行中のクエリを分析するために使用できるのはこのライブラリです。DB パラメータグループで `pg_stat_statements` が設定されていることを確認してください。このライブラリが提供する情報を使用した RDS for PostgreSQL DB インスタンスのモニタリングの詳細については、「[RDS PostgreSQL での SQL 統計](USER_PerfInsights.UsingDashboard.AnalyzeDBLoad.AdditionalMetrics.PostgreSQL.md)」を参照してください。
+ `log_hostname` パラメータは、各クライアント接続のホスト名をログに取り込みます。PostgreSQL バージョン 12 以降のバージョンの RDS では、このパラメータはデフォルトで `off` に設定されています。オンにする場合は、必ずセッション接続時間をモニタリングしてください。オンにすると、サービスはドメインネームシステム (DNS) 逆ルックアップリクエストを使用して接続しているクライアントのホスト名を取得し、PostgreSQL ログに追加します。これはセッション接続中に顕著な影響を及ぼします。このパラメータはトラブルシューティングの目的のみでオンにすることをお勧めします。

一般に、ログ記録のポイントは、DBA がモニタリング、パフォーマンスのチューニング、およびトラブルシューティングを実行できるようにすることです。ログの多くは、Amazon CloudWatch または Performance Insights に自動的にアップロードされます。ここでは、DB インスタンスの完全なメトリクスを提供するためにソートおよびグループ化されています。Amazon RDS のモニタリングとメトリクスの詳細については、「[Amazon RDS インスタンスでのメトリクスのモニタリング](CHAP_Monitoring.md)」を参照してください。

# PostgreSQL による一時ファイルの管理
<a name="PostgreSQL.ManagingTempFiles"></a>

PostgreSQL では、複雑なクエリが、インスタンスメモリを使用して [https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM) パラメータで指定された値までの結果を保存する、複数のソート操作またはハッシュ操作を同時に実行する場合があります。インスタンスメモリが不足すると、結果を保存する一時ファイルが作成されます。これらは、クエリの実行を完了するためにディスクに書き込まれます。その後、これらのファイルは、クエリが完了すると自動的に削除されます。RDS for PostgreSQL では、これらのファイルはデータボリュームの Amazon EBS に保存されます。詳細については、「[Amazon RDS DB インスタンスのストレージ](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html)」を参照してください。CloudWatch で提供される `FreeStorageSpace` メトリクスを常にモニタリングして、DB インスタンスのストレージに十分な空き容量があることを確認できます。詳細については、「[https://repost.aws/knowledge-center/storage-full-rds-cloudwatch-alarm](https://repost.aws/knowledge-center/storage-full-rds-cloudwatch-alarm)」を参照してください。

複数のクエリが同時に実行され、一時ファイルの使用量が増えるワークロードには、Amazon RDS Optimized Read インスタンスを使用することをお勧めします。これらのインスタンスがローカルの不揮発性メモリエクスプレス (NVMe) ベースのソリッドステートドライブ (SSD) ブロックレベルストレージを使用することで、一時ファイルを配置します。詳細については、「[Amazon RDS Optimized Reads による RDS for PostgreSQL のクエリパフォーマンスの向上](USER_PostgreSQL.optimizedreads.md)」を参照してください。

以下のパラメータと関数を使用して、インスタンスの一時ファイルを管理することができます。
+ **[https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-DISK](https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-DISK)** — このパラメータは、temp\$1files のサイズ (KB 単位) を超えるクエリをすべてキャンセルします。この制限により、クエリが延々と実行され、一時ファイルでディスクスペースが消費されるのを防ぐことができます。`log_temp_files` パラメータの結果を使用して値を推定できます。ベストプラクティスとして、ワークロードの動作を調べ、推定値に従って制限を設定してください。次の例は、クエリが制限を超えた場合にキャンセルされる様子を示しています。

  ```
  postgres=>select * from pgbench_accounts, pg_class, big_table;
  ```

  ```
  ERROR: temporary file size exceeds temp_file_limit (64kB)
  ```
+ **[https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-TEMP-FILES](https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-TEMP-FILES)** — このパラメータは、セッションの一時ファイルが削除されたときに postgresql.log にメッセージを送信します。このパラメータは、クエリが正常に完了した後にログを生成します。そのため、アクティブで長時間実行されるクエリのトラブルシューティングには役立たない可能性があります。

  次の例は、クエリが正常に完了すると、エントリが postgresql.log ファイルに記録され、一時ファイルがクリーンアップされることを示しています。

  ```
                      
  2023-02-06 23:48:35 UTC:205.251.233.182(12456):adminuser@postgres:[31236]:LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp31236.5", size 140353536
  2023-02-06 23:48:35 UTC:205.251.233.182(12456):adminuser@postgres:[31236]:STATEMENT:  select a.aid from pgbench_accounts a, pgbench_accounts b where a.bid=b.bid order by a.bid limit 10;
  2023-02-06 23:48:35 UTC:205.251.233.182(12456):adminuser@postgres:[31236]:LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp31236.4", size 180428800
  2023-02-06 23:48:35 UTC:205.251.233.182(12456):adminuser@postgres:[31236]:STATEMENT:  select a.aid from pgbench_accounts a, pgbench_accounts b where a.bid=b.bid order by a.bid limit 10;
  ```
+ **[https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADMIN-GENFILE](https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADMIN-GENFILE)** — この関数は RDS for PostgreSQL 13 以降で使用でき、現在の一時ファイルの使用状況を可視化できます。完了したクエリは、関数の結果には表示されません。次の例では、この関数の結果を表示できます。

  ```
  postgres=>select * from pg_ls_tmpdir();
  ```

  ```
        name       |    size    |      modification
  -----------------+------------+------------------------
   pgsql_tmp8355.1 | 1072250880 | 2023-02-06 22:54:56+00
   pgsql_tmp8351.0 | 1072250880 | 2023-02-06 22:54:43+00
   pgsql_tmp8327.0 | 1072250880 | 2023-02-06 22:54:56+00
   pgsql_tmp8351.1 |  703168512 | 2023-02-06 22:54:56+00
   pgsql_tmp8355.0 | 1072250880 | 2023-02-06 22:54:00+00
   pgsql_tmp8328.1 |  835031040 | 2023-02-06 22:54:56+00
   pgsql_tmp8328.0 | 1072250880 | 2023-02-06 22:54:40+00
  (7 rows)
  ```

  ```
  postgres=>select query from pg_stat_activity where pid = 8355;
                  
  query
  ----------------------------------------------------------------------------------------
  select a.aid from pgbench_accounts a, pgbench_accounts b where a.bid=b.bid order by a.bid
  (1 row)
  ```

  ファイル名には、一時ファイルを生成したセッションの処理 ID (PID) が含まれます。次の例のような、より高度なクエリでは、各 PID の一時ファイルの合計が実行されます。

  ```
  postgres=>select replace(left(name, strpos(name, '.')-1),'pgsql_tmp','') as pid, count(*), sum(size) from pg_ls_tmpdir() group by pid;
  ```

  ```
   pid  | count |   sum
  ------+-------------------
   8355 |     2 | 2144501760
   8351 |     2 | 2090770432
   8327 |     1 | 1072250880
   8328 |     2 | 2144501760
  (4 rows)
  ```
+ **`[ pg\$1stat\$1statements](https://www.postgresql.org/docs/current/pgstatstatements.html)`** — pg\$1stat\$1statements パラメータを有効にすると、呼び出しごとの一時ファイルの平均使用量を表示できます。次の例に示すように、クエリの query\$1id を特定し、それを使用して一時ファイルの使用状況を調べることができます。

  ```
  postgres=>select queryid from pg_stat_statements where query like 'select a.aid from pgbench%';
  ```

  ```
         queryid
  ----------------------
   -7170349228837045701
  (1 row)
  ```

  ```
  postgres=>select queryid, substr(query,1,25), calls, temp_blks_read/calls temp_blks_read_per_call, temp_blks_written/calls temp_blks_written_per_call from pg_stat_statements where queryid = -7170349228837045701;
  ```

  ```
         queryid        |          substr           | calls | temp_blks_read_per_call | temp_blks_written_per_call
  ----------------------+---------------------------+-------+-------------------------+----------------------------
   -7170349228837045701 | select a.aid from pgbench |    50 |                  239226 |                     388678
  (1 row)
  ```
+ **`[Performance Insights](https://aws.amazon.com/rds/performance-insights/)`** — Performance Insights ダッシュボードで、**temp\$1bytes** と **temp\$1files** のメトリクスをオンにすると、一時ファイルの使用状況を確認できます。次に、これら両方のメトリクスの平均と、それらがクエリワークロードにどのように対応しているかを確認できます。Performance Insights 内のビューには、一時ファイルを生成しているクエリが具体的に表示されません。ただし、Performance Insights と `pg_ls_tmpdir` に示されるクエリを組み合わせると、クエリワークロードの変化をトラブルシューティング、分析、判断できます。

  Performance Insights を使用してメトリクスとクエリを分析する方法については、「[Performance Insights ダッシュボードを使用してメトリクスを分析する](USER_PerfInsights.UsingDashboard.md)」を参照してください。

  Performance Insights で一時ファイルの使用状況を表示する例については、「[Performance Insights を使用した一時ファイルの使用状況の確認](PostgreSQL.ManagingTempFiles.Example.md)」を参照してください。

# Performance Insights を使用した一時ファイルの使用状況の確認
<a name="PostgreSQL.ManagingTempFiles.Example"></a>

Performance Insights で、**temp\$1bytes** と **temp\$1files** のメトリクスをオンにすると、一時ファイルの使用状況を確認できます。Performance Insights のビューには、一時ファイルを生成する特定のクエリは表示されませんが、Performance Insights を `pg_ls_tmpdir` に示されているクエリと組み合わせると、クエリワークロードの変更をトラブルシューティング、分析、判断できます。

1. Performance Insights ダッシュボードで、**[メトリクスを管理]** を選択します。

1. 次の画像に示すように、**[データベースメトリクス]** を選択して、**[temp\$1bytes]** と **[temp\$1files]** を選択します。  
![\[メトリクスがグラフに表示されます。\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/images/rpg_mantempfiles_metrics.png)

1. **[トップ SQL]** タブで、**[設定]** アイコンを選択します。

1. **[設定]** ウィンドウで、**[トップ SQL]** タブに以下の統計が表示されるようにして、**[続行]** を選択します。
   + Temp writes/sec
   + Temp reads/sec
   + Tmp blk write/call
   + Tmp blk read/call

1. 次の例に示すように、`pg_ls_tmpdir` で示したクエリと組み合わせると、この一時ファイルが抜き出されます。  
![\[一時ファイルの使用状況を表示するクエリ。\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/images/rpg_mantempfiles_query.png)

`IO:BufFileRead` と `IO:BufFileWrite` イベントは、ワークロードの上位クエリが一時ファイルを頻繁に作成するときに発生します。Performance Insights を使用することで、「データベース負荷」と「上位 SQL」セクションの「平均アクティブセッション (AAS)」を参照して、`IO:BufFileRead` と `IO:BufFileWrite` を待機中の上位クエリの特定が可能になります。

![\[グラフの IO:BufFileRead および IO:BufFileWrite。\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/images/perfinsights_IOBufFile.png)


Performance Insights を使用して上位クエリを分析して、待機イベント別にロードする方法については、「[[トップ SQL] タブの概要](USER_PerfInsights.UsingDashboard.AnalyzeDBLoad.AdditionalMetrics.md#USER_PerfInsights.UsingDashboard.Components.AvgActiveSessions.TopLoadItemsTable.TopSQL)」を参照してください テンポラリファイルの使用量と関連する待機イベントの増加の原因となるクエリを特定し、調整する必要があります。これらの待機イベントと修復方法の詳細については、「[IO:BufFileRead および IO:BufFileWrite](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/wait-event.iobuffile.html)」「」を参照してください。

**注記**  
[https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM) パラメータは、ソート操作がメモリ不足になり、結果が一時ファイルに書き込まれるタイミングを制御します。このパラメータの設定をデフォルト値より高く変更しないことをお勧めします。変更すると、すべてのデータベースセッションでより多くのメモリを消費することになります。また、複雑な結合とソートを実行する単一セッションでは、それぞれの処理がメモリを消費する並列処理を実行できます。  
ベストプラクティスとして、複数の結合とソートを含む大規模なレポートがある場合は、`SET work_mem` コマンドを使用してこのパラメータをセッションレベルで設定します。そうすれば、変更は現在のセッションにのみ適用され、値がグローバルに変更されることはありません。

## pgBadger を使用した PostgreSQL でのログ分析
<a name="Appendix.PostgreSQL.CommonDBATasks.Badger"></a>

[pgBadger](http://dalibo.github.io/pgbadger/) などのログ分析ツールを使用して、PostgreSQL のログを分析できます。pgBadger のドキュメントでは %l パターン (セッションやプロセスに関するログの行) をプレフィックスに含める必要があると説明されています。ただし、最新の RDS `log_line_prefix` をパラメータとして pgBadger に渡すことでも、レポートが作成されます。

例えば、次のコマンドでは、pgBadger を使用して、2014-02-04 の日付の Amazon RDS for PostgreSQL のログファイルを適切にフォーマットします。

```
./pgbadger -f stderr -p '%t:%r:%u@%d:[%p]:' postgresql.log.2014-02-04-00 
```

## PostgreSQL をモニタリングするために PGSnapper を使用する
<a name="Appendix.PostgreSQL.CommonDBATasks.Snapper"></a>

PGSnapper を使用すると、Amazon RDS for PostgreSQL のパフォーマンス関連の統計やメトリクスを定期的に収集することができます。詳細については、「[PGSnapper を使用して Amazon RDS for PostgreSQL のパフォーマンスをモニタリングする](https://aws.amazon.com/blogs/database/monitor-amazon-rds-for-postgresql-and-amazon-aurora-postgresql-performance-using-pgsnapper/)」を参照してください。

# RDS for PostgreSQL でのカスタムキャストの管理
<a name="PostgreSQL.CustomCasts"></a>

PostgreSQL での**型キャスト**は、あるデータ型から別のデータ型に値を変換するプロセスです。PostgreSQL には多くの一般的な変換用の組み込みキャストがありますが、カスタムキャストを作成して、特定の型変換の動作を定義することもできます。

キャストは、あるデータ型から別のデータ型への変換を実行する方法を指定します。例えば、テキスト `'123'` を整数 `123` に変換したり、数値 `45.67` をテキスト `'45.67'` に変換したりします。

PostgreSQL のキャストの概念と構文に関する包括的な情報については、「[PostgreSQL CREATE CAST のドキュメント](https://www.postgresql.org/docs/current/sql-createcast.html)」を参照してください。

RDS for PostgreSQL バージョン 13.23、14.20、15.15、16.11、17.7、および 18.1 以降では、rds\$1casts 拡張機能を使用して組み込みタイプの追加のキャストをインストールできるだけでなく、カスタムタイプの独自のキャストを作成することもできます。

**Topics**
+ [

## rds\$1casts 拡張機能のインストールと使用
](#PostgreSQL.CustomCasts.Installing)
+ [

## サポートされているキャスト
](#PostgreSQL.CustomCasts.Supported)
+ [

## キャストの作成または削除
](#PostgreSQL.CustomCasts.Creating)
+ [

## 適切なコンテキスト戦略を使用してカスタムキャストを作成する
](#PostgreSQL.CustomCasts.BestPractices)

## rds\$1casts 拡張機能のインストールと使用
<a name="PostgreSQL.CustomCasts.Installing"></a>

`rds_casts` 拡張機能を作成するには、`rds_superuser` として RDS for PostgreSQL DB インスタンスに接続し、次のコマンドを実行します。

```
CREATE EXTENSION IF NOT EXISTS rds_casts;
```

## サポートされているキャスト
<a name="PostgreSQL.CustomCasts.Supported"></a>

カスタムキャストを使用する各データベースに拡張機能を作成します。拡張機能を作成した後、次のコマンドを使用して使用可能なすべてのキャストを表示します。

```
SELECT * FROM rds_casts.list_supported_casts();
```

この関数は、使用可能なキャストの組み合わせ (ソースタイプ、ターゲットタイプ、強制コンテキスト、キャスト関数) を一覧表示します。例えば、`text` から `numeric` への `implicit` キャストを作成する場合です。次のクエリを使用して、キャストを作成できるかどうかを確認できます。

```
SELECT * FROM rds_casts.list_supported_casts()
WHERE source_type = 'text' AND target_type = 'numeric';
 id | source_type | target_type |          qualified_function          | coercion_context
----+-------------+-------------+--------------------------------------+------------------
 10 | text        | numeric     | rds_casts.rds_text_to_numeric_custom | implicit
 11 | text        | numeric     | rds_casts.rds_text_to_numeric_custom | assignment
 13 | text        | numeric     | rds_casts.rds_text_to_numeric_custom | explicit
 20 | text        | numeric     | rds_casts.rds_text_to_numeric_inout  | implicit
 21 | text        | numeric     | rds_casts.rds_text_to_numeric_inout  | assignment
 23 | text        | numeric     | rds_casts.rds_text_to_numeric_inout  | explicit
```

rds\$1casts 拡張機能は、キャストごとに 2 種類の変換関数を提供します。
+ *\$1inout 関数* - PostgreSQL の標準 I/O 変換メカニズムを使用し、INOUT メソッドで作成されたキャストと同じように動作します。
+ *\$1custom 関数* - 変換エラーを避けるために空の文字列を NULL 値に変換するなど、エッジケースを処理する拡張変換ロジックを提供します。

`inout` 関数は PostgreSQL のネイティブキャスト動作をレプリケートしますが、`custom` 関数は、空の文字列を整数に変換するなど、標準の INOUT キャストが対応できないシナリオを処理することでこの機能を拡張します。

## キャストの作成または削除
<a name="PostgreSQL.CustomCasts.Creating"></a>

次の 2 つの方法を使用して、サポートされているキャストを作成および削除できます。

### キャストの作成
<a name="PostgreSQL.CustomCasts.Creating.Methods"></a>

**方法 1: ネイティブの CREATE CAST コマンドを使用する**

```
CREATE CAST (text AS numeric)
WITH FUNCTION rds_casts.rds_text_to_numeric_custom
AS IMPLICIT;
```

**方法 2: rds\$1casts.create\$1cast 関数を使用する**

```
SELECT rds_casts.create_cast(10);
```

`create_cast` 関数は、`list_supported_casts()` 出力から ID を取得します。この方法はよりシンプルで、正しい関数とコンテキストの組み合わせを使用していることが確認されます。この ID は、異なる postgres バージョン間で同じままであることが保証されています。

キャストが正常に作成されたことを確認するには、pg\$1cast システムカタログをクエリします。

```
SELECT oid, castsource::regtype, casttarget::regtype, castfunc::regproc, castcontext, castmethod
FROM pg_cast
WHERE castsource = 'text'::regtype AND casttarget = 'numeric'::regtype;
  oid   | castsource | casttarget |               castfunc               | castcontext | castmethod
--------+------------+------------+--------------------------------------+-------------+------------
 356372 | text       | numeric    | rds_casts.rds_text_to_numeric_custom | i           | f
```

`castcontext` 列には、EXPLICIT の場合は `e`、ASSIGNMENT の場合は `a`、IMPLICIT の場合は `i` が表示されます。

### キャストの削除
<a name="PostgreSQL.CustomCasts.Dropping"></a>

**方法 1: DROP CAST コマンドを使用する**

```
DROP CAST IF EXISTS (text AS numeric);
```

**方法 2: rds\$1casts.drop\$1cast 関数を使用する**

```
SELECT rds_casts.drop_cast(10);
```

`drop_cast` 関数は、キャストの作成時と同じ ID を使用します。この方法では、対応する ID で作成されたキャストを正確に削除できます。

## 適切なコンテキスト戦略を使用してカスタムキャストを作成する
<a name="PostgreSQL.CustomCasts.BestPractices"></a>

整数型に対して複数のキャストを作成する場合、すべてのキャストが IMPLICIT として作成されると、演算子のあいまいさのエラーが発生する可能性があります。次の例は、テキストから異なる整数幅に 2 つの暗黙的なキャストを作成することで、この問題を示しています。

```
-- Creating multiple IMPLICIT casts causes ambiguity
postgres=> CREATE CAST (text AS int4) WITH FUNCTION rds_casts.rds_text_to_int4_custom(text) AS IMPLICIT;
CREATE CAST
postgres=> CREATE CAST (text AS int8) WITH FUNCTION rds_casts.rds_text_to_int8_custom(text) AS IMPLICIT;
CREATE CAST

postgres=> CREATE TABLE test_cast(col int);
CREATE TABLE
postgres=> INSERT INTO test_cast VALUES ('123'::text);
INSERT 0 1
postgres=> SELECT * FROM test_cast WHERE col='123'::text;
ERROR:  operator is not unique: integer = text
LINE 1: SELECT * FROM test_cast WHERE col='123'::text;
                                         ^
HINT:  Could not choose a best candidate operator. You might need to add explicit type casts.
```

このエラーは、PostgreSQL が整数列とテキスト値を比較するときに使用する暗黙的なキャストを特定できないために発生します。int4 と int8 の両方の暗黙的なキャストが有効な候補であるため、あいまいさが生じます。

この演算子のあいまいさを回避するには、小さい整数幅には ASSIGNMENT コンテキストを使用し、大きい整数幅には IMPLICIT コンテキストを使用します。

```
-- Use ASSIGNMENT for smaller integer widths
CREATE CAST (text AS int2)
WITH FUNCTION rds_casts.rds_text_to_int2_custom(text)
AS ASSIGNMENT;

CREATE CAST (text AS int4)
WITH FUNCTION rds_casts.rds_text_to_int4_custom(text)
AS ASSIGNMENT;

-- Use IMPLICIT for larger integer widths
CREATE CAST (text AS int8)
WITH FUNCTION rds_casts.rds_text_to_int8_custom(text)
AS IMPLICIT;

postgres=> INSERT INTO test_cast VALUES ('123'::text);
INSERT 0 1
postgres=> SELECT * FROM test_cast WHERE col='123'::text;
 col
-----
 123
(1 row)
```

この戦略では、int8 キャストのみが暗黙的であるため、PostgreSQL はどのキャストを使用するかを明確に判断できます。

# RDS for PostgreSQL での並列クエリのベストプラクティス
<a name="PostgreSQL.ParallelQueries"></a>

並列クエリ実行は、PostgreSQL の機能であり、単一の SQL クエリをより小さなタスクに分割し、複数のバックグラウンドワーカープロセスによって同時に処理することを可能にします。PostgreSQL は、クエリ全体を単一のバックエンドプロセスで実行する代わりに、スキャン、結合、集約、ソートなどのクエリの一部を複数の CPU コアに分散させることができます。*リーダープロセス*は、この実行を調整し、*並列ワーカー*から結果を収集します。

ただし、ほとんどの本稼働ワークロード、特に高同時実行 OLTP システムでは、自動並列クエリ実行を無効にすることをお勧めします。並列処理は、分析またはレポートワークロードの大規模なデータセットに対するクエリを高速化できますが、負荷の高い本番環境では、多くの場合、メリットを上回る重大なリスクをもたらします。

並列実行では、大きなオーバーヘッドも発生します。各並列ワーカーは完全な PostgreSQL バックエンドプロセスであり、プロセスのフォーク (メモリ構造のコピーとプロセス状態の初期化) と認証 (`max_connections` 制限の接続スロットの消費) が必要です。各ワーカーは、ソートやハッシュ操作のための `work_mem` を含め、独自のメモリも消費します。クエリごとに複数のワーカーがある場合、メモリ使用量は急速に増加します (例: 4 つのワーカー × 64MB `work_mem` = クエリあたり 256MB)。その結果、並列クエリは単一プロセスクエリよりもかなり多くのシステムリソースを消費する可能性があります。正しくチューニングされていない場合は、CPU 飽和 (複数のワーカーが使用可能な処理能力を圧倒する)、コンテキスト切り替えの増加 (オペレーティングシステムが多数のワーカープロセスを頻繁に切り替えるため、オーバーヘッドが増加しスループットが低下する)、または接続の枯渇 (各並列ワーカーが接続スロットを消費するため、4 つのワーカーを含む単一のクエリでは、リーダー 1 つとワーカー 4 つの合計 5 つの接続が使用され、高い同時実行性のもとでは接続プールがすぐに枯渇し、新しいクライアント接続が妨げられ、アプリケーション障害が発生する) につながる可能性があります。これらの問題は、複数のクエリが同時に並列実行を試みる可能性がある同時実行性の高いワークロードでは特に深刻です。

PostgreSQL は、コスト見積もりに基づいて並列処理を使用するかどうかを決定します。場合によっては、プランナーは、実際には理想的でない場合でも、より安価に見える場合、並列プランに自動的に切り替えることがあります。これは、インデックス統計が古くなった場合や、肥大化してシーケンシャルスキャンがインデックス検索よりも魅力的に見える場合に発生する可能性があります。この動作により、自動並列プランによってクエリのパフォーマンスやシステムの安定性にリグレッションを引き起こすことがあります。

RDS for PostgreSQL で並列クエリを最大限に活用するには、ワークロードに基づいて並列クエリをテストおよびチューニングし、システムへの影響をモニタリングし、自動並列プラン選択を無効にして、クエリレベルで制御することが重要です。

## 設定パラメータ
<a name="PostgreSQL.ParallelQueries.ConfigurationParameters"></a>

PostgreSQL は、複数のパラメータを使用して並列クエリの動作と可用性を制御します。これらを理解して調整することは、予測可能なパフォーマンスを達成するために不可欠です。


| パラメータ | 説明 | デフォルト | 
| --- | --- | --- | 
| max\$1parallel\$1workers | 同時に実行できるバックグラウンドワーカープロセスの最大数 | GREATEST(\$1DBInstanceVCPU/2,8) | 
| max\$1parallel\$1workers\$1per\$1gather | クエリプランノードあたりのワーカーの最大数 (例: Gather あたり) | 2 | 
| parallel\$1setup\$1cost | 並列クエリインフラストラクチャを開始するためのプランナーコストの追加 | 1,000 | 
| parallel\$1tuple\$1cost | 並列モードで処理されたタプルあたりのコスト (プランナーの決定に影響する) | 0.1 | 
| force\$1parallel\$1mode | プランナーに並列プランのテストを強制する (off、on、regress) | off | 

### 主な考慮事項
<a name="PostgreSQL.ParallelQueries.ConfigurationParameters.KeyConsiderations"></a>
+ `max_parallel_workers` は、並列ワーカーの合計プールを制御します。設定が低すぎると、一部のクエリが直列実行にフォールバックする可能性があります。
+ `max_parallel_workers_per_gather` は、単一のクエリで使用できるワーカーの数に影響します。値を大きくすると、同時実行数は増加しますが、リソースの使用量も増加します。
+ `parallel_setup_cost` と `parallel_tuple_cost` は、プランナーのコストモデルに影響を与えます。これらの値を下げると、並列プランを選択する可能性が高くなります。
+ `force_parallel_mode` はテストに便利ですが、必要でない限り本番環境では使用しないでください。

**注記**  
`max_parallel_workers` パラメータのデフォルト値は、式 `GREATEST($DBInstanceVCPU/2, 8)` を使用してインスタンスサイズに基づいて動的に計算されます。つまり、DB インスタンスをより多くの vCPU でより大きなコンピューティングサイズにスケールすると、使用可能な並列ワーカーの最大数が自動的に増加します。その結果、以前に連続して実行されたクエリや、並列処理が制限されたクエリでは、スケールアップ操作後に突然、より多くの並列ワーカーが使用され、接続使用量、CPU 使用率、メモリ消費量が予期せず増加する可能性があります。コンピューティングスケーリングイベントの後に並列クエリの動作をモニタリングし、予測可能なリソース使用量を維持するために必要に応じて `max_parallel_workers_per_gather` を調整することが重要です。

## 並列クエリの使用状況を特定する
<a name="PostgreSQL.ParallelQueries.IdentifyUsage"></a>

クエリは、データの分布または統計に基づいて並列プランに切り替わる場合があります。例えば、次のようになります。

```
SELECT count(*) FROM customers WHERE last_login < now() - interval '6 months';
```

このクエリは、最近のデータにインデックスを使用しますが、履歴データに対しては並列シーケンシャルスキャンに切り替える可能性があります。

`auto_explain` モジュールをロードすることでクエリ実行計画を記録できます。詳細については、AWS ナレッジセンターの「[クエリ実行計画のログ記録](https://aws.amazon.com/premiumsupport/knowledge-center/rds-postgresql-tune-query-performance/#)」をご覧ください。



[CloudWatch Database Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Database-Insights-Database-Instance-Dashboard.html) を使用すると、並列クエリに関連する待機イベントをモニタリングできます。並列クエリに関連する待機イベントの詳細については、「[IPC:parallel 待機イベント](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/apg-ipc-parallel.html)」を参照してください。

PostgreSQL バージョン 18 以降では、[https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW) と [https://www.postgresql.org/docs/current/pgstatstatements.html](https://www.postgresql.org/docs/current/pgstatstatements.html) の新しい列を使用して、並列ワーカーのアクティビティをモニタリングできます。
+ `parallel_workers_to_launch`: 起動が予定されている並列ワーカーの数
+ `parallel_workers_launched`: 実際に起動された並列ワーカーの数

これらのメトリクスは、計画された並列処理と実際の並列処理との間の差異を特定するのに役立ち、リソースの制約や設定の問題を示している可能性があります。次のクエリを使用して、並列実行をモニタリングします。

データベースレベルの並列ワーカーメトリクスの場合。

```
SELECT datname, parallel_workers_to_launch, parallel_workers_launched
FROM pg_stat_database
WHERE datname = current_database();
```

クエリレベルの並列ワーカーメトリクスの場合

```
SELECT query, parallel_workers_to_launch, parallel_workers_launched
FROM pg_stat_statements
ORDER BY parallel_workers_launched;
```

## 並列処理を制御する方法
<a name="PostgreSQL.ParallelQueries.ControlParallelism"></a>

クエリの並列処理を制御するにはいくつかの方法があり、それぞれがさまざまなシナリオと要件に合わせて設計されています。

自動並列処理をグローバルに無効にするには、[パラメータグループを変更して](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithParamGroups.Modifying.html)、次のように設定します。

```
max_parallel_workers_per_gather = 0;
```

永続的なユーザー固有の設定の場合、ALTER ROLE コマンドを使用すると、特定のユーザーの今後のすべてのセッションに適用されるパラメータを設定できます。

例えば、次のようになります。

`ALTER ROLE username SET max_parallel_workers_per_gather = 4;` は、このユーザーがデータベースに接続するたびに、セッションが必要に応じてこの並列ワーカー設定を使用するようにします。

セッションレベルの制御は、現在のデータベースセッションの期間中にパラメータを変更する SET コマンドを使用して実現できます。これは、他のユーザーや今後のセッションに影響を与えることなく、設定を一時的に調整する必要がある場合に特に便利です。設定すると、これらのパラメータは明示的にリセットされるまで、またはセッションが終了するまで有効です。コマンドは簡単です。

```
SET max_parallel_workers_per_gather = 4;
-- Run your queries
RESET max_parallel_workers_per_gather;
```

さらに詳細な制御を行うには、SET LOCAL を使用すると、単一のトランザクションのパラメータを変更できます。これは、トランザクション内の特定のクエリセットの設定を調整する必要がある場合に最適です。その後、設定は自動的に以前の値に戻ります。このアプローチは、同じセッション内の他のオペレーションへの意図しない影響を防ぐのに役立ちます。

## 並列クエリ動作の診断
<a name="PostgreSQL.ParallelQueries.Diagnosing"></a>

`EXPLAIN (ANALYZE, VERBOSE)` を使用して、クエリが並列実行を使用したかどうかを確認します。
+ `Gather`、`Gather Merge`、`Parallel Seq Scan` などのノードを探します。
+ 並列処理ありの場合と並列処理なしの場合の計画を比較します。

比較のために並列処理を一時的に無効にするには。

```
SET max_parallel_workers_per_gather = 0;
EXPLAIN ANALYZE <your_query>;
RESET max_parallel_workers_per_gather;
```

# RDS for PostgreSQL DB インスタンスでのパラメータの使用
<a name="Appendix.PostgreSQL.CommonDBATasks.Parameters"></a>

場合によっては、カスタムパラメータグループを指定せずに RDS for PostgreSQL DB インスタンスを作成することがあります。その場合、DB インスタンスは、選択したバージョンの PostgreSQL のデフォルトのパラメータグループを使用して作成されます。例えば、PostgreSQL 13.3 を使用して PostgreSQL DB インスタンス用の RDS を作成するとします。この場合、DB インスタンスは PostgreSQL 13 リリースのパラメータグループの値 `default.postgres13` を使用して作成されます。

独自のカスタム DB パラメータグループを作成することもできます。RDS for PostgreSQL DB インスタンスの設定をデフォルト値から変更する場合は、これを実行する必要があります。この方法の詳細は、「[Amazon RDS のパラメータグループ](USER_WorkingWithParamGroups.md)」を参照してください。

RDS for PostgreSQL DB インスタンスの設定は、いくつかの異なる方法で追跡できます。AWS マネジメントコンソール、AWS CLI、または Amazon RDS API を使用できます。次のように、インスタンスの PostgreSQL `pg_settings` テーブルから値をクエリすることもできます。

```
SELECT name, setting, boot_val, reset_val, unit
 FROM pg_settings
 ORDER BY name;
```

このクエリから返される値の詳細については、PostgreSQL ドキュメントの「[https://www.postgresql.org/docs/current/view-pg-settings.html](https://www.postgresql.org/docs/current/view-pg-settings.html)」を参照してください。

RDS for PostgreSQL DB インスタンスで `max_connections` と `shared_buffers` の設定を変更するときは、特に注意してください。例えば、`max_connections` または `shared_buffers` の設定を変更し、実際のワークロードに対して高すぎる値を使用するとします。この場合、RDS for PostgreSQL DB インスタンスは起動しません。この場合、`postgres.log` に次のようなエラーが表示されます。

```
2018-09-18 21:13:15 UTC::@:[8097]:FATAL:  could not map anonymous shared memory: Cannot allocate memory
2018-09-18 21:13:15 UTC::@:[8097]:HINT:  This error usually means that PostgreSQL's request for a shared memory segment
exceeded available memory or swap space. To reduce the request size (currently 3514134274048 bytes), reduce 
PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
```

ただし、デフォルトの RDS for PostgreSQL DB パラメータグループに含まれる設定の値は変更できません。パラメータの設定を変更するには、まずカスタム DB パラメータグループを作成します。次に、そのカスタムグループの設定を変更し、カスタムパラメータグループを RDS for PostgreSQL DB インスタンスに適用します。詳細については[Amazon RDS のパラメータグループ](USER_WorkingWithParamGroups.md)を参照してください。

RDS for PostgreSQL には、2 種類のパラメータがあります。
+ **静的パラメータ** – 静的パラメータでは、変更後に RDS for PostgreSQL DB インスタンスを再起動して、新しい値を有効にする必要があります。
+ **動的パラメータ** – 動的パラメータでは、設定を変更した後に再起動する必要はありません。

**注記**  
RDS for PostgreSQL DB インスタンスで独自のカスタム DB パラメータグループを使用している場合は、実行中の DB インスタンスの動的パラメータの値を変更できます。これを行うには、AWS マネジメントコンソール、AWS CLI、または Amazon RDS API を使用します。

権限がある場合は、`ALTER DATABASE`、`ALTER ROLE`、および `SET` コマンドを使用して、パラメータ値を変更することもできます。

## RDS for PostgreSQL DB インスタンスのパラメータのリスト
<a name="Appendix.PostgreSQL.CommonDBATasks.Parameters.parameters-list"></a>

RDS for PostgreSQL DB インスタンスで使用可能なパラメータの一部 (すべてではありません) を次の表に示します。使用可能なすべてのパラメータを表示するには、[describe-db-parameters](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-parameters.html)AWS CLI コマンドを使用します。例えば、RDS for PostgreSQL バージョン 13 のデフォルトパラメータグループで使用可能なすべてのパラメータのリストを取得するには、以下を実行します。

```
aws rds describe-db-parameters --db-parameter-group-name default.postgres13
```

コンソールを使用することもできます。Amazon RDS メニューから **[Parameter groups]** (パラメータグループ) を選択し、AWS リージョン で利用できるパラメータグループの中からパラメータグループを選択します。


|  パラメータ名  |  Apply\$1Type  |  説明  | 
| --- | --- | --- | 
|  `application_name`  | 動的 | 統計情報とログで報告されるアプリケーション名を設定します。 | 
|  `archive_command`  | 動的 | WAL ファイルをアーカイブするために呼び出されるシェルコマンドを設定します。 | 
|  `array_nulls`  | 動的 | 配列での NULL 要素の入力を有効にします。 | 
|  `authentication_timeout`  | 動的 | クライアント認証の実行で許可する最大時間を設定します。 | 
|  `autovacuum`  | 動的 | autovacuum サブプロセスを起動します。 | 
|  `autovacuum_analyze_scale_factor`  | 動的 | 分析する前のタプルの挿入、更新、削除の数 (reltuples の割合として指定)。 | 
|  `autovacuum_analyze_threshold`  | 動的 | 分析する前のタプルの挿入、更新、削除の最小数。 | 
|  `autovacuum_freeze_max_age`  | 静的 | トランザクション ID の循環を防ぐためにテーブルに対して autovacuum を実行する期間。 | 
|  `autovacuum_naptime`  | 動的 | autovacuum の実行の間で休止状態になっている時間。 | 
|  `autovacuum_max_workers`  | 静的 | 同時に実行される autovacuum ワーカープロセスの最大数を設定します。 | 
|  `autovacuum_vacuum_cost_delay`  | 動的 | autovacuum でのバキューム処理のコスト遅延の値 (ミリ秒単位)。 | 
|  `autovacuum_vacuum_cost_limit`  | 動的 | autovacuum でバキューム処理を停止する制限値となるバキューム処理のコスト | 
|  `autovacuum_vacuum_scale_factor`  | 動的 | バキューム処理する前のタプルの更新または削除の数 (reltuples の割合として指定)。 | 
|  `autovacuum_vacuum_threshold`  | 動的 | バキューム処理する前のタプルの更新また削除の最小数。 | 
|  `backslash_quote`  | 動的 | 文字列リテラルでバックスラッシュ (\$1) を許可するかどうかを指定します。 | 
|  `bgwriter_delay`  | 動的 | ラウンド間でのバックグラウンドライターの休止時間。 | 
|  `bgwriter_lru_maxpages`  | 動的 | ラウンドあたりのフラッシュするバックグラウンドライター LRU ページの最大数。 | 
|  `bgwriter_lru_multiplier`  | 動的 | ラウンドあたりの解放される平均バッファ使用量の倍数。 | 
|  `bytea_output`  | 動的 | バイトの出力形式を設定します。 | 
|  `check_function_bodies`  | 動的 | CREATE FUNCTION の実行中に関数の本文をチェックします。 | 
|  `checkpoint_completion_target`  | 動的 | チェックポイント中にダーティバッファのフラッシュにかかった時間 (チェックポイント間隔の割合として指定)。 | 
|  `checkpoint_segments`  | 動的 | 自動 WAL (ログ先行書き込み) チェックポイント間のログセグメントの最大間隔を設定します。 | 
|  `checkpoint_timeout`  | 動的 | 自動 WAL チェックポイント間の最大時間を設定します。 | 
|  `checkpoint_warning`  | 動的 | チェックポイントセグメントがこの値よりも頻繁に満杯になる場合に警告を出します。 | 
|  `client_connection_check_interval`  | 動的 |  クエリ実行中の切断を確認する時間間隔を設定します。 | 
|  `client_encoding`  | 動的 | クライアントの文字セットエンコードを設定します。 | 
|  `client_min_messages`  | 動的 | クライアントへ送信されるメッセージレベルを設定します。 | 
|  `commit_delay`  | 動的 | トランザクションのコミットからディスクへの WAL のフラッシュまでの遅延間隔をマイクロ秒単位で設定します。 | 
|  `commit_siblings`  | 動的 | commit\$1delay を実行する前に同時に開いている必要があるトランザクションの最小数を設定します。 | 
|  `constraint_exclusion`  | 動的 | クエリを最適化するために、プランナーが制約を使用できるようにします。 | 
|  `cpu_index_tuple_cost`  | 動的 | インデックススキャンの実行中に各インデックスエントリを処理する際にかかるコストに対するプランナーの見積もりを設定します。 | 
|  `cpu_operator_cost`  | 動的 | 演算子の呼び出しや関数呼び出しのそれぞれを処理する際にかかるコストに対するプランナーの見積もりを設定します。 | 
|  `cpu_tuple_cost`  | 動的 | 各タプル (行) の処理にかかるコストに対するプランナーの見積もりを設定します。 | 
|  `cursor_tuple_fraction`  | 動的 | 取得されるカーソル行の割合に対するプランナーの見積もりを設定します。 | 
|  `datestyle`  | 動的 | 日付と時刻の値の表示形式を設定します。 | 
|  `deadlock_timeout`  | 動的 | デッドロックをチェックするまでロックを待機する時間を設定します。 | 
|  `debug_pretty_print`  | 動的 | 分析ツリーや計画ツリーの表示をインデントして見やすくします。 | 
|  `debug_print_parse`  | 動的 | 各クエリの分析ツリーをログに記録します。 | 
|  `debug_print_plan`  | 動的 | 各クエリの実行計画をログに記録します。 | 
|  `debug_print_rewritten`  | 動的 | 各クエリの書き直された分析ツリーをログに記録します。 | 
|  `default_statistics_target`  | 動的 | デフォルトの統計情報の対象を設定します。 | 
|  `default_tablespace`  | 動的 | テーブルとインデックスを作成するためのデフォルトのテーブルスペースを設定します。 | 
|  `default_transaction_deferrable`  | 動的 | 新しいトランザクションのデフォルトの遅延ステータスを設定します。 | 
|  `default_transaction_isolation`  | 動的 | 新しい各トランザクションのトランザクション分離レベルを設定します。 | 
|  `default_transaction_read_only`  | 動的 | 新しいトランザクションのデフォルトの読み取り専用ステータスを設定します。 | 
|  `default_with_oids`  | 動的 | デフォルトでオブジェクト ID (OID) を使用して新しいテーブルを作成します。 | 
|  `effective_cache_size`  | 動的 | ディスクキャッシュのサイズに関するプランナーの予測を設定します。 | 
|  `effective_io_concurrency`  | 動的 | ディスクサブシステムで効率的に処理できる同時リクエストの数。 | 
|  `enable_bitmapscan`  | 動的 | プランナーがビットマップスキャン計画を使用できるようにします。 | 
|  `enable_hashagg`  | 動的 | プランナーがハッシュされた集計計画を使用できるようにします。 | 
|  `enable_hashjoin`  | 動的 | プランナーがハッシュ結合計画を使用できるようにします。 | 
|  `enable_indexscan`  | 動的 | プランナーがインデックススキャン計画を使用できるようにします。 | 
|  `enable_material`  | 動的 | プランナーがマテリアル化を使用できるようにします。 | 
|  `enable_mergejoin`  | 動的 | プランナーがマージ結合計画を使用できるようにします。 | 
|  `enable_nestloop`  | 動的 | プランナーがネステッドループ結合計画を使用できるようにします。 | 
|  `enable_seqscan`  | 動的 | プランナーがシーケンシャルスキャン計画を使用できるようにします。 | 
|  `enable_sort`  | 動的 | プランナーが明示的なソートステップを使用できるようにします。 | 
|  `enable_tidscan`  | 動的 | プランナーが TID スキャン計画を使用できるようにします。 | 
|  `escape_string_warning`  | 動的 | 通常の文字列リテラルにバックスラッシュ (\$1) が含まれている場合に警告を出します。 | 
|  `extra_float_digits`  | 動的 | 浮動小数点値の表示桁数を設定します。 | 
|  `from_collapse_limit`  | 動的 | FROM リストのサイズを設定します。この値を超えるとサブクエリが折りたたまれなくなります。 | 
|  `fsync`  | 動的 | ディスクへの更新の同期を強制的に行います。 | 
|  `full_page_writes`  | 動的 | チェックポイントの後でページに初期の変更を加えた時点で、WAL にすべてのページを書き込みます。 | 
|  `geqo`  | 動的 | 遺伝的クエリ最適化を有効にします。 | 
|  `geqo_effort`  | 動的 | GEQO: 他の GEQO パラメータのデフォルト値を設定するために使用されます。 | 
|  `geqo_generations`  | 動的 | GEQO: アルゴリズムの反復の数。 | 
|  `geqo_pool_size`  | 動的 | GEQO: 母集団内の個体の数。 | 
|  `geqo_seed`  | 動的 | GEQO: 無作為のパスを選択するための初期値。 | 
|  `geqo_selection_bias`  | 動的 | GEQO: 母集団内の選択圧。 | 
|  `geqo_threshold`  | 動的 | FROM 項目のしきい値を設定します。この値を超えると GEQO が使用されます。 | 
|  `gin_fuzzy_search_limit`  | 動的 | GIN による完全一致検索で許可される結果の最大数を設定します。 | 
|  `hot_standby_feedback`  | 動的 | ホットスタンバイがフィードバックメッセージをプライマリあるいはアップストリーミングスタンバイに送信するかを決定します。 | 
|  `intervalstyle`  | 動的 | 間隔値の表示形式を設定します。 | 
|  `join_collapse_limit`  | 動的 | FROM リストのサイズを設定します。この値を超えると JOIN 構造が平坦化されなくなります。 | 
|  `lc_messages`  | 動的 | メッセージを表示する言語を設定します。 | 
|  `lc_monetary`  | 動的 | 金額の書式のロケールを設定します。 | 
|  `lc_numeric`  | 動的 | 数値の書式のロケールを設定します。 | 
|  `lc_time`  | 動的 | 日付と時刻の書式のロケールを設定します。 | 
|  `log_autovacuum_min_duration`  | 動的 | autovacuum に関する最小実行時間を設定します。この値を超えると autovacuum アクションがログに記録されます。 | 
|  `log_checkpoints`  | 動的 | 各チェックポイントをログに記録します。 | 
|  `log_connections`  | 動的 | 成功した各接続をログに記録します。 | 
|  `log_disconnections`  | 動的 | セッションの終了をログに記録します (セッションの有効期間も含まれます)。 | 
|  `log_duration`  | 動的 | 完了した各 SQL ステートメントの期間をログに記録します。 | 
|  `log_error_verbosity`  | 動的 | ログに記録されるメッセージの詳細を設定します。 | 
|  `log_executor_stats`  | 動的 | 実行プログラムのパフォーマンスの統計情報をサーバーログに書き込みます。 | 
|  `log_filename`  | 動的 | ログファイルのファイル名のパターンを設定します。 | 
|  `log_file_mode`  | 動的 | ログファイルのファイルアクセス許可を設定します。デフォルト値は 0644 です。 | 
|  `log_hostname`  | 動的 | 接続ログにホスト名を記録します。PostgreSQL 12 以降のバージョンでは、このパラメータはデフォルトで「off」になっています。オンにすると、接続は DNS 逆引き参照を使用してホスト名を取得し、接続ログに取り込まれます。このパラメータをオンにする場合は、接続の確立にかかる時間への影響をモニタリングする必要があります。 | 
|  `log_line_prefix `  | 動的 | 各ログ行の先頭に付ける情報を制御します。 | 
|  `log_lock_waits`  | 動的 | 長期間にわたるロックの待機をログに記録します。 | 
|  `log_min_duration_statement`  | 動的 | 最小実行時間を設定します。この値を超えるとステートメントがログに記録されます。 | 
|  `log_min_error_statement`  | 動的 | 設定したレベル以上のエラーが発生したすべてのステートメントをログに記録します。 | 
|  `log_min_messages`  | 動的 | ログに記録するメッセージレベルを設定します。 | 
|  `log_parser_stats`  | 動的 | 分析のパフォーマンスの統計情報をサーバーログに書き込みます。 | 
|  `log_planner_stats`  | 動的 | プランナーのパフォーマンスの統計情報をサーバーログに書き込みます。 | 
|  `log_rotation_age`  | 動的 | N 分が経過するとログファイルのローテーションが自動的に発生します。 | 
|  `log_rotation_size`  | 動的 | N キロバイトを超えるとログファイルのローテーションが自動的に発生します。 | 
|  `log_statement`  | 動的 | ログに記録するステートメントのタイプを設定します。 | 
|  `log_statement_stats`  | 動的 | 累積処理のパフォーマンスの統計情報をサーバーログに書き込みます。 | 
|  `log_temp_files`  | 動的 | 指定したサイズ (キロバイト) を超えるテンポラリファイルの使用をログに記録します。 | 
|  `log_timezone`  | 動的 | ログメッセージで使用するタイムゾーンを設定します。 | 
|  `log_truncate_on_rotation`  | 動的 | ログローテーション中に同じ名前の既存のログファイルを切り捨てます。 | 
|  `logging_collector`  | 静的 | サブプロセスを開始して、stderr 出力や csvlogs をログファイルにキャプチャします。 | 
|  `maintenance_work_mem`  | 動的 | メンテナンスオペレーションに使用するメモリの最大量を設定します。 | 
|  `max_connections`  | 静的 | 同時接続の最大数を設定します。 | 
|  `max_files_per_process`  | 静的 | 各サーバープロセスで同時に開くことができるファイルの最大数を設定します。 | 
|  `max_locks_per_transaction`  | 静的 | トランザクションあたりのロックの最大数を設定します。 | 
|  `max_pred_locks_per_transaction`  | 静的 | トランザクションあたりの述語ロックの最大数を設定します。 | 
|  `max_prepared_transactions`  | 静的 | 同時に準備できるトランザクションの最大数を設定します。 | 
|  `max_stack_depth`  | 動的 | スタックの深度の最大値をキロバイト単位で指定します。 | 
|  `max_standby_archive_delay`  | 動的 | ホットスタンバイサーバーがアーカイブされた WAL データを処理しているときにクエリをキャンセルするまでの最大遅延間隔を設定します。 | 
|  `max_standby_streaming_delay`  | 動的 | ホットスタンバイサーバーがストリーミングされた WAL データを処理しているときにクエリをキャンセルするまでの最大遅延間隔を設定します。 | 
| max\$1wal\$1size | 動的 | チェックポイントをトリガーする WAL サイズ (MB) を設定します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Parameters.html) Amazon RDS for PostgreSQL DB インスタンスで以下のコマンドを使用して現在の値を確認します。 <pre>SHOW max_wal_size;</pre>  | 
| min\$1wal\$1size | 動的 | WAL を縮小する最小サイズを設定します。PostgreSQL バージョン 9.6 以前の場合、min\$1wal\$1size の単位は 16 MB です。PostgreSQL バージョン 10 以降の場合、min\$1wal\$1size の単位は 1 MB です。 | 
|  `quote_all_identifiers`  | 動的 | SQL フラグメントを生成するときに、すべての識別子に引用符 (") を追加します。 | 
|  `random_page_cost`  | 動的 | 非連続的に取得されたディスクページのコストに対するプランナーの見積もりを設定します。クエリプラン管理 (QPM) がオンでない限り、このパラメータには値はありません。QPM がオンの場合、このパラメータ 4 はデフォルト値です。 | 
| rds.adaptive\$1autovacuum | 動的 | トランザクション ID のしきい値を超えるたびに、autovacuum パラメータを自動的に微調整します。 | 
| rds.force\$1ssl | 動的 | SSL 接続を使用する必要があります。PostgreSQL バージョン 15 の RDS では、デフォルト値は 1 (オン) に設定されています。PostgreSQL のメジャーバージョン 14 以前のその他すべての RDS では、デフォルト値が 0 (オフ) に設定されています。 | 
|  `rds.local_volume_spill_enabled`  | 静的 | ローカルボリュームへの論理スピルファイルの書き込みを有効にします。 | 
|  `rds.log_retention_period`  | 動的 | n 分より古い PostgreSQL ログは Amazon RDS で削除されるようにログ保持期間を設定します。 | 
| rds.rds\$1superuser\$1reserved\$1connections | 静的 | rds\$1superusers 用に予約されている接続スロットの数を設定します。このパラメータは、バージョン 15 以前でのみ使用できます。詳細については、PostgreSQL ドキュメントの「[reserved\$1connections](https://www.postgresql.org/docs/current/runtime-config-connection.html#GUC-RESERVED-CONNECTIONS)」を参照してください。 | 
| `rds.replica_identity_full` | 動的 | このパラメータを `on` に設定すると、すべてのデータベーステーブルのレプリカ ID 設定が `FULL` に上書きされます。つまり、`REPLICA IDENTITY FULL` 設定に関係なく、すべての列値が先書きログ (WAL) に書き込まれます。  このパラメータをオンにすると、追加の WAL ログ記録のためにデータベースインスタンスの IOPS が増加する可能性があります。   | 
| rds.restrict\$1password\$1commands | 静的 | rds\$1password ロールを持つユーザーに対して、だれがパスワードを管理するかを制限します。パスワードの制限を有効にするには、このパラメータを 1 に設定します。デフォルトは 0 です。 | 
|  `search_path`  | 動的 | スキーマによって修飾されていない名前でスキーマを検索する順序を設定します。 | 
|  `seq_page_cost`  | 動的 | 連続的に取得されたディスクページのコストに対するプランナーの見積もりを設定します。 | 
|  `session_replication_role`  | 動的 | トリガーと再書き込みルールに対するセッション動作を設定します。 | 
|  `shared_buffers`  | 静的 | サーバーで使用される共有メモリバッファの数を設定します。 | 
|  `shared_preload_libraries `  | 静的 | RDS for PostgreSQL DB インスタンスにプリロードする共有ライブラリをリストします。サポートされている値は、auto\$1explain、orafce、pgaudit、pglogical、pg\$1bigm、pg\$1cron、pg\$1hint\$1plan、pg\$1prewarm、pg\$1similarity、pg\$1stat\$1statements、pg\$1transport、plprofiler、および plrust です。 | 
|  `ssl`  | 動的 | SSL 接続を有効にします。 | 
|  `sql_inheritance`  | 動的 | さまざまなコマンドにデフォルトでサブテーブルが取り込まれます。 | 
|  `ssl_renegotiation_limit`  | 動的 | 暗号化キーを再度ネゴシエートする前に送受信されるトラフィックの量を設定します。 | 
|  `standard_conforming_strings`  | 動的 | ... 文字列をリテラルのバックスラッシュとして扱います。 | 
|  `statement_timeout`  | 動的 | すべてのステートメントに許可される最大実行時間を設定します。 | 
|  `synchronize_seqscans`  | 動的 | シーケンシャルスキャンの同期を有効にします。 | 
|  `synchronous_commit`  | 動的 | 現在のトランザクションの同期レベルを設定します。 | 
|  `tcp_keepalives_count`  | 動的 | TCP キープアライブを再送信する最大回数。 | 
|  `tcp_keepalives_idle`  | 動的 | TCP キープアライブを発行する間隔の時間。 | 
|  `tcp_keepalives_interval`  | 動的 | TCP キープアライブを再送信する間隔の時間。 | 
|  `temp_buffers`  | 動的 | 各セッションで使用されるテンポラリバッファの最大数を設定します。 | 
| temp\$1file\$1limit | 動的 | テンポラリファイルの最大サイズを KB 単位で設定します。 | 
|  `temp_tablespaces`  | 動的 | テンポラリテーブルとソートファイルで使用するテーブルスペースを設定します。 | 
|  `timezone`  | 動的 | 表示やタイムスタンプの解釈で必要となるタイムゾーンを設定します。 Internet Assigned Numbers Authority (IANA) は年に数回、[https://www.iana.org/time-zones](https://www.iana.org/time-zones) で新しいタイムゾーンを公開します。RDS が PostgreSQL の新しいマイナーメンテナンスリリースをリリースするたびに、リリース時の最新のタイムゾーンデータが付属しています。最新の RDS for PostgreSQL バージョンを使用すると、RDS からの最新のタイムゾーンデータが得られます。DB インスタンスに最新のタイムゾーンデータがあることを確認するには、DB エンジンの上位バージョンにアップグレードすることをお勧めします。PostgreSQL DB インスタンスのタイムゾーン テーブルを手動で変更することはできません。RDS は、実行中の DB インスタンスのタイムゾーンデータを変更またはリセットしません。新しいタイムゾーンデータは、データベースエンジンのバージョンアップグレードを実行する場合にのみインストールされます。 | 
|  `track_activities`  | 動的 | コマンドの実行に関する情報を収集します。 | 
|  `track_activity_query_size`  | 静的 | pg\$1stat\$1activity.current\$1query 用に予約するサイズをバイト単位で設定します。 | 
|  `track_counts`  | 動的 | データベースアクティビティの統計情報を収集します。 | 
|  `track_functions`  | 動的 | データベースアクティビティの関数レベルの統計情報を収集します。 | 
|  `track_io_timing`  | 動的 | データベース I/O アクティビティのタイミングに関する統計情報を収集します。 | 
|  `transaction_deferrable`  | 動的 | 読み取り専用のシリアル化可能なトランザクションを、シリアル化が失敗する可能性がない状況でスタートできるようになるまで延期するかどうかを示します。 | 
|  `transaction_isolation`  | 動的 | 現在のトランザクションの分離レベルを設定します。 | 
|  `transaction_read_only`  | 動的 | 現在のトランザクションの読み取り専用ステータスを設定します。 | 
|  `transform_null_equals`  | 動的 | expr=NULL を expr IS NULL として扱います。 | 
|  `update_process_title`  | 動的 | アクティブな SQL コマンドを表示するようにプロセスのタイトルを更新します。 | 
|  `vacuum_cost_delay`  | 動的 | バキューム処理のコスト遅延の値 (ミリ秒単位)。 | 
|  `vacuum_cost_limit`  | 動的 | バキューム処理を停止する制限値となるバキューム処理のコスト。 | 
|  `vacuum_cost_page_dirty`  | 動的 | バキューム処理によってダーティになったページに対するバキューム処理のコスト。 | 
|  `vacuum_cost_page_hit`  | 動的 | バッファキャッシュ内で検出されたページに対するバキューム処理のコスト。 | 
|  `vacuum_cost_page_miss`  | 動的 | バッファキャッシュ内で検出されなかったページに対するバキューム処理のコスト。 | 
|  `vacuum_defer_cleanup_age`  | 動的 | バキューム処理とホットクリーンアップが延期されるトランザクションの数 (存在する場合)。 | 
|  `vacuum_freeze_min_age`  | 動的 | バキューム処理でテーブルの行をフリーズする最小期間。 | 
|  `vacuum_freeze_table_age`  | 動的 | バキューム処理でテーブル全体をスキャンしタプルをフリーズするための期間。 | 
|  `wal_buffers`  | 静的 | WAL 用の共有メモリ内のディスクページバッファの数を設定します。 | 
|  `wal_writer_delay`  | 動的 | WAL のフラッシュが行われる間の WAL ライターの休止時間。 | 
|  `work_mem`  | 動的 | クエリワークスペースに使用するメモリの最大量を設定します。 | 
|  `xmlbinary`  | 動的 | バイナリ値を XML にエンコードする方法を設定します。 | 
|  `xmloption`  | 動的 | 黙示的な分析とシリアル化オペレーションでの XML データをドキュメントとして見なすか、コンテンツのフラグメントとして見なすかを設定します。 | 

Amazon RDS では、すべてのパラメータについて PostgreSQL のデフォルトの単位を使用します。次の表は、PostgreSQL のパラメータ別のデフォルト単位を示しています。


|  パラメータ名  |  Unit  | 
| --- | --- | 
| `archive_timeout` | s | 
| `authentication_timeout` | s | 
| `autovacuum_naptime` | s | 
| `autovacuum_vacuum_cost_delay` | ms | 
| `bgwriter_delay` | ms | 
| `checkpoint_timeout` | s | 
| `checkpoint_warning` | s | 
| `deadlock_timeout` | ms | 
| `effective_cache_size` | 8 KB | 
| `lock_timeout` | ms | 
| `log_autovacuum_min_duration` | ms | 
| `log_min_duration_statement` | ms | 
| `log_rotation_age` | minutes | 
| `log_rotation_size` | KB | 
| `log_temp_files` | KB | 
| `maintenance_work_mem` | KB | 
| `max_stack_depth` | KB | 
| `max_standby_archive_delay` | ms | 
| `max_standby_streaming_delay` | ms | 
| `post_auth_delay` | s | 
| `pre_auth_delay` | s | 
| `segment_size` | 8 KB | 
| `shared_buffers` | 8 KB | 
| `statement_timeout` | ms | 
| `ssl_renegotiation_limit` | KB | 
| `tcp_keepalives_idle` | s | 
| `tcp_keepalives_interval` | s | 
| `temp_file_limit` | KB | 
| `work_mem` | KB | 
| `temp_buffers` | 8 KB | 
| `vacuum_cost_delay` | ms | 
| `wal_buffers` | 8 KB | 
| `wal_receiver_timeout` | ms | 
| `wal_segment_size` | B | 
| `wal_sender_timeout` | ms | 
| `wal_writer_delay` | ms | 
| `wal_receiver_status_interval` | s | 