Skip to content

Commit 266427d

Browse files
knizhnikkvap
authored andcommitted
Make it possible to abort transaction from XTM TransactionIdSetStatus call
1 parent 66fc52b commit 266427d

File tree

6 files changed

+36
-26
lines changed

6 files changed

+36
-26
lines changed

src/backend/access/transam/clog.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ static void TransactionIdSetStatusBit(TransactionId xid, XidStatus status,
9393
static void set_status_by_pages(int nsubxids, TransactionId *subxids,
9494
XidStatus status, XLogRecPtr lsn);
9595

96-
void
96+
bool
9797
TransactionIdSetTreeStatus(TransactionId xid, int nsubxids,
98-
TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
98+
TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
9999
{
100-
TM->SetTransactionStatus(xid, nsubxids, subxids, status, lsn);
100+
return TM->SetTransactionStatus(xid, nsubxids, subxids, status, lsn);
101101
}
102102

103103
/*
@@ -151,7 +151,7 @@ TransactionIdSetTreeStatus(TransactionId xid, int nsubxids,
151151
* but aren't yet in cache, as well as hinting pages not to fall out of
152152
* cache yet.
153153
*/
154-
void
154+
bool
155155
PgTransactionIdSetTreeStatus(TransactionId xid, int nsubxids,
156156
TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
157157
{
@@ -217,6 +217,7 @@ PgTransactionIdSetTreeStatus(TransactionId xid, int nsubxids,
217217
subxids + nsubxids_on_first_page,
218218
status, lsn);
219219
}
220+
return true;
220221
}
221222

222223
/*

src/backend/access/transam/transam.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -256,24 +256,24 @@ TransactionIdIsKnownCompleted(TransactionId transactionId)
256256
* This commit operation is not guaranteed to be atomic, but if not, subxids
257257
* are correctly marked subcommit first.
258258
*/
259-
void
259+
bool
260260
TransactionIdCommitTree(TransactionId xid, int nxids, TransactionId *xids)
261261
{
262-
TransactionIdSetTreeStatus(xid, nxids, xids,
263-
TRANSACTION_STATUS_COMMITTED,
264-
InvalidXLogRecPtr);
262+
return TransactionIdSetTreeStatus(xid, nxids, xids,
263+
TRANSACTION_STATUS_COMMITTED,
264+
InvalidXLogRecPtr);
265265
}
266266

267267
/*
268268
* TransactionIdAsyncCommitTree
269269
* Same as above, but for async commits. The commit record LSN is needed.
270270
*/
271-
void
271+
bool
272272
TransactionIdAsyncCommitTree(TransactionId xid, int nxids, TransactionId *xids,
273273
XLogRecPtr lsn)
274274
{
275-
TransactionIdSetTreeStatus(xid, nxids, xids,
276-
TRANSACTION_STATUS_COMMITTED, lsn);
275+
return TransactionIdSetTreeStatus(xid, nxids, xids,
276+
TRANSACTION_STATUS_COMMITTED, lsn);
277277
}
278278

279279
/*

src/backend/access/transam/xact.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,7 @@ RecordTransactionCommit(void)
11351135
SharedInvalidationMessage *invalMessages = NULL;
11361136
bool RelcacheInitFileInval = false;
11371137
bool wrote_xlog;
1138+
bool committed = false;
11381139

11391140
/* Get data needed for commit record */
11401141
nrels = smgrGetPendingDeletes(true, &rels);
@@ -1273,8 +1274,9 @@ RecordTransactionCommit(void)
12731274
/*
12741275
* Now we may update the CLOG, if we wrote a COMMIT record above
12751276
*/
1276-
if (markXidCommitted)
1277-
TransactionIdCommitTree(xid, nchildren, children);
1277+
if (markXidCommitted) {
1278+
committed = TransactionIdCommitTree(xid, nchildren, children);
1279+
}
12781280
}
12791281
else
12801282
{
@@ -1296,8 +1298,9 @@ RecordTransactionCommit(void)
12961298
* XLOG. Instead, we store the LSN up to which the XLOG must be
12971299
* flushed before the CLOG may be updated.
12981300
*/
1299-
if (markXidCommitted)
1300-
TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1301+
if (markXidCommitted) {
1302+
committed = TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1303+
}
13011304
}
13021305

13031306
/*
@@ -1308,6 +1311,9 @@ RecordTransactionCommit(void)
13081311
{
13091312
MyPgXact->delayChkpt = false;
13101313
END_CRIT_SECTION();
1314+
if (!committed) {
1315+
elog(ERROR, "Transaction commit rejected by XTM");
1316+
}
13111317
}
13121318

13131319
/* Compute latestXid while we have the child XIDs handy */
@@ -5310,6 +5316,7 @@ xact_redo_commit(xl_xact_parsed_commit *parsed,
53105316
TransactionId max_xid;
53115317
int i;
53125318
TimestampTz commit_time;
5319+
bool committed;
53135320

53145321
max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
53155322

@@ -5345,7 +5352,7 @@ xact_redo_commit(xl_xact_parsed_commit *parsed,
53455352
/*
53465353
* Mark the transaction committed in pg_clog.
53475354
*/
5348-
TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
5355+
committed = TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
53495356
}
53505357
else
53515358
{
@@ -5369,8 +5376,8 @@ xact_redo_commit(xl_xact_parsed_commit *parsed,
53695376
* bits set on changes made by transactions that haven't yet
53705377
* recovered. It's unlikely but it's good to be safe.
53715378
*/
5372-
TransactionIdAsyncCommitTree(
5373-
xid, parsed->nsubxacts, parsed->subxacts, lsn);
5379+
committed = TransactionIdAsyncCommitTree(
5380+
xid, parsed->nsubxacts, parsed->subxacts, lsn);
53745381

53755382
/*
53765383
* We must mark clog before we update the ProcArray.
@@ -5397,7 +5404,9 @@ xact_redo_commit(xl_xact_parsed_commit *parsed,
53975404
*/
53985405
StandbyReleaseLockTree(xid, 0, NULL);
53995406
}
5400-
5407+
if (!committed) {
5408+
elog(NOTICE, "XTM rejected recovert of tran saction %u", xid);
5409+
}
54015410
if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
54025411
{
54035412
/* recover apply progress */

src/include/access/clog.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ typedef int XidStatus;
3030
#define TRANSACTION_STATUS_UNKNOWN 0x03
3131

3232

33-
extern void TransactionIdSetTreeStatus(TransactionId xid, int nsubxids,
34-
TransactionId *subxids, XidStatus status, XLogRecPtr lsn);
33+
extern bool TransactionIdSetTreeStatus(TransactionId xid, int nsubxids,
34+
TransactionId *subxids, XidStatus status, XLogRecPtr lsn);
3535
extern XidStatus TransactionIdGetStatus(TransactionId xid, XLogRecPtr *lsn);
3636

3737
extern Size CLOGShmemBuffers(void);

src/include/access/transam.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@ extern bool TransactionIdDidCommit(TransactionId transactionId);
157157
extern bool TransactionIdDidAbort(TransactionId transactionId);
158158
extern bool TransactionIdIsKnownCompleted(TransactionId transactionId);
159159
extern void TransactionIdAbort(TransactionId transactionId);
160-
extern void TransactionIdCommitTree(TransactionId xid, int nxids, TransactionId *xids);
161-
extern void TransactionIdAsyncCommitTree(TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn);
160+
extern bool TransactionIdCommitTree(TransactionId xid, int nxids, TransactionId *xids);
161+
extern bool TransactionIdAsyncCommitTree(TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn);
162162
extern void TransactionIdAbortTree(TransactionId xid, int nxids, TransactionId *xids);
163163
extern bool TransactionIdPrecedes(TransactionId id1, TransactionId id2);
164164
extern bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2);

src/include/access/xtm.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ typedef struct
2121
XidStatus (*GetTransactionStatus)(TransactionId xid, XLogRecPtr *lsn);
2222

2323
/* Set current transaction status (encapsulation of TransactionIdGetStatus in clog.c) */
24-
void (*SetTransactionStatus)(TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn);
24+
bool (*SetTransactionStatus)(TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn);
2525

2626
/* Get current transaction snaphot (encapsulation of GetSnapshotData in procarray.c) */
2727
Snapshot (*GetSnapshot)(Snapshot snapshot);
@@ -51,8 +51,8 @@ extern TransactionManager PgTM; /* Standard PostgreSQL transaction manager */
5151
/* Standard PostgreSQL function implementing TM interface */
5252
extern bool PgXidInMVCCSnapshot(TransactionId xid, Snapshot snapshot);
5353

54-
extern void PgTransactionIdSetTreeStatus(TransactionId xid, int nsubxids,
55-
TransactionId *subxids, XidStatus status, XLogRecPtr lsn);
54+
extern bool PgTransactionIdSetTreeStatus(TransactionId xid, int nsubxids,
55+
TransactionId *subxids, XidStatus status, XLogRecPtr lsn);
5656
extern XidStatus PgTransactionIdGetStatus(TransactionId xid, XLogRecPtr *lsn);
5757

5858
extern Snapshot PgGetSnapshotData(Snapshot snapshot);

0 commit comments

Comments
 (0)