28.2. 통계 수집기

PostgreSQL 통계 수집기 statistics collector는 서버 운영 상태에 대한 정보를 수집하거나 보고하기 위한 작업을 하는 백그라운드 시스템이다. 현재, 이 수집기는 테이블이나 인덱스의 디스크 블록 단위 또는 개별 로우 단위의 접근 회수를 수집할 수 있다. 또한 각 테이블에 저장 되어있는 총 로우 수를 수집하며, 각 테이블에 대한 vacuum 작업과, analyze 작업에 관한 정보들도 수집한다. 또한 사용자 정의 함수들의 호출 회수와, 그것들의 각각 총 수행 시간들도 수집한다.

또한 PostgreSQL에서는 현재 시스템에서 어떻게 운영 되고 있는지에 대한 동적 정보를 제공한다. 예를 들어 다른 서버 프로세스가 현재 어떤 작업을 하고 있는지, 어떤 클라이언트들이 접속해 있는지를 알 수 있다. 이 기능은 수집기 프로세스와 별개로 제공하고 있는 기능이다.

28.2.1. 통계 수집기 환경설정

통계 자료를 수집한다는 것은 궁극적으로는 그 만큼의 추가 비용을 서버가 사용한다는 것을 의미한다. 그래서, 그 추가 비용을 얼마만큼 쓸 것인지에 대한 결정을 서버 환경변수로 제어할 수 있다. 다음은 postgresql.conf 환경설정 파일에서 사용할 수 있는 환경변수들이다. (이들에 대한 보다 자세한 부분은 19장을 참고하라.)

track_activities 설정값을 활성화하면 각각의 서버 프로세스들은 현재 자신이 하고 있는 작업을 프로세스 이름으로 보여준다.

track_counts 설정값을 활성화하면 테이블과 인덱스의 사용빈도를 통계 수집기가 수집한다.

track_functions 설정값을 활성화하면 사용자 정의 함수들의 사용빈도를 통계 수집기가 수집한다.

track_io_timing 설정값을 활성화면 블록 읽기 쓰기 회수를 통계 수집기가 수집한다.

일반적으로 이 환경설정 변수들은 postgresql.conf에서 그 값을 지정하면, 이것은 모든 서버의 프로세스들을 대상으로 작동하게 된다. 하지만, SET 명령을 이용해서, 개별 세션 단위로 이 설정값을 변경할 수도 있다. (이 작업은 일반 사용자가 악의적으로 사용될 가능성이 있기 때문에, 슈퍼유저만 사용할 수 있다.)

통계 수집기가 만든 정보는 stats_temp_directory 설정값으로 지정한 디렉토리 (초기값은 pg_stat_tmp) 안에 있는 임시파일로 저장되고, 그것을 여러 다른 PostgreSQL 프로세스들이 이용한다. 보다 나은 성능을 위해서는 이 파일의 I/O 성능을 높이기 위해 이 디렉토리를 메모리 기반 파일시스템에 두는 것도 좋은 방법이다. 이 통계 정보는 서버가 중지 될 때 pg_stat 디렉토리 쪽으로 복사하는 작업을 하기 때문에, 서버 중지, 재시작에도 자료를 그대로 유지할 수 있다.

28.2.2. 통계 정보 보기

위에서 설명한 시스템의 현재 상태는 표 28-1 뷰들을 통해서 살펴볼 수 있고, 그 외 수집된 통계 정보는 아래 표 28-2에서 나열한 여러 뷰를 통해서 살펴 볼 수 있다. 다른 방법으로는 28.2.3절에서 제공하는 여러 통계 정보 보기 함수들을 이용해서 필요한 뷰를 직접 만들어서 살펴 볼 수도 있을 것이다.

여기서 중요한 점은 살펴 보고 있는 수집된 통계 정보는 현재 데이터베이스의 정확한 현재 상태가 아니라는 점이다. 각 개별 프로세스들이 수집한 통계 정보는 그 프로세스가 아무런 작업을 하고 있지 않을 때, 수집기에게 전달한다. 즉 한 쿼리가 실행 되고 있다거나 트랜잭션 내에 있다면, 그 과정에 생긴 통계 정보들은 반영되지 않고 있다는 것이다. 또한 통계 수집기의 작업은 PGSTAT_STAT_INTERVAL (기본값은 500ms 이다) 시간 간격으로 진행된다. 즉 이 만큼의 통계 정보 오차가 발생한다. 하지만, track_activities 관련 정보는 항상 즉시 반영 된다.

또 다른 중요한 점은 한 통계 정보는 해당 뷰나, 함수로 출력할 때, 한 트랜잭션 내에서는 항상 같은 값을 출력한다. 즉, 트랜젹션이 끝날 때까지 그 값을 유지한다. 이와 비슷하게 모든 세션들의 현재 쿼리에 대한 정보도 하나의 트랜잭션 내에서는 같은 정보를 출력한다. 이것은 버그가 아니라 특성이다. 이것은 한 트랜잭션 내에서 그 통계 정보가 일정하게 유지 되도록해서 여러 다른 쿼리들에서 그 값을 일관성 있게 한다. 하지만 이것을 원치 않는다면 각 쿼리들을 트랜잭션 단위로 분리해서 작업하면 된다. 다른 방법으로 pg_stat_clear_snapshot() 함수를 사용해서, 현재 스냅숏으로 지정된 통계 정보를 버리고 새 통계 정보를 사용할 수도 있다.

하나의 트랜잭션 내에서 그 자신의 통계 정보 (아직까지 수집기 쪽으로 보내지 않은 현재 작업 내역에 대한 정보)들은 다음과 같은 뷰에서 제공한다: pg_stat_xact_all_tables, pg_stat_xact_sys_tables, pg_stat_xact_user_tables, pg_stat_xact_user_functions. 이들의 통계 정보는 현재 트랜잭션 내에서도 자신의 세션 작업에 대한 통계치를 반영 해서 다른 세션에서 수집된 정보와 자신의 세션에서 수집된 정보와 차이가 생길 수도 있다.

