모니터링·통계 (Monitoring and Statistics)
모니터링·통계 (Monitoring and Statistics)
PostgreSQL의 누적 통계 시스템(cumulative statistics system) 은 서버 활동 정보를 수집하고 보고하는 데 쓰여요. 지금 시점에는 테이블과 인덱스에 대한 접근을 디스크 블록 단위와 개별 행 단위로 각각 세어서 기록합니다. 각 테이블의 총 행 수, 그리고 각 테이블에 대해 수행된 VACUUM 과 ANALYZE 작업 정보도 함께 셉니다. 그리고 켜 두면 사용자 정의 함수에 대한 호출 횟수와 각 함수에 소요된 총 시간도 기록합니다.
PostgreSQL은 또 지금 시스템에서 정확히 무슨 일이 벌어지고 있는지에 대한 동적 정보도 보고할 수 있어요. 예를 들어 다른 서버 프로세스가 지금 실행 중인 정확한 명령이나, 시스템에 존재하는 다른 연결들이 무엇인지 같은 것들이죠. 이 기능은 누적 통계 시스템과는 별개로 동작합니다.
27.2.1 통계 수집 설정 (Statistics Collection Configuration)
통계 수집은 쿼리 실행에 약간의 오버헤드를 더하기 때문에, 시스템은 정보를 수집할지 말지를 설정할 수 있게 되어 있어요. 이는 보통 postgresql.conf 에 설정하는 구성 파라미터로 제어합니다. (설정 파라미터를 정하는 자세한 방법은 설정 관련 문서를 참고하세요.)
관련 파라미터를 살펴볼게요.
track_activities— 어떤 서버 프로세스가 실행 중인 현재 명령을 모니터링할지 켭니다.track_cost_delay_timing— 비용 기반 vacuum 지연(cost-based vacuum delay)의 모니터링을 켭니다.track_counts— 테이블과 인덱스 접근에 대한 누적 통계를 수집할지 제어합니다.track_functions— 사용자 정의 함수의 사용 추적을 켭니다.track_io_timing— 블록 읽기·쓰기·확장·fsync 시간의 모니터링을 켭니다.track_wal_io_timing— WAL 읽기·쓰기·fsync 시간의 모니터링을 켭니다.
이 파라미터들은 보통 postgresql.conf 에 설정해서 모든 서버 프로세스에 적용되지만, 개별 세션에서는 SET 명령으로 켜고 끌 수도 있어요. 다만 일반 사용자가 관리자로부터 자신의 활동을 숨기지 못하게 하려고, 이 파라미터들을 SET 으로 바꾸는 것은 슈퍼유저만 허용합니다.
누적 통계는 공유 메모리(shared memory)에 수집됩니다. 모든 PostgreSQL 프로세스는 통계를 로컬로 수집한 뒤, 적절한 간격으로 공유 메모리 데이터를 갱신해요. 서버(물리적 복제 서버 포함)가 깨끗하게 종료되면 통계 데이터의 영구 복사본이 pg_stat 서브디렉터리에 저장되어, 서버 재시작 후에도 통계가 유지됩니다. 반면 깨끗하지 않은 종료(예: immediate shutdown, 서버 크래시, 베이스 백업에서 시작, point-in-time recovery)로 시작하면 모든 통계 카운터가 초기화됩니다.
27.2.2 통계 보기 (Viewing Statistics)
시스템의 현재 상태를 보여주는 몇 가지 미리 정의된 뷰와, 누적 통계를 보여주는 또 다른 뷰들이 있어요. 아래에서 자세히 다룰게요. 또는 누적 통계 함수를 사용해 나만의 커스텀 뷰를 만들 수도 있어요.
누적 통계 뷰와 함수로 수집 데이터를 모니터링할 때 꼭 알아둬야 할 점이 있어요. 정보가 즉시 갱신되지 않습니다. 각 서버 프로세스는 누적된 통계를 유휴 상태로 들어가기 직전에 공유 메모리로 내보내는데, PGSTAT_MIN_INTERVAL 밀리초(서버 빌드 때 바꾸지 않았다면 1초)보다 자주 내보내지는 않아요. 그래서 아직 진행 중인 쿼리나 트랜잭션은 표시되는 합계에 반영되지 않고, 표시되는 정보는 실제 활동보다 뒤처집니다. 다만 track_activities 가 수집하는 현재 쿼리 정보는 항상 최신이에요.
또 한 가지 중요한 점이 있어요. 서버 프로세스가 누적 통계 중 어느 하나를 표시하도록 요청받으면, 기본 설정에서는 접근한 값이 현재 트랜잭션이 끝날 때까지 캐시됩니다. 그래서 현재 트랜잭션을 이어가는 동안에는 통계가 정적인 정보로 보여요. 마찬가지로 모든 세션의 현재 쿼리 정보도 트랜잭션 안에서 처음 요청될 때 수집되어, 트랜잭션 내내 같은 정보가 표시됩니다. 이는 버그가 아니라 의도된 동작이에요 — 통계에 대해 여러 쿼리를 수행하고 그 결과를 서로 연관 지어도, 그 사이에 숫자가 바뀌는 걱정을 하지 않아도 되게 해 주거든요.
통계를 대화형으로, 또는 값비싼 쿼리로 분석할 때는 개별 통계에 접근하는 시간 차이 때문에 캐시된 통계에 꽤 큰 왜곡(skew)이 생길 수 있어요. 이 왜곡을 줄이려면 stats_fetch_consistency 를 snapshot 으로 설정하면 되는데, 필요하지 않은 통계 데이터까지 캐싱하느라 메모리 사용량이 늘어나는 대가가 있어요. 반대로 통계를 한 번만 접근한다는 걸 안다면 캐싱은 불필요한 일이라 stats_fetch_consistency 를 none 으로 설정해 피할 수 있어요. pg_stat_clear_snapshot() 을 호출하면 현재 트랜잭션의 통계 스냅샷 또는 캐시된 값(있다면)을 버릴 수 있어요. 이후 통계 정보를 다시 사용하면, 스냅샷 모드에서는 새 스냅샷을 만들고, 캐시 모드에서는 접근한 통계를 캐시합니다.
트랜잭션은 아직 공유 메모리 통계로 내보내지지 않은 자기 자신의 통계도 pg_stat_xact_all_tables, pg_stat_xact_sys_tables, pg_stat_xact_user_tables, pg_stat_xact_user_functions 뷰에서 볼 수 있어요. 이 숫자들은 위에서 설명한 대로 동작하지 않고, 트랜잭션 내내 계속 갱신됩니다.
동적 통계 뷰에 담긴 정보 중 일부는 보안상 제한됩니다. 일반 사용자는 자신의 세션(자신이 멤버인 역할에 속한 세션)에 대한 모든 정보만 볼 수 있어요. 다른 세션에 대한 행에서는 많은 컬럼이 null 이 됩니다. 다만 세션의 존재 자체와 세션 사용자·데이터베이스 같은 일반 속성은 모든 사용자에게 보입니다. 슈퍼유저와 내장 역할 pg_read_all_stats 권한을 가진 역할은 모든 세션에 대한 모든 정보를 볼 수 있어요.
동적 통계 뷰 (Dynamic Statistics Views)
| 뷰 이름 | 설명 |
|---|---|
pg_stat_activity |
서버 프로세스당 한 행. 상태, 현재 쿼리 등 해당 프로세스의 현재 활동 관련 정보. |
pg_stat_replication |
WAL sender 프로세스당 한 행. 그 sender에 연결된 대기(standby) 서버로의 복제 통계. |
pg_stat_wal_receiver |
한 행만. 연결된 서버로부터의 WAL receiver 통계. |
pg_stat_recovery_prefetch |
한 행만. 복구 중 프리페치된 블록 통계. |
pg_stat_subscription |
구독당 최소 한 행. 구독 worker 정보. |
pg_stat_ssl |
연결당 한 행(일반·복제 모두). 해당 연결에서 사용된 SSL 정보. |
pg_stat_gssapi |
연결당 한 행(일반·복제 모두). 해당 연결에서 사용된 GSSAPI 인증·암호화 정보. |
pg_stat_progress_analyze |
ANALYZE 를 실행 중인 각 백엔드(autovacuum worker 포함)당 한 행. 현재 진행 상황. |
pg_stat_progress_create_index |
CREATE INDEX 또는 REINDEX 를 실행 중인 각 백엔드당 한 행. 현재 진행 상황. |
pg_stat_progress_vacuum |
VACUUM 을 실행 중인 각 백엔드(autovacuum worker 포함)당 한 행. 현재 진행 상황. |
pg_stat_progress_cluster |
CLUSTER 또는 VACUUM FULL 을 실행 중인 각 백엔드당 한 행. 현재 진행 상황. |
pg_stat_progress_basebackup |
베이스 백업을 스트리밍하는 각 WAL sender 프로세스당 한 행. 현재 진행 상황. |
pg_stat_progress_copy |
COPY 를 실행 중인 각 백엔드당 한 행. 현재 진행 상황. |
수집 통계 뷰 (Collected Statistics Views)
| 뷰 이름 | 설명 |
|---|---|
pg_stat_archiver |
한 행만. WAL 아카이버 프로세스 활동 통계. |
pg_stat_bgwriter |
한 행만. 백그라운드 라이터 프로세스 활동 통계. |
pg_stat_checkpointer |
한 행만. 체크포인터 프로세스 활동 통계. |
pg_stat_database |
데이터베이스당 한 행. 데이터베이스 전체 통계. |
pg_stat_database_conflicts |
데이터베이스당 한 행. 대기 서버에서 복구와의 충돌로 인한 쿼리 취소 통계. |
pg_stat_io |
백엔드 유형·컨텍스트·대상 객체 조합당 한 행. 클러스터 전체 I/O 통계. |
pg_stat_replication_slots |
복제 슬롯당 한 행. 슬롯 사용 통계. |
pg_stat_slru |
SLRU당 한 행. 연산 통계. |
pg_stat_subscription_stats |
구독당 한 행. 오류·충돌 통계. |
pg_stat_wal |
한 행만. WAL 활동 통계. |
pg_stat_all_tables |
현재 데이터베이스의 테이블당 한 행. 해당 테이블에 대한 접근 통계. |
pg_stat_sys_tables |
pg_stat_all_tables 와 동일하되 시스템 테이블만 표시. |
pg_stat_user_tables |
pg_stat_all_tables 와 동일하되 사용자 테이블만 표시. |
pg_stat_xact_all_tables |
pg_stat_all_tables 와 유사하나, 현재 트랜잭션 안에서 지금까지 취한 액션을 계산합니다(아직 pg_stat_all_tables 와 관련 뷰에 포함되지 않은 것들). 이 뷰에는 라이브·데드 행 수, vacuum·analyze 액션 컬럼이 없어요. |
pg_stat_xact_sys_tables |
pg_stat_xact_all_tables 와 동일하되 시스템 테이블만 표시. |
pg_stat_xact_user_tables |
pg_stat_xact_all_tables 와 동일하되 사용자 테이블만 표시. |
pg_stat_all_indexes |
현재 데이터베이스의 인덱스당 한 행. 해당 인덱스에 대한 접근 통계. |
pg_stat_sys_indexes |
pg_stat_all_indexes 와 동일하되 시스템 테이블의 인덱스만 표시. |
pg_stat_user_indexes |
pg_stat_all_indexes 와 동일하되 사용자 테이블의 인덱스만 표시. |
pg_stat_user_functions |
추적되는 함수당 한 행. 함수 실행 통계. |
pg_stat_xact_user_functions |
pg_stat_user_functions 와 유사하나, 현재 트랜잭션 중의 호출만 계산합니다(아직 pg_stat_user_functions 에 포함되지 않은 것들). |
pg_statio_all_tables |
현재 데이터베이스의 테이블당 한 행. 해당 테이블의 I/O 통계. |
pg_statio_sys_tables |
pg_statio_all_tables 와 동일하되 시스템 테이블만 표시. |
pg_statio_user_tables |
pg_statio_all_tables 와 동일하되 사용자 테이블만 표시. |
pg_statio_all_indexes |
현재 데이터베이스의 인덱스당 한 행. 해당 인덱스의 I/O 통계. |
pg_statio_sys_indexes |
pg_statio_all_indexes 와 동일하되 시스템 테이블의 인덱스만 표시. |
pg_statio_user_indexes |
pg_statio_all_indexes 와 동일하되 사용자 테이블의 인덱스만 표시. |
pg_statio_all_sequences |
현재 데이터베이스의 시퀀스당 한 행. 해당 시퀀스의 I/O 통계. |
pg_statio_sys_sequences |
pg_statio_all_sequences 와 동일하되 시스템 시퀀스만 표시. (현재 정의된 시스템 시퀀스가 없어 이 뷰는 항상 비어 있어요.) |
pg_statio_user_sequences |
pg_statio_all_sequences 와 동일하되 사용자 시퀀스만 표시. |
인덱스별 통계는 어떤 인덱스가 사용되고 있는지, 얼마나 효과적인지 판단하는 데 특히 유용합니다.
pg_stat_io 와 pg_statio_ 뷰 묶음은 버퍼 캐시의 효과를 판단하는 데 유용해요. 이들로 캐시 히트율(cache hit ratio)을 계산할 수 있습니다. 다만 PostgreSQL의 I/O 통계가 커널을 호출해 I/O를 수행한 대부분의 경우를 잡아내기는 하지만, 디스크에서 가져와야 했던 데이터와 이미 커널 페이지 캐시에 있던 데이터를 구분하지는 않아요. 그래서 데이터베이스 I/O 성능의 더 완전한 그림을 얻으려면 PostgreSQL 통계 뷰를 운영체제 유틸리티와 함께 쓰는 걸 권장합니다.
27.2.3 pg_stat_activity
pg_stat_activity 뷰는 서버 프로세스당 한 행을 가지며, 해당 프로세스의 현재 활동과 관련된 정보를 보여줍니다.
주요 컬럼을 살펴볼게요.
| 컬럼 | 타입 | 설명 |
|---|---|---|
datid |
oid |
이 백엔드가 연결된 데이터베이스의 OID |
datname |
name |
이 백엔드가 연결된 데이터베이스 이름 |
pid |
integer |
이 백엔드의 프로세스 ID |
leader_pid |
integer |
병렬 쿼리 worker면 병렬 그룹 리더의 프로세스 ID, 병렬 apply worker면 리더 apply worker의 프로세스 ID. NULL 이면 병렬 그룹 리더이거나 병렬 연산에 참여하지 않음을 뜻함 |
usesysid |
oid |
이 백엔드에 로그인한 사용자의 OID |
usename |
name |
이 백엔드에 로그인한 사용자 이름 |
application_name |
text |
이 백엔드에 연결된 애플리케이션 이름 |
client_addr |
inet |
이 백엔드에 연결된 클라이언트의 IP 주소. null 이면 클라이언트가 서버 머신의 유닉스 소켓으로 연결됐거나 autovacuum 같은 내부 프로세스임을 뜻함 |
client_hostname |
text |
client_addr 의 역 DNS 조회로 얻은 연결 클라이언트의 호스트 이름. IP 연결에서만, 그리고 log_hostname 이 켜져 있을 때만 non-null |
client_port |
integer |
클라이언트가 이 백엔드와 통신할 때 쓰는 TCP 포트 번호. 유닉스 소켓을 쓰면 -1. null 이면 내부 서버 프로세스임을 뜻함 |
backend_start |
timestamp with time zone |
이 프로세스가 시작된 시각. 클라이언트 백엔드의 경우 클라이언트가 서버에 연결한 시각 |
xact_start |
timestamp with time zone |
이 프로세스의 현재 트랜잭션이 시작된 시각, 활성 트랜잭션이 없으면 null. 현재 쿼리가 트랜잭션의 첫 번째면 query_start 와 같음 |
query_start |
timestamp with time zone |
현재 활성 쿼리가 시작된 시각, 또는 state 가 active 가 아니면 마지막 쿼리가 시작된 시각 |
state_change |
timestamp with time zone |
state 가 마지막으로 바뀐 시각 |
wait_event_type |
text |
백엔드가 대기 중인 이벤트 유형, 없으면 NULL |
wait_event |
text |
백엔드가 현재 대기 중이면 대기 이벤트 이름, 아니면 NULL |
state |
text |
이 백엔드의 현재 전반적 상태. 가능한 값: starting(초기 시작, 이 단계에서 클라이언트 인증 수행), active(쿼리 실행 중), idle(새 클라이언트 명령 대기), idle in transaction(트랜잭션 안이지만 쿼리 실행 중은 아님), idle in transaction (aborted)(트랜잭션 안에서 한 문장이 오류를 일으킨 상태), fastpath function call(fast-path 함수 실행 중), disabled(이 백엔드에서 track_activities 가 꺼짐) |
backend_xid |
xid |
이 백엔드의 최상위 트랜잭션 식별자(있다면) |
backend_xmin |
xid |
현재 백엔드의 xmin 지평선 |
query_id |
bigint |
이 백엔드의 가장 최근 쿼리 식별자. state 가 active 면 현재 실행 중인 쿼리, 그 외 상태에서는 마지막으로 실행된 쿼리를 표시. 쿼리 식별자는 기본적으로 계산되지 않아 compute_query_id 파라미터를 켜거나 쿼리 식별자를 계산하는 서드파티 모듈을 설정하지 않으면 null |
query |
text |
이 백엔드의 가장 최근 쿼리 텍스트. state 가 active 면 현재 실행 중인 쿼리, 그 외 상태에서는 마지막으로 실행된 쿼리. 기본적으로 쿼리 텍스트는 1024바이트에서 잘리며, 이 값은 track_activity_query_size 파라미터로 바꿀 수 있음 |
backend_type |
text |
현재 백엔드 유형. 가능한 유형은 autovacuum launcher, autovacuum worker, logical replication launcher, logical replication worker, parallel worker, background writer, client backend, checkpointer, archiver, standalone backend, startup, walreceiver, walsender, walwriter, walsummarizer. 확장이 등록한 백그라운드 worker는 추가 유형을 가질 수 있음 |
참고
wait_event 와 state 컬럼은 서로 독립적입니다. 백엔드가 active 상태여도 어떤 이벤트에서 waiting 하고 있을 수도 있고 아닐 수도 있어요. state 가 active 인데 wait_event 가 non-null 이면, 쿼리가 실행 중이긴 하지만 시스템 어딘가에서 막혀 있다는 뜻입니다. 보고 오버헤드를 낮게 유지하려고 시스템은 한 백엔드의 활동 데이터 서로 다른 측면을 동기화하려 하지 않아요. 그 결과 뷰의 컬럼들 사이에 일시적인 불일치가 존재할 수 있습니다.
대기 이벤트 유형 (Wait Event Types)
| 대기 이벤트 유형 | 설명 |
|---|---|
Activity |
서버 프로세스가 유휴 상태. 메인 처리 루프에서 활동을 기다리는 상태를 뜻함 |
BufferPin |
데이터 버퍼에 대한 배타적 접근을 기다림. 다른 프로세스가 해당 버퍼에서 마지막으로 데이터를 읽은 열린 커서를 갖고 있으면 버퍼 핀 대기는 길어질 수 있음 |
Client |
사용자 애플리케이션에 연결된 소켓에서 활동을 기다림. 내부 프로세스와 무관하게 무언가 일어나기를 기대하는 상태 |
Extension |
확장 모듈이 정의한 어떤 조건을 기다림 |
InjectionPoint |
테스트에서 정의한 결과에 injection point 가 도달하기를 기다림. 미리 정의된 대기 지점은 없음 |
IO |
I/O 연산 완료를 기다림 |
IPC |
다른 서버 프로세스와의 상호작용을 기다림 |
Lock |
heavyweight lock 을 기다림. heavyweight lock(또는 lock manager lock, 그냥 lock)은 주로 테이블 같은 SQL에 보이는 객체를 보호하지만, relation 확장 같은 특정 내부 연산의 상호 배제에도 쓰임 |
LWLock |
lightweight lock 을 기다림. 대부분의 이러한 lock 은 공유 메모리의 특정 데이터 구조를 보호함 |
Timeout |
타임아웃이 만료되기를 기다림 |
대기 이벤트 유형별 목록
Activity 유형: ArchiverMain(아카이버 프로세스 메인 루프), AutovacuumMain(autovacuum 런처 메인 루프), BgwriterHibernate(백그라운드 라이터, 하이버네이션), BgwriterMain(백그라운드 라이터 메인 루프), CheckpointerMain(체크포인터 메인 루프), CheckpointerShutdown(체크포인터 종료 대기), IoWorkerMain(IO Worker 메인 루프), LogicalApplyMain(논리 복제 apply 메인 루프), LogicalLauncherMain(논리 복제 런처 메인 루프), LogicalParallelApplyMain(논리 복제 병렬 apply 메인 루프), RecoveryWalStream(스트리밍 복구 중 startup 프로세스가 WAL 도착 대기), ReplicationSlotsyncMain(슬롯 sync worker 메인 루프), ReplicationSlotsyncShutdown(슬롯 sync worker 종료 대기), SysloggerMain(syslogger 메인 루프), WalReceiverMain(WAL receiver 메인 루프), WalSenderMain(WAL sender 메인 루프), WalSummarizerWal(WAL summarizer 가 더 많은 WAL 생성 대기), WalWriterMain(WAL writer 메인 루프).
BufferPin 유형: BufferPin(버퍼에 대한 배타적 핀 획득 대기).
Client 유형: ClientRead(클라이언트로부터 데이터 읽기 대기), ClientWrite(클라이언트에 데이터 쓰기 대기), GssOpenServer(GSSAPI 세션 수립 중 클라이언트 데이터 읽기 대기), LibpqwalreceiverConnect(WAL receiver 가 원격 서버 연결 수립 대기), LibpqwalreceiverReceive(WAL receiver 가 원격 서버로부터 데이터 수신 대기), SslOpenServer(연결 시도 중 SSL 대기), WaitForStandbyConfirmation(물리 standby 가 WAL 을 수신·플러시하기를 대기), WalSenderWaitForWal(WAL sender 가 WAL 플러시 대기), WalSenderWriteData(WAL sender 가 WAL receiver 응답 처리 중 활동 대기).
Extension 유형: Extension(확장 안에서 대기).
IO 유형: AioIoCompletion, AioIoUringExecution, AioIoUringSubmit, BasebackupRead, BasebackupSync, BasebackupWrite, BuffileRead, BuffileTruncate, BuffileWrite, ControlFileRead, ControlFileSync, ControlFileSyncUpdate, ControlFileWrite, ControlFileWriteUpdate, CopyFileCopy, CopyFileRead, CopyFileWrite, DataFileExtend, DataFileFlush, DataFileImmediateSync, DataFilePrefetch, DataFileRead, DataFileSync, DataFileTruncate, DataFileWrite, DsmAllocate, DsmFillZeroWrite, LockFileAddtodatadirRead, LockFileAddtodatadirSync, LockFileAddtodatadirWrite, LockFileCreateRead, LockFileCreateSync, LockFileCreateWrite, LockFileRecheckdatadirRead, LogicalRewriteCheckpointSync, LogicalRewriteMappingSync, LogicalRewriteMappingWrite, LogicalRewriteSync, LogicalRewriteTruncate, LogicalRewriteWrite, RelationMapRead, RelationMapReplace, RelationMapWrite, ReorderBufferRead, ReorderBufferWrite, ReorderLogicalMappingRead, ReplicationSlotRead, ReplicationSlotRestoreSync, ReplicationSlotSync, ReplicationSlotWrite, SlruFlushSync, SlruRead, SlruSync, SlruWrite, SnapbuildRead, SnapbuildSync, SnapbuildWrite, TimelineHistoryFileSync, TimelineHistoryFileWrite, TimelineHistoryRead, TimelineHistorySync, TimelineHistoryWrite, TwophaseFileRead, TwophaseFileSync, TwophaseFileWrite, VersionFileSync, VersionFileWrite, WalsenderTimelineHistoryRead, WalBootstrapSync, WalBootstrapWrite, WalCopyRead, WalCopySync, WalCopyWrite, WalInitSync, WalInitWrite, WalRead, WalSummaryRead, WalSummaryWrite, WalSync, WalSyncMethodAssign, WalWrite.
IPC 유형: AppendReady, ArchiveCleanupCommand, ArchiveCommand, BackendTermination, BackupWaitWalArchive, BgworkerShutdown, BgworkerStartup, BtreePage, BufferIo, CheckpointDelayComplete, CheckpointDelayStart, CheckpointDone, CheckpointStart, ExecuteGather, HashBatchAllocate, HashBatchElect, HashBatchLoad, HashBuildAllocate, HashBuildElect, HashBuildHashInner, HashBuildHashOuter, HashGrowBatchesDecide, HashGrowBatchesElect, HashGrowBatchesFinish, HashGrowBatchesReallocate, HashGrowBatchesRepartition, HashGrowBucketsElect, HashGrowBucketsReallocate, HashGrowBucketsReinsert, LogicalApplySendData, LogicalParallelApplyStateChange, LogicalSyncData, LogicalSyncStateChange, MessageQueueInternal, MessageQueuePutMessage, MessageQueueReceive, MessageQueueSend, MultixactCreation, ParallelBitmapScan, ParallelCreateIndexScan, ParallelFinish, ProcarrayGroupUpdate, ProcSignalBarrier, Promote, RecoveryConflictSnapshot, RecoveryConflictTablespace, RecoveryEndCommand, RecoveryPause, ReplicationOriginDrop, ReplicationSlotDrop, RestoreCommand, SafeSnapshot, SyncRep, WalReceiverExit, WalReceiverUpstreamCatchup, WalReceiverWaitStart, WalSummaryReady, XactGroupUpdate.
Lock 유형: advisory(advisory 사용자 lock 획득 대기), applytransaction(논리 복제 구독자가 적용 중인 원격 트랜잭션 lock 대기), extend(relation 확장 대기), frozenid(pg_database.datfrozenxid·datminmxid 갱신 대기), object(relation 이 아닌 데이터베이스 객체 lock 대기), page(relation 의 페이지 lock 대기), relation(relation lock 대기), spectoken(추측성 삽입 lock 대기), transactionid(트랜잭션 종료 대기), tuple(튜플 lock 대기), userlock(사용자 lock 대기), virtualxid(가상 트랜잭션 ID lock 대기).
LWLock 유형: AddinShmemInit(확장의 공유 메모리 공간 할당 관리 대기), AioUringCompletion, AioWorkerSubmissionQueue, AutoFile(postgresql.auto.conf 갱신 대기), Autovacuum(autovacuum worker 현재 상태 읽기·갱신 대기), AutovacuumSchedule, BackgroundWorker, BtreeVacuum, BufferContent(메모리의 데이터 페이지 접근 대기), BufferMapping(버퍼 풀에서 데이터 블록을 버퍼와 연결하는 대기), CheckpointerComm(fsync 요청 관리 대기), CommitTs, CommitTsBuffer, CommitTsSLRU, ControlFile, DSMRegistry, DSMRegistryDSA, DSMRegistryHash, DynamicSharedMemoryControl, InjectionPoint, LockFastPath, LockManager(heavyweight lock 정보 읽기·갱신 대기), LogicalRepLauncherDSA, LogicalRepLauncherHash, LogicalRepWorker, MultiXactGen, MultiXactMemberBuffer, MultiXactMemberSLRU, MultiXactOffsetBuffer, MultiXactOffsetSLRU, MultiXactTruncation, NotifyBuffer, NotifyQueue(NOTIFY 메시지 읽기·갱신 대기), NotifyQueueTail, NotifySLRU, OidGen(새 OID 할당 대기), ParallelAppend, ParallelBtreeScan, ParallelHashJoin, ParallelQueryDSA, ParallelVacuumDSA, PerSessionDSA, PerSessionRecordType, PerSessionRecordTypmod, PerXactPredicateList, PgStatsData(공유 메모리 통계 데이터 접근 대기), PgStatsDSA, PgStatsHash, PredicateLockManager, ProcArray(공유 프로세스별 데이터 구조 접근, 주로 스냅샷 획득이나 세션 트랜잭션 ID 보고 시), RelationMapping(pg_filenode.map 파일 읽기·갱신 대기), RelCacheInit(pg_internal.init relation 캐시 초기화 파일 읽기·갱신 대기), ReplicationOrigin, ReplicationOriginState, ReplicationSlotAllocation, ReplicationSlotControl, ReplicationSlotIO, SerialBuffer, SerialControl, SerializableFinishedList, SerializablePredicateList, SerializableXactHash, SerialSLRU, SharedTidBitmap, SharedTupleStore, ShmemIndex(공유 메모리 공간 찾기·할당 대기), SInvalRead, SInvalWrite, SubtransBuffer, SubtransSLRU, SyncRep(동기 복제 상태 읽기·갱신 대기), SyncScan, TablespaceCreate, TwoPhaseState, WaitEventCustom, WALBufMapping(WAL 버퍼에서 페이지 교체 대기), WALInsert(WAL 데이터를 메모리 버퍼에 삽입 대기), WALSummarizer, WALWrite(WAL 버퍼를 디스크에 쓰기 대기), WrapLimitsVacuum(트랜잭션 ID·multixact 소비 한도 갱신 대기), XactBuffer, XactSLRU, XactTruncation, XidGen(새 트랜잭션 ID 할당 대기).
Timeout 유형: BaseBackupThrottle(베이스 백업 중 throttling 시 대기), CheckpointWriteDelay(체크포인트 수행 중 쓰기 사이 대기), PgSleep(pg_sleep 또는 계열 함수 호출로 인한 대기), RecoveryApplyDelay(지연 설정 때문에 복구 중 WAL 적용 대기), RecoveryRetrieveRetryInterval(어떤 소스에서도 WAL 을 얻을 수 없을 때 복구 중 대기), RegisterSyncRequest(요청 큐가 가득 차서 체크포인터에 동기화 요청을 보내는 동안 대기), SpinDelay(경합 중인 스핀락 획득 대기), VacuumDelay(비용 기반 vacuum 지연 지점에서 대기), VacuumTruncate(vacuum 한 테이블 끝의 빈 페이지 잘라내기 위한 배타적 lock 획득 대기), WalSummarizerError(WAL summarizer 오류 후 대기).
대기 이벤트는 이렇게 조회할 수 있어요.
SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event is NOT NULL;
pid | wait_event_type | wait_event
------+-----------------+------------
2540 | Lock | relation
6644 | LWLock | ProcArray
(2 rows)
SELECT a.pid, a.wait_event, w.description
FROM pg_stat_activity a JOIN
pg_wait_events w ON (a.wait_event_type = w.type AND
a.wait_event = w.name)
WHERE a.wait_event is NOT NULL and a.state = 'active';
-[ RECORD 1 ]------------------------------------------------------------------
pid | 686674
wait_event | WALInitSync
description | Waiting for a newly initialized WAL file to reach durable storage
참고
확장은 위 목록(Table 27.8 과 Table 27.12)에 Extension, InjectionPoint, LWLock 이벤트를 추가할 수 있어요. 어떤 경우에는 확장이 할당한 LWLock 이름이 모든 서버 프로세스에서 쓰이지 않을 수도 있습니다. 확장이 할당한 이름 대신 그냥 "extension" 으로 보고될 수도 있어요.
이 페이지는 누적 통계 시스템의 개요, 설정, 통계 보기, 그리고 pg_stat_activity 뷰와 대기 이벤트까지를 다룹니다. 그 뒤의 각 뷰(pg_stat_replication, pg_stat_database 등)에 대한 상세 컬럼 설명은 이어지는 섹션에서 계속됩니다.