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

Commita2a718b

Browse files
committed
Treat 2PC commit/abort the same as regular xacts in recovery.
There were several oversights in recovery code where COMMIT/ABORT PREPAREDrecords were ignored:* pg_last_xact_replay_timestamp() (wasn't updated for 2PC commits)* recovery_min_apply_delay (2PC commits were applied immediately)* recovery_target_xid (recovery would not stop if the XID used 2PC)The first of those was reported by Sergiy Zuban in bug #11032, analyzed byTom Lane and Andres Freund. The bug was always there, but was masked beforecommitd19bd29, because COMMIT PREPAREDalways created an extra regular transaction that was WAL-logged.Backpatch to all supported versions (older versions didn't have all thefeatures and therefore didn't have all of the above bugs).
1 parent51fc613 commita2a718b

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

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

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4494,6 +4494,7 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
44944494
boolstopsHere;
44954495
uint8record_info;
44964496
TimestampTzrecordXtime;
4497+
TransactionIdrecordXid;
44974498
charrecordRPName[MAXFNAMELEN];
44984499

44994500
/* We only consider stopping at COMMIT, ABORT or RESTORE POINT records */
@@ -4506,27 +4507,47 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
45064507

45074508
recordXactCommitData= (xl_xact_commit_compact*)XLogRecGetData(record);
45084509
recordXtime=recordXactCommitData->xact_time;
4510+
recordXid=record->xl_xid;
45094511
}
45104512
elseif (record->xl_rmid==RM_XACT_ID&&record_info==XLOG_XACT_COMMIT)
45114513
{
45124514
xl_xact_commit*recordXactCommitData;
45134515

45144516
recordXactCommitData= (xl_xact_commit*)XLogRecGetData(record);
45154517
recordXtime=recordXactCommitData->xact_time;
4518+
recordXid=record->xl_xid;
4519+
}
4520+
elseif (record->xl_rmid==RM_XACT_ID&&record_info==XLOG_XACT_COMMIT_PREPARED)
4521+
{
4522+
xl_xact_commit_prepared*recordXactCommitData;
4523+
4524+
recordXactCommitData= (xl_xact_commit_prepared*)XLogRecGetData(record);
4525+
recordXtime=recordXactCommitData->crec.xact_time;
4526+
recordXid=recordXactCommitData->xid;
45164527
}
45174528
elseif (record->xl_rmid==RM_XACT_ID&&record_info==XLOG_XACT_ABORT)
45184529
{
45194530
xl_xact_abort*recordXactAbortData;
45204531

45214532
recordXactAbortData= (xl_xact_abort*)XLogRecGetData(record);
45224533
recordXtime=recordXactAbortData->xact_time;
4534+
recordXid=record->xl_xid;
4535+
}
4536+
elseif (record->xl_rmid==RM_XACT_ID&&record_info==XLOG_XACT_ABORT_PREPARED)
4537+
{
4538+
xl_xact_abort_prepared*recordXactAbortData;
4539+
4540+
recordXactAbortData= (xl_xact_abort_prepared*)XLogRecGetData(record);
4541+
recordXtime=recordXactAbortData->arec.xact_time;
4542+
recordXid=recordXactAbortData->xid;
45234543
}
45244544
elseif (record->xl_rmid==RM_XLOG_ID&&record_info==XLOG_RESTORE_POINT)
45254545
{
45264546
xl_restore_point*recordRestorePointData;
45274547

45284548
recordRestorePointData= (xl_restore_point*)XLogRecGetData(record);
45294549
recordXtime=recordRestorePointData->rp_time;
4550+
recordXid=InvalidTransactionId;
45304551
strlcpy(recordRPName,recordRestorePointData->rp_name,MAXFNAMELEN);
45314552
}
45324553
else
@@ -4555,7 +4576,7 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
45554576
* they complete. A higher numbered xid will complete before you about
45564577
* 50% of the time...
45574578
*/
4558-
stopsHere= (record->xl_xid==recoveryTargetXid);
4579+
stopsHere= (recordXid==recoveryTargetXid);
45594580
if (stopsHere)
45604581
*includeThis=recoveryTargetInclusive;
45614582
}
@@ -4590,11 +4611,13 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
45904611

45914612
if (stopsHere)
45924613
{
4593-
recoveryStopXid=record->xl_xid;
4614+
recoveryStopXid=recordXid;
45944615
recoveryStopTime=recordXtime;
45954616
recoveryStopAfter=*includeThis;
45964617

4597-
if (record_info==XLOG_XACT_COMMIT_COMPACT||record_info==XLOG_XACT_COMMIT)
4618+
if (record_info==XLOG_XACT_COMMIT_COMPACT||
4619+
record_info==XLOG_XACT_COMMIT||
4620+
record_info==XLOG_XACT_COMMIT_PREPARED)
45984621
{
45994622
if (recoveryStopAfter)
46004623
ereport(LOG,
@@ -4607,7 +4630,8 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
46074630
recoveryStopXid,
46084631
timestamptz_to_str(recoveryStopTime))));
46094632
}
4610-
elseif (record_info==XLOG_XACT_ABORT)
4633+
elseif (record_info==XLOG_XACT_ABORT||
4634+
record_info==XLOG_XACT_ABORT_PREPARED)
46114635
{
46124636
if (recoveryStopAfter)
46134637
ereport(LOG,

‎src/include/access/xact.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,7 @@ typedef struct xl_xact_abort
180180
/*
181181
* COMMIT_PREPARED and ABORT_PREPARED are identical to COMMIT/ABORT records
182182
* except that we have to store the XID of the prepared transaction explicitly
183-
* --- the XID in the record header will be for the transaction doing the
184-
* COMMIT PREPARED or ABORT PREPARED command.
183+
* --- the XID in the record header will be invalid.
185184
*/
186185

187186
typedefstructxl_xact_commit_prepared

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp