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

Commite30fd09

Browse files
committed
Fix race in SERIALIZABLE READ ONLY.
Commitbdaabb9 started skipping doomed transactions when building thelist of possible conflicts for SERIALIZABLE READ ONLY. That makessense, because doomed transactions won't commit, but a couple of subtlethings broke:1. If all uncommitted r/w transactions are doomed, a READ ONLYtransaction would arbitrarily not benefit from the safe snapshotoptimization. It would not be taken immediately, and yet no othertransaction would set SXACT_FLAG_RO_SAFE later.2. In the same circumstances but with DEFERRABLE, GetSafeSnapshot()would correctly exit its wait loop without sleeping and then take theoptimization in non-assert builds, but assert builds would fail a sanitycheck that SXACT_FLAG_RO_SAFE had been set by another transaction.This is similar to the case for PredXact->WritableSxactCount == 0. Weshould opt out immediately if our possibleUnsafeConflicts list is emptyafter filtering.The code to maintain the serializable global xmin is moved down belowthe new opt out site, because otherwise we'd have to reverse its effectsbefore returning.Back-patch to all supported releases. Bug #17368.Reported-by: Alexander Lakhin <exclusion@gmail.com>Discussion:https://postgr.es/m/17116-d6ca217acc180e30%40postgresql.orgDiscussion:https://postgr.es/m/20110707212159.GF76634%40csail.mit.edu
1 parent3c92f7e commite30fd09

File tree

1 file changed

+31
-18
lines changed

1 file changed

+31
-18
lines changed

‎src/backend/storage/lmgr/predicate.c

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,24 +1854,6 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot,
18541854
returnsnapshot;
18551855
}
18561856

1857-
/* Maintain serializable global xmin info. */
1858-
if (!TransactionIdIsValid(PredXact->SxactGlobalXmin))
1859-
{
1860-
Assert(PredXact->SxactGlobalXminCount==0);
1861-
PredXact->SxactGlobalXmin=snapshot->xmin;
1862-
PredXact->SxactGlobalXminCount=1;
1863-
OldSerXidSetActiveSerXmin(snapshot->xmin);
1864-
}
1865-
elseif (TransactionIdEquals(snapshot->xmin,PredXact->SxactGlobalXmin))
1866-
{
1867-
Assert(PredXact->SxactGlobalXminCount>0);
1868-
PredXact->SxactGlobalXminCount++;
1869-
}
1870-
else
1871-
{
1872-
Assert(TransactionIdFollows(snapshot->xmin,PredXact->SxactGlobalXmin));
1873-
}
1874-
18751857
/* Initialize the structure. */
18761858
sxact->vxid=vxid;
18771859
sxact->SeqNo.lastCommitBeforeSnapshot=PredXact->LastSxactCommitSeqNo;
@@ -1908,6 +1890,19 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot,
19081890
SetPossibleUnsafeConflict(sxact,othersxact);
19091891
}
19101892
}
1893+
1894+
/*
1895+
* If we didn't find any possibly unsafe conflicts because every
1896+
* uncommitted writable transaction turned out to be doomed, then we
1897+
* can "opt out" immediately. See comments above the earlier check for
1898+
* PredXact->WritableSxactCount == 0.
1899+
*/
1900+
if (SHMQueueEmpty(&sxact->possibleUnsafeConflicts))
1901+
{
1902+
ReleasePredXact(sxact);
1903+
LWLockRelease(SerializableXactHashLock);
1904+
returnsnapshot;
1905+
}
19111906
}
19121907
else
19131908
{
@@ -1916,6 +1911,24 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot,
19161911
(MaxBackends+max_prepared_xacts));
19171912
}
19181913

1914+
/* Maintain serializable global xmin info. */
1915+
if (!TransactionIdIsValid(PredXact->SxactGlobalXmin))
1916+
{
1917+
Assert(PredXact->SxactGlobalXminCount==0);
1918+
PredXact->SxactGlobalXmin=snapshot->xmin;
1919+
PredXact->SxactGlobalXminCount=1;
1920+
OldSerXidSetActiveSerXmin(snapshot->xmin);
1921+
}
1922+
elseif (TransactionIdEquals(snapshot->xmin,PredXact->SxactGlobalXmin))
1923+
{
1924+
Assert(PredXact->SxactGlobalXminCount>0);
1925+
PredXact->SxactGlobalXminCount++;
1926+
}
1927+
else
1928+
{
1929+
Assert(TransactionIdFollows(snapshot->xmin,PredXact->SxactGlobalXmin));
1930+
}
1931+
19191932
MySerializableXact=sxact;
19201933
MyXactDidWrite= false;/* haven't written anything yet */
19211934

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp