Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5f79580

Browse files
committed
Fix memory lifetime issues of replication slot stats.
When accessing replication slot stats, introduced in 9868167, pgstat_read_statsfiles() reads the data into newly allocated memory. Unfortunately the current memory context at that point is the callers, leading to leaks and use-after-free dangers. The fix is trivial, explicitly use pgStatLocalContext. There's some potential for further improvements, but that's outside of the scope of this bugfix. No backpatch necessary, feature is only in HEAD. Author: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/20210317230447.c7uc4g3vbs4wi32i@alap3.anarazel.de
1 parent 7094564 commit 5f79580

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

contrib/test_decoding/expected/stats.out

+16
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,22 @@ SELECT slot_name, spill_txns > 0 AS spill_txns, spill_count > 0 AS spill_count F
101101
regression_slot | t | t
102102
(1 row)
103103

104+
-- Ensure stats can be repeatedly accessed using the same stats snapshot. See
105+
-- https://postgr.es/m/20210317230447.c7uc4g3vbs4wi32i%40alap3.anarazel.de
106+
BEGIN;
107+
SELECT slot_name FROM pg_stat_replication_slots;
108+
slot_name
109+
-----------------
110+
regression_slot
111+
(1 row)
112+
113+
SELECT slot_name FROM pg_stat_replication_slots;
114+
slot_name
115+
-----------------
116+
regression_slot
117+
(1 row)
118+
119+
COMMIT;
104120
DROP FUNCTION wait_for_decode_stats(bool);
105121
DROP TABLE stats_test;
106122
SELECT pg_drop_replication_slot('regression_slot');

contrib/test_decoding/sql/stats.sql

+7
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ SELECT count(*) FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL,
5959
SELECT wait_for_decode_stats(false);
6060
SELECT slot_name, spill_txns > 0 AS spill_txns, spill_count > 0 AS spill_count FROM pg_stat_replication_slots;
6161

62+
-- Ensure stats can be repeatedly accessed using the same stats snapshot. See
63+
-- https://postgr.es/m/20210317230447.c7uc4g3vbs4wi32i%40alap3.anarazel.de
64+
BEGIN;
65+
SELECT slot_name FROM pg_stat_replication_slots;
66+
SELECT slot_name FROM pg_stat_replication_slots;
67+
COMMIT;
68+
6269
DROP FUNCTION wait_for_decode_stats(bool);
6370
DROP TABLE stats_test;
6471
SELECT pg_drop_replication_slot('regression_slot');

src/backend/postmaster/pgstat.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -5568,7 +5568,9 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep)
55685568
HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
55695569

55705570
/* Allocate the space for replication slot statistics */
5571-
replSlotStats = palloc0(max_replication_slots * sizeof(PgStat_ReplSlotStats));
5571+
replSlotStats = MemoryContextAllocZero(pgStatLocalContext,
5572+
max_replication_slots
5573+
* sizeof(PgStat_ReplSlotStats));
55725574
nReplSlotStats = 0;
55735575

55745576
/*
@@ -6323,6 +6325,8 @@ pgstat_clear_snapshot(void)
63236325
pgStatDBHash = NULL;
63246326
localBackendStatusTable = NULL;
63256327
localNumBackends = 0;
6328+
replSlotStats = NULL;
6329+
nReplSlotStats = 0;
63266330
}
63276331

63286332

0 commit comments

Comments
 (0)