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

Commitde88ec6

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 parent8d49bf1 commitde88ec6

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

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

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5648,6 +5648,7 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
56485648
boolstopsHere;
56495649
uint8record_info;
56505650
TimestampTzrecordXtime;
5651+
TransactionIdrecordXid;
56515652
charrecordRPName[MAXFNAMELEN];
56525653

56535654
/* We only consider stopping at COMMIT, ABORT or RESTORE POINT records */
@@ -5660,20 +5661,39 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
56605661

56615662
recordXactCommitData= (xl_xact_commit*)XLogRecGetData(record);
56625663
recordXtime=recordXactCommitData->xact_time;
5664+
recordXid=record->xl_xid;
5665+
}
5666+
elseif (record->xl_rmid==RM_XACT_ID&&record_info==XLOG_XACT_COMMIT_PREPARED)
5667+
{
5668+
xl_xact_commit_prepared*recordXactCommitData;
5669+
5670+
recordXactCommitData= (xl_xact_commit_prepared*)XLogRecGetData(record);
5671+
recordXtime=recordXactCommitData->crec.xact_time;
5672+
recordXid=recordXactCommitData->xid;
56635673
}
56645674
elseif (record->xl_rmid==RM_XACT_ID&&record_info==XLOG_XACT_ABORT)
56655675
{
56665676
xl_xact_abort*recordXactAbortData;
56675677

56685678
recordXactAbortData= (xl_xact_abort*)XLogRecGetData(record);
56695679
recordXtime=recordXactAbortData->xact_time;
5680+
recordXid=record->xl_xid;
5681+
}
5682+
elseif (record->xl_rmid==RM_XACT_ID&&record_info==XLOG_XACT_ABORT_PREPARED)
5683+
{
5684+
xl_xact_abort_prepared*recordXactAbortData;
5685+
5686+
recordXactAbortData= (xl_xact_abort_prepared*)XLogRecGetData(record);
5687+
recordXtime=recordXactAbortData->arec.xact_time;
5688+
recordXid=recordXactAbortData->xid;
56705689
}
56715690
elseif (record->xl_rmid==RM_XLOG_ID&&record_info==XLOG_RESTORE_POINT)
56725691
{
56735692
xl_restore_point*recordRestorePointData;
56745693

56755694
recordRestorePointData= (xl_restore_point*)XLogRecGetData(record);
56765695
recordXtime=recordRestorePointData->rp_time;
5696+
recordXid=InvalidTransactionId;
56775697
strlcpy(recordRPName,recordRestorePointData->rp_name,MAXFNAMELEN);
56785698
}
56795699
else
@@ -5702,7 +5722,7 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
57025722
* they complete. A higher numbered xid will complete before you about
57035723
* 50% of the time...
57045724
*/
5705-
stopsHere= (record->xl_xid==recoveryTargetXid);
5725+
stopsHere= (recordXid==recoveryTargetXid);
57065726
if (stopsHere)
57075727
*includeThis=recoveryTargetInclusive;
57085728
}
@@ -5737,11 +5757,12 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
57375757

57385758
if (stopsHere)
57395759
{
5740-
recoveryStopXid=record->xl_xid;
5760+
recoveryStopXid=recordXid;
57415761
recoveryStopTime=recordXtime;
57425762
recoveryStopAfter=*includeThis;
57435763

5744-
if (record_info==XLOG_XACT_COMMIT)
5764+
if (record_info==XLOG_XACT_COMMIT||
5765+
record_info==XLOG_XACT_COMMIT_PREPARED)
57455766
{
57465767
if (recoveryStopAfter)
57475768
ereport(LOG,
@@ -5754,7 +5775,8 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
57545775
recoveryStopXid,
57555776
timestamptz_to_str(recoveryStopTime))));
57565777
}
5757-
elseif (record_info==XLOG_XACT_ABORT)
5778+
elseif (record_info==XLOG_XACT_ABORT||
5779+
record_info==XLOG_XACT_ABORT_PREPARED)
57585780
{
57595781
if (recoveryStopAfter)
57605782
ereport(LOG,

‎src/include/access/xact.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,7 @@ typedef struct xl_xact_abort
165165
/*
166166
* COMMIT_PREPARED and ABORT_PREPARED are identical to COMMIT/ABORT records
167167
* except that we have to store the XID of the prepared transaction explicitly
168-
* --- the XID in the record header will be for the transaction doing the
169-
* COMMIT PREPARED or ABORT PREPARED command.
168+
* --- the XID in the record header will be invalid.
170169
*/
171170

172171
typedefstructxl_xact_commit_prepared

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp