0002-Address-review-comments-20250919.patch
text/x-patch
Filename: 0002-Address-review-comments-20250919.patch
Type: text/x-patch
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch 0002
Subject: Address review comments
| File | + | − |
|---|---|---|
| contrib/test_decoding/expected/stats.out | 29 | 29 |
| contrib/test_decoding/sql/stats.sql | 9 | 8 |
| contrib/test_decoding/t/001_repl_stats.pl | 3 | 3 |
| doc/src/sgml/logicaldecoding.sgml | 3 | 3 |
| doc/src/sgml/monitoring.sgml | 9 | 9 |
| src/backend/catalog/system_views.sql | 2 | 2 |
| src/backend/utils/adt/pgstatfuncs.c | 2 | 2 |
| src/include/catalog/pg_proc.dat | 1 | 1 |
| src/test/regress/expected/rules.out | 3 | 3 |
From e2500f1c610d2f73b53e353b98856a90db4cc452 Mon Sep 17 00:00:00 2001
From: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Date: Thu, 18 Sep 2025 15:55:01 +0530
Subject: [PATCH 2/2] Address review comments
Among others rename total_txns and total_bytes to total_wal_txns and
total_wal_bytes respectively.
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Shveta Malik <shveta.malik@gmail.com>
---
contrib/test_decoding/expected/stats.out | 58 +++++++++++------------
contrib/test_decoding/sql/stats.sql | 17 +++----
contrib/test_decoding/t/001_repl_stats.pl | 6 +--
doc/src/sgml/logicaldecoding.sgml | 6 +--
doc/src/sgml/monitoring.sgml | 18 +++----
src/backend/catalog/system_views.sql | 4 +-
src/backend/utils/adt/pgstatfuncs.c | 4 +-
src/include/catalog/pg_proc.dat | 2 +-
src/test/regress/expected/rules.out | 6 +--
9 files changed, 61 insertions(+), 60 deletions(-)
diff --git a/contrib/test_decoding/expected/stats.out b/contrib/test_decoding/expected/stats.out
index d19fe6a1c61..4834b3460a6 100644
--- a/contrib/test_decoding/expected/stats.out
+++ b/contrib/test_decoding/expected/stats.out
@@ -37,17 +37,17 @@ SELECT pg_stat_force_next_flush();
(1 row)
--- total_txns may vary based on the background activity but sent_txns should
--- always be 1 since the background transactions are always skipped. Filtered
--- bytes would be set only when there's a change that was passed to the plugin
--- but was filtered out. Depending upon the background transactions, filtered
--- bytes may or may not be zero.
-SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes, plugin_sent_txns, plugin_sent_bytes > 0 AS sent_bytes, plugin_filtered_bytes >= 0 AS filtered_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
- slot_name | spill_txns | spill_count | total_txns | total_bytes | plugin_sent_txns | sent_bytes | filtered_bytes
-------------------------+------------+-------------+------------+-------------+------------------+------------+----------------
- regression_slot_stats1 | t | t | t | t | 1 | t | t
- regression_slot_stats2 | t | t | t | t | 1 | t | t
- regression_slot_stats3 | t | t | t | t | 1 | t | t
+-- total_wal_txns may vary based on the background activity but plugin_sent_txns
+-- should always be 1 since the background transactions are always skipped.
+-- Filtered bytes would be set only when there's a change that was passed to the
+-- plugin but was filtered out. Depending upon the background transactions,
+-- filtered bytes may or may not be zero.
+SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_wal_txns > 0 AS total_wal_txns, total_wal_bytes > 0 AS total_wal_bytes, plugin_sent_txns, plugin_sent_bytes > 0 AS sent_bytes, plugin_filtered_bytes >= 0 AS filtered_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
+ slot_name | spill_txns | spill_count | total_wal_txns | total_wal_bytes | plugin_sent_txns | sent_bytes | filtered_bytes
+------------------------+------------+-------------+----------------+-----------------+------------------+------------+----------------
+ regression_slot_stats1 | t | t | t | t | 1 | t | t
+ regression_slot_stats2 | t | t | t | t | 1 | t | t
+ regression_slot_stats3 | t | t | t | t | 1 | t | t
(3 rows)
RESET logical_decoding_work_mem;
@@ -58,12 +58,12 @@ SELECT pg_stat_reset_replication_slot('regression_slot_stats1');
(1 row)
-SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes, plugin_sent_txns, plugin_sent_bytes > 0 AS sent_bytes, plugin_filtered_bytes >= 0 AS filtered_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
- slot_name | spill_txns | spill_count | total_txns | total_bytes | plugin_sent_txns | sent_bytes | filtered_bytes
-------------------------+------------+-------------+------------+-------------+------------------+------------+----------------
- regression_slot_stats1 | t | t | f | f | | |
- regression_slot_stats2 | t | t | t | t | 1 | t | t
- regression_slot_stats3 | t | t | t | t | 1 | t | t
+SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_wal_txns > 0 AS total_wal_txns, total_wal_bytes > 0 AS total_wal_bytes, plugin_sent_txns, plugin_sent_bytes > 0 AS sent_bytes, plugin_filtered_bytes >= 0 AS filtered_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
+ slot_name | spill_txns | spill_count | total_wal_txns | total_wal_bytes | plugin_sent_txns | sent_bytes | filtered_bytes
+------------------------+------------+-------------+----------------+-----------------+------------------+------------+----------------
+ regression_slot_stats1 | t | t | f | f | | |
+ regression_slot_stats2 | t | t | t | t | 1 | t | t
+ regression_slot_stats3 | t | t | t | t | 1 | t | t
(3 rows)
-- reset stats for all slots
@@ -73,27 +73,27 @@ SELECT pg_stat_reset_replication_slot(NULL);
(1 row)
-SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes, plugin_sent_txns, plugin_sent_bytes, plugin_filtered_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
- slot_name | spill_txns | spill_count | total_txns | total_bytes | plugin_sent_txns | plugin_sent_bytes | plugin_filtered_bytes
-------------------------+------------+-------------+------------+-------------+------------------+-------------------+-----------------------
- regression_slot_stats1 | t | t | f | f | | |
- regression_slot_stats2 | t | t | f | f | | |
- regression_slot_stats3 | t | t | f | f | | |
+SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_wal_txns > 0 AS total_wal_txns, total_wal_bytes > 0 AS total_wal_bytes, plugin_sent_txns, plugin_sent_bytes, plugin_filtered_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
+ slot_name | spill_txns | spill_count | total_wal_txns | total_wal_bytes | plugin_sent_txns | plugin_sent_bytes | plugin_filtered_bytes
+------------------------+------------+-------------+----------------+-----------------+------------------+-------------------+-----------------------
+ regression_slot_stats1 | t | t | f | f | | |
+ regression_slot_stats2 | t | t | f | f | | |
+ regression_slot_stats3 | t | t | f | f | | |
(3 rows)
-- verify accessing/resetting stats for non-existent slot does something reasonable
SELECT * FROM pg_stat_get_replication_slot('do-not-exist');
- slot_name | spill_txns | spill_count | spill_bytes | stream_txns | stream_count | stream_bytes | total_txns | total_bytes | plugin_filtered_bytes | plugin_sent_txns | plugin_sent_bytes | stats_reset
---------------+------------+-------------+-------------+-------------+--------------+--------------+------------+-------------+-----------------------+------------------+-------------------+-------------
- do-not-exist | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | |
+ slot_name | spill_txns | spill_count | spill_bytes | stream_txns | stream_count | stream_bytes | total_wal_txns | total_wal_bytes | plugin_filtered_bytes | plugin_sent_txns | plugin_sent_bytes | stats_reset
+--------------+------------+-------------+-------------+-------------+--------------+--------------+----------------+-----------------+-----------------------+------------------+-------------------+-------------
+ do-not-exist | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | |
(1 row)
SELECT pg_stat_reset_replication_slot('do-not-exist');
ERROR: replication slot "do-not-exist" does not exist
SELECT * FROM pg_stat_get_replication_slot('do-not-exist');
- slot_name | spill_txns | spill_count | spill_bytes | stream_txns | stream_count | stream_bytes | total_txns | total_bytes | plugin_filtered_bytes | plugin_sent_txns | plugin_sent_bytes | stats_reset
---------------+------------+-------------+-------------+-------------+--------------+--------------+------------+-------------+-----------------------+------------------+-------------------+-------------
- do-not-exist | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | |
+ slot_name | spill_txns | spill_count | spill_bytes | stream_txns | stream_count | stream_bytes | total_wal_txns | total_wal_bytes | plugin_filtered_bytes | plugin_sent_txns | plugin_sent_bytes | stats_reset
+--------------+------------+-------------+-------------+-------------+--------------+--------------+----------------+-----------------+-----------------------+------------------+-------------------+-------------
+ do-not-exist | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | | |
(1 row)
-- spilling the xact
diff --git a/contrib/test_decoding/sql/stats.sql b/contrib/test_decoding/sql/stats.sql
index 1077cea5855..99f513902d3 100644
--- a/contrib/test_decoding/sql/stats.sql
+++ b/contrib/test_decoding/sql/stats.sql
@@ -15,21 +15,22 @@ SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats1', NULL,
SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats2', NULL, NULL, 'skip-empty-xacts', '1');
SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats3', NULL, NULL, 'skip-empty-xacts', '1');
SELECT pg_stat_force_next_flush();
--- total_txns may vary based on the background activity but sent_txns should
--- always be 1 since the background transactions are always skipped. Filtered
--- bytes would be set only when there's a change that was passed to the plugin
--- but was filtered out. Depending upon the background transactions, filtered
--- bytes may or may not be zero.
-SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes, plugin_sent_txns, plugin_sent_bytes > 0 AS sent_bytes, plugin_filtered_bytes >= 0 AS filtered_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
+
+-- total_wal_txns may vary based on the background activity but plugin_sent_txns
+-- should always be 1 since the background transactions are always skipped.
+-- Filtered bytes would be set only when there's a change that was passed to the
+-- plugin but was filtered out. Depending upon the background transactions,
+-- filtered bytes may or may not be zero.
+SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_wal_txns > 0 AS total_wal_txns, total_wal_bytes > 0 AS total_wal_bytes, plugin_sent_txns, plugin_sent_bytes > 0 AS sent_bytes, plugin_filtered_bytes >= 0 AS filtered_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
RESET logical_decoding_work_mem;
-- reset stats for one slot, others should be unaffected
SELECT pg_stat_reset_replication_slot('regression_slot_stats1');
-SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes, plugin_sent_txns, plugin_sent_bytes > 0 AS sent_bytes, plugin_filtered_bytes >= 0 AS filtered_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
+SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_wal_txns > 0 AS total_wal_txns, total_wal_bytes > 0 AS total_wal_bytes, plugin_sent_txns, plugin_sent_bytes > 0 AS sent_bytes, plugin_filtered_bytes >= 0 AS filtered_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
-- reset stats for all slots
SELECT pg_stat_reset_replication_slot(NULL);
-SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes, plugin_sent_txns, plugin_sent_bytes, plugin_filtered_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
+SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_wal_txns > 0 AS total_wal_txns, total_wal_bytes > 0 AS total_wal_bytes, plugin_sent_txns, plugin_sent_bytes, plugin_filtered_bytes FROM pg_stat_replication_slots ORDER BY slot_name;
-- verify accessing/resetting stats for non-existent slot does something reasonable
SELECT * FROM pg_stat_get_replication_slot('do-not-exist');
diff --git a/contrib/test_decoding/t/001_repl_stats.pl b/contrib/test_decoding/t/001_repl_stats.pl
index 76dd86fc420..756fc691ed6 100644
--- a/contrib/test_decoding/t/001_repl_stats.pl
+++ b/contrib/test_decoding/t/001_repl_stats.pl
@@ -28,8 +28,8 @@ sub test_slot_stats
# guaranteed that such transactions would be present.
my $result = $node->safe_psql(
'postgres', qq[
- SELECT slot_name, total_txns > 0 AS total_txn,
- total_bytes > 0 AS total_bytes,
+ SELECT slot_name, total_wal_txns > 0 AS total_txn,
+ total_wal_bytes > 0 AS total_bytes,
plugin_sent_txns > 0 AS sent_txn,
plugin_sent_bytes > 0 AS sent_bytes,
plugin_filtered_bytes >= 0 AS filtered_bytes
@@ -71,7 +71,7 @@ $node->poll_query_until(
'postgres', qq[
SELECT count(slot_name) >= 4 FROM pg_stat_replication_slots
WHERE slot_name ~ 'regression_slot'
- AND total_txns > 0 AND total_bytes > 0;
+ AND total_wal_txns > 0 AND total_wal_bytes > 0;
]) or die "Timed out while waiting for statistics to be updated";
# Test to drop one of the replication slot and verify replication statistics data is
diff --git a/doc/src/sgml/logicaldecoding.sgml b/doc/src/sgml/logicaldecoding.sgml
index 8ac10cda90c..3952f68e806 100644
--- a/doc/src/sgml/logicaldecoding.sgml
+++ b/doc/src/sgml/logicaldecoding.sgml
@@ -956,11 +956,11 @@ typedef struct OutputPluginStats
} OutputPluginStats;
</programlisting>
<literal>sentTxns</literal> is the number of transactions sent downstream
- by the output plugin. <literal>sentBytes</literal> is the amount of data
+ by the output plugin. <literal>sentBytes</literal> is the amount of data, in bytes,
sent downstream by the output plugin.
- <function>OutputPluginWrite</function> is expected to update this counter
+ <function>OutputPluginWrite</function> will update this counter
if <literal>ctx->stats</literal> is initialized by the output plugin.
- <literal>filteredBytes</literal> is the size of changes in bytes that are
+ <literal>filteredBytes</literal> is the size of changes, in bytes, that are
filtered out by the output plugin. Function
<literal>ReorderBufferChangeSize</literal> may be used to find the size of
filtered <literal>ReorderBufferChange</literal>.
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index e121f55c9c2..fbe03ffd670 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -1633,19 +1633,19 @@ description | Waiting for a newly initialized WAL file to reach durable storage
<row>
<entry role="catalog_table_entry"><para role="column_definition">
- <structfield>total_txns</structfield> <type>bigint</type>
+ <structfield>total_wal_txns</structfield> <type>bigint</type>
</para>
<para>
- Number of decoded transactions sent to the decoding output plugin for
- this slot. This counts top-level transactions only, and is not incremented
- for subtransactions. Note that this includes the transactions that are
- streamed and/or spilled.
+ Number of decoded transactions from WAL sent to the decoding output
+ plugin for this slot. This counts top-level transactions only, and is
+ not incremented for subtransactions. Note that this includes the
+ transactions that are streamed and/or spilled.
</para></entry>
</row>
<row>
<entry role="catalog_table_entry"><para role="column_definition">
- <structfield>total_bytes</structfield><type>bigint</type>
+ <structfield>total_wal_bytes</structfield><type>bigint</type>
</para>
<para>
Amount of transaction data decoded for sending transactions to the
@@ -1660,9 +1660,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage
<structfield>plugin_filtered_bytes</structfield> <type>bigint</type>
</para>
<para>
- Amount of changes, from <structfield>total_bytes</structfield>, filtered
+ Amount of changes, from <structfield>total_wal_bytes</structfield>, filtered
out by the output plugin and not sent downstream. Please note that it
- does not include the changes filtered before a change is handed over to
+ does not include the changes filtered before a change is sent to
the output plugin, e.g. the changes filtered by origin. The count is
maintained by the output plugin mentioned in
<structfield>plugin</structfield>. It is NULL when statistics is not
@@ -1680,7 +1680,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage
counts top-level transactions only, and is not incremented for
subtransactions. These transactions are subset of transctions sent to
the decoding plugin. Hence this count is expected to be lesser than or
- equal to <structfield>total_txns</structfield>. The count is maintained
+ equal to <structfield>total_wal_txns</structfield>. The count is maintained
by the output plugin mentioned in <structfield>plugin</structfield>. It
is NULL when statistics is not initialized or immediately after a reset or
when not maintained by the output plugin.
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index d38c21150b0..9e8e32b5849 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1060,8 +1060,8 @@ CREATE VIEW pg_stat_replication_slots AS
s.stream_txns,
s.stream_count,
s.stream_bytes,
- s.total_txns,
- s.total_bytes,
+ s.total_wal_txns,
+ s.total_wal_bytes,
s.plugin_filtered_bytes,
s.plugin_sent_txns,
s.plugin_sent_bytes,
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 796dacddcfb..15bafe63b24 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -2125,9 +2125,9 @@ pg_stat_get_replication_slot(PG_FUNCTION_ARGS)
INT8OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stream_bytes",
INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 8, "total_txns",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 8, "total_wal_txns",
INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 9, "total_bytes",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 9, "total_wal_bytes",
INT8OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 10, "plugin_filtered_bytes",
INT8OID, -1, 0);
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 7519941bcf3..9e4f6620214 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5689,7 +5689,7 @@
proparallel => 'r', prorettype => 'record', proargtypes => 'text',
proallargtypes => '{text,text,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,timestamptz}',
proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o}',
- proargnames => '{slot_name,slot_name,spill_txns,spill_count,spill_bytes,stream_txns,stream_count,stream_bytes,total_txns,total_bytes,plugin_filtered_bytes,plugin_sent_txns,plugin_sent_bytes,stats_reset}',
+ proargnames => '{slot_name,slot_name,spill_txns,spill_count,spill_bytes,stream_txns,stream_count,stream_bytes,total_wal_txns,total_wal_bytes,plugin_filtered_bytes,plugin_sent_txns,plugin_sent_bytes,stats_reset}',
prosrc => 'pg_stat_get_replication_slot' },
{ oid => '6230', descr => 'statistics: check if a stats object exists',
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 2a048af3569..2a401552a7a 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2139,14 +2139,14 @@ pg_stat_replication_slots| SELECT s.slot_name,
s.stream_txns,
s.stream_count,
s.stream_bytes,
- s.total_txns,
- s.total_bytes,
+ s.total_wal_txns,
+ s.total_wal_bytes,
s.plugin_filtered_bytes,
s.plugin_sent_txns,
s.plugin_sent_bytes,
s.stats_reset
FROM pg_replication_slots r,
- LATERAL pg_stat_get_replication_slot((r.slot_name)::text) s(slot_name, spill_txns, spill_count, spill_bytes, stream_txns, stream_count, stream_bytes, total_txns, total_bytes, plugin_filtered_bytes, plugin_sent_txns, plugin_sent_bytes, stats_reset)
+ LATERAL pg_stat_get_replication_slot((r.slot_name)::text) s(slot_name, spill_txns, spill_count, spill_bytes, stream_txns, stream_count, stream_bytes, total_wal_txns, total_wal_bytes, plugin_filtered_bytes, plugin_sent_txns, plugin_sent_bytes, stats_reset)
WHERE (r.datoid IS NOT NULL);
pg_stat_slru| SELECT name,
blks_zeroed,
--
2.34.1