Skip to content

Commit 0e5b8ef

Browse files
committed
port xtm to 11-current
1 parent ad25a6b commit 0e5b8ef

File tree

15 files changed

+336
-26
lines changed

15 files changed

+336
-26
lines changed

src/backend/access/transam/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ include $(top_builddir)/src/Makefile.global
1515
OBJS = clog.o commit_ts.o generic_xlog.o multixact.o parallel.o rmgr.o slru.o \
1616
subtrans.o timeline.o transam.o twophase.o twophase_rmgr.o varsup.o \
1717
xact.o xlog.o xlogarchive.o xlogfuncs.o \
18-
xloginsert.o xlogreader.o xlogutils.o
18+
xloginsert.o xlogreader.o xlogutils.o xtm.o
1919

2020
include $(top_srcdir)/src/backend/common.mk
2121

src/backend/access/transam/clog.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "access/xlog.h"
3939
#include "access/xloginsert.h"
4040
#include "access/xlogutils.h"
41+
#include "access/xtm.h"
4142
#include "miscadmin.h"
4243
#include "pgstat.h"
4344
#include "pg_trace.h"
@@ -87,6 +88,12 @@ static SlruCtlData ClogCtlData;
8788

8889
#define ClogCtl (&ClogCtlData)
8990

91+
void
92+
TransactionIdSetTreeStatus(TransactionId xid, int nsubxids,
93+
TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
94+
{
95+
return TM->SetTransactionStatus(xid, nsubxids, subxids, status, lsn);
96+
}
9097

9198
static int ZeroCLOGPage(int pageno, bool writeXlog);
9299
static bool CLOGPagePrecedes(int page1, int page2);
@@ -160,7 +167,7 @@ static void TransactionIdSetPageStatusInternal(TransactionId xid, int nsubxids,
160167
* cache yet.
161168
*/
162169
void
163-
TransactionIdSetTreeStatus(TransactionId xid, int nsubxids,
170+
PgTransactionIdSetTreeStatus(TransactionId xid, int nsubxids,
164171
TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
165172
{
166173
int pageno = TransactionIdToPage(xid); /* get page of parent */
@@ -594,10 +601,10 @@ TransactionIdSetStatusBit(TransactionId xid, XidStatus status, XLogRecPtr lsn, i
594601
* Current state change should be from 0 or subcommitted to target state
595602
* or we should already be there when replaying changes during recovery.
596603
*/
597-
Assert(curval == 0 ||
598-
(curval == TRANSACTION_STATUS_SUB_COMMITTED &&
599-
status != TRANSACTION_STATUS_IN_PROGRESS) ||
600-
curval == status);
604+
/* Assert(curval == 0 || */
605+
/* (curval == TRANSACTION_STATUS_SUB_COMMITTED && */
606+
/* status != TRANSACTION_STATUS_IN_PROGRESS) || */
607+
/* curval == status); */
601608

602609
/* note this assumes exclusive access to the clog page */
603610
byteval = *byteptr;
@@ -639,6 +646,12 @@ TransactionIdSetStatusBit(TransactionId xid, XidStatus status, XLogRecPtr lsn, i
639646
*/
640647
XidStatus
641648
TransactionIdGetStatus(TransactionId xid, XLogRecPtr *lsn)
649+
{
650+
return TM->GetTransactionStatus(xid, lsn);
651+
}
652+
653+
XidStatus
654+
PgTransactionIdGetStatus(TransactionId xid, XLogRecPtr *lsn)
642655
{
643656
int pageno = TransactionIdToPage(xid);
644657
int byteno = TransactionIdToByte(xid);

src/backend/access/transam/subtrans.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ SubTransGetParent(TransactionId xid)
115115
TransactionId parent;
116116

117117
/* Can't ask about stuff that might not be around anymore */
118-
Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin));
118+
//Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin));
119119

120120
/* Bootstrap and frozen XIDs have no parent */
121121
if (!TransactionIdIsNormal(xid))
@@ -153,7 +153,10 @@ SubTransGetTopmostTransaction(TransactionId xid)
153153
previousXid = xid;
154154

155155
/* Can't ask about stuff that might not be around anymore */
156-
Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin));
156+
if (!TransactionIdFollowsOrEquals(xid, TransactionXmin))
157+
{
158+
return xid;
159+
}
157160

158161
while (TransactionIdIsValid(parentXid))
159162
{

src/backend/access/transam/varsup.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "access/transam.h"
2020
#include "access/xact.h"
2121
#include "access/xlog.h"
22+
#include "access/xtm.h"
2223
#include "commands/dbcommands.h"
2324
#include "miscadmin.h"
2425
#include "postmaster/autovacuum.h"
@@ -33,6 +34,11 @@
3334
/* pointer to "variable cache" in shared memory (set up by shmem.c) */
3435
VariableCache ShmemVariableCache = NULL;
3536

37+
TransactionId
38+
GetNewTransactionId(bool isSubXact)
39+
{
40+
return TM->GetNewTransactionId(isSubXact);
41+
}
3642

3743
/*
3844
* Allocate the next XID for a new transaction or subtransaction.
@@ -45,7 +51,7 @@ VariableCache ShmemVariableCache = NULL;
4551
* issue a warning about XID wrap.
4652
*/
4753
TransactionId
48-
GetNewTransactionId(bool isSubXact)
54+
PgGetNewTransactionId(bool isSubXact)
4955
{
5056
TransactionId xid;
5157

src/backend/access/transam/xact.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "access/transam.h"
2828
#include "access/twophase.h"
2929
#include "access/xact.h"
30+
#include "access/xtm.h"
3031
#include "access/xlog.h"
3132
#include "access/xloginsert.h"
3233
#include "access/xlogutils.h"
@@ -5021,6 +5022,7 @@ SerializeTransactionState(Size maxsize, char *start_address)
50215022
Assert(maxsize >= (nParallelCurrentXids + c) * sizeof(TransactionId));
50225023
memcpy(&result[c], ParallelCurrentXids,
50235024
nParallelCurrentXids * sizeof(TransactionId));
5025+
TM->SerializeTransactionState(&result[c + nParallelCurrentXids]);
50245026
return;
50255027
}
50265028

@@ -5054,6 +5056,7 @@ SerializeTransactionState(Size maxsize, char *start_address)
50545056
/* Copy data into output area. */
50555057
result[c++] = (TransactionId) nxids;
50565058
memcpy(&result[c], workspace, nxids * sizeof(TransactionId));
5059+
TM->SerializeTransactionState(&result[c + nxids]);
50575060
}
50585061

50595062
/*
@@ -5076,6 +5079,7 @@ StartParallelWorkerTransaction(char *tstatespace)
50765079
currentCommandId = tstate[4];
50775080
nParallelCurrentXids = (int) tstate[5];
50785081
ParallelCurrentXids = &tstate[6];
5082+
TM->DeserializeTransactionState(&tstate[nParallelCurrentXids + 6]);
50795083

50805084
CurrentTransactionState->blockState = TBLOCK_PARALLEL_INPROGRESS;
50815085
}

src/backend/access/transam/xtm.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* xtm.c
4+
* PostgreSQL implementation of transaction manager protocol
5+
*
6+
* This module defines default iplementaiton of PostgreSQL transaction manager protocol
7+
*
8+
* Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
9+
* Portions Copyright (c) 1994, Regents of the University of California
10+
*
11+
* src/backend/access/transam/xtm.c
12+
*
13+
*-------------------------------------------------------------------------
14+
*/
15+
16+
#include "postgres.h"
17+
18+
#include "access/transam.h"
19+
#include "access/xtm.h"
20+
21+
TransactionId
22+
PgGetGlobalTransactionId(void)
23+
{
24+
return InvalidTransactionId;
25+
}
26+
27+
bool
28+
PgDetectGlobalDeadLock(PGPROC *proc)
29+
{
30+
return false;
31+
}
32+
33+
char const *
34+
PgGetTransactionManagerName(void)
35+
{
36+
return "postgres";
37+
}
38+
39+
size_t
40+
PgGetTransactionStateSize(void)
41+
{
42+
return 0;
43+
}
44+
45+
void
46+
PgSerializeTransactionState(void* ctx)
47+
{
48+
}
49+
50+
void
51+
PgDeserializeTransactionState(void* ctx)
52+
{
53+
}
54+
55+
void PgInitializeSequence(int64* init, int64* step)
56+
{
57+
*init = 1;
58+
*step = 1;
59+
}
60+
61+
62+
TransactionManager PgTM = {
63+
PgTransactionIdGetStatus,
64+
PgTransactionIdSetTreeStatus,
65+
PgGetSnapshotData,
66+
PgGetNewTransactionId,
67+
PgGetOldestXmin,
68+
PgTransactionIdIsInProgress,
69+
PgGetGlobalTransactionId,
70+
PgXidInMVCCSnapshot,
71+
PgDetectGlobalDeadLock,
72+
PgGetTransactionManagerName,
73+
PgGetTransactionStateSize,
74+
PgSerializeTransactionState,
75+
PgDeserializeTransactionState,
76+
PgInitializeSequence
77+
};
78+
79+
TransactionManager *TM = &PgTM;
80+
81+
TransactionManager *
82+
GetTransactionManager(void)
83+
{
84+
return TM;
85+
}

src/backend/storage/ipc/procarray.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "access/twophase.h"
5252
#include "access/xact.h"
5353
#include "access/xlog.h"
54+
#include "access/xtm.h"
5455
#include "catalog/catalog.h"
5556
#include "miscadmin.h"
5657
#include "pgstat.h"
@@ -969,6 +970,12 @@ ProcArrayApplyXidAssignment(TransactionId topxid,
969970
LWLockRelease(ProcArrayLock);
970971
}
971972

973+
bool
974+
TransactionIdIsInProgress(TransactionId xid)
975+
{
976+
return TM->IsInProgress(xid);
977+
}
978+
972979
/*
973980
* TransactionIdIsInProgress -- is given transaction running in some backend
974981
*
@@ -996,7 +1003,7 @@ ProcArrayApplyXidAssignment(TransactionId topxid,
9961003
* PGXACT again anyway; see GetNewTransactionId).
9971004
*/
9981005
bool
999-
TransactionIdIsInProgress(TransactionId xid)
1006+
PgTransactionIdIsInProgress(TransactionId xid)
10001007
{
10011008
static TransactionId *xids = NULL;
10021009
int nxids = 0;
@@ -1256,6 +1263,11 @@ TransactionIdIsActive(TransactionId xid)
12561263
return result;
12571264
}
12581265

1266+
TransactionId
1267+
GetOldestXmin(Relation rel, int flags)
1268+
{
1269+
return TM->GetOldestXmin(rel, flags);
1270+
}
12591271

12601272
/*
12611273
* GetOldestXmin -- returns oldest transaction that was running
@@ -1312,7 +1324,7 @@ TransactionIdIsActive(TransactionId xid)
13121324
* GetOldestXmin() move backwards, with no consequences for data integrity.
13131325
*/
13141326
TransactionId
1315-
GetOldestXmin(Relation rel, int flags)
1327+
PgGetOldestXmin(Relation rel, int flags)
13161328
{
13171329
ProcArrayStruct *arrayP = procArray;
13181330
TransactionId result;
@@ -1469,6 +1481,12 @@ GetMaxSnapshotSubxidCount(void)
14691481
return TOTAL_MAX_CACHED_SUBXIDS;
14701482
}
14711483

1484+
Snapshot
1485+
GetSnapshotData(Snapshot snapshot)
1486+
{
1487+
return TM->GetSnapshot(snapshot);
1488+
}
1489+
14721490
/*
14731491
* GetSnapshotData -- returns information about running transactions.
14741492
*
@@ -1506,7 +1524,7 @@ GetMaxSnapshotSubxidCount(void)
15061524
* not statically allocated (see xip allocation below).
15071525
*/
15081526
Snapshot
1509-
GetSnapshotData(Snapshot snapshot)
1527+
PgGetSnapshotData(Snapshot snapshot)
15101528
{
15111529
ProcArrayStruct *arrayP = procArray;
15121530
TransactionId xmin;

src/backend/storage/lmgr/deadlock.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "pgstat.h"
3131
#include "storage/lmgr.h"
3232
#include "storage/proc.h"
33+
#include "access/xtm.h"
3334
#include "utils/memutils.h"
3435

3536

@@ -281,7 +282,7 @@ DeadLockCheck(PGPROC *proc)
281282
else if (blocking_autovacuum_proc != NULL)
282283
return DS_BLOCKED_BY_AUTOVACUUM;
283284
else
284-
return DS_NO_DEADLOCK;
285+
return TM->DetectGlobalDeadLock(proc) ? DS_DISTRIBUTED_DEADLOCK : DS_NO_DEADLOCK;
285286
}
286287

287288
/*

src/backend/storage/lmgr/lock.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3849,6 +3849,20 @@ GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode)
38493849
return LockMethods[lockmethodid]->lockModeNames[mode];
38503850
}
38513851

3852+
void
3853+
EnumerateLocks(LockIterator iterator, void* arg)
3854+
{
3855+
PROCLOCK *proclock;
3856+
HASH_SEQ_STATUS status;
3857+
3858+
hash_seq_init(&status, LockMethodProcLockHash);
3859+
3860+
while ((proclock = (PROCLOCK *) hash_seq_search(&status)) != NULL)
3861+
{
3862+
iterator(proclock, arg);
3863+
}
3864+
}
3865+
38523866
#ifdef LOCK_DEBUG
38533867
/*
38543868
* Dump all locks in the given proc's myProcLocks lists.

src/backend/storage/lmgr/predicate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4011,7 +4011,7 @@ CheckForSerializableConflictOut(bool visible, Relation relation,
40114011
xid = InvalidTransactionId;
40124012
}
40134013
Assert(TransactionIdIsValid(xid));
4014-
Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin));
4014+
//Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin));
40154015

40164016
/*
40174017
* Find top level xid. Bail out if xid is too early to be a conflict, or

src/backend/storage/lmgr/proc.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,6 +1458,22 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
14581458
"Processes holding the lock: %s. Wait queue: %s.",
14591459
lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
14601460
}
1461+
else if (deadlock_state == DS_DISTRIBUTED_DEADLOCK)
1462+
{
1463+
/*
1464+
* This message is a bit redundant with the error that will be
1465+
* reported subsequently, but in some cases the error report
1466+
* might not make it to the log (eg, if it's caught by an
1467+
* exception handler), and we want to ensure all long-wait
1468+
* events get logged.
1469+
*/
1470+
ereport(LOG,
1471+
(errmsg("process %d detected distributed deadlock while waiting for %s on %s after %ld.%03d ms",
1472+
MyProcPid, modename, buf.data, msecs, usecs),
1473+
(errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1474+
"Processes holding the lock: %s. Wait queue: %s.",
1475+
lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
1476+
}
14611477

14621478
if (myWaitStatus == STATUS_WAITING)
14631479
ereport(LOG,
@@ -1482,7 +1498,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
14821498
* future-proofing, print a message if it looks like someone
14831499
* else kicked us off the lock.
14841500
*/
1485-
if (deadlock_state != DS_HARD_DEADLOCK)
1501+
if (deadlock_state != DS_HARD_DEADLOCK && deadlock_state != DS_DISTRIBUTED_DEADLOCK)
14861502
ereport(LOG,
14871503
(errmsg("process %d failed to acquire %s on %s after %ld.%03d ms",
14881504
MyProcPid, modename, buf.data, msecs, usecs),
@@ -1702,7 +1718,7 @@ CheckDeadLock(void)
17021718
/* Run the deadlock check, and set deadlock_state for use by ProcSleep */
17031719
deadlock_state = DeadLockCheck(MyProc);
17041720

1705-
if (deadlock_state == DS_HARD_DEADLOCK)
1721+
if (deadlock_state == DS_HARD_DEADLOCK || deadlock_state == DS_DISTRIBUTED_DEADLOCK)
17061722
{
17071723
/*
17081724
* Oops. We have a deadlock.

0 commit comments

Comments
 (0)