postgresql/src/test/regress/sql/sysviews.sql
Michael Paquier 01d485b142 Add system view pg_stat_recovery
This commit introduces pg_stat_recovery, that exposes at SQL level the
state of recovery as tracked by XLogRecoveryCtlData in shared memory,
maintained by the startup process.  This new view includes the following
fields, that are useful for monitoring purposes on a standby, once it
has reached a consistent state (making the execution of the SQL function
possible):
- Last-successfully replayed WAL record LSN boundaries and its timeline.
- Currently replaying WAL record end LSN and its timeline.
- Current WAL chunk start time.
- Promotion trigger state.
- Timestamp of latest processed commit/abort.
- Recovery pause state.

Some of this data can already be recovered from different system
functions, but not all of it.  See pg_get_wal_replay_pause_state or
pg_last_xact_replay_timestamp.  This new view offers a stronger
consistency guarantee, by grabbing the recovery state for all fields
through one spinlock acquisition.

The system view relies on a new function, called pg_stat_get_recovery().
Querying this data requires the pg_read_all_stats privilege.  The view
returns no rows if the node is not in recovery.

This feature originates from a suggestion I have made while discussion
the addition of a CONNECTING state to the WAL receiver's shared memory
state, because we lacked access to some of the state data.  The author
has taken the time to implement it, so thanks for that.

Bump catalog version.

Author: Xuneng Zhou <xunengzhou@gmail.com>
Discussion: https://postgr.es/m/CABPTF7W+Nody-+P9y4PNk37-QWuLpfUrEonHuEhrX+Vx9Kq+Kw@mail.gmail.com
Discussion: https://postgr.es/m/aW13GJn_RfTJIFCa@paquier.xyz
2026-03-06 12:37:40 +09:00

106 lines
4.5 KiB
PL/PgSQL

--
-- Test assorted system views
--
-- This test is mainly meant to provide some code coverage for the
-- set-returning functions that underlie certain system views.
-- The output of most of these functions is very environment-dependent,
-- so our ability to test with fixed expected output is pretty limited;
-- but even a trivial check of count(*) will exercise the normal code path
-- through the SRF.
select count(*) >= 0 as ok from pg_available_extension_versions;
select count(*) >= 0 as ok from pg_available_extensions;
-- The entire output of pg_backend_memory_contexts is not stable,
-- we test only the existence and basic condition of TopMemoryContext.
select type, name, ident, level, total_bytes >= free_bytes
from pg_backend_memory_contexts where level = 1;
-- We can exercise some MemoryContext type stats functions. Most of the
-- column values are too platform-dependent to display.
-- Ensure stats from the bump allocator look sane. Bump isn't a commonly
-- used context, but it is used in tuplesort.c, so open a cursor to keep
-- the tuplesort alive long enough for us to query the context stats.
begin;
declare cur cursor for select left(a,10), b
from (values(repeat('a', 512 * 1024),1),(repeat('b', 512),2)) v(a,b)
order by v.a desc;
fetch 1 from cur;
select type, name, total_bytes > 0, total_nblocks, free_bytes > 0, free_chunks
from pg_backend_memory_contexts where name = 'Caller tuples';
rollback;
-- Further sanity checks on pg_backend_memory_contexts. We expect
-- CacheMemoryContext to have multiple children. Ensure that's the case.
with contexts as (
select * from pg_backend_memory_contexts
)
select count(*) > 1
from contexts c1, contexts c2
where c2.name = 'CacheMemoryContext'
and c1.path[c2.level] = c2.path[c2.level];
-- At introduction, pg_config had 23 entries; it may grow
select count(*) > 20 as ok from pg_config;
-- We expect no cursors in this test; see also portals.sql
select count(*) = 0 as ok from pg_cursors;
select count(*) >= 0 as ok from pg_file_settings;
-- There will surely be at least one rule, with no errors.
select count(*) > 0 as ok, count(*) FILTER (WHERE error IS NOT NULL) = 0 AS no_err
from pg_hba_file_rules;
-- There may be no rules, and there should be no errors.
select count(*) >= 0 as ok, count(*) FILTER (WHERE error IS NOT NULL) = 0 AS no_err
from pg_ident_file_mappings;
-- There will surely be at least one active lock
select count(*) > 0 as ok from pg_locks;
-- We expect no prepared statements in this test; see also prepare.sql
select count(*) = 0 as ok from pg_prepared_statements;
-- See also prepared_xacts.sql
select count(*) >= 0 as ok from pg_prepared_xacts;
-- There will surely be at least one SLRU cache
select count(*) > 0 as ok from pg_stat_slru;
-- There must be only one record
select count(*) = 1 as ok from pg_stat_wal;
-- We expect no walreceiver running in this test
select count(*) = 0 as ok from pg_stat_wal_receiver;
-- We expect no recovery state in this test (running on primary)
select count(*) = 0 as ok from pg_stat_recovery;
-- This is to record the prevailing planner enable_foo settings during
-- a regression test run.
select name, setting from pg_settings where name like 'enable%';
-- There are always wait event descriptions for various types. InjectionPoint
-- may be present or absent, depending on history since last postmaster start.
select type, count(*) > 0 as ok FROM pg_wait_events
where type <> 'InjectionPoint' group by type order by type COLLATE "C";
-- Test that the pg_timezone_names and pg_timezone_abbrevs views are
-- more-or-less working. We can't test their contents in any great detail
-- without the outputs changing anytime IANA updates the underlying data,
-- but it seems reasonable to expect at least one entry per major meridian.
-- (At the time of writing, the actual counts are around 38 because of
-- zones using fractional GMT offsets, so this is a pretty loose test.)
select count(distinct utc_offset) >= 24 as ok from pg_timezone_names;
select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs;
-- Let's check the non-default timezone abbreviation sets, too
set timezone_abbreviations = 'Australia';
select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs;
set timezone_abbreviations = 'India';
select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs;
-- One specific case we can check without much fear of breakage
-- is the historical local-mean-time value used for America/Los_Angeles.
select * from pg_timezone_abbrevs where abbrev = 'LMT';