표 28-1. 동적 통계 정보 뷰들

뷰 이름설명
pg_stat_activity 세션 프로세스들의 정보를 각각 하나의 로우로 보여준다. 이 프로세스들은 현재 서버를 사용하고는 있는 - 클라이언트가 서버로 접속 해서 만들어진 하위 서버 프로세스들이며, 이들의 현재 상태, 실행 중인 쿼리들을 살펴 볼 수 있다. 자세한 내용은 pg_stat_activity 참조.
pg_stat_replication 하나의 WAL 송신 프로세스에 대해서 하나의 로우로, 대기 서버 쪽으로 보내는 리플리케이션 작업에 대한 통계 정보를 보여준다. 자세한 내용은 pg_stat_replication 참조.
pg_stat_wal_receiverOnly one row, showing statistics about the WAL receiver from that receiver's connected server. See pg_stat_wal_receiver for details.
pg_stat_sslOne row per connection (regular and replication), showing information about SSL used on this connection. See pg_stat_ssl for details.

표 28-2. 수집된 통계 정보 뷰들

뷰 이름설명
pg_stat_archiverWAL 아카이버 프로세스 작동에 대한 통계 정보를 하나의 로우로 보여준다. 자세한 사항은 pg_stat_archiver 참조.
pg_stat_bgwriter 백그라운드 라이터 프로세스의 작업 통계 정보. 자세한 내용은 pg_stat_bgwriter 참조.
pg_stat_database한 로우에 하나씩 각 데이터베이스 전역 통계 정보를 보여 준다. 자세한 내용은 pg_stat_database 참조.
pg_stat_database_conflicts 하나의 데이터베이스에서 그 전역에 걸쳐 발생한 대기 서버 복제 작업 충돌에 의한 쿼리 실행 실패 통계 정보를 각각 하나의 로우로 보여준다. 자세한 내용은 pg_stat_database_conflicts 참조.
pg_stat_all_tables 현재 접속한 데이터베이스에 속한 모든 테이블에 대해서 한 로우씩 그 테이블 사용에 대한 통계 정보를 보여 준다. 자세한 내용은 pg_stat_all_tables 참조.
pg_stat_sys_tablespg_stat_all_tables 내용과 같은데, 시스템 테이블에 대해서만 보여준다.
pg_stat_user_tablespg_stat_all_tables 내용과 같은데, 시스템 테이블을 제외한 현재 사용자 접근 할 수 있는 테이블에 대한 정보만 보여준다.
pg_stat_xact_all_tablespg_stat_all_tables 내용과 비슷하지만, 여기서 반영된 숫자들은 현재 트랜잭션 내에서 반영된 정보만 보여준다. (즉 pg_stat_all_tables 쪽으로 반영 되지 않은 트랜잭션 내의 정보다). 이 뷰에는 사용하는 실 로우 수, 사용하지 않는 로우(dead row) 수, vacuum과 analyze 작업에 관계된 정보는 제공하지 않는다.
pg_stat_xact_sys_tablespg_stat_xact_all_tables 내용과 같은데, 시스템 테이블에 대해서만 보여준다.
pg_stat_xact_user_tablespg_stat_xact_all_tables 내용과 같은데, 시스템 테이블을 제외한 현재 사용자가 접근 할 수 있는 테이블에 대해서만 보여준다.
pg_stat_all_indexes 현재 접속한 데이터베이스에 속한 모든 인덱스에 대해서 한 로우씩 그 인덱스 사용에 대한 통계 정보를 보여 준다. 자세한 내용은 pg_stat_all_indexes 참조.
pg_stat_sys_indexespg_stat_all_indexes 내용과 같은데, 시스템 인덱스에 대해서만 보여준다.
pg_stat_user_indexespg_stat_all_indexes 내용과 같은데, 시스템 인덱스를 제외한 현재 사용자가 접근 할 수 있는 인덱스에 대해서만 보여준다.
pg_statio_all_tables 현재 접속한 데이터베이스에 속한 모든 테이블에 대해서 한 로우씩 그 테이블에 대한 I/O 통계 정보를 보여 준다. 자세한 내용은 pg_statio_all_tables 참조.
pg_statio_sys_tablespg_statio_all_tables 내용과 같은데, 시스템 테이블에 대해서만 보여준다.
pg_statio_user_tablespg_statio_all_tables 내용과 같은데, 시스템 테이블을 제외한 현재 사용자가 접근 할 수 있는 테이블에 대해서만 보여준다.
pg_statio_all_indexes 현재 접속한 데이터베이스에 속한 모든 인덱스에 대해서 한 로우씩 그 인덱스에 대한 I/O 통계 정보를 보여 준다. 자세한 내용은 pg_statio_all_indexes 참조.
pg_statio_sys_indexespg_statio_all_indexes 내용과 같은데, 시스템 인덱스에 대해서만 보여준다.
pg_statio_user_indexespg_statio_all_indexes 내용과 같은데, 시스템 인덱스를 제외한 현재 사용자가 접근 할 수 있는 인덱스에 대해서만 보여준다.
pg_statio_all_sequences 현재 접속한 데이터베이스에 속한 모든 시퀀스에 대해서 한 로우씩 그 시퀀스에 대한 I/O 통계 정보를 보여 준다. 자세한 내용은 pg_statio_all_sequences 참조.
pg_statio_sys_sequencespg_statio_all_sequences 내용과 같은데, 시스템 시퀀스에 대해서만 보여준다. (현재 사용하고 있는 시스템 시퀀스가 없음으로 이 뷰는 항상 그 내용이 비어있을 것이다.)
pg_statio_user_sequencespg_statio_all_sequences 내용과 같은데, 시스템 시퀀스를 제외한 현재 사용자가 접근 할 수 있는 시퀀스에 대해서만 보여준다.
pg_stat_user_functions 현재 데이터베이스에 만들어진 사용자 정의 함수들의 실행에 대한 통계 정보를 보여준다. 자세한 내용은 pg_stat_user_functions 참조.
pg_stat_xact_user_functionspg_stat_user_functions 내용과 비슷하지만, 여기서 반영된 숫자들은 현재 트랜잭션 내에서 반영된 정보만 보여준다, (즉 pg_stat_user_functions 쪽으로 반영 되지 않은 트랜잭션 내의 정보다).
pg_stat_progress_vacuumOne row for each backend (including autovacuum worker processes) running VACUUM, showing current progress. See 28.4.1절.

