

# 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) パラメータで指定された値までの結果を保存する、複数のソート操作またはハッシュ操作を同時に実行する場合があります。インスタンスメモリが不足すると、結果を保存する一時ファイルが作成されます。これらは、クエリの実行を完了するためにディスクに書き込まれます。その後、これらのファイルは、クエリが完了すると自動的に削除されます。Aurora PostgreSQL では、これらのファイルはローカルストレージを他のログファイルと共有します。Aurora PostgreSQL DB クラスターのローカルストレージスペースをモニタリングするには、Amazon CloudWatch メトリックスで `FreeLocalStorage` を監視します。詳細については、「[Troubleshoot local storage issues](https://aws.amazon.com/premiumsupport/knowledge-center/postgresql-aurora-storage-issue/)」(ローカルストレージの問題のトラブルシューティング) を参照してください。

複数のクエリが同時に実行され、一時ファイルの使用量が増えるワークロードには、Aurora Optimized Read クラスターを使用することをお勧めします。これらのクラスターがローカルの不揮発性メモリエクスプレス (NVMe) ベースのソリッドステートドライブ (SSD) ブロックレベルストレージを使用することで、一時ファイルを配置します。詳細については、「[Amazon Optimized Reads による Aurora PostgreSQL のクエリパフォーマンスの向上](AuroraPostgreSQL.optimized.reads.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/AuroraUserGuide/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/AuroraUserGuide/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/AuroraUserGuide/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/AuroraUserGuide/apg-waits.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` コマンドを使用してこのパラメータをセッションレベルで設定します。そうすれば、変更は現在のセッションにのみ適用され、値がグローバルに変更されることはありません。