Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd9bb719

Browse files
committed
Avoid assertion failure with LISTEN in a serializable transaction.
If LISTEN is the only action in a serializable-mode transaction,and the session was not previously listening, and the notify queueis not empty, predicate.c reported an assertion failure. Thathappened because we'd acquire the transaction's initial snapshotduring PreCommit_Notify, which was called *after* predicate.cexpects any such snapshot to have been established.To fix, just swap the order of the PreCommit_Notify andPreCommit_CheckForSerializationFailure calls during CommitTransaction.This will imply holding the notify-insertion lock slightly longer,but the difference could only be meaningful in serializable mode,which is an expensive option anyway.It appears that this is just an assertion failure, with noconsequences in non-assert builds. A snapshot used only to scanthe notify queue could not have been involved in any serializationconflicts, so there would be nothing forPreCommit_CheckForSerializationFailure to do except assign it aprepareSeqNo and set the SXACT_FLAG_PREPARED flag. And given noconflicts, neither of those omissions affect the behavior ofReleasePredicateLocks. This admittedly once-over-lightly analysisis backed up by the lack of field reports of trouble.Per report from Mark Dilger. The bug is old, so back-patch to allsupported branches; but the new test case only goes back to 9.6,for lack of adequate isolationtester infrastructure before that.Discussion:https://postgr.es/m/3ac7f397-4d5f-be8e-f354-440020675694@gmail.comDiscussion:https://postgr.es/m/13881.1574557302@sss.pgh.pa.us
1 parent1451287 commitd9bb719

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

‎src/backend/access/transam/xact.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,20 +2038,21 @@ CommitTransaction(void)
20382038
/* close large objects before lower-level cleanup */
20392039
AtEOXact_LargeObject(true);
20402040

2041+
/*
2042+
* Insert notifications sent by NOTIFY commands into the queue. This
2043+
* should be late in the pre-commit sequence to minimize time spent
2044+
* holding the notify-insertion lock. However, this could result in
2045+
* creating a snapshot, so we must do it before serializable cleanup.
2046+
*/
2047+
PreCommit_Notify();
2048+
20412049
/*
20422050
* Mark serializable transaction as complete for predicate locking
20432051
* purposes. This should be done as late as we can put it and still allow
20442052
* errors to be raised for failure patterns found at commit.
20452053
*/
20462054
PreCommit_CheckForSerializationFailure();
20472055

2048-
/*
2049-
* Insert notifications sent by NOTIFY commands into the queue. This
2050-
* should be late in the pre-commit sequence to minimize time spent
2051-
* holding the notify-insertion lock.
2052-
*/
2053-
PreCommit_Notify();
2054-
20552056
/* Prevent cancel/die interrupt while cleaning up */
20562057
HOLD_INTERRUPTS();
20572058

@@ -2266,15 +2267,15 @@ PrepareTransaction(void)
22662267
/* close large objects before lower-level cleanup */
22672268
AtEOXact_LargeObject(true);
22682269

2270+
/* NOTIFY requires no work at this point */
2271+
22692272
/*
22702273
* Mark serializable transaction as complete for predicate locking
22712274
* purposes. This should be done as late as we can put it and still allow
22722275
* errors to be raised for failure patterns found at commit.
22732276
*/
22742277
PreCommit_CheckForSerializationFailure();
22752278

2276-
/* NOTIFY will be handled below */
2277-
22782279
/*
22792280
* Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
22802281
* this transaction. Having the prepared xact hold locks on another

‎src/test/isolation/expected/async-notify.out

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Parsed test spec with2 sessions
1+
Parsed test spec with3 sessions
22

33
starting permutation: listenc notify1 notify2 notify3 notifyf
44
step listenc: LISTEN c1; LISTEN c2;
@@ -85,6 +85,17 @@ listener: NOTIFY "c1" with payload "" from notifier
8585
listener: NOTIFY "c2" with payload "payload" from notifier
8686
listener: NOTIFY "c2" with payload "" from notifier
8787

88+
starting permutation: l2listen l2begin notify1 lbegins llisten lcommit l2commit l2stop
89+
step l2listen: LISTEN c1;
90+
step l2begin: BEGIN;
91+
step notify1: NOTIFY c1;
92+
step lbegins: BEGIN ISOLATION LEVEL SERIALIZABLE;
93+
step llisten: LISTEN c1; LISTEN c2;
94+
step lcommit: COMMIT;
95+
step l2commit: COMMIT;
96+
listener2: NOTIFY "c1" with payload "" from notifier
97+
step l2stop: UNLISTEN *;
98+
8899
starting permutation: llisten lbegin usage bignotify usage
89100
step llisten: LISTEN c1; LISTEN c2;
90101
step lbegin: BEGIN;

‎src/test/isolation/specs/async-notify.spec

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,18 @@ session "listener"
4141
step"llisten"{LISTENc1;LISTENc2;}
4242
step"lcheck"{SELECT1ASx;}
4343
step"lbegin"{ BEGIN;}
44+
step"lbegins"{ BEGINISOLATIONLEVELSERIALIZABLE;}
45+
step"lcommit"{COMMIT;}
4446
teardown{UNLISTEN *;}
4547

48+
# In some tests we need a second listener, just to block the queue.
49+
50+
session"listener2"
51+
step"l2listen"{LISTENc1;}
52+
step"l2begin"{ BEGIN;}
53+
step"l2commit"{COMMIT;}
54+
step"l2stop"{UNLISTEN *;}
55+
4656

4757
# Trivial cases.
4858
permutation"listenc""notify1""notify2""notify3""notifyf"
@@ -59,6 +69,10 @@ permutation "llisten" "notify1" "notify2" "notify3" "notifyf" "lcheck"
5969
# Again, with local delivery too.
6070
permutation"listenc""llisten""notify1""notify2""notify3""notifyf""lcheck"
6171

72+
# Check for bug when initial listen is only action in a serializable xact,
73+
# and notify queue is not empty
74+
permutation"l2listen""l2begin""notify1""lbegins""llisten""lcommit""l2commit""l2stop"
75+
6276
# Verify that pg_notification_queue_usage correctly reports a non-zero result,
6377
# after submitting notifications while another connection is listening for
6478
# those notifications and waiting inside an active transaction. We have to

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp