

# LWLock:pg\$1stat\$1statements
<a name="apg-rpg-lwlockpgstat"></a>

LWLock:pg\$1stat\$1statements 대기 이벤트는 `pg_stat_statements` 확장이 SQL 문을 추적하는 해시 테이블에서 배타적 잠금을 수행할 때 발생합니다. 다음 시나리오에서 발생할 수 있습니다.
+ 추적된 문 수가 구성된 `pg_stat_statements.max` 파라미터 값에 도달하고 더 많은 항목을 위한 공간을 확보해야 하는 경우, 확장은 직접 호출 수를 기준으로 정렬을 수행하고 가장 적게 실행된 문 중 5%를 제거한 다음 해시를 나머지 항목으로 다시 채웁니다.
+ `pg_stat_statements`가 디스크의 `pgss_query_texts.stat` 파일에 대해 `garbage collection` 작업을 수행하고 파일을 다시 쓰는 경우

**Topics**
+ [지원되는 엔진 버전](#apg-rpg-lwlockpgstat.supported)
+ [컨텍스트](#apg-rpg-lwlockpgstat.context)
+ [대기 증가의 가능한 원인](#apg-rpg-lwlockpgstat.causes)
+ [작업](#apg-rpg-lwlockpgstat.actions)

## 지원되는 엔진 버전
<a name="apg-rpg-lwlockpgstat.supported"></a>

 이 대기 이벤트 정보는 모든 Aurora PostgreSQL 버전에서 지원됩니다.

## 컨텍스트
<a name="apg-rpg-lwlockpgstat.context"></a>

**pg\$1stat\$1statements 확장 이해** - pg\$1stat\$1statements 확장은 해시 테이블에서 SQL 문 실행 통계를 추적합니다. 이 확장은 `pg_stat_statements.max` 파라미터에서 정의된 한도까지 SQL 문을 추적합니다. 이 파라미터는 추적할 수 있는 문의 최대 수를 결정하며, 이는 pg\$1stat\$1statements 뷰의 최대 행 수에 해당합니다.

**문 통계 지속성** - 이 확장은 다음을 통해 인스턴스 재시작 시 문 통계를 유지합니다.
+ pg\$1stat\$1statements.stat라는 파일에 데이터 쓰기
+ pg\$1stat\$1statements.save 파라미터를 사용하여 지속성 동작 제어

pg\$1stat\$1statements.save가 다음과 같이 설정된 경우:
+ on(기본값): 통계는 종료 시 저장되고 서버 시작 시 다시 로드됩니다.
+ off: 통계는 종료 시 저장되지 않으며 서버 시작 시 다시 로드되지 않습니다.

**쿼리 텍스트 저장소** - 이 확장은 추적된 쿼리의 텍스트를 `pgss_query_texts.stat`라는 파일에 저장합니다. 이 파일은 폐영역 회수가 발생하기 전에 추적된 모든 SQL 문의 평균 크기의 두 배까지 늘어날 수 있습니다. 이 확장에는 정리 작업 및 `pgss_query_texts.stat` 파일 재작성 중에 해시 테이블에 대한 배타적 잠금이 필요합니다.

**문 할당 취소 프로세스** - 추적된 문 수가 `pg_stat_statements.max` 한도에 도달하고 새 문을 추적해야 하는 경우 확장은 다음을 수행합니다.
+ 해시 테이블에서 배타적 잠금(LWLock:pg\$1stat\$1statements)을 수행합니다.
+ 기존 데이터를 로컬 메모리에 로드합니다.
+ 직접 호출 수를 기반으로 빠른 정렬을 수행합니다.
+ 가장 적게 호출된 문(하위 5%)을 제거합니다.
+ 해시 테이블을 나머지 항목으로 다시 채웁니다.

**문 할당 취소 모니터링** - PostgreSQL 14 이상에서는 pg\$1stat\$1statements\$1info 뷰를 사용하여 문 할당 취소를 모니터링할 수 있습니다. 이 뷰에는 새 문을 위한 공간을 마련하기 위해 문을 할당 취소한 횟수를 보여주는 dealloc 열이 포함되어 있습니다.

문의 할당 취소가 자주 발생하면 디스크에서 `pgss_query_texts.stat` 파일의 폐영역 회수가 더 자주 발생합니다.

## 대기 증가의 가능한 원인
<a name="apg-rpg-lwlockpgstat.causes"></a>

`LWLock:pg_stat_statements` 대기 시간 증가의 일반적인 원인은 다음과 같습니다.
+ 애플리케이션에서 사용하는 고유 쿼리 수가 증가함
+ 사용되는 고유 쿼리 수 대비 `pg_stat_statements.max` 파라미터 값이 작음

## 작업
<a name="apg-rpg-lwlockpgstat.actions"></a>

대기 이벤트의 원인에 따라 다른 작업을 권장합니다. Amazon RDS Performance Insights를 사용하거나 `pg_stat_activity` 뷰를 쿼리하여 `LWLock:pg_stat_statements` 이벤트를 식별할 수 있습니다.

다음 `pg_stat_statements` 파라미터를 조정하여 추적 동작을 제어하고 LWLock:pg\$1stat\$1 문 대기 이벤트를 줄입니다.

**Topics**
+ [pg\$1stat\$1statements.track 파라미터 비활성화](#apg-rpg-lwlockpgstat.actions.disabletrack)
+ [pg\$1stat\$1statements.max 파라미터 증가](#apg-rpg-lwlockpgstat.actions.increasemax)
+ [pg\$1stat\$1statements.track\$1utility 파라미터 비활성화](#apg-rpg-lwlockpgstat.actions.disableutility)

### pg\$1stat\$1statements.track 파라미터 비활성화
<a name="apg-rpg-lwlockpgstat.actions.disabletrack"></a>

LWLock:pg\$1stat\$1statements 대기 이벤트가 데이터베이스 성능에 부정적인 영향을 미치고 근본 원인을 식별하기 위해 `pg_stat_statements` 뷰를 추가로 분석하기 전에 신속한 솔루션이 필요한 경우 `pg_stat_statements.track` 파라미터를 `none`으로 설정하여 파라미터를 비활성화할 수 있습니다. 그러면 문 통계 수집이 비활성화됩니다.

### pg\$1stat\$1statements.max 파라미터 증가
<a name="apg-rpg-lwlockpgstat.actions.increasemax"></a>

할당 취소를 줄이고 디스크에서 `pgss_query_texts.stat` 파일의 폐영역 회수를 최소화하려면 `pg_stat_statements.max` 파라미터 값을 늘립니다. 기본값은 `5,000`입니다.

**참고**  
`pg_stat_statements.max` 파라미터는 정적입니다. 이 파라미터에 변경 사항을 적용하려면 DB 인스턴스를 다시 시작해야 합니다.

### pg\$1stat\$1statements.track\$1utility 파라미터 비활성화
<a name="apg-rpg-lwlockpgstat.actions.disableutility"></a>

pg\$1stat\$1statements 뷰를 분석하여 `pg_stat_statements`에서 추적하는 리소스를 가장 많이 소비하는 유틸리티 명령을 확인할 수 있습니다.

`pg_stat_statements.track_utility` 파라미터는 모듈이 SELECT, INSERT, UPDATE, DELETE 및 MERGE를 제외한 모든 명령을 포함하는 유틸리티 명령을 추적하는지를 제어합니다. 이 파라미터는 기본적으로 `on`로 설정되어 있습니다.

예를 들어 애플리케이션이 본질적으로 고유한 많은 저장점 쿼리를 사용하는 경우 문 할당 취소가 증가할 수 있습니다. 이를 해결하기 위해 `pg_stat_statements.track_utility` 파라미터를 비활성화하여 `pg_stat_statements`가 저장점 쿼리를 추적하지 않도록 할 수 있습니다.

**참고**  
`pg_stat_statements.track_utility` 파라미터는 동적 파라미터입니다. 데이터베이스 인스턴스를 다시 시작하지 않고도 값을 변경할 수 있습니다.

**Example pg\$1stat\$1statements의 고유한 저장점 쿼리 예시**  <a name="savepoint-queries"></a>

```
                     query                       |       queryid       
-------------------------------------------------+---------------------
 SAVEPOINT JDBC_SAVEPOINT_495701                 | -7249565344517699703
 SAVEPOINT JDBC_SAVEPOINT_1320                   | -1572997038849006629
 SAVEPOINT JDBC_SAVEPOINT_26739                  |  54791337410474486
 SAVEPOINT JDBC_SAVEPOINT_1294466                |  8170064357463507593
 ROLLBACK TO SAVEPOINT JDBC_SAVEPOINT_65016      | -33608214779996400
 SAVEPOINT JDBC_SAVEPOINT_14185                  | -2175035613806809562
 SAVEPOINT JDBC_SAVEPOINT_45837                  | -6201592986750645383
 SAVEPOINT JDBC_SAVEPOINT_1324                   |  6388797791882029332
```

PostgreSQL 17에는 유틸리티 명령 추적을 위한 몇 가지 향상된 기능이 도입되었습니다.
+ 이제 Savepoint 이름이 상수로 표시됩니다.
+ 이제 두 단계 커밋 명령의 글로벌 트랜잭션 ID(GID)가 상수로 표시됩니다.
+ DEALLOCATE 문의 이름이 상수로 표시됩니다.
+ 이제 CALL 파라미터가 상수로 표시됩니다.