Skip to content

Commit 7c17aac

Browse files
committed
logical decoding: fix decoding of a commit's commit time.
When adding replication origins in 5aa2350, I somehow managed to set the timestamp of decoded transactions to InvalidXLogRecptr when decoding one made without a replication origin. Fix that, and the wrong type of the new commit_time variable. This didn't trigger a regression test failure because we explicitly don't show commit timestamps in the regression tests, as they obviously are variable. Add a test that checks that a decoded commit's timestamp is within minutes of NOW() from before the commit. Reported-By: Weiping Qu Diagnosed-By: Artur Zakirov Discussion: 56D4197E.9050706@informatik.uni-kl.de, 56D42918.1010108@postgrespro.ru Backpatch: 9.5, where 5aa2350 originates.
1 parent a9d199f commit 7c17aac

File tree

4 files changed

+64
-2
lines changed

4 files changed

+64
-2
lines changed

contrib/test_decoding/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ submake-test_decoding:
3838
$(MAKE) -C $(top_builddir)/contrib/test_decoding
3939

4040
REGRESSCHECKS=ddl rewrite toast permissions decoding_in_xact decoding_into_rel \
41-
binary prepared replorigin
41+
binary prepared replorigin time
4242

4343
regresscheck: | submake-regress submake-test_decoding temp-install
4444
$(MKDIR_P) regression_output
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
SET synchronous_commit = on;
2+
CREATE TABLE test_time(data text);
3+
-- remember the current time
4+
SELECT set_config('test.time_before', NOW()::text, false) IS NOT NULL;
5+
?column?
6+
----------
7+
t
8+
(1 row)
9+
10+
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
11+
?column?
12+
----------
13+
init
14+
(1 row)
15+
16+
-- a single transaction, to get the commit time
17+
INSERT INTO test_time(data) VALUES ('');
18+
-- parse the commit time from the changeset
19+
SELECT set_config('test.time_after', regexp_replace(data, '^COMMIT \(at (.*)\)$', '\1'), false) IS NOT NULL
20+
FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-timestamp', '1')
21+
WHERE data ~ 'COMMIT' LIMIT 1;
22+
?column?
23+
----------
24+
t
25+
(1 row)
26+
27+
-- ensure commit time is sane in relation to the previous time
28+
SELECT (time_after - time_before) <= '10 minutes'::interval, time_after >= time_before
29+
FROM (SELECT current_setting('test.time_after')::timestamptz AS time_after, (SELECT current_setting('test.time_before')::timestamptz) AS time_before) AS d;
30+
?column? | ?column?
31+
----------+----------
32+
t | t
33+
(1 row)
34+
35+
SELECT pg_drop_replication_slot('regression_slot');
36+
pg_drop_replication_slot
37+
--------------------------
38+
39+
(1 row)
40+

contrib/test_decoding/sql/time.sql

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
SET synchronous_commit = on;
2+
3+
CREATE TABLE test_time(data text);
4+
5+
-- remember the current time
6+
SELECT set_config('test.time_before', NOW()::text, false) IS NOT NULL;
7+
8+
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
9+
10+
-- a single transaction, to get the commit time
11+
INSERT INTO test_time(data) VALUES ('');
12+
13+
-- parse the commit time from the changeset
14+
SELECT set_config('test.time_after', regexp_replace(data, '^COMMIT \(at (.*)\)$', '\1'), false) IS NOT NULL
15+
FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-timestamp', '1')
16+
WHERE data ~ 'COMMIT' LIMIT 1;
17+
18+
-- ensure commit time is sane in relation to the previous time
19+
SELECT (time_after - time_before) <= '10 minutes'::interval, time_after >= time_before
20+
FROM (SELECT current_setting('test.time_after')::timestamptz AS time_after, (SELECT current_setting('test.time_before')::timestamptz) AS time_before) AS d;
21+
22+
SELECT pg_drop_replication_slot('regression_slot');

src/backend/replication/logical/decode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ DecodeCommit(LogicalDecodingContext *ctx, XLogRecordBuffer *buf,
449449
xl_xact_parsed_commit *parsed, TransactionId xid)
450450
{
451451
XLogRecPtr origin_lsn = InvalidXLogRecPtr;
452-
XLogRecPtr commit_time = InvalidXLogRecPtr;
452+
TimestampTz commit_time = parsed->xact_time;
453453
XLogRecPtr origin_id = XLogRecGetOrigin(buf->record);
454454
int i;
455455

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