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

Commit7aea105

Browse files
committed
Avoid transaction-commit race condition while receiving a NOTIFY message.
Use TransactionIdIsInProgress, then TransactionIdDidCommit, to distinguishwhether a NOTIFY message's originating transaction is in progress,committed, or aborted. The previous coding could accept a message from atransaction that was still in-progress according to the PGPROC array;if the client were fast enough at starting a new transaction, it might failto see table rows added/updated by the message-sending transaction. Whichof course would usually be the point of receiving the message. We notedthis type of race condition long ago in tqual.c, but async.c overlooked it.The race condition probably cannot occur unless there are multiple NOTIFYsenders in action, since an individual backend doesn't send NOTIFY signalsuntil well after it's done committing. But if two senders commit in closesuccession, it's certainly possible that we could see the second sender'smessage within the race condition window while responding to the signalfrom the first one.Per bug #9557 from Marko Tiikkaja. This patch is slightly more invasivethan what he proposed, since it removes the now-redundantTransactionIdDidAbort call.Back-patch to 9.0, where the current NOTIFY implementation was introduced.
1 parent9954e1f commit7aea105

File tree

1 file changed

+24
-18
lines changed

1 file changed

+24
-18
lines changed

‎src/backend/commands/async.c

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
#include"miscadmin.h"
127127
#include"storage/ipc.h"
128128
#include"storage/lmgr.h"
129+
#include"storage/procarray.h"
129130
#include"storage/procsignal.h"
130131
#include"storage/sinval.h"
131132
#include"tcop/tcopprot.h"
@@ -2001,7 +2002,27 @@ asyncQueueProcessPageEntries(QueuePosition *current,
20012002
/* Ignore messages destined for other databases */
20022003
if (qe->dboid==MyDatabaseId)
20032004
{
2004-
if (TransactionIdDidCommit(qe->xid))
2005+
if (TransactionIdIsInProgress(qe->xid))
2006+
{
2007+
/*
2008+
* The source transaction is still in progress, so we can't
2009+
* process this message yet. Break out of the loop, but first
2010+
* back up *current so we will reprocess the message next
2011+
* time. (Note: it is unlikely but not impossible for
2012+
* TransactionIdDidCommit to fail, so we can't really avoid
2013+
* this advance-then-back-up behavior when dealing with an
2014+
* uncommitted message.)
2015+
*
2016+
* Note that we must test TransactionIdIsInProgress before we
2017+
* test TransactionIdDidCommit, else we might return a message
2018+
* from a transaction that is not yet visible to snapshots;
2019+
* compare the comments at the head of tqual.c.
2020+
*/
2021+
*current=thisentry;
2022+
reachedStop= true;
2023+
break;
2024+
}
2025+
elseif (TransactionIdDidCommit(qe->xid))
20052026
{
20062027
/* qe->data is the null-terminated channel name */
20072028
char*channel=qe->data;
@@ -2014,27 +2035,12 @@ asyncQueueProcessPageEntries(QueuePosition *current,
20142035
NotifyMyFrontEnd(channel,payload,qe->srcPid);
20152036
}
20162037
}
2017-
elseif (TransactionIdDidAbort(qe->xid))
2018-
{
2019-
/*
2020-
* If the source transaction aborted, we just ignore its
2021-
* notifications.
2022-
*/
2023-
}
20242038
else
20252039
{
20262040
/*
2027-
* The transaction has neither committed nor aborted so far,
2028-
* so we can't process its message yet. Break out of the
2029-
* loop, but first back up *current so we will reprocess the
2030-
* message next time. (Note: it is unlikely but not
2031-
* impossible for TransactionIdDidCommit to fail, so we can't
2032-
* really avoid this advance-then-back-up behavior when
2033-
* dealing with an uncommitted message.)
2041+
* The source transaction aborted or crashed, so we just
2042+
* ignore its notifications.
20342043
*/
2035-
*current=thisentry;
2036-
reachedStop= true;
2037-
break;
20382044
}
20392045
}
20402046

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp