

# 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 최적화된 읽기 인스턴스를 사용하는 것이 좋습니다. 이러한 인스턴스는 SSD(Solid State Drive) 블록 스토리지에 기반한 NVMe(Non-Volatile Memory Express)를 사용하여 임시 파일을 배치할 수 있습니다. 자세한 내용은 [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/)`** - 성능 개선 도우미 대시보드에서 **temp\$1bytes** 및 **temp\$1files** 메트릭을 켜서 임시 파일 사용량을 확인할 수 있습니다. 그런 다음, 이 두 지표의 평균을 확인하고 두 지표가 쿼리 워크로드에 어떻게 상응하는지 확인할 수 있습니다. 성능 개선 도우미 내부의 보기에는 임시 파일을 생성 중인 쿼리가 구체적으로 표시되지 않습니다. 그러나 성능 개선 도우미를 `pg_ls_tmpdir`에 대해 표시된 쿼리와 결합하면 쿼리 워크로드의 문제를 해결하고, 분석하고, 변경 사항을 확인할 수 있습니다.

  성능 개선 도우미를 사용하여 지표를 분석하고 쿼리를 분석하는 방법에 대한 자세한 내용은 [성능 개선 도우미 대시보드를 사용한 지표 분석](USER_PerfInsights.UsingDashboard.md) 섹션을 참조하세요.

  성능 개선 도우미를 사용하여 임시 파일 사용량을 보는 예제는 [성능 개선 도우미를 사용하여 임시 파일 사용량 확인](PostgreSQL.ManagingTempFiles.Example.md) 섹션을 참조하세요.

# 성능 개선 도우미를 사용하여 임시 파일 사용량 확인
<a name="PostgreSQL.ManagingTempFiles.Example"></a>

성능 개선 도우미를 통해 지표 **temp\$1bytes** 및 **temp\$1files**를 설정하여 임시 파일 사용량을 볼 수 있습니다. 성능 개선 도우미 보기에는 임시 파일을 생성하는 특정 쿼리가 표시되지 않지만, `pg_ls_tmpdir`에 대해 표시된 쿼리와 성능 개선 도우미를 결합하면 쿼리 워크로드를 분석하고, 변경 사항을 확인하고, 문제를 해결할 수 있습니다.

1. 성능 개선 도우미 대시보드에서 **지표 관리**를 선택합니다.

1. 다음 이미지에 나와 있는 것처럼 **데이터베이스 지표**를 선택하고, **temp\$1bytes** 및 **temp\$1files**를 선택합니다.  
![\[지표가 그래프로 표시됩니다.\]](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/images/rpg_mantempfiles_metrics.png)

1. **상위 SQL** 탭에서 **기본 설정** 아이콘을 선택합니다.

1. **기본 설정** 창에서 **상위 SQL** 탭에 표시할 다음 통계를 켜고 **계속**을 선택합니다.
   + 임시 쓰기/초
   + 임시 읽기/초
   + 임시 대량 쓰기/호출
   + 임시 대량 읽기/호출

1. 다음 예제에 나온 것처럼, 임시 파일은 `pg_ls_tmpdir`에 대해 표시된 쿼리와 함께 통합될 때 분할됩니다.  
![\[임시 파일 사용량을 표시하는 쿼리.\]](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/images/rpg_mantempfiles_query.png)

`IO:BufFileRead` 및 `IO:BufFileWrite` 이벤트는 대개 워크로드의 상위 쿼리에서 임시 파일이 생성될 때 발생합니다. 데이터베이스 부하 및 상위 SQL 섹션의 AAS(상위 활성 세션)를 검토하여 `IO:BufFileRead` 및 `IO:BufFileWrite`에서 대기 중인 상위 쿼리를 식별하는 데 성능 개선 도우미를 사용할 수 있습니다.

![\[그래프에 IO:BufFileRead 및 IO:BufFileWrite가 표시되어 있습니다.\]](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/images/perfinsights_IOBufFile.png)


성능 개선 도우미를 사용하여 상위 쿼리와 대기 이벤트에서 부하를 분석하는 방법에 대한 자세한 내용은 [상위 SQL(Top 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` 명령을 사용하여 세션 수준에서 이 파라미터를 설정하는 것이 가장 좋습니다. 그러면 변경 사항이 현재 세션에만 적용되고 값이 전체적으로 변경되지 않습니다.