인덱스 별 통계 정보는 어느 인덱스가 많이 사용되며, 어떻게 영향을 미치는 지를 조사하는데 특히 유용하게 쓰인다.

pg_statio_ 뷰들은 공유 버퍼의 사용 빈도를 파악하는데 가장 기본이 되는 것들이다. 이상적인 서버 운영 모습은 디스크 읽기 빈도 보다 공유 버퍼를 사용하는(buffer hit) 빈도가 훨씬 높아서, 대부분의 작업이 커널 호출 작업 없이 이루워 지도록 하는 것이다. 한편, PostgreSQL 에서는 단지 이 서버 기준으로 디스크를 읽은 것과 서버의 공유 버퍼를 사용한 것에 대한 정보만 제공 할 뿐이다. 즉, 커널의 I/O 캐시 사용 빈도에 대해서는 제공하지 않는다. 다시 말하면, 정말 디스크를 읽은 것인지, OS의 I/O 캐시를 사용한 것인지는 이 뷰를 통해서는 알 수 없다. 이런 세세한 부분까지 살펴 보려면, OS 관련 도구들을 이용해야 할 것이다.

표 28-3. pg_stat_activity View

칼럼자료형설명
datidoid이 백엔드가 연결된 데이터베이스의 OID
datnamename이 백엔드가 연결된 데이터베이스의 이름
pidinteger이 백엔드의 프로세스 ID
usesysidoid이 백엔드에 로그인 한 사용자의 OID
usenamename이 백엔드에 로그인 한 사용자의 이름
application_nametext이 백엔드에 연결된 애플리케이션의 이름
client_addrinet이 백엔드에 연결된 클라이언트의 IP 주소. 이 필드가 null이면 클라이언트가 서버 머신의 UNIX 소켓으로 연결이 되어 있다는 뜻이거나 autovacuum같은 내부 프로세스라는 뜻임
client_hostnametextclient_addr의 DNS를 역조회해서 찾은 클라이언트의 호스트명. 이 필드는 IP 연결했을 때와 log_hostname이 활성화됐을 때만 null이 아닌 값으로 저장됨
client_portinteger이 백엔드와 교류하는 데 클라이언트가 쓰는 TCP 포트 넘버. -1은 UNIX 소켓이 사용됐을 때
backend_starttimestamp with time zone이 프로세스가 시작된 시간. 예를 들어 클라이언트가 서버에 연결되었을 때
xact_starttimestamp with time zone이 프로세스의 현재 트랜잭션이 시작된 시간이거나 어떤 트랜잭션도 수행되고 있지 않을 때 null로 표시함 현재 쿼리가 트랜잭션의 첫 번째 쿼리이면 이 칼럼은 query_start 칼럼과 같다.
query_starttimestamp with time zone현재 수행 중인 쿼리가 시작된 시간이거나 stateactive가 아닐 때에는 마지막 쿼리가 시작된 시간을 뜻함
state_changetimestamp with time zonestate가 마지막으로 변경된 시간
wait_event_typetextThe type of event for which the backend is waiting, if any; otherwise NULL. Possible values are:

  • LWLockNamed: The backend is waiting for a specific named lightweight lock. Each such lock protects a particular data structure in shared memory. wait_event will contain the name of the lightweight lock.

  • LWLockTranche: The backend is waiting for one of a group of related lightweight locks. All locks in the group perform a similar function; wait_event will identify the general purpose of locks in that group.

  • Lock: The backend is waiting for a heavyweight lock. Heavyweight locks, also known as lock manager locks or simply locks, primarily protect SQL-visible objects such as tables. However, they are also used to ensure mutual exclusion for certain internal operations such as relation extension. wait_event will identify the type of lock awaited.

  • BufferPin: The server process is waiting to access to a data buffer during a period when no other process can be examining that buffer. Buffer pin waits can be protracted if another process holds an open cursor which last read data from the buffer in question.

wait_eventtextWait event name if backend is currently waiting, otherwise NULL. See 표 28-4 for details.
statetext현재 이 백엔드의 전체 상태. 가능한 값들은 아래와 같다.

  • active: 백엔드가 쿼리를 수행하고 있다는 뜻

  • idle: 백엔드가 새로운 클라이언트 명령어를 기다리고 있음을 나타냄

  • idle in transaction: 백엔드가 트랜잭션을 수행하고 있지만 쿼리를 수행하고 있지는 않은 상태

  • idle in transaction (aborted): idle in transaction과 비슷하지만 트랜잭션의 구문들 중 하나가 에러를 발생시켰을 때

  • fastpath function call: 백엔드가 fast-path함수를 수행할 때

  • disabled: track_activities가 이 백엔드에서 비활성화됐을 때

backend_xidxid있다면, 해당 백엔드의 최상위 트랜잭션 식별자
backend_xminxid백엔드 현재 xmin.
querytext이 백엔드의 가장 최근 쿼리 내 텍스트. stateactive이면 이 필드는 현재 수행 중인 쿼리를 보여 줌. 다른 state들에서는 마지막으로 수행된 쿼리를 보여 줌

