Skip to content

Commit 9181077

Browse files
author
Amit Kapila
committed
Fix fetching default toast value during decoding of in-progress transactions.
During logical decoding of in-progress transactions, we perform the toast table scan while fetching the default toast value for an attribute. We forgot to initialize the flag during this scan to indicate that the system table scan is in progress. We need this flag to ensure that during logical decoding we never directly access the tableam or heap APIs because we check for concurrent aborts only in systable_* APIs. Reported-by: Alexander Lakhin Author: Takeshi Ideriha, Hou Zhijie Reviewed-by: Amit Kapila, Hou Zhijie Backpatch-through: 14 Discussion: https://postgr.es/m/18641-6687273b7f15269d@postgresql.org
1 parent 3daeb53 commit 9181077

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

contrib/test_decoding/expected/stream.out

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,28 @@ SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL,
128128
5
129129
(1 row)
130130

131+
-- Test that accessing a TOAST table in streaming mode is allowed.
132+
-- Create a table with a column that uses a TOASTed default value.
133+
-- (temporarily hide query, to avoid the long CREATE TABLE stmt)
134+
\set ECHO none
135+
SET debug_logical_replication_streaming = immediate;
136+
BEGIN;
137+
INSERT INTO test_tab VALUES(1);
138+
-- Force WAL flush, so that the above changes will be streamed.
139+
SELECT 'force flush' FROM pg_switch_wal();
140+
?column?
141+
-------------
142+
force flush
143+
(1 row)
144+
145+
SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
146+
count
147+
-------
148+
3
149+
(1 row)
150+
151+
COMMIT;
152+
RESET debug_logical_replication_streaming;
131153
DROP TABLE stream_test;
132154
SELECT pg_drop_replication_slot('regression_slot');
133155
pg_drop_replication_slot

contrib/test_decoding/sql/stream.sql

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,27 @@ ROLLBACK TO s1;
5959
COMMIT;
6060
SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
6161

62+
-- Test that accessing a TOAST table in streaming mode is allowed.
63+
64+
-- Create a table with a column that uses a TOASTed default value.
65+
-- (temporarily hide query, to avoid the long CREATE TABLE stmt)
66+
\set ECHO none
67+
SELECT 'CREATE TABLE test_tab (a text DEFAULT ''' || string_agg('toast value', '') || ''');' FROM generate_series(1, 4000)
68+
\gexec
69+
\set ECHO all
70+
71+
SET debug_logical_replication_streaming = immediate;
72+
73+
BEGIN;
74+
INSERT INTO test_tab VALUES(1);
75+
76+
-- Force WAL flush, so that the above changes will be streamed.
77+
SELECT 'force flush' FROM pg_switch_wal();
78+
79+
SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
80+
COMMIT;
81+
82+
RESET debug_logical_replication_streaming;
83+
6284
DROP TABLE stream_test;
6385
SELECT pg_drop_replication_slot('regression_slot');

src/backend/access/index/genam.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,14 @@ systable_beginscan_ordered(Relation heapRelation,
702702
index_rescan(sysscan->iscan, key, nkeys, NULL, 0);
703703
sysscan->scan = NULL;
704704

705+
/*
706+
* If CheckXidAlive is set then set a flag to indicate that system table
707+
* scan is in-progress. See detailed comments in xact.c where these
708+
* variables are declared.
709+
*/
710+
if (TransactionIdIsValid(CheckXidAlive))
711+
bsysscan = true;
712+
705713
return sysscan;
706714
}
707715

@@ -746,6 +754,14 @@ systable_endscan_ordered(SysScanDesc sysscan)
746754
index_endscan(sysscan->iscan);
747755
if (sysscan->snapshot)
748756
UnregisterSnapshot(sysscan->snapshot);
757+
758+
/*
759+
* Reset the bsysscan flag at the end of the systable scan. See detailed
760+
* comments in xact.c where these variables are declared.
761+
*/
762+
if (TransactionIdIsValid(CheckXidAlive))
763+
bsysscan = false;
764+
749765
pfree(sysscan);
750766
}
751767

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy