이번 블로그에서는 PostgreSQL 데이터베이스를 사용 중 모니터링을 할 경우가 종종 있는데, 모니터링을 할 경우 사용가능한 쿼리들에 대해서 조사한 내용을 정리해보겠습니다.

1. Database Wraparoud
transaction ID란?
PostgreSQL은 vacuum 없이 21억여 개의 트랜잭션까지 처리할 수 있다. 만약 vacuum 없이 처리된 트랜잭션의 수가 2^31 - 10,000,000에 도달하게 되면, Postgresql은 베큠이 필요하다는 로그를 남기기 시작한다. 그리고 (2^31 - 1,000,000)에 도달하면, PostgreSQL은 Read-only 모드로 설정되고, 오프라인, 단일 유저, standalone vacuum 모드가 된다. 이렇게 되면 vacuum은 데이터 크기에 따라 몇 시간에서 며칠간의 데이터베이스 다운타임을 일으키게 된다.
가용할 수 있는 transaction ID 수가 20억개를 넘어가는 경우, transaction ID가 다시 첫 번째 순서로 로테이션할 수 있도록
처리해줘야 한다. 이를 transaction ID wraparound라고 하며, vacuum에서 이러한 역할을 담당하고 있다.
[출처: https://americanopeople.tistory.com/369]
아래 쿼리예제는 PostgreSQL에서 transaction ID의 상태를 모니터링을 하기 위한 쿼리입니다. 쿼리의 컬럼 설명은 아래와 같습니다.
- age_datfrozenxid_seconds:Age of the oldest transaction ID that has not been frozen.
- age_datminmxid_seconds:Age of the oldest multi-transaction ID that has been replaced with a transaction ID
--database Wraparound Query
SELECT
datname,
age(d.datfrozenxid) as age_datfrozenxid,
mxid_age(d.datminmxid) as age_datminmxid
FROM
pg_catalog.pg_database d
WHERE
d.datallowconn;
datname |age_datfrozenxid|age_datminmxid|
---------+----------------+--------------+
postgres | 2649904| 0|
template1| 2649904| 0|
2. Database 사이즈
데이터베이스 전체 사이즈를 조회 하기 위한 쿼리 입니다. 우선 생성된 데이터베이스를 조회를 한 후에 pg_database_size() 함수를 사용하여 전체 사이즈를 조회 합니다.
pg_database_size() 함수는 데이터베이스 총 디스크 사용량을 byte 형식의 bigint 데이터 타입으로 반환하는 함수 입니다.
-- pgDatabaseQuery
SELECT pg_database.datname FROM pg_database;
datname |
---------+
postgres |
template0|
template1|
--pgDatabaseSizeQuery
SELECT pg_database_size('postgres');
pg_database_size|
----------------+
7240216|
3. Locks
Database lock을 이해하는 것은 동시성 문제를 해결하는데 중요한 요소입니다. Table-level locks 종류에 대한 설명은 아래와 같습니다.
AccessShareLock
A read-lock mode acquired automatically on tables being queried.
Conflicts with AccessExclusiveLock only.
RowShareLock
Acquired by SELECT FOR UPDATE and LOCK TABLE for IN ROW SHARE MODE statements.
Conflicts with ExclusiveLock and AccessExclusiveLock modes.
RowExclusiveLock
Acquired by UPDATE, DELETE, INSERT and LOCK TABLE for IN ROW EXCLUSIVE MODE statements.
Conflicts with ShareLock, ShareRowExclusiveLock, ExclusiveLock and AccessExclusiveLock modes.
ShareUpdateExclusiveLock
Acquired by VACUUM (without FULL) and LOCK TABLE table for IN SHARE UPDATE EXCLUSIVE MODE statements.
Conflicts with ShareUpdateExclusiveLock, ShareLock, ShareRowExclusiveLock, ExclusiveLock and AccessExclusiveLock modes.
ShareLock
Acquired by CREATE INDEX and LOCK TABLE table for IN SHARE MODE statements.
Conflicts with RowExclusiveLock, ShareUpdateExclusiveLock, ShareRowExclusiveLock, ExclusiveLock and AccessExclusiveLock modes.
ShareRowExclusiveLock
Acquired by LOCK TABLE for IN SHARE ROW EXCLUSIVE MODE statements.
Conflicts with RowExclusiveLock, ShareUpdateExclusiveLock, ShareLock, ShareRowExclusiveLock, ExclusiveLock and AccessExclusiveLock modes.
ExclusiveLock
Acquired by LOCK TABLE table for IN EXCLUSIVE MODE statements.
Conflicts with RowShareLock, RowExclusiveLock, ShareUpdateExclusiveLock, ShareLock, ShareRowExclusiveLock, ExclusiveLock and AccessExclusiveLock modes.
AccessExclusiveLock
Acquired by ALTER TABLE, DROP TABLE, VACUUM FULL and LOCK TABLE statements.
Conflicts with all modes (AccessShareLock, RowShareLock, RowExclusiveLock, ShareUpdateExclusiveLock, ShareLock, ShareRowExclusiveLock, ExclusiveLock and AccessExclusiveLock).
[출처:https://www.postgresql.org/docs/7.2/locking-tables.html]
SIReadLock
stands for Serializable Isolation Read. It is a predicate lock that is acquired for relations, pages, and tuples
--pgLocksQuery = `
SELECT
pg_database.datname as datname,
tmp.mode as mode,
COALESCE(count, 0) as count
FROM
(
VALUES
('accesssharelock'),
('rowsharelock'),
('rowexclusivelock'),
('shareupdateexclusivelock'),
('sharelock'),
('sharerowexclusivelock'),
('exclusivelock'),
('accessexclusivelock'),
('sireadlock')
) AS tmp(mode)
CROSS JOIN pg_database
LEFT JOIN (
SELECT
database,
lower(mode) AS mode,
count(*) AS count
FROM
pg_locks
WHERE
database IS NOT NULL
GROUP BY
database,
lower(mode)
) AS tmp2 ON tmp.mode = tmp2.mode
and pg_database.oid = tmp2.database
where datname='postgres'
ORDER BY 1;
datname |mode |count|
--------+------------------------+-----+
postgres|accessexclusivelock | 0|
postgres|sharerowexclusivelock | 0|
postgres|rowsharelock | 0|
postgres|shareupdateexclusivelock| 0|
postgres|sharelock | 0|
postgres|sireadlock | 0|
postgres|exclusivelock | 0|
postgres|accesssharelock | 0|
postgres|rowexclusivelock | 0|
4. 실행중인 쿼리 조회
실행중인 쿼리를 확인하기 위한 쿼리 입니다. state 값은 아래와 같습니다 .
- active : 쿼리 실행 중
- idle : 새로운 명령을 기다리는 중
- idle in transaction : 트랜잭션은 있지만 현재 실행중인 쿼리 없음
- idle in transaction (aborted) : idle in transaction 비슷하지만 트랜잭션에 오류가 있음
- fastpath function call : 함수 실행 중
- disabled : track_activities 무효
쿼리의 결과 컬럼 정의는 다음과 같습니다.
- transactions: Current number of long running transactions
- oldest_timestamp_seconds: The current maximum transaction age in seconds
쿼리 WHERE 부분에서 DISTINCT를 하여 조회 하였는데요, 이 부분은 NULL값을 포함하여 NOT EQUAL을 사용하고 싶을때 사용하는 기법입니다.
--longRunningTransactionsQuery = `
SELECT
COUNT(*) as transactions,
MAX(EXTRACT(EPOCH FROM clock_timestamp())) AS oldest_timestamp_seconds
FROM pg_catalog.pg_stat_activity
WHERE state is distinct from 'idle' AND query not like 'autovacuum:%';
transactions|oldest_timestamp_seconds|
------------+------------------------+
1| 1702271267.654078|
5. pg_postmaster_start_time()
pg시스템 핸들링 함수로써, db가 시작된 시간을 반환한다. 결과 값에 대한 정의는 아래와 같습니다.
- start_time_seconds: Time at which postmaster started
-- pgPostmasterQuery = "
SELECT extract(epoch from pg_postmaster_start_time) from pg_postmaster_start_time();
date_part |
-----------------+
1701669040.802288|
6. process idle
프로세스 중에 idle 된 프로세스를 조회 하는 쿼리 입니다.
- seconds: Idle time of server processes
아래 쿼리 문법을 보시면 ~ 표시가 되어 있는 부분이 있는데, 이 것은 POSIX 정규표현식 기법입니다.
with metrics as (
select
state,
application_name,
SUM(extract(EPOCH from (CURRENT_TIMESTAMP - state_change))::bigint)::float as process_idle_seconds_sum,
COUNT(*) as process_idle_seconds_count
from
pg_stat_activity
where
state ~ '^idle'
group by
state,
application_name
),
buckets as (
select
state,
application_name,
le,
SUM(
case when extract(EPOCH from (CURRENT_TIMESTAMP - state_change)) <= le
then 1
else 0
end
)::bigint as bucket
from
pg_stat_activity,
unnest(array[1, 2, 5, 15, 30, 60, 90, 120, 300]) as le
group by
state,
application_name,
le
order by
state,
application_name,
le
)
select
state,
application_name,
process_idle_seconds_sum as seconds_sum,
process_idle_seconds_count as seconds_count,
ARRAY_AGG(le) as seconds,
ARRAY_AGG(bucket) as seconds_bucket
from
metrics
join buckets
using (state,
application_name)
group by
1,
2,
3,
4;
state|application_name |seconds_sum|seconds_count|seconds |seconds_bucket |
-----+-------------------------------------+-----------+-------------+---------------------------+-----------------------+
idle | | 740534.0| 17|{1,2,5,15,30,60,90,120,300}|{0,0,0,1,6,12,12,12,13}|
idle |DBeaver 22.1.0 - Main <sysmaster> | 9.0| 1|{1,2,5,15,30,60,90,120,300}|{0,0,0,1,1,1,1,1,1} |
idle |DBeaver 22.1.0 - Metadata <sysmaster>| 9.0| 1|{1,2,5,15,30,60,90,120,300}|{0,0,0,1,1,1,1,1,1} |
7. 통계정보
PostgreSQL 통계 수집기 statistics collector는 서버 운영 상태에 대한 정보를 수집하거나 보고하기 위한 작업을 하는 백그라운드 시스템이다. 현재, 이 수집기는 테이블이나 인덱스의 디스크 블록 단위 또는 개별 로우 단위의 접근 회수를 수집할 수 있다. 또한 각 테이블에 저장 되어있는 총 로우 수를 수집하며, 각 테이블에 대한 vacuum 작업과, analyze 작업에 관한 정보들도 수집한다. 또한 사용자 정의 함수들의 호출 회수와, 그것들의 각각 총 수행 시간들도 수집한다.
또한 PostgreSQL에서는 현재 시스템에서 어떻게 운영 되고 있는지에 대한 동적 정보를 제공한다. 예를 들어 다른 서버 프로세스가 현재 어떤 작업을 하고 있는지, 어떤 클라이언트들이 접속해 있는지를 알 수 있다. 이 기능은 수집기 프로세스와 별개로 제공하고 있는 기능이다.
- pg_stat_replication : 하나의 WAL 송신 프로세스에 대해서 하나의 로우로, 대기 서버 쪽으로 보내는 리플리케이션 작 업에 대한 통계 정보
- pg_replication_slots : 현재 상태와 함께 데이터베이스 클러스터에 현재 존재하는 모든 복제 슬롯 목록을 제공
- pg_stat_archiver : WAL 아카이버 프로세스 작동에 대한 통계 정보를 하나의 로우 제공
- pg_stat_activity : 뷰는 서버 프로세스당 한 개의 로우를 가지며 이는 해당 프로세스의 현재 활동 관련 정보 제공
- pg_stat_bgwriter : 백그라운드 라이터 프로세스의 작업 통계 정보 제공
- pg_stat_database: 한 로우에 하나씩 각 데이터베이스 전역 통계 정보 제공
- pg_stat_user_tables : 시스템 테이블을 제외한 현재 사용자 접근 할 수 있는 테이블에 대한 정보 제공
- pg_statio_user_indexes : 시스템 인덱스를 제외한 현재 사용자가 접근 할 수 있는 인덱스에 대해서만 보여줌
- pg_statio_user_tables : 스템 테이블을 제외한 현재 사용자가 접근 할 수 있는 테이블에 대해서만 보여
pg_stat_database 테이블의 컬럼정의는 다음과 같습니다.
- datid:데이터베이스의 OID
- datname:해당 데이터베이스의 이름
- numbackends:현재 연결된 백엔드의 수. 현재 상태를 가리키는 값을 리턴 하는 유일한 칼럼. 다른 칼럼들은 마지막 리셋 시점 이후로 축적된 값들을 리턴함.
- xact_commit:커밋된 트랜잭션의 수
- xact_rollback:롤백한 트랜잭션의 수
- blks_read:읽힌 디스크 블록의 수
- blks_hit:버퍼 캐쉬에 이미 존재하는 디스크 블록을 감지하여 읽기가 불필요함을 알려줌. (PostgreSQL 버퍼 캐쉬 내 히트 수만 계산하고, 운영체제 파일 시스템 캐쉬는 확인하지 않음)
- tup_returned:쿼리가 리턴한 로우의 개수
- tup_fetched:쿼리가 fetch한 로우의 개수
- tup_inserted:쿼리로 삽입된 로우의 개수
- tup_updated:쿼리로 업데이트된 로우의 개수
- tup_deleted:쿼리로 삭제된 로우의 개수
- conflicts:복구 충돌로 인해 취소된 쿼리의 개수 (대기 서버에서만 발생하는 충돌을 말함. pg_stat_database_conflicts 참조)
- temp_files:쿼리로 생성된 임시 파일의 개수. 모든 임시 파일은 임시 파일이 생성된 이유와 log_temp_files 설정을 불문하고 카운트 됨
- temp_bytes:쿼리로 임시 파일에 쓰여진 데이터의 총합. 모든 임시 파일은 임시 파일이 생성된 이유와 log_temp_files 설정을 불문하고 카운트 됨
- deadlocks:감지된 교착상태의 개수
- blk_read_time:백엔드가 데이터 파일 블록을 읽는 데 소요된 시간으로 밀리세컨드 단위를 사용
- blk_write_time:백엔드가 데이터 파일 블록을 쓰는데 소요된 시간으로 밀리세컨드 단위를 사용
- stats_reset:통계치가 마지막으로 리셋된 시간
pg_stat_user_tables 테이블의 컬럼 정의는 다음과 같습니다.
- seq_scan:Number of sequential scans initiated on this table
- seq_tup_read:Number of live rows fetched by sequential scans
- idx_scan:Number of index scans initiated on this table
- idx_tup_fetch:Number of live rows fetched by index scans
- n_tup_ins:Number of rows inserted
- n_tup_upd:Number of rows updated
- n_tup_del:Number of rows deleted
- n_tup_hot_upd:Number of rows HOT updated (i.e., with no separate index update required)
- n_live_tup:Estimated number of live rows
- n_dead_tup:Estimated number of dead rows
- n_mod_since_analyze:Estimated number of rows changed since last analyze
- last_vacuum:Last time at which this table was manually vacuumed (not counting VACUUM FULL)
- last_autovacuum:Last time at which this table was vacuumed by the autovacuum daemon
- last_analyze:Last time at which this table was manually analyzed
- last_autoanalyze:Last time at which this table was analyzed by the autovacuum daemon
- vacuum_coun:Number of times this table has been manually vacuumed (not counting VACUUM FULL)
- autovacuum_count:Number of times this table has been vacuumed by the autovacuum daemon
- analyze_count:Number of times this table has been manually analyzed
- autoanalyze_count:Number of times this table has been analyzed by the autovacuum daemon
- size_bytes:Total disk space used by this table, in bytes, including all indexes and TOAST data
pg_statio_user_indexes 뷰 테이블의 결과 값 정의는 다음과 같습니다.
- schemaname : 인덱스가 포함된 스키마의 이름
- relname : 인덱스가 포함된 테이블의 이름
- indexrelname : 인덱스명
- idx_blks_read : 인덱스로 읽힌 디스크 블록의 수
- idx_blks_hit : 인덱스 내 버퍼 히트 수
pg_statio_user_tables 뷰 테이블 결과 값 정의는 다음과 같습니다.
- datname : 데이터베이스 이름
- schemaname :이 테이블이 속한 스키마 이름
- relname :이 테이블의 이름
- heap_blks_read :이 테이블에서 읽힌 디스크 블록의 수
- heap_blks_hit :이 테이블 내 버퍼 히트 수
- idx_blks_read :테이블의 전체 인덱스에서 읽힌 디스크 블록의 수
- idx_blks_hit :테이블 내 모든 인덱스에 대한 버퍼 히트의 수
- toast_blks_read :TOAST 테이블(있으면)에서 읽힌 디스크 블록의 수
- toast_blks_hit :TOAST 테이블(있으면) 내 버퍼 히트 수
- tidx_blks_read :TOAST 테이블 인덱스(있으면)에서 읽힌 디스크 블록 수
- tidx_blks_hit :TOAST 테이블 인덱스(있으면) 내 버퍼 히트 수
[출처: https://www.postgresql.kr/docs/10/monitoring-stats.html#PG-STAT-ACTIVITY-VIEW ]
-- pg_stat_replication
SELECT *,
(case pg_is_in_recovery() when 't' then null else pg_current_xlog_location() end) AS pg_current_xlog_location,
(case pg_is_in_recovery() when 't' then null else pg_xlog_location_diff(pg_current_xlog_location(), replay_location)::float end) AS pg_xlog_location_diff
FROM pg_stat_replication;
pid|usesysid|usename|application_name|client_addr|client_hostname|client_port|backend_start|backend_xmin|state|sent_location|write_location|flush_location|replay_location|sync_priority|sync_state|pg_current_xlog_location|pg_xlog_location_diff|
---+--------+-------+----------------+-----------+---------------+-----------+-------------+------------+-----+-------------+--------------+--------------+---------------+-------------+----------+------------------------+---------------------+
-- pg_replication_slots
SELECT slot_name, database, active, pg_xlog_location_diff(pg_current_xlog_location(), restart_lsn)
FROM pg_replication_slots;
slot_name|database|active|pg_xlog_location_diff|
---------+--------+------+---------------------+
--pg_stat_archiver
SELECT *,
extract(epoch from now() - last_archived_time) AS last_archive_age
FROM pg_stat_archiver;
archived_count|last_archived_wal|last_archived_time|failed_count|last_failed_wal|last_failed_time|stats_reset |last_archive_age|
--------------+-----------------+------------------+------------+---------------+----------------+-----------------------------+----------------+
0| | | 0| | |2023-12-01 17:16:38.584 +0900| |
--pg_stat_activity
SELECT
pg_database.datname,
tmp.state,
tmp2.usename,
tmp2.application_name,
COALESCE(count,0) as count,
COALESCE(max_tx_duration,0) as max_tx_duration
FROM
(
VALUES ('active'),
('idle'),
('idle in transaction'),
('idle in transaction (aborted)'),
('fastpath function call'),
('disabled')
) AS tmp(state) CROSS JOIN pg_database
LEFT JOIN
(
SELECT
datname,
state,
usename,
application_name,
count(*) AS count,
MAX(EXTRACT(EPOCH FROM now() - xact_start))::float AS max_tx_duration
FROM pg_stat_activity GROUP BY datname,state,usename,application_name) AS tmp2
ON tmp.state = tmp2.state AND pg_database.datname = tmp2.datname;
datname |state |usename|application_name |count|max_tx_duration|
---------+-----------------------------+-------+--------------------------------------------------+-----+---------------+
postgres |active | | | 0| 0.0|
postgres |idle | | | 0| 0.0|
postgres |idle in transaction | | | 0| 0.0|
postgres |idle in transaction (aborted)| | | 0| 0.0|
postgres |fastpath function call | | | 0| 0.0|
postgres |disabled | | | 0| 0.0|
--statBGWriter
SELECT
checkpoints_timed
,checkpoints_req
,checkpoint_write_time
,checkpoint_sync_time
,buffers_checkpoint
,buffers_clean
,maxwritten_clean
,buffers_backend
,buffers_backend_fsync
,buffers_alloc
,stats_reset
FROM pg_stat_bgwriter;
checkpoints_timed|checkpoints_req|checkpoint_write_time|checkpoint_sync_time|buffers_checkpoint|buffers_clean|maxwritten_clean|buffers_backend|buffers_backend_fsync|buffers_alloc|stats_reset |
-----------------+---------------+---------------------+--------------------+------------------+-------------+----------------+---------------+---------------------+-------------+-----------------------------+
2838| 21| 54660603| 2586673.0| 611555| 41815| 175| 3638801| 0| 28037062|2023-12-01 17:16:38.584 +0900|
--statDatabaseQuery
SELECT
datid
,datname
,numbackends
,xact_commit
,xact_rollback
,blks_read
,blks_hit
,tup_returned
,tup_fetched
,tup_inserted
,tup_updated
,tup_deleted
,conflicts
,temp_files
,temp_bytes
,deadlocks
,blk_read_time
,blk_write_time
,stats_reset
FROM pg_stat_database;
datid|datname |numbackends|xact_commit|xact_rollback|blks_read|blks_hit |tup_returned|tup_fetched|tup_inserted|tup_updated|tup_deleted|conflicts|temp_files|temp_bytes |deadlocks|blk_read_time|blk_write_time|stats_reset |
-----+---------+-----------+-----------+-------------+---------+---------+------------+-----------+------------+-----------+-----------+---------+----------+-----------+---------+-------------+--------------+-----------------------------+
12401|postgres | 0| 28435| 5| 5576| 978164| 13885232| 158195| 19| 7| 0| 0| 0| 0| 0| 0.0| 0.0|2023-12-01 17:16:43.632 +0900|
12400|template0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0.0| 0.0| |
1|template1| 0| 20611| 0| 5608| 706831| 10072559| 114248| 0| 5| 0| 0| 0| 0| 0| 0.0| 0.0|2023-12-04 10:35:18.508 +0900|
--statUserTablesQuery
SELECT
current_database() datname,
schemaname,
relname,
seq_scan,
seq_tup_read,
idx_scan,
idx_tup_fetch,
n_tup_ins,
n_tup_upd,
n_tup_del,
n_tup_hot_upd,
n_live_tup,
n_dead_tup,
n_mod_since_analyze,
COALESCE(last_vacuum, '1970-01-01Z') as last_vacuum,
COALESCE(last_autovacuum, '1970-01-01Z') as last_autovacuum,
COALESCE(last_analyze, '1970-01-01Z') as last_analyze,
COALESCE(last_autoanalyze, '1970-01-01Z') as last_autoanalyze,
vacuum_count,
autovacuum_count,
analyze_count,
autoanalyze_count,
pg_total_relation_size(relid) as total_size
FROM
pg_stat_user_tables;
datname |schemaname|relname |seq_scan|seq_tup_read|idx_scan|idx_tup_fetch|n_tup_ins|n_tup_upd|n_tup_del|n_tup_hot_upd|n_live_tup|n_dead_tup|n_mod_since_analyze|last_vacuum |last_autovacuum |last_analyze |last_autoanalyze |vacuum_count|autovacuum_count|analyze_count|autoanalyze_count|total_size|
---------+----------+--------------------+--------+------------+--------+-------------+---------+---------+---------+-------------+----------+----------+-------------------+-----------------------------+-----------------------------+-----------------------------+-----------------------------+------------+----------------+-------------+-----------------+----------+
postgres |public |test_chk | 1| 0| 168| 0| 0| 0| 0| 0| 0| 0| 0|1970-01-01 09:00:00.000 +0900|1970-01-01 09:00:00.000 +0900|1970-01-01 09:00:00.000 +0900|1970-01-01 09:00:00.000 +0900| 0| 0| 0| 0| 8192|
--statioUserIndexesQuery =
SELECT
schemaname,
relname,
indexrelname,
idx_blks_read,
idx_blks_hit
FROM pg_statio_user_indexes;
schemaname|relname |indexrelname |idx_blks_read|idx_blks_hit|
----------+----------------------+-----------------------------------------+-------------+------------+
postgres |test_chk |postgres_idx | 167| 238|
--statioUserTables
SELECT
current_database() datname,
schemaname,
relname,
heap_blks_read,
heap_blks_hit,
idx_blks_read,
idx_blks_hit,
toast_blks_read,
toast_blks_hit,
tidx_blks_read,
tidx_blks_hit
FROM pg_statio_user_tables;
datname |schemaname|relname |heap_blks_read|heap_blks_hit|idx_blks_read|idx_blks_hit|toast_blks_read|toast_blks_hit|tidx_blks_read|tidx_blks_hit|
---------+----------+------------+--------------+-------------+-------------+------------+---------------+--------------+--------------+-------------+
postgres |public |test_chk | 426| 38198| 180| 2162| 0| 0| 0| 0|
8. state Activity Autovacuum
세션 프로세스들의 정보를 각각 하나의 로우를 보여는 뷰 테이블에서 query에서 autovacuum으로 시작되는 것을 조회하여 vacuum 프로세스 시작 시간을 조회 합니다. 쿼리의 결과 정의는 아래와 같습니다.
- timestamp_seconds: Start timestamp of the vacuum process in seconds
-- statActivityAutovacuum
SELECT
SPLIT_PART(query, '.', 2) AS relname,
EXTRACT(EPOCH FROM xact_start) AS timestamp_seconds
FROM
pg_catalog.pg_stat_activity
WHERE
query LIKE 'autovacuum:%';
relname|timestamp_seconds|
-------+-----------------+
9. 현재 사용중인 로그 확인
복구 정보 함수를 사용하여 현재 사용중인로그 byte를 출력
- pg_is_in_recovery(): 복구가 아직 진행 중인 경우 True 임
- pg_last_xlog_replay_location() 텍스트 복구 중에 재생된 마지막 트랜잭션 로그 위치를 가져옴
- pg_current_xlog_locatioin() : 현재 사용중인 로그 출력
결과 값에 대한 정의는 다음과 같습니다.
- bytes:Postgres LSN (log sequence number) being generated on primary or replayed on replica (truncated to low 52 bits)
--xlogLocationQuery = `
SELECT CASE
WHEN pg_is_in_recovery() THEN (pg_last_xlog_replay_location() - '0/0') % (2^52)::bigint
ELSE (pg_current_xlog_location() - '0/0') % (2^52)::bigint
END AS bytes;
bytes |
-----------+
13103539000|