pg_stat_activity 뷰는 서버 프로세스당 한 개의 로우를 가지며 이는 해당 프로세스의 현재 활동 관련 정보를 보여준다.

참고: wait_eventstate칼럼은 독립적이다. 백엔드가 active 상태일 때, 그 이벤트가 waiting 일 수도 있고 아닐 수도 있다. 상태가 active이고, wait_event 값이 비어 있지 않으면, 쿼리가 현재 실행 중이지만, 시스템 어딘가에서 지연이 발생했음을 의미한다.

표 28-4. wait_event Description

Wait Event TypeWait Event NameDescription
LWLockNamedShmemIndexLockWaiting to find or allocate space in shared memory.
OidGenLockWaiting to allocate or assign an OID.
XidGenLockWaiting to allocate or assign a transaction id.
ProcArrayLockWaiting to get a snapshot or clearing a transaction id at transaction end.
SInvalReadLockWaiting to retrieve or remove messages from shared invalidation queue.
SInvalWriteLockWaiting to add a message in shared invalidation queue.
WALBufMappingLockWaiting to replace a page in WAL buffers.
WALWriteLockWaiting for WAL buffers to be written to disk.
ControlFileLockWaiting to read or update the control file or creation of a new WAL file.
CheckpointLockWaiting to perform checkpoint.
CLogControlLockWaiting to read or update transaction status.
SubtransControlLockWaiting to read or update sub-transaction information.
MultiXactGenLockWaiting to read or update shared multixact state.
MultiXactOffsetControlLockWaiting to read or update multixact offset mappings.
MultiXactMemberControlLockWaiting to read or update multixact member mappings.
RelCacheInitLockWaiting to read or write relation cache initialization file.
CheckpointerCommLockWaiting to manage fsync requests.
TwoPhaseStateLockWaiting to read or update the state of prepared transactions.
TablespaceCreateLockWaiting to create or drop the tablespace.
BtreeVacuumLockWaiting to read or update vacuum-related information for a B-tree index.
AddinShmemInitLockWaiting to manage space allocation in shared memory.
AutovacuumLockAutovacuum worker or launcher waiting to update or read the current state of autovacuum workers.
AutovacuumScheduleLockWaiting to ensure that the table it has selected for a vacuum still needs vacuuming.
SyncScanLockWaiting to get the start location of a scan on a table for synchronized scans.
RelationMappingLockWaiting to update the relation map file used to store catalog to filenode mapping.
AsyncCtlLockWaiting to read or update shared notification state.
AsyncQueueLockWaiting to read or update notification messages.
SerializableXactHashLockWaiting to retrieve or store information about serializable transactions.
SerializableFinishedListLockWaiting to access the list of finished serializable transactions.
SerializablePredicateLockListLockWaiting to perform an operation on a list of locks held by serializable transactions.
OldSerXidLockWaiting to read or record conflicting serializable transactions.
SyncRepLockWaiting to read or update information about synchronous replicas.
BackgroundWorkerLockWaiting to read or update background worker state.
DynamicSharedMemoryControlLockWaiting to read or update dynamic shared memory state.
AutoFileLockWaiting to update the postgresql.auto.conf file.
ReplicationSlotAllocationLockWaiting to allocate or free a replication slot.
ReplicationSlotControlLockWaiting to read or update replication slot state.
CommitTsControlLockWaiting to read or update transaction commit timestamps.
CommitTsLockWaiting to read or update the last value set for the transaction timestamp.
ReplicationOriginLockWaiting to setup, drop or use replication origin.
MultiXactTruncationLockWaiting to read or truncate multixact information.
OldSnapshotTimeMapLockWaiting to read or update old snapshot control information.
LWLockTrancheclogWaiting for I/O on a clog (transaction status) buffer.
commit_timestampWaiting for I/O on commit timestamp buffer.
subtransWaiting for I/O a subtransaction buffer.
multixact_offsetWaiting for I/O on a multixact offset buffer.
multixact_memberWaiting for I/O on a multixact_member buffer.
asyncWaiting for I/O on an async (notify) buffer.
oldserxidWaiting to I/O on an oldserxid buffer.
wal_insertWaiting to insert WAL into a memory buffer.
buffer_contentWaiting to read or write a data page in memory.
buffer_ioWaiting for I/O on a data page.
replication_originWaiting to read or update the replication progress.
replication_slot_ioWaiting for I/O on a replication slot.
procWaiting to read or update the fast-path lock information.
buffer_mappingWaiting to associate a data block with a buffer in the buffer pool.
lock_managerWaiting to add or examine locks for backends, or waiting to join or exit a locking group (used by parallel query).
predicate_lock_managerWaiting to add or examine predicate lock information.
LockrelationWaiting to acquire a lock on a relation.
extendWaiting to extend a relation.
pageWaiting to acquire a lock on page of a relation.
tupleWaiting to acquire a lock on a tuple.
transactionidWaiting for a transaction to finish.
virtualxidWaiting to acquire a virtual xid lock.
speculative tokenWaiting to acquire a speculative insertion lock.
objectWaiting to acquire a lock on a non-relation database object.
userlockWaiting to acquire a userlock.
advisoryWaiting to acquire an advisory user lock.
BufferPinBufferPinWaiting to acquire a pin on a buffer.

참고: For tranches registered by extensions, the name is specified by extension and this will be displayed as wait_event. It is quite possible that user has registered the tranche in one of the backends (by having allocation in dynamic shared memory) in which case other backends won't have that information, so we display extension for such cases.

Here is an example of how wait events can be viewed

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 | LWLockNamed     | ProcArrayLock
(2 rows)

