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

Commit1578d13

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 parentaf9d516 commit1578d13

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
@@ -5880,6 +5880,7 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
58805880
boolstopsHere;
58815881
uint8record_info;
58825882
TimestampTzrecordXtime;
5883+
TransactionIdrecordXid;
58835884
charrecordRPName[MAXFNAMELEN];
58845885

58855886
/* We only consider stopping at COMMIT, ABORT or RESTORE POINT records */
@@ -5892,27 +5893,47 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
58925893

58935894
recordXactCommitData= (xl_xact_commit_compact*)XLogRecGetData(record);
58945895
recordXtime=recordXactCommitData->xact_time;
5896+
recordXid=record->xl_xid;
58955897
}
58965898
elseif (record->xl_rmid==RM_XACT_ID&&record_info==XLOG_XACT_COMMIT)
58975899
{
58985900
xl_xact_commit*recordXactCommitData;
58995901

59005902
recordXactCommitData= (xl_xact_commit*)XLogRecGetData(record);
59015903
recordXtime=recordXactCommitData->xact_time;
5904+
recordXid=record->xl_xid;
5905+
}
5906+
elseif (record->xl_rmid==RM_XACT_ID&&record_info==XLOG_XACT_COMMIT_PREPARED)
5907+
{
5908+
xl_xact_commit_prepared*recordXactCommitData;
5909+
5910+
recordXactCommitData= (xl_xact_commit_prepared*)XLogRecGetData(record);
5911+
recordXtime=recordXactCommitData->crec.xact_time;
5912+
recordXid=recordXactCommitData->xid;
59025913
}
59035914
elseif (record->xl_rmid==RM_XACT_ID&&record_info==XLOG_XACT_ABORT)
59045915
{
59055916
xl_xact_abort*recordXactAbortData;
59065917

59075918
recordXactAbortData= (xl_xact_abort*)XLogRecGetData(record);
59085919
recordXtime=recordXactAbortData->xact_time;
5920+
recordXid=record->xl_xid;
5921+
}
5922+
elseif (record->xl_rmid==RM_XACT_ID&&record_info==XLOG_XACT_ABORT_PREPARED)
5923+
{
5924+
xl_xact_abort_prepared*recordXactAbortData;
5925+
5926+
recordXactAbortData= (xl_xact_abort_prepared*)XLogRecGetData(record);
5927+
recordXtime=recordXactAbortData->arec.xact_time;
5928+
recordXid=recordXactAbortData->xid;
59095929
}
59105930
elseif (record->xl_rmid==RM_XLOG_ID&&record_info==XLOG_RESTORE_POINT)
59115931
{
59125932
xl_restore_point*recordRestorePointData;
59135933

59145934
recordRestorePointData= (xl_restore_point*)XLogRecGetData(record);
59155935
recordXtime=recordRestorePointData->rp_time;
5936+
recordXid=InvalidTransactionId;
59165937
strlcpy(recordRPName,recordRestorePointData->rp_name,MAXFNAMELEN);
59175938
}
59185939
else
@@ -5941,7 +5962,7 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
59415962
* they complete. A higher numbered xid will complete before you about
59425963
* 50% of the time...
59435964
*/
5944-
stopsHere= (record->xl_xid==recoveryTargetXid);
5965+
stopsHere= (recordXid==recoveryTargetXid);
59455966
if (stopsHere)
59465967
*includeThis=recoveryTargetInclusive;
59475968
}
@@ -5976,11 +5997,13 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
59765997

59775998
if (stopsHere)
59785999
{
5979-
recoveryStopXid=record->xl_xid;
6000+
recoveryStopXid=recordXid;
59806001
recoveryStopTime=recordXtime;
59816002
recoveryStopAfter=*includeThis;
59826003

5983-
if (record_info==XLOG_XACT_COMMIT_COMPACT||record_info==XLOG_XACT_COMMIT)
6004+
if (record_info==XLOG_XACT_COMMIT_COMPACT||
6005+
record_info==XLOG_XACT_COMMIT||
6006+
record_info==XLOG_XACT_COMMIT_PREPARED)
59846007
{
59856008
if (recoveryStopAfter)
59866009
ereport(LOG,
@@ -5993,7 +6016,8 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
59936016
recoveryStopXid,
59946017
timestamptz_to_str(recoveryStopTime))));
59956018
}
5996-
elseif (record_info==XLOG_XACT_ABORT)
6019+
elseif (record_info==XLOG_XACT_ABORT||
6020+
record_info==XLOG_XACT_ABORT_PREPARED)
59976021
{
59986022
if (recoveryStopAfter)
59996023
ereport(LOG,

‎src/include/access/xact.h

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

184183
typedefstructxl_xact_commit_prepared

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp