v4-0001-Rework-pg_walinspect-functions.patch
application/octet-stream
Filename: v4-0001-Rework-pg_walinspect-functions.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v4-0001
Subject: Rework pg_walinspect functions
| File | + | − |
|---|---|---|
| contrib/pg_walinspect/expected/oldextversions.out | 64 | 0 |
| contrib/pg_walinspect/expected/pg_walinspect.out | 76 | 9 |
| contrib/pg_walinspect/Makefile | 1 | 1 |
| contrib/pg_walinspect/meson.build | 1 | 0 |
| contrib/pg_walinspect/pg_walinspect--1.0--1.1.sql | 55 | 2 |
| contrib/pg_walinspect/pg_walinspect.c | 145 | 90 |
| contrib/pg_walinspect/sql/oldextversions.sql | 27 | 0 |
| contrib/pg_walinspect/sql/pg_walinspect.sql | 31 | 39 |
| doc/src/sgml/pgwalinspect.sgml | 28 | 45 |
From ecd578361158f4c6d90a1d983c2a2e055945c638 Mon Sep 17 00:00:00 2001
From: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
Date: Fri, 10 Mar 2023 05:07:18 +0000
Subject: [PATCH v4] Rework pg_walinspect functions
---
contrib/pg_walinspect/Makefile | 2 +-
.../pg_walinspect/expected/oldextversions.out | 64 +++++
.../pg_walinspect/expected/pg_walinspect.out | 85 ++++++-
contrib/pg_walinspect/meson.build | 1 +
.../pg_walinspect/pg_walinspect--1.0--1.1.sql | 57 ++++-
contrib/pg_walinspect/pg_walinspect.c | 235 +++++++++++-------
contrib/pg_walinspect/sql/oldextversions.sql | 27 ++
contrib/pg_walinspect/sql/pg_walinspect.sql | 70 +++---
doc/src/sgml/pgwalinspect.sgml | 73 +++---
9 files changed, 428 insertions(+), 186 deletions(-)
create mode 100644 contrib/pg_walinspect/expected/oldextversions.out
create mode 100644 contrib/pg_walinspect/sql/oldextversions.sql
diff --git a/contrib/pg_walinspect/Makefile b/contrib/pg_walinspect/Makefile
index 7033878a79..22090f7716 100644
--- a/contrib/pg_walinspect/Makefile
+++ b/contrib/pg_walinspect/Makefile
@@ -9,7 +9,7 @@ PGFILEDESC = "pg_walinspect - functions to inspect contents of PostgreSQL Write-
EXTENSION = pg_walinspect
DATA = pg_walinspect--1.0.sql pg_walinspect--1.0--1.1.sql
-REGRESS = pg_walinspect
+REGRESS = pg_walinspect oldextversions
REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_walinspect/walinspect.conf
diff --git a/contrib/pg_walinspect/expected/oldextversions.out b/contrib/pg_walinspect/expected/oldextversions.out
new file mode 100644
index 0000000000..0ac82dfeb1
--- /dev/null
+++ b/contrib/pg_walinspect/expected/oldextversions.out
@@ -0,0 +1,64 @@
+-- test old extension version entry points
+DROP EXTENSION pg_walinspect;
+CREATE EXTENSION pg_walinspect WITH VERSION '1.0';
+-- Move to new version 1.1
+ALTER EXTENSION pg_walinspect UPDATE TO '1.1';
+-- New function introduced in 1.1
+SELECT pg_get_functiondef('pg_get_wal_block_info'::regproc);
+ pg_get_functiondef
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ CREATE OR REPLACE FUNCTION public.pg_get_wal_block_info(start_lsn pg_lsn, end_lsn pg_lsn DEFAULT NULL::pg_lsn, OUT lsn pg_lsn, OUT blockid smallint, OUT reltablespace oid, OUT reldatabase oid, OUT relfilenode oid, OUT relblocknumber bigint, OUT forkname text, OUT blockdata bytea, OUT fpi bytea, OUT fpilen integer, OUT fpiinfo text[])+
+ RETURNS SETOF record +
+ LANGUAGE c +
+ PARALLEL SAFE +
+ AS '$libdir/pg_walinspect', $function$pg_get_wal_block_info$function$ +
+
+(1 row)
+
+-- Redefined function
+SELECT pg_get_functiondef('pg_get_wal_records_info'::regproc);
+ pg_get_functiondef
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ CREATE OR REPLACE FUNCTION public.pg_get_wal_records_info(start_lsn pg_lsn, end_lsn pg_lsn DEFAULT NULL::pg_lsn, OUT start_lsn pg_lsn, OUT end_lsn pg_lsn, OUT prev_lsn pg_lsn, OUT xid xid, OUT resource_manager text, OUT record_type text, OUT record_length integer, OUT main_data_length integer, OUT fpi_length integer, OUT description text, OUT block_ref text)+
+ RETURNS SETOF record +
+ LANGUAGE c +
+ PARALLEL SAFE +
+ AS '$libdir/pg_walinspect', $function$pg_get_wal_records_info$function$ +
+
+(1 row)
+
+-- Removed function
+SELECT pg_get_functiondef('pg_get_wal_records_info_till_end_of_wal'::regproc);
+ERROR: function "pg_get_wal_records_info_till_end_of_wal" does not exist
+LINE 1: SELECT pg_get_functiondef('pg_get_wal_records_info_till_end_...
+ ^
+-- Redefined function
+SELECT pg_get_functiondef('pg_get_wal_stats'::regproc);
+ pg_get_functiondef
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ CREATE OR REPLACE FUNCTION public.pg_get_wal_stats(start_lsn pg_lsn, end_lsn pg_lsn DEFAULT NULL::pg_lsn, per_record boolean DEFAULT false, OUT "resource_manager/record_type" text, OUT count bigint, OUT count_percentage double precision, OUT record_size bigint, OUT record_size_percentage double precision, OUT fpi_size bigint, OUT fpi_size_percentage double precision, OUT combined_size bigint, OUT combined_size_percentage double precision)+
+ RETURNS SETOF record +
+ LANGUAGE c +
+ PARALLEL SAFE +
+ AS '$libdir/pg_walinspect', $function$pg_get_wal_stats$function$ +
+
+(1 row)
+
+-- Removed function
+SELECT pg_get_functiondef('pg_get_wal_stats_till_end_of_wal'::regproc);
+ERROR: function "pg_get_wal_stats_till_end_of_wal" does not exist
+LINE 1: SELECT pg_get_functiondef('pg_get_wal_stats_till_end_of_wal'...
+ ^
+-- Redefined function
+SELECT pg_get_functiondef('pg_get_wal_block_info'::regproc);
+ pg_get_functiondef
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ CREATE OR REPLACE FUNCTION public.pg_get_wal_block_info(start_lsn pg_lsn, end_lsn pg_lsn DEFAULT NULL::pg_lsn, OUT lsn pg_lsn, OUT blockid smallint, OUT reltablespace oid, OUT reldatabase oid, OUT relfilenode oid, OUT relblocknumber bigint, OUT forkname text, OUT blockdata bytea, OUT fpi bytea, OUT fpilen integer, OUT fpiinfo text[])+
+ RETURNS SETOF record +
+ LANGUAGE c +
+ PARALLEL SAFE +
+ AS '$libdir/pg_walinspect', $function$pg_get_wal_block_info$function$ +
+
+(1 row)
+
+DROP EXTENSION pg_walinspect;
diff --git a/contrib/pg_walinspect/expected/pg_walinspect.out b/contrib/pg_walinspect/expected/pg_walinspect.out
index e0eb7ca08f..31ef22a2cc 100644
--- a/contrib/pg_walinspect/expected/pg_walinspect.out
+++ b/contrib/pg_walinspect/expected/pg_walinspect.out
@@ -14,38 +14,89 @@ INSERT INTO sample_tbl SELECT * FROM generate_series(3, 4);
-- ===================================================================
-- Tests for input validation
-- ===================================================================
-SELECT COUNT(*) >= 0 AS ok FROM pg_get_wal_records_info(:'wal_lsn2', :'wal_lsn1'); -- ERROR
-ERROR: WAL start LSN must be less than end LSN
-SELECT COUNT(*) >= 0 AS ok FROM pg_get_wal_stats(:'wal_lsn2', :'wal_lsn1'); -- ERROR
-ERROR: WAL start LSN must be less than end LSN
+-- Invalid input LSNs
+SELECT * FROM pg_get_wal_record_info('0/0'); -- ERROR
+ERROR: invalid input LSN
+SELECT * FROM pg_get_wal_records_info('0/0'); -- ERROR
+ERROR: invalid start LSN
+SELECT * FROM pg_get_wal_stats('0/0'); -- ERROR
+ERROR: invalid start LSN
+SELECT * FROM pg_get_wal_block_info('0/0'); -- ERROR
+ERROR: invalid start LSN
+-- Start LSN NULL
+SELECT * FROM pg_get_wal_records_info(NULL); -- ERROR
+ERROR: invalid start LSN
+SELECT * FROM pg_get_wal_stats(NULL); -- ERROR
+ERROR: invalid start LSN
+SELECT * FROM pg_get_wal_block_info(NULL); -- ERROR
+ERROR: invalid start LSN
+-- Start LSN > End LSN
+SELECT * FROM pg_get_wal_records_info(:'wal_lsn2', :'wal_lsn1'); -- NULL
+ start_lsn | end_lsn | prev_lsn | xid | resource_manager | record_type | record_length | main_data_length | fpi_length | description | block_ref
+-----------+---------+----------+-----+------------------+-------------+---------------+------------------+------------+-------------+-----------
+ | | | | | | | | | |
+(1 row)
+
+SELECT * FROM pg_get_wal_stats(:'wal_lsn2', :'wal_lsn1'); -- NULL
+ resource_manager/record_type | count | count_percentage | record_size | record_size_percentage | fpi_size | fpi_size_percentage | combined_size | combined_size_percentage
+------------------------------+-------+------------------+-------------+------------------------+----------+---------------------+---------------+--------------------------
+ | | | | | | | |
+(1 row)
+
+SELECT * FROM pg_get_wal_block_info(:'wal_lsn2', :'wal_lsn1'); -- NULL
+ lsn | blockid | reltablespace | reldatabase | relfilenode | relblocknumber | forkname | blockdata | fpi | fpilen | fpiinfo
+-----+---------+---------------+-------------+-------------+----------------+----------+-----------+-----+--------+---------
+ | | | | | | | | | |
+(1 row)
+
-- ===================================================================
-- Tests for all function executions
-- ===================================================================
-SELECT COUNT(*) >= 0 AS ok FROM pg_get_wal_record_info(:'wal_lsn1');
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_record_info(:'wal_lsn1');
+ ok
+----
+ t
+(1 row)
+
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_records_info(:'wal_lsn1', :'wal_lsn2');
+ ok
+----
+ t
+(1 row)
+
+-- Get info till end of WAL
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_records_info(:'wal_lsn1');
ok
----
t
(1 row)
-SELECT COUNT(*) >= 0 AS ok FROM pg_get_wal_records_info(:'wal_lsn1', :'wal_lsn2');
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_records_info(:'wal_lsn1', '0/0');
ok
----
t
(1 row)
-SELECT COUNT(*) >= 0 AS ok FROM pg_get_wal_records_info_till_end_of_wal(:'wal_lsn1');
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_records_info(:'wal_lsn1', NULL);
ok
----
t
(1 row)
-SELECT COUNT(*) >= 0 AS ok FROM pg_get_wal_stats(:'wal_lsn1', :'wal_lsn2');
+-- Get stats till end of WAL
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_stats(:'wal_lsn1');
ok
----
t
(1 row)
-SELECT COUNT(*) >= 0 AS ok FROM pg_get_wal_stats_till_end_of_wal(:'wal_lsn1');
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_stats(:'wal_lsn1', '0/0');
+ ok
+----
+ t
+(1 row)
+
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_stats(:'wal_lsn1', NULL);
ok
----
t
@@ -88,6 +139,14 @@ SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_block_info(:'wal_lsn3', :'wal_lsn4')
t
(1 row)
+-- Check till end of WAL if we get block data from WAL record.
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_block_info(:'wal_lsn3')
+ WHERE relfilenode = :'sample_tbl_oid';
+ ok
+----
+ t
+(1 row)
+
-- Force full-page image on the next update.
SELECT pg_current_wal_lsn() AS wal_lsn5 \gset
CHECKPOINT;
@@ -101,6 +160,14 @@ SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_block_info(:'wal_lsn5', :'wal_lsn6')
t
(1 row)
+-- Check till end of WAL if we get FPI from WAL record.
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_block_info(:'wal_lsn5')
+ WHERE relfilenode = :'sample_tbl_oid';
+ ok
+----
+ t
+(1 row)
+
-- ===================================================================
-- Tests for permissions
-- ===================================================================
diff --git a/contrib/pg_walinspect/meson.build b/contrib/pg_walinspect/meson.build
index bf7b79b1b7..80059f6119 100644
--- a/contrib/pg_walinspect/meson.build
+++ b/contrib/pg_walinspect/meson.build
@@ -30,6 +30,7 @@ tests += {
'regress': {
'sql': [
'pg_walinspect',
+ 'oldextversions',
],
# Disabled because these tests require "wal_level=replica", which
# some runningcheck users do not have (e.g. buildfarm clients).
diff --git a/contrib/pg_walinspect/pg_walinspect--1.0--1.1.sql b/contrib/pg_walinspect/pg_walinspect--1.0--1.1.sql
index e674ef25aa..8d9b82ead2 100644
--- a/contrib/pg_walinspect/pg_walinspect--1.0--1.1.sql
+++ b/contrib/pg_walinspect/pg_walinspect--1.0--1.1.sql
@@ -3,11 +3,64 @@
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
\echo Use "ALTER EXTENSION pg_walinspect UPDATE TO '1.1'" to load this file. \quit
+/* Drop the unneeded functions and redefine needed ones */
+DROP FUNCTION pg_get_wal_records_info(pg_lsn, pg_lsn);
+DROP FUNCTION pg_get_wal_records_info_till_end_of_wal(pg_lsn);
+DROP FUNCTION pg_get_wal_stats(pg_lsn, pg_lsn, boolean);
+DROP FUNCTION pg_get_wal_stats_till_end_of_wal(pg_lsn, boolean);
+
+--
+-- pg_get_wal_records_info()
+--
+CREATE FUNCTION pg_get_wal_records_info(IN start_lsn pg_lsn,
+ IN end_lsn pg_lsn DEFAULT NULL,
+ OUT start_lsn pg_lsn,
+ OUT end_lsn pg_lsn,
+ OUT prev_lsn pg_lsn,
+ OUT xid xid,
+ OUT resource_manager text,
+ OUT record_type text,
+ OUT record_length int4,
+ OUT main_data_length int4,
+ OUT fpi_length int4,
+ OUT description text,
+ OUT block_ref text
+)
+RETURNS SETOF record
+AS 'MODULE_PATHNAME', 'pg_get_wal_records_info'
+LANGUAGE C CALLED ON NULL INPUT PARALLEL SAFE;
+
+REVOKE EXECUTE ON FUNCTION pg_get_wal_records_info(pg_lsn, pg_lsn) FROM PUBLIC;
+GRANT EXECUTE ON FUNCTION pg_get_wal_records_info(pg_lsn, pg_lsn) TO pg_read_server_files;
+
+--
+-- pg_get_wal_stats()
+--
+CREATE FUNCTION pg_get_wal_stats(IN start_lsn pg_lsn,
+ IN end_lsn pg_lsn DEFAULT NULL,
+ IN per_record boolean DEFAULT false,
+ OUT "resource_manager/record_type" text,
+ OUT count int8,
+ OUT count_percentage float8,
+ OUT record_size int8,
+ OUT record_size_percentage float8,
+ OUT fpi_size int8,
+ OUT fpi_size_percentage float8,
+ OUT combined_size int8,
+ OUT combined_size_percentage float8
+)
+RETURNS SETOF record
+AS 'MODULE_PATHNAME', 'pg_get_wal_stats'
+LANGUAGE C CALLED ON NULL INPUT PARALLEL SAFE;
+
+REVOKE EXECUTE ON FUNCTION pg_get_wal_stats(pg_lsn, pg_lsn, boolean) FROM PUBLIC;
+GRANT EXECUTE ON FUNCTION pg_get_wal_stats(pg_lsn, pg_lsn, boolean) TO pg_read_server_files;
+
--
-- pg_get_wal_block_info()
--
CREATE FUNCTION pg_get_wal_block_info(IN start_lsn pg_lsn,
- IN end_lsn pg_lsn,
+ IN end_lsn pg_lsn DEFAULT NULL,
OUT lsn pg_lsn,
OUT blockid int2,
OUT reltablespace oid,
@@ -22,7 +75,7 @@ CREATE FUNCTION pg_get_wal_block_info(IN start_lsn pg_lsn,
)
RETURNS SETOF record
AS 'MODULE_PATHNAME', 'pg_get_wal_block_info'
-LANGUAGE C STRICT PARALLEL SAFE;
+LANGUAGE C CALLED ON NULL INPUT PARALLEL SAFE;
REVOKE EXECUTE ON FUNCTION pg_get_wal_block_info(pg_lsn, pg_lsn) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION pg_get_wal_block_info(pg_lsn, pg_lsn) TO pg_read_server_files;
diff --git a/contrib/pg_walinspect/pg_walinspect.c b/contrib/pg_walinspect/pg_walinspect.c
index ee88dc4992..4a8974ac1f 100644
--- a/contrib/pg_walinspect/pg_walinspect.c
+++ b/contrib/pg_walinspect/pg_walinspect.c
@@ -38,13 +38,13 @@ PG_FUNCTION_INFO_V1(pg_get_wal_records_info_till_end_of_wal);
PG_FUNCTION_INFO_V1(pg_get_wal_stats);
PG_FUNCTION_INFO_V1(pg_get_wal_stats_till_end_of_wal);
-static bool IsFutureLSN(XLogRecPtr lsn, XLogRecPtr *curr_lsn);
+static XLogRecPtr GetCurrentLSN(void);
static XLogReaderState *InitXLogReaderState(XLogRecPtr lsn);
static XLogRecord *ReadNextXLogRecord(XLogReaderState *xlogreader);
static void GetWALRecordInfo(XLogReaderState *record, Datum *values,
bool *nulls, uint32 ncols);
-static XLogRecPtr ValidateInputLSNs(bool till_end_of_wal,
- XLogRecPtr start_lsn, XLogRecPtr end_lsn);
+static void GetInputLSNs(FunctionCallInfo fcinfo, XLogRecPtr *start_lsn,
+ XLogRecPtr *end_lsn);
static void GetWALRecordsInfo(FunctionCallInfo fcinfo, XLogRecPtr start_lsn,
XLogRecPtr end_lsn);
static void GetXLogSummaryStats(XLogStats *stats, ReturnSetInfo *rsinfo,
@@ -60,27 +60,25 @@ static void GetWalStats(FunctionCallInfo fcinfo, XLogRecPtr start_lsn,
static void GetWALBlockInfo(FunctionCallInfo fcinfo, XLogReaderState *record);
/*
- * Check if the given LSN is in future. Also, return the LSN up to which the
- * server has WAL.
+ * Return the LSN up to which the server has WAL.
*/
-static bool
-IsFutureLSN(XLogRecPtr lsn, XLogRecPtr *curr_lsn)
+static XLogRecPtr
+GetCurrentLSN(void)
{
+ XLogRecPtr curr_lsn;
+
/*
* We determine the current LSN of the server similar to how page_read
* callback read_local_xlog_page_no_wait does.
*/
if (!RecoveryInProgress())
- *curr_lsn = GetFlushRecPtr(NULL);
+ curr_lsn = GetFlushRecPtr(NULL);
else
- *curr_lsn = GetXLogReplayRecPtr(NULL);
+ curr_lsn = GetXLogReplayRecPtr(NULL);
- Assert(!XLogRecPtrIsInvalid(*curr_lsn));
+ Assert(!XLogRecPtrIsInvalid(curr_lsn));
- if (lsn >= *curr_lsn)
- return true;
-
- return false;
+ return curr_lsn;
}
/*
@@ -355,8 +353,14 @@ GetWALBlockInfo(FunctionCallInfo fcinfo, XLogReaderState *record)
* to a record. Decompression is applied to the full page images, if
* necessary.
*
- * This function emits an error if a future start or end WAL LSN i.e. WAL LSN
- * the database system doesn't know about is specified.
+ * This function determines end LSN if it is not specified or specified as NULL
+ * or invalid. In such cases, the end LSN is assigned with the last flushed LSN
+ * when not in recovery or the last replayed LSN when in recovery.
+ *
+ * This function emits an error if start LSN is invalid or in future i.e. LSN
+ * the database system doesn't know about.
+ *
+ * This function returns NULL, when start LSN is past the end LSN.
*/
Datum
pg_get_wal_block_info(PG_FUNCTION_ARGS)
@@ -367,10 +371,14 @@ pg_get_wal_block_info(PG_FUNCTION_ARGS)
MemoryContext old_cxt;
MemoryContext tmp_cxt;
- start_lsn = PG_GETARG_LSN(0);
- end_lsn = PG_GETARG_LSN(1);
+ GetInputLSNs(fcinfo, &start_lsn, &end_lsn);
- end_lsn = ValidateInputLSNs(false, start_lsn, end_lsn);
+ /*
+ * When start LSN is past the end LSN, let's return NULL instead of raising
+ * an error for better usability of the functions.
+ */
+ if (start_lsn >= end_lsn)
+ PG_RETURN_NULL();
InitMaterializedSRF(fcinfo, 0);
@@ -405,8 +413,8 @@ pg_get_wal_block_info(PG_FUNCTION_ARGS)
/*
* Get WAL record info.
*
- * This function emits an error if a future WAL LSN i.e. WAL LSN the database
- * system doesn't know about is specified.
+ * This function emits an error if input LSN is invalid or in future i.e. LSN
+ * the database system doesn't know about.
*/
Datum
pg_get_wal_record_info(PG_FUNCTION_ARGS)
@@ -423,7 +431,14 @@ pg_get_wal_record_info(PG_FUNCTION_ARGS)
lsn = PG_GETARG_LSN(0);
- if (IsFutureLSN(lsn, &curr_lsn))
+ if (XLogRecPtrIsInvalid(lsn))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid input LSN")));
+
+ curr_lsn = GetCurrentLSN();
+
+ if (lsn >= curr_lsn)
{
/*
* GetFlushRecPtr or GetXLogReplayRecPtr gives "end+1" LSN of the last
@@ -462,44 +477,36 @@ pg_get_wal_record_info(PG_FUNCTION_ARGS)
}
/*
- * Validate the input LSNs and compute end LSN for till_end_of_wal versions.
+ * Get start LSN and get/deduce end LSN.
*/
-static XLogRecPtr
-ValidateInputLSNs(bool till_end_of_wal, XLogRecPtr start_lsn,
- XLogRecPtr end_lsn)
+static void
+GetInputLSNs(FunctionCallInfo fcinfo, XLogRecPtr *start_lsn,
+ XLogRecPtr *end_lsn)
{
XLogRecPtr curr_lsn;
- if (IsFutureLSN(start_lsn, &curr_lsn))
- {
- /*
- * GetFlushRecPtr or GetXLogReplayRecPtr gives "end+1" LSN of the last
- * record flushed or replayed respectively. But let's use the LSN up
- * to "end" in user facing message.
- */
+ if (PG_ARGISNULL(0) ||
+ ((*start_lsn = PG_GETARG_LSN(0)) == InvalidXLogRecPtr))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("cannot accept future start LSN"),
- errdetail("Last known WAL LSN on the database system is at %X/%X.",
- LSN_FORMAT_ARGS(curr_lsn))));
- }
-
- if (till_end_of_wal)
- end_lsn = curr_lsn;
+ errmsg("invalid start LSN")));
- if (end_lsn > curr_lsn)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("cannot accept future end LSN"),
- errdetail("Last known WAL LSN on the database system is at %X/%X.",
- LSN_FORMAT_ARGS(curr_lsn))));
+ curr_lsn = GetCurrentLSN();
- if (start_lsn >= end_lsn)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("WAL start LSN must be less than end LSN")));
+ if (PG_ARGISNULL(1))
+ *end_lsn = curr_lsn;
+ else
+ {
+ *end_lsn = PG_GETARG_LSN(1);
- return end_lsn;
+ /*
+ * Adjust end LSN to what the system knows at this point instead of
+ * raising errors for better usability of the functions.
+ */
+ if (XLogRecPtrIsInvalid(*end_lsn) ||
+ *end_lsn > curr_lsn)
+ *end_lsn = curr_lsn;
+ }
}
/*
@@ -554,8 +561,14 @@ GetWALRecordsInfo(FunctionCallInfo fcinfo, XLogRecPtr start_lsn,
/*
* Get info and data of all WAL records between start LSN and end LSN.
*
- * This function emits an error if a future start or end WAL LSN i.e. WAL LSN
- * the database system doesn't know about is specified.
+ * This function determines end LSN if it is not specified or specified as NULL
+ * or invalid. In such cases, the end LSN is assigned with the last flushed LSN
+ * when not in recovery or the last replayed LSN when in recovery.
+ *
+ * This function emits an error if start LSN is invalid or in future i.e. LSN
+ * the database system doesn't know about.
+ *
+ * This function returns NULL, when start LSN is past the end LSN.
*/
Datum
pg_get_wal_records_info(PG_FUNCTION_ARGS)
@@ -563,31 +576,14 @@ pg_get_wal_records_info(PG_FUNCTION_ARGS)
XLogRecPtr start_lsn;
XLogRecPtr end_lsn;
- start_lsn = PG_GETARG_LSN(0);
- end_lsn = PG_GETARG_LSN(1);
-
- end_lsn = ValidateInputLSNs(false, start_lsn, end_lsn);
-
- GetWALRecordsInfo(fcinfo, start_lsn, end_lsn);
-
- PG_RETURN_VOID();
-}
-
-/*
- * Get info and data of all WAL records from start LSN till end of WAL.
- *
- * This function emits an error if a future start i.e. WAL LSN the database
- * system doesn't know about is specified.
- */
-Datum
-pg_get_wal_records_info_till_end_of_wal(PG_FUNCTION_ARGS)
-{
- XLogRecPtr start_lsn;
- XLogRecPtr end_lsn = InvalidXLogRecPtr;
-
- start_lsn = PG_GETARG_LSN(0);
+ GetInputLSNs(fcinfo, &start_lsn, &end_lsn);
- end_lsn = ValidateInputLSNs(true, start_lsn, end_lsn);
+ /*
+ * When start LSN is past the end LSN, let's return NULL instead of raising
+ * an error for better usability of the functions.
+ */
+ if (start_lsn >= end_lsn)
+ PG_RETURN_NULL();
GetWALRecordsInfo(fcinfo, start_lsn, end_lsn);
@@ -792,8 +788,14 @@ GetWalStats(FunctionCallInfo fcinfo, XLogRecPtr start_lsn,
/*
* Get stats of all WAL records between start LSN and end LSN.
*
- * This function emits an error if a future start or end WAL LSN i.e. WAL LSN
- * the database system doesn't know about is specified.
+ * This function determines end LSN if it is not specified or specified as NULL
+ * or invalid. In such cases, the end LSN is assigned with the last flushed LSN
+ * when not in recovery or the last replayed LSN when in recovery.
+ *
+ * This function emits an error if start LSN is invalid or in future i.e. LSN
+ * the database system doesn't know about.
+ *
+ * This function returns NULL, when start LSN is past the end LSN.
*/
Datum
pg_get_wal_stats(PG_FUNCTION_ARGS)
@@ -802,11 +804,16 @@ pg_get_wal_stats(PG_FUNCTION_ARGS)
XLogRecPtr end_lsn;
bool stats_per_record;
- start_lsn = PG_GETARG_LSN(0);
- end_lsn = PG_GETARG_LSN(1);
- stats_per_record = PG_GETARG_BOOL(2);
+ GetInputLSNs(fcinfo, &start_lsn, &end_lsn);
+
+ /*
+ * When start LSN is past the end LSN, let's return NULL instead of raising
+ * an error for better usability of the functions.
+ */
+ if (start_lsn >= end_lsn)
+ PG_RETURN_NULL();
- end_lsn = ValidateInputLSNs(false, start_lsn, end_lsn);
+ stats_per_record = PG_GETARG_BOOL(2);
GetWalStats(fcinfo, start_lsn, end_lsn, stats_per_record);
@@ -814,22 +821,70 @@ pg_get_wal_stats(PG_FUNCTION_ARGS)
}
/*
- * Get stats of all WAL records from start LSN till end of WAL.
+ * NB: Following till_end_of_wal functions have been removed in newer versions
+ * of extension. However, we keep them around for backward compatibility. Which
+ * means, these functions work if someone explicitly installs the older
+ * extension version (using CREATE EXTENSION pg_walinspect WITH VERSION '1.0';)
+ * containing them.
*
- * This function emits an error if a future start i.e. WAL LSN the database
- * system doesn't know about is specified.
+ * If definitions of these functions are removed completely, the extension
+ * fails to install.
+ *
+ * In newer versions, one can use pg_get_wal_records_info()/pg_get_wal_stats()
+ * for the same till_end_of_wal functionality.
*/
+
+Datum
+pg_get_wal_records_info_till_end_of_wal(PG_FUNCTION_ARGS)
+{
+ XLogRecPtr start_lsn;
+ XLogRecPtr end_lsn;
+
+ if (PG_ARGISNULL(0) ||
+ ((start_lsn = PG_GETARG_LSN(0)) == InvalidXLogRecPtr))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid start LSN")));
+
+ /* Let's compute end LSN ourselves. */
+ end_lsn = GetCurrentLSN();
+
+ /*
+ * When start LSN is past the end LSN, let's return NULL instead of raising
+ * an error for better usability of the functions.
+ */
+ if (start_lsn >= end_lsn)
+ PG_RETURN_NULL();
+
+ GetWALRecordsInfo(fcinfo, start_lsn, end_lsn);
+
+ PG_RETURN_VOID();
+}
+
Datum
pg_get_wal_stats_till_end_of_wal(PG_FUNCTION_ARGS)
{
XLogRecPtr start_lsn;
- XLogRecPtr end_lsn = InvalidXLogRecPtr;
+ XLogRecPtr end_lsn;
bool stats_per_record;
- start_lsn = PG_GETARG_LSN(0);
- stats_per_record = PG_GETARG_BOOL(1);
+ if (PG_ARGISNULL(0) ||
+ ((start_lsn = PG_GETARG_LSN(0)) == InvalidXLogRecPtr))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid start LSN")));
+
+ /* Let's compute end LSN ourselves. */
+ end_lsn = GetCurrentLSN();
+
+ /*
+ * When start LSN is past the end LSN, let's return NULL instead of raising
+ * an error for better usability of the functions.
+ */
+ if (start_lsn >= end_lsn)
+ PG_RETURN_NULL();
- end_lsn = ValidateInputLSNs(true, start_lsn, end_lsn);
+ stats_per_record = PG_GETARG_BOOL(2);
GetWalStats(fcinfo, start_lsn, end_lsn, stats_per_record);
diff --git a/contrib/pg_walinspect/sql/oldextversions.sql b/contrib/pg_walinspect/sql/oldextversions.sql
new file mode 100644
index 0000000000..3ccea0cdb2
--- /dev/null
+++ b/contrib/pg_walinspect/sql/oldextversions.sql
@@ -0,0 +1,27 @@
+-- test old extension version entry points
+
+DROP EXTENSION pg_walinspect;
+CREATE EXTENSION pg_walinspect WITH VERSION '1.0';
+
+-- Move to new version 1.1
+ALTER EXTENSION pg_walinspect UPDATE TO '1.1';
+
+-- New function introduced in 1.1
+SELECT pg_get_functiondef('pg_get_wal_block_info'::regproc);
+
+-- Redefined function
+SELECT pg_get_functiondef('pg_get_wal_records_info'::regproc);
+
+-- Removed function
+SELECT pg_get_functiondef('pg_get_wal_records_info_till_end_of_wal'::regproc);
+
+-- Redefined function
+SELECT pg_get_functiondef('pg_get_wal_stats'::regproc);
+
+-- Removed function
+SELECT pg_get_functiondef('pg_get_wal_stats_till_end_of_wal'::regproc);
+
+-- Redefined function
+SELECT pg_get_functiondef('pg_get_wal_block_info'::regproc);
+
+DROP EXTENSION pg_walinspect;
diff --git a/contrib/pg_walinspect/sql/pg_walinspect.sql b/contrib/pg_walinspect/sql/pg_walinspect.sql
index 01a120f398..602aa9c7ae 100644
--- a/contrib/pg_walinspect/sql/pg_walinspect.sql
+++ b/contrib/pg_walinspect/sql/pg_walinspect.sql
@@ -4,43 +4,50 @@ CREATE EXTENSION pg_walinspect;
SELECT 'init' FROM pg_create_physical_replication_slot('regress_pg_walinspect_slot', true, false);
CREATE TABLE sample_tbl(col1 int, col2 int);
-
SELECT pg_current_wal_lsn() AS wal_lsn1 \gset
-
INSERT INTO sample_tbl SELECT * FROM generate_series(1, 2);
-
SELECT pg_current_wal_lsn() AS wal_lsn2 \gset
-
INSERT INTO sample_tbl SELECT * FROM generate_series(3, 4);
-- ===================================================================
-- Tests for input validation
-- ===================================================================
-
-SELECT COUNT(*) >= 0 AS ok FROM pg_get_wal_records_info(:'wal_lsn2', :'wal_lsn1'); -- ERROR
-
-SELECT COUNT(*) >= 0 AS ok FROM pg_get_wal_stats(:'wal_lsn2', :'wal_lsn1'); -- ERROR
+-- Invalid input LSNs
+SELECT * FROM pg_get_wal_record_info('0/0'); -- ERROR
+SELECT * FROM pg_get_wal_records_info('0/0'); -- ERROR
+SELECT * FROM pg_get_wal_stats('0/0'); -- ERROR
+SELECT * FROM pg_get_wal_block_info('0/0'); -- ERROR
+
+-- Start LSN NULL
+SELECT * FROM pg_get_wal_records_info(NULL); -- ERROR
+SELECT * FROM pg_get_wal_stats(NULL); -- ERROR
+SELECT * FROM pg_get_wal_block_info(NULL); -- ERROR
+
+-- Start LSN > End LSN
+SELECT * FROM pg_get_wal_records_info(:'wal_lsn2', :'wal_lsn1'); -- NULL
+SELECT * FROM pg_get_wal_stats(:'wal_lsn2', :'wal_lsn1'); -- NULL
+SELECT * FROM pg_get_wal_block_info(:'wal_lsn2', :'wal_lsn1'); -- NULL
-- ===================================================================
-- Tests for all function executions
-- ===================================================================
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_record_info(:'wal_lsn1');
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_records_info(:'wal_lsn1', :'wal_lsn2');
-SELECT COUNT(*) >= 0 AS ok FROM pg_get_wal_record_info(:'wal_lsn1');
-
-SELECT COUNT(*) >= 0 AS ok FROM pg_get_wal_records_info(:'wal_lsn1', :'wal_lsn2');
-
-SELECT COUNT(*) >= 0 AS ok FROM pg_get_wal_records_info_till_end_of_wal(:'wal_lsn1');
+-- Get info till end of WAL
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_records_info(:'wal_lsn1');
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_records_info(:'wal_lsn1', '0/0');
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_records_info(:'wal_lsn1', NULL);
-SELECT COUNT(*) >= 0 AS ok FROM pg_get_wal_stats(:'wal_lsn1', :'wal_lsn2');
-
-SELECT COUNT(*) >= 0 AS ok FROM pg_get_wal_stats_till_end_of_wal(:'wal_lsn1');
+-- Get stats till end of WAL
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_stats(:'wal_lsn1');
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_stats(:'wal_lsn1', '0/0');
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_stats(:'wal_lsn1', NULL);
-- ===================================================================
-- Test for filtering out WAL records of a particular table
-- ===================================================================
-
SELECT oid AS sample_tbl_oid FROM pg_class WHERE relname = 'sample_tbl' \gset
-
SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_records_info(:'wal_lsn1', :'wal_lsn2')
WHERE block_ref LIKE concat('%', :'sample_tbl_oid', '%') AND resource_manager = 'Heap';
@@ -48,14 +55,12 @@ SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_records_info(:'wal_lsn1', :'wal_lsn2'
-- Test for filtering out WAL records based on resource_manager and
-- record_type
-- ===================================================================
-
SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_records_info(:'wal_lsn1', :'wal_lsn2')
WHERE resource_manager = 'Heap' AND record_type = 'INSERT';
-- ===================================================================
-- Tests to get block information from WAL record
-- ===================================================================
-
-- Update table to generate some block data
SELECT pg_current_wal_lsn() AS wal_lsn3 \gset
UPDATE sample_tbl SET col1 = col1 + 1 WHERE col1 = 1;
@@ -63,6 +68,9 @@ SELECT pg_current_wal_lsn() AS wal_lsn4 \gset
-- Check if we get block data from WAL record.
SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_block_info(:'wal_lsn3', :'wal_lsn4')
WHERE relfilenode = :'sample_tbl_oid' AND blockdata IS NOT NULL;
+-- Check till end of WAL if we get block data from WAL record.
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_block_info(:'wal_lsn3')
+ WHERE relfilenode = :'sample_tbl_oid';
-- Force full-page image on the next update.
SELECT pg_current_wal_lsn() AS wal_lsn5 \gset
@@ -72,6 +80,9 @@ SELECT pg_current_wal_lsn() AS wal_lsn6 \gset
-- Check if we get FPI from WAL record.
SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_block_info(:'wal_lsn5', :'wal_lsn6')
WHERE relfilenode = :'sample_tbl_oid' AND fpi IS NOT NULL;
+-- Check till end of WAL if we get FPI from WAL record.
+SELECT COUNT(*) >= 1 AS ok FROM pg_get_wal_block_info(:'wal_lsn5')
+ WHERE relfilenode = :'sample_tbl_oid';
-- ===================================================================
-- Tests for permissions
@@ -80,29 +91,22 @@ CREATE ROLE regress_pg_walinspect;
SELECT has_function_privilege('regress_pg_walinspect',
'pg_get_wal_record_info(pg_lsn)', 'EXECUTE'); -- no
-
SELECT has_function_privilege('regress_pg_walinspect',
'pg_get_wal_records_info(pg_lsn, pg_lsn) ', 'EXECUTE'); -- no
-
SELECT has_function_privilege('regress_pg_walinspect',
'pg_get_wal_stats(pg_lsn, pg_lsn, boolean) ', 'EXECUTE'); -- no
-
SELECT has_function_privilege('regress_pg_walinspect',
'pg_get_wal_block_info(pg_lsn, pg_lsn) ', 'EXECUTE'); -- no
-- Functions accessible by users with role pg_read_server_files
-
GRANT pg_read_server_files TO regress_pg_walinspect;
SELECT has_function_privilege('regress_pg_walinspect',
'pg_get_wal_record_info(pg_lsn)', 'EXECUTE'); -- yes
-
SELECT has_function_privilege('regress_pg_walinspect',
'pg_get_wal_records_info(pg_lsn, pg_lsn) ', 'EXECUTE'); -- yes
-
SELECT has_function_privilege('regress_pg_walinspect',
'pg_get_wal_stats(pg_lsn, pg_lsn, boolean) ', 'EXECUTE'); -- yes
-
SELECT has_function_privilege('regress_pg_walinspect',
'pg_get_wal_block_info(pg_lsn, pg_lsn) ', 'EXECUTE'); -- yes
@@ -111,46 +115,34 @@ REVOKE pg_read_server_files FROM regress_pg_walinspect;
-- Superuser can grant execute to other users
GRANT EXECUTE ON FUNCTION pg_get_wal_record_info(pg_lsn)
TO regress_pg_walinspect;
-
GRANT EXECUTE ON FUNCTION pg_get_wal_records_info(pg_lsn, pg_lsn)
TO regress_pg_walinspect;
-
GRANT EXECUTE ON FUNCTION pg_get_wal_stats(pg_lsn, pg_lsn, boolean)
TO regress_pg_walinspect;
-
GRANT EXECUTE ON FUNCTION pg_get_wal_block_info(pg_lsn, pg_lsn)
TO regress_pg_walinspect;
SELECT has_function_privilege('regress_pg_walinspect',
'pg_get_wal_record_info(pg_lsn)', 'EXECUTE'); -- yes
-
SELECT has_function_privilege('regress_pg_walinspect',
'pg_get_wal_records_info(pg_lsn, pg_lsn) ', 'EXECUTE'); -- yes
-
SELECT has_function_privilege('regress_pg_walinspect',
'pg_get_wal_stats(pg_lsn, pg_lsn, boolean) ', 'EXECUTE'); -- yes
-
SELECT has_function_privilege('regress_pg_walinspect',
'pg_get_wal_block_info(pg_lsn, pg_lsn) ', 'EXECUTE'); -- yes
REVOKE EXECUTE ON FUNCTION pg_get_wal_record_info(pg_lsn)
FROM regress_pg_walinspect;
-
REVOKE EXECUTE ON FUNCTION pg_get_wal_records_info(pg_lsn, pg_lsn)
FROM regress_pg_walinspect;
-
REVOKE EXECUTE ON FUNCTION pg_get_wal_stats(pg_lsn, pg_lsn, boolean)
FROM regress_pg_walinspect;
-
REVOKE EXECUTE ON FUNCTION pg_get_wal_block_info(pg_lsn, pg_lsn)
FROM regress_pg_walinspect;
-- ===================================================================
-- Clean up
-- ===================================================================
-
DROP ROLE regress_pg_walinspect;
-
SELECT pg_drop_replication_slot('regress_pg_walinspect_slot');
-
DROP TABLE sample_tbl;
diff --git a/doc/src/sgml/pgwalinspect.sgml b/doc/src/sgml/pgwalinspect.sgml
index 3b19863dce..4ecbd32ba1 100644
--- a/doc/src/sgml/pgwalinspect.sgml
+++ b/doc/src/sgml/pgwalinspect.sgml
@@ -61,6 +61,7 @@
Gets WAL record information of a given LSN. If the given LSN isn't
at the start of a WAL record, it gives the information of the next
available valid WAL record; or an error if no such record is found.
+ If given LSN is not yet available, the function will raise an error.
For example, usage of the function is as
follows:
<screen>
@@ -85,7 +86,7 @@ block_ref | blkref #0: rel 1663/5/60221 fork main blk 2
<varlistentry id="pgwalinspect-funcs-pg-get-wal-records-info">
<term>
<function>
- pg_get_wal_records_info(start_lsn pg_lsn, end_lsn pg_lsn)
+ pg_get_wal_records_info(start_lsn pg_lsn, end_lsn pg_lsn DEFAULT NULL)
returns setof record
</function>
</term>
@@ -95,8 +96,9 @@ block_ref | blkref #0: rel 1663/5/60221 fork main blk 2
Gets information of all the valid WAL records between
<replaceable>start_lsn</replaceable> and <replaceable>end_lsn</replaceable>.
Returns one row per WAL record. If <replaceable>start_lsn</replaceable>
- or <replaceable>end_lsn</replaceable> are not yet available, the
- function will raise an error. For example:
+ is not yet available, it will raise an error. If <replaceable>end_lsn</replaceable>
+ isn't specified, it returns information till the end of WAL. For example,
+ usage of the function is as follows:
<screen>
postgres=# SELECT * FROM pg_get_wal_records_info('0/1E913618', '0/1E913740') LIMIT 1;
-[ RECORD 1 ]----+--------------------------------------------------------------
@@ -116,27 +118,10 @@ block_ref |
</listitem>
</varlistentry>
- <varlistentry id="pgwalinspect-funcs-pg-get-wal-records-info-till-end-of-wal">
- <term>
- <function>
- pg_get_wal_records_info_till_end_of_wal(start_lsn pg_lsn)
- returns setof record
- </function>
- </term>
-
- <listitem>
- <para>
- This function is the same as <function>pg_get_wal_records_info()</function>,
- except that it gets information of all the valid WAL records from
- <replaceable>start_lsn</replaceable> till the end of WAL.
- </para>
- </listitem>
- </varlistentry>
-
<varlistentry id="pgwalinspect-funcs-pg-get-wal-stats">
<term>
<function>
- pg_get_wal_stats(start_lsn pg_lsn, end_lsn pg_lsn, per_record boolean DEFAULT false)
+ pg_get_wal_stats(start_lsn pg_lsn, end_lsn pg_lsn DEFAULT NULL, per_record boolean DEFAULT false)
returns setof record
</function>
</term>
@@ -149,9 +134,10 @@ block_ref |
<replaceable>resource_manager</replaceable> type. When
<replaceable>per_record</replaceable> is set to <literal>true</literal>,
it returns one row per <replaceable>record_type</replaceable>.
- If <replaceable>start_lsn</replaceable>
- or <replaceable>end_lsn</replaceable> are not yet available, the
- function will raise an error. For example:
+ If <replaceable>start_lsn</replaceable> is not yet available, it will
+ raise an error. If <replaceable>end_lsn</replaceable> isn't specified, it
+ returns information till the end of WAL. For example, usage of the
+ function is as follows:
<screen>
postgres=# SELECT * FROM pg_get_wal_stats('0/1E847D00', '0/1E84F500')
WHERE count > 0 LIMIT 1 AND
@@ -171,23 +157,6 @@ combined_size_percentage | 2.8634072910530795
</listitem>
</varlistentry>
- <varlistentry id="pgwalinspect-funcs-pg-get-wal-stats-till-end-of-wal">
- <term>
- <function>
- pg_get_wal_stats_till_end_of_wal(start_lsn pg_lsn, per_record boolean DEFAULT false)
- returns setof record
- </function>
- </term>
-
- <listitem>
- <para>
- This function is the same as <function>pg_get_wal_stats()</function>,
- except that it gets statistics of all the valid WAL records from
- <replaceable>start_lsn</replaceable> till end of WAL.
- </para>
- </listitem>
- </varlistentry>
-
<varlistentry>
<term>
<function>pg_get_wal_block_info(start_lsn pg_lsn, end_lsn pg_lsn) returns setof record</function>
@@ -202,9 +171,10 @@ combined_size_percentage | 2.8634072910530795
and their information associated with all the valid WAL records between
<replaceable>start_lsn</replaceable> and
<replaceable>end_lsn</replaceable>. Returns one row per block registered
- in a WAL record. If <replaceable>start_lsn</replaceable> or
- <replaceable>end_lsn</replaceable> are not yet available, the function
- will raise an error. For example:
+ in a WAL record. If <replaceable>start_lsn</replaceable> is not yet
+ available, it will raise an error. If <replaceable>end_lsn</replaceable>
+ isn't specified, it returns information till the end of WAL. For example,
+ usage of the function is as follows:
<screen>
postgres=# SELECT lsn, blockid, reltablespace, reldatabase, relfilenode,
relblocknumber, forkname,
@@ -227,8 +197,21 @@ fpiinfo | {HAS_HOLE,APPLY}
</para>
</listitem>
</varlistentry>
-
</variablelist>
+
+ <note>
+ <para>
+ Note that <function>pg_get_wal_records_info_till_end_of_wal</function> and
+ <function>pg_get_wal_stats_till_end_of_wal</function> functions have been
+ removed in the <filename>pg_walinspect</filename> version
+ <literal>1.1</literal>. The same functionality can be achieved with
+ <function>pg_get_wal_records_info</function> and
+ <function>pg_get_wal_stats</function> functions. However,
+ <function>till_end_of_wal</function> functions will still work if the
+ extension is installed explicitly with version <literal>1.0</literal>.
+ </para>
+ </note>
+
</sect2>
<sect2 id="pgwalinspect-author">
--
2.34.1