표 28-5. pg_stat_replication View

칼럼자료형설명
pidintegerWAL 송신 프로세스의 프로세스 ID
usesysidoidWAL 송신 프로세스에 로그인 된 사용자의 OID
usenamenameWAL 송신 프로세스에 로그인 된 사용자의 이름
application_nametextWAL 송신 프로세스에 연결된 애플리케이션명
client_addrinetWAL 송신자에 연결된 클라이언트의 IP 주소. 이 필드가 null이면 클라이언트가 서버 머신의 UNIX 소켓으로 연결되었음을 의미함
client_hostnametextclient_addr의 DNS를 역조회해서 찾은 클라이언트의 호스트명. 이 필드는 IP로 연결했을 때와 log_hostname이 활성화됐을 때만 null이 아닌 값으로 저장됨
client_portinteger클라이언트가 WAL 송신자와 커뮤니케이션 하기 위해 쓰는 TCP 포트 넘버. -1 이면 유닉스 소켓이 사용됐을 때
backend_starttimestamp with time zone이 프로세스가 시작된 시간. 예를 들어 WAL 송신자와 클라이언트가 연결된 시간
backend_xminxidThis standby's xmin horizon reported by hot_standby_feedback.
statetext현재 WAL 송신자 상태
sent_locationpg_lsn이 연결에 전송된 마지막 트랜잭션 로그 위치
write_locationpg_lsn대기 서버가 디스크에 쓴 마지막 트랜잭션 로그 위치
flush_locationpg_lsn대기 서버가 디스크로 내린 마지막 트랜잭션 로그 위치
replay_locationpg_lsn대기 서버에 있는 데이터베이스로 리플레이 된 마지막 트랜잭션 로그 위치
sync_priorityinteger동기적인 대기 서버로 선택된 대기 서버의 우선순위
sync_statetext대기 서버의 동기적 상태

pg_stat_replication뷰는 WAL 송신자 프로세스당 하나의 로우를 가지며, 송신자가 연결된 대기 서버의 리플리케이션에 관한 통계치를 보여준다. 직접 연결된 대기 서버만 보여진다. 다운스트림 대기 서버에 관한 정보는 없다.

표 28-6. pg_stat_wal_receiver View

ColumnTypeDescription
pidintegerProcess ID of the WAL receiver process
statustextActivity status of the WAL receiver process
receive_start_lsnpg_lsnFirst transaction log position used when WAL receiver is started
receive_start_tliintegerFirst timeline number used when WAL receiver is started
received_lsnpg_lsnLast transaction log position already received and flushed to disk, the initial value of this field being the first log position used when WAL receiver is started
received_tliintegerTimeline number of last transaction log position received and flushed to disk, the initial value of this field being the timeline number of the first log position used when WAL receiver is started
last_msg_send_timetimestamp with time zoneSend time of last message received from origin WAL sender
last_msg_receipt_timetimestamp with time zoneReceipt time of last message received from origin WAL sender
latest_end_lsnpg_lsnLast transaction log position reported to origin WAL sender
latest_end_timetimestamp with time zoneTime of last transaction log position reported to origin WAL sender
slot_nametextReplication slot name used by this WAL receiver
conninfotext Connection string used by this WAL receiver, with security-sensitive fields obfuscated.

The pg_stat_wal_receiver view will contain only one row, showing statistics about the WAL receiver from that receiver's connected server.

표 28-7. pg_stat_ssl View

ColumnTypeDescription
pidintegerProcess ID of a backend or WAL sender process
sslbooleanTrue if SSL is used on this connection
versiontextVersion of SSL in use, or NULL if SSL is not in use on this connection
ciphertextName of SSL cipher in use, or NULL if SSL is not in use on this connection
bitsintegerNumber of bits in the encryption algorithm used, or NULL if SSL is not used on this connection
compressionbooleanTrue if SSL compression is in use, false if not, or NULL if SSL is not in use on this connection
clientdntextDistinguished Name (DN) field from the client certificate used, or NULL if no client certificate was supplied or if SSL is not in use on this connection. This field is truncated if the DN field is longer than NAMEDATALEN (64 characters in a standard build)

The pg_stat_ssl view will contain one row per backend or WAL sender process, showing statistics about SSL usage on this connection. It can be joined to pg_stat_activity or pg_stat_replication on the pid column to get more details about the connection.

표 28-8. pg_stat_archiver View

칼럼자료형설명
archived_countbigint성공적으로 아카이브 된 WAL 파일의 개수
last_archived_waltext최근 성공적으로 아카이브 된 WAL 파일의 이름
last_archived_timetimestamp with time zone최근 성공적으로 아카이브 작업을 한 시간
failed_countbigintWAL 파일 아카이빙 시도에 실패한 횟수
last_failed_waltext마지막으로 아카이빙 작업에 실패한 WAL 파일의 이름
last_failed_timetimestamp with time zone마지막으로 아카이빙 작업에 실패한 시간
stats_resettimestamp with time zone이 통계치가 마지막으로 리셋된 시간

pg_stat_archiver 뷰는 클러스터의 아카이버 프로세스에 관한 데이터가 있는 하나의 로우만 갖고 있다.

표 28-9. pg_stat_bgwriter

칼럼자료형설명
checkpoints_timedbigintcheckpoint_timeout 환경 설정값에 따른 체크 포인트 작업 회수
checkpoints_reqbigint체크포인트 명령이 수행되어 진행한 작업 회수
checkpoint_write_timedouble precision 체크포인트 작업으로 발생한 디스크 쓰기 작업의 밀리세컨드 총 시간.
checkpoint_sync_timedouble precision 체크포인트 작업으로 발생할 디스크 쓰기에 대한 디스크 동기화 작업(fsync)에 소요된 밀리세컨드 총 시간.
buffers_checkpointbigintcheckpointer 프로세스가 기록한 총 버퍼 수
buffers_cleanbigintwriter 프로세스가 기록한 총 버퍼 수
maxwritten_cleanbigintwriter 프로세스가 기록해야 할 버퍼수가 bgwriter_lru_maxpages 환경 설정값보다 많아서 작업이 중지된 회수
buffers_backendbigint백엔드(세션) 프로세스가 직접 기록한 총 버퍼 수
buffers_backend_fsyncbigint백엔드(세션) 프로세스가 직접 fsync 작업을 한 회수 (일반적으로 백엔드(세션) 프로세스가 공유 버퍼를 디스크로 내려 쓰더라도, 이 동기화 작업은 writer 프로세스가 담당한다. 즉 writer 프로세스의 fsync 작업 부하량을 파악하는데 도움이 됨 - 옮긴이)
buffers_allocbigintNumber of buffers allocated
stats_resettimestamp with time zone이 통계값들이 초기화 된 시각

pg_stat_bgwriter 뷰는 항상 한 개의 로우만 보여준다. 이 자료는 데이터클러스터 전역 정보다.

표 28-10. pg_stat_database View

칼럼자료형설명
datidoid데이터베이스의 OID
datnamename해당 데이터베이스의 이름
numbackendsinteger현재 연결된 백엔드의 수. 현재 상태를 가리키는 값을 리턴 하는 유일한 칼럼. 다른 칼럼들은 마지막 리셋 시점 이후로 축적된 값들을 리턴함.
xact_commitbigint커밋된 트랜잭션의 수
xact_rollbackbigint롤백한 트랜잭션의 수
blks_readbigint읽힌 디스크 블록의 수
blks_hitbigint버퍼 캐쉬에 이미 존재하는 디스크 블록을 감지하여 읽기가 불필요함을 알려줌. (PostgreSQL 버퍼 캐쉬 내 히트 수만 계산하고, 운영체제 파일 시스템 캐쉬는 확인하지 않음)
tup_returnedbigint쿼리가 리턴한 로우의 개수
tup_fetchedbigint쿼리가 fetch한 로우의 개수
tup_insertedbigint쿼리로 삽입된 로우의 개수
tup_updatedbigint쿼리로 업데이트된 로우의 개수
tup_deletedbigint쿼리로 삭제된 로우의 개수
conflictsbigint복구 충돌로 인해 취소된 쿼리의 개수 (대기 서버에서만 발생하는 충돌을 말함. pg_stat_database_conflicts 참조)
temp_filesbigint쿼리로 생성된 임시 파일의 개수. 모든 임시 파일은 임시 파일이 생성된 이유와 log_temp_files 설정을 불문하고 카운트 됨
temp_bytesbigint쿼리로 임시 파일에 쓰여진 데이터의 총합. 모든 임시 파일은 임시 파일이 생성된 이유와 log_temp_files 설정을 불문하고 카운트 됨
deadlocksbigint감지된 교착상태의 개수
blk_read_timedouble precision백엔드가 데이터 파일 블록을 읽는 데 소요된 시간으로 밀리세컨드 단위를 사용
blk_write_timedouble precision백엔드가 데이터 파일 블록을 쓰는데 소요된 시간으로 밀리세컨드 단위를 사용
stats_resettimestamp with time zone통계치가 마지막으로 리셋된 시간

pg_stat_database 뷰는 클러스터 내 데이터베이스 당 한 개의 로우를 가지며 전체 데이터베이스 통계치를 보여준다.

표 28-11. pg_stat_database_conflicts View

칼럼자료형설명
datidoid데이터베이스의 OID
datnamename데이터베이스명
confl_tablespacebigint드롭된 테이블스페이스로 인해 취소된 쿼리의 수
confl_lockbigint잠금 시간초과로 취소된 쿼리의 수
confl_snapshotbigint이전 스냅샷으로 취소된 쿼리의 수
confl_bufferpinbigint고정된 버퍼로 취소된 쿼리의 수
confl_deadlockbigint교착상태로 취소된 쿼리의 수

pg_stat_database_conflicts 뷰는 데이터베이스당 하나의 로우를 가지며, 대기 서버의 복구 충돌로 인해 발생한 쿼리 취소에 대해 전체 데이터베이스 통계치를 보여준다. 마스터 서버에서 충돌이 발생하지 않으므로 이 뷰는 대기 서버의 정보만 갖고 있다.

표 28-12. pg_stat_all_tables View

칼럼자료형설명
relidoid테이블의 OID
schemanamename테이블을 포함하는 스키마 이름
relnamename테이블명
seq_scanbigint풀스캔을 시도한 횟수
seq_tup_readbigint풀스캔으로 가져온 live row 개수
idx_scanbigint인덱스 스캔을 시도한 횟수
idx_tup_fetchbigint인덱스 스캔으로 가져온 live row 개수
n_tup_insbigint삽입된 로우 개수
n_tup_updbigint업데이트된 로우 개수 (HOT 업데이터 로우도 포함)
n_tup_delbigint삭제된 로우 개수
n_tup_hot_updbigintHOT 업데이트 된 로우 개수 (예를 들어 따로 인덱스 업데이트 필요가 없는)
n_live_tupbigint추정되는 live row 개수
n_dead_tupbigint추정되는 dead row 개수
n_mod_since_analyzebigint마지막 analyze 이후 변경된 로우 수 (추정치)
last_vacuumtimestamp with time zone테이블이 수동적으로 vacuum된 마지막 시간 (VACUUM FULL은 해당되지 않음)
last_autovacuumtimestamp with time zoneautovacuum 데몬으로 테이블이 vacuum된 마지막 시간
last_analyzetimestamp with time zone테이블이 수동적으로 분석된 마지막 시간
last_autoanalyzetimestamp with time zoneautovacuum 데몬으로 테이블이 분석된 마지막 시간
vacuum_countbigint수동적으로 vacuum된 횟수 (VACUUM FULL은 제외)
autovacuum_countbigintautovacuum 데몬으로 vacuum된 횟수
analyze_countbigint수동적으로 분석된 횟수
autoanalyze_countbigintautovacuum 데몬으로 분석된 횟수

pg_stat_all_tables 뷰는 현재 데이터베이스의 테이블(TOAST 테이블 포함)당 한 개의 로우를 가지며, 이는 해당 테이블 접근에 대한 통계치를 보여준다. pg_stat_user_tablespg_stat_sys_tables뷰는 같은 정보를 가지나 사용자와 시스템 테이블 각각을 보여주는 데만 쓰인다.

표 28-13. pg_stat_all_indexes View

칼럼자료형설명
relidoid이 인덱스를 갖는 테이블의 OID
indexrelidoid이 인덱스의 OID
schemanamename이 인덱스가 있는 스키마의 이름
relnamename이 인덱스를 갖는 테이블명
indexrelnamename인덱스명
idx_scanbigint이 인덱스로 스캔한 횟수
idx_tup_readbigint이 인덱스로 스캔해서 리턴된 인덱스 엔트리의 개수
idx_tup_fetchbigint이 인덱스로 인덱스 스캔해서 가져온 live 테이블 로우의 개수

pg_stat_all_indexes 뷰는 현재 데이터베이스에서 인덱스 당 한 개의 로우를 가지며 해당 인덱스 접근에 대한 통계치를 보여준다. pg_stat_user_indexespg_stat_sys_indexes 뷰는 같은 정보를 갖지만 각각 사용자와 시스템 인덱스만 보여준다.

인덱스는 단순한 인덱스 스캔, "bitmap" 인덱스 스캔, 쿼리 최적화기에서 사용된다. 비트맵 스캔에서 일부 인덱스 결과는 AND나 OR 규칙으로 통합될 수 있어서, 비트맵 스캔이 사용되면 각각의 heap 로우들을 특정 인덱스에 매칭하기 어렵다. 비트맵 스캔은 사용된 인덱스의 pg_stat_all_indexes.idx_tup_read 를 증가시키고, 테이블의 pg_stat_all_tables.idx_tup_fetch 를 증가시키지만 pg_stat_all_indexes.idx_tup_fetch에는 영향을 미치지 않는다. The optimizer also accesses indexes to check for supplied constants whose values are outside the recorded range of the optimizer statistics because the optimizer statistics might be stale.

참고: idx_tup_readidx_tup_fetch의 값은 비트맵 스캔을 하지 않아도 다를 수 있다. idx_tup_read는 인덱스에서 회수된 인덱스 엔트리 개수를 세지만, idx_tup_fetch 는 테이블에서 가져온 live row를 세기 때문이다. 후자는 죽었거나 아직 커밋되지 않은 로우가 fetch되어 인덱스를 사용할 경우나 index-only 스캔으로 heap fetch들을 감지하지 못한 경우 감소한다.

표 28-14. pg_statio_all_tables View

칼럼자료형설명
relidoid테이블의 OID
schemanamename이 테이블이 속한 스키마 이름
relnamename이 테이블의 이름
heap_blks_readbigint이 테이블에서 읽힌 디스크 블록의 수
heap_blks_hitbigint이 테이블 내 버퍼 히트 수
idx_blks_readbigint테이블의 전체 인덱스에서 읽힌 디스크 블록의 수
idx_blks_hitbigint테이블 내 모든 인덱스에 대한 버퍼 히트의 수
toast_blks_readbigintTOAST 테이블(있으면)에서 읽힌 디스크 블록의 수
toast_blks_hitbigintTOAST 테이블(있으면) 내 버퍼 히트 수
tidx_blks_readbigintTOAST 테이블 인덱스(있으면)에서 읽힌 디스크 블록 수
tidx_blks_hitbigintTOAST 테이블 인덱스(있으면) 내 버퍼 히트 수

pg_statio_all_tables 뷰는 현재 데이터베이스에서 각 테이블당(TOAST 테이블을 포함해서) 한 개의 로우를 갖는데, 해당 테이블의 I/O에 대한 통계치를 보여준다. pg_statio_user_tablespg_statio_sys_tables 뷰도 같은 정보를 갖지만 각기 사용자와 시스템 테이블만 보여준다.

표 28-15. pg_statio_all_indexes View

칼럼자료형설명
relidoid인덱스가 포함된 테이블의 OID
indexrelidoid인덱스의 OID
schemanamename인덱스가 포함된 스키마의 이름
relnamename인덱스가 포함된 테이블의 이름
indexrelnamename인덱스명
idx_blks_readbigint인덱스로 읽힌 디스크 블록의 수
idx_blks_hitbigint인덱스 내 버퍼 히트 수

pg_statio_all_indexes뷰는 현재 데이터베이스의 각 인덱스당 하나의 로우를 갖는데, 해당 인덱스의 I/O에 대한 통계치를 보여준다. pg_statio_user_indexespg_statio_sys_indexes 뷰도 같은 정보를 갖지만 사용자와 시스템 인덱스만 각각 보여준다.

표 28-16. pg_statio_all_sequences View

칼럼자료형설명
relidoid시퀀스의 OID
schemanamename시퀀스가 포함된 스키마명
relnamename시퀀스명
blks_readbigint시퀀스에서 읽힌 디스크 블록의 수
blks_hitbigint시퀀스 내 버퍼 히트 수

pg_statio_all_sequences 뷰는 현재 데이터베이스의 각 시퀀스당 한 개의 로우를 갖고, 해당 시퀀스의 I/O에 대한 통계치를 보여준다.

표 28-17. pg_stat_user_functions View

칼럼자료형설명
funcidoid함수의 OID
schemanamename함수가 포함된 스키마명
funcnamename함수명
callsbigint함수가 호출된 횟수
total_timedouble precision함수와 호출된 함수들에 소요된 밀리세컨드 총 시간
self_timedouble precision호출된 함수들을 제외하고 이 함수에 소요된 밀리세컨드 총 시간

pg_stat_user_functions 뷰는 추적된 각 함수당 한 개의 로우를 가지며, 함수 수행에 대한 통계치를 보여 준다. track_functions는 정확히 어떤 함수가 추적되어야 하는지 정한다.

28.2.3. 통계 함수들

위에서 소개한 뷰를 통해서 서버 통계 정보를 살펴보는 방법과 함께 또 다른 한 방법은 각각의 정보를 제공하는 함수를 사용하는 방법이다. 위에서 소개한 뷰들의 뷰 정의를 살펴보면, 각각의 뷰가 어떤 함수들을 사용하는지 알 수 있다. (예를 들면, psql 에서 \d+ pg_stat_activity 명령을 사용하면 된다.) 데이터베이스 단위로 통계 정보를 보여주는 함수들에 대해서는 함수의 입력 인자로 데이터베이스 OID를 입력해야 한다. 이처럼, 테이블별, 인덱스별, 함수별 통계 정보를 살펴보려면, 그 각 객체의 OID를 입력 인자로 사용하면 된다. 기억해야 할 점은, 테이블, 인덱스, 함수 같은 각 데이터베이스 소속 객체들을 입력 인자로 쓰는 함수라면, 그 데이터베이스는 현재 접속한 데이터베이스가 된다.

부가적으로 제공하는 통계 관련 함수들은 표 28-18에서 소개한다.

표 28-18. 부가 통계 함수들

함수이름리턴 자료형설명
pg_backend_pid()integer 현재 세션을 처리하는 서버 프로세스의 프로세스 ID
pg_stat_get_activity(integer)setof record 특정 PID를 갖는 백엔드 정보를 담은 레코드를 리턴하거나 인자가 NULL일 경우에는 시스템에서 활성화된 각 백엔드의 레코드를 리턴함. 리턴된 필드는 pg_stat_activity 뷰의 부분집합
pg_stat_get_snapshot_timestamp()timestamp with time zone 현재 통계 스냅샷 시간
pg_stat_clear_snapshot()void 현재 통계치 스냅샷을 버림
pg_stat_reset()void 현재 데이터베이스의 통계치 카운터 전체를 0으로 만듦(슈퍼 유저 권한이 필요함, EXECUTE 권한 부여 가능)
pg_stat_reset_shared(text)void 인자에 따라서 전체 클러스터 통계치 카운터를 0으로 만듦(슈퍼 유저 권한이 필요함, EXECUTE 권한 부여 가능) pg_stat_reset_shared('bgwriter')를 호출하면 pg_stat_bgwriter뷰에 보여진 전체 카운터들을 0으로 만듦
pg_stat_reset_single_table_counters(oid)void 현재 데이터베이스의 한 테이블 혹은 인덱스에 대한 통계치를 0으로 만듦(슈퍼 유저 권한이 필요함, EXECUTE 권한 부여 가능)
pg_stat_reset_single_function_counters(oid)void 현재 데이터베이스의 한 함수에 대한 통계치를 0으로 만듦(슈퍼 유저 권한이 필요함, EXECUTE 권한 부여 가능)

pg_stat_activity 뷰에서 사용되는 pg_stat_get_activity 함수는 지정한 한 세션의 현재 상태에 대한 모든 정보를 레코드 자료형으로 리턴한다. 이렇게, 가끔은 뷰보다, 함수를 직접 사용하는 것이 보다 유용할 때가 있다. 위에서 소개한 뷰들(표 28-19)은 함수를 호출하고 그것을 뷰로 보여주기 때문에, 뷰를 내용으로 출력 되는 결과는 이미 지난 자료 집합이다 보다 정확한 현재 상태를 파악 하고자 할 때, 이런 함수를 직접 사용하는 방법이 좋다. 한 예제를 소개하면, 다음은, 현재 접속해 있는 세션들의 PID와 현재 실행 중인 쿼리 내용을 보는 쿼리다:

SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
       pg_stat_get_backend_activity(s.backendid) AS query
    FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s;

표 28-19. 백엔드 단위 통계 함수들

함수이름리턴 자료형설명
pg_stat_get_backend_idset()setof integer현재 활성화된 백엔드 ID 넘버 집합(1부터 활성화된 백엔드 개수까지)
pg_stat_get_backend_activity(integer)text백엔드의 최근 쿼리의 텍스트
pg_stat_get_backend_activity_start(integer)timestamp with time zone최근 쿼리가 시작된 시간
pg_stat_get_backend_client_addr(integer)inet백엔드에 연결된 클라이언트의 IP 주소
pg_stat_get_backend_client_port(integer)integer클라이언트가 커뮤니케이션에 쓰고 있는 TCP 포트 넘버
pg_stat_get_backend_dbid(integer)oid백엔드가 연결된 데이터베이스의 OID
pg_stat_get_backend_pid(integer)integer백엔드의 프로세스 ID
pg_stat_get_backend_start(integer)timestamp with time zone프로세스가 시작된 시간
pg_stat_get_backend_userid(integer)oid백엔드에 로그인한 사용자의 OID
pg_stat_get_backend_wait_event_type(integer)textWait event type name if backend is currently waiting, otherwise NULL. See 표 28-4 for details.
pg_stat_get_backend_wait_event(integer)textWait event name if backend is currently waiting, otherwise NULL. See 표 28-4 for details.
pg_stat_get_backend_xact_start(integer)timestamp with time zone현재 트랜잭션이 시작된 시간