@@ -5431,11 +5431,21 @@ getRecordTimestamp(XLogRecord *record, TimestampTz *recordXtime)
54315431* recordXtime = ((xl_xact_commit * )XLogRecGetData (record ))-> xact_time ;
54325432return true;
54335433}
5434+ if (record -> xl_rmid == RM_XACT_ID && record_info == XLOG_XACT_COMMIT_PREPARED )
5435+ {
5436+ * recordXtime = ((xl_xact_commit_prepared * )XLogRecGetData (record ))-> crec .xact_time ;
5437+ return true;
5438+ }
54345439if (record -> xl_rmid == RM_XACT_ID && record_info == XLOG_XACT_ABORT )
54355440{
54365441* recordXtime = ((xl_xact_abort * )XLogRecGetData (record ))-> xact_time ;
54375442return true;
54385443}
5444+ if (record -> xl_rmid == RM_XACT_ID && record_info == XLOG_XACT_ABORT_PREPARED )
5445+ {
5446+ * recordXtime = ((xl_xact_abort_prepared * )XLogRecGetData (record ))-> arec .xact_time ;
5447+ return true;
5448+ }
54395449return false;
54405450}
54415451
@@ -5454,6 +5464,7 @@ recoveryStopsBefore(XLogRecord *record)
54545464uint8 record_info ;
54555465bool isCommit ;
54565466TimestampTz recordXtime = 0 ;
5467+ TransactionId recordXid ;
54575468
54585469/* Check if we should stop as soon as reaching consistency */
54595470if (recoveryTarget == RECOVERY_TARGET_IMMEDIATE && reachedConsistency )
@@ -5472,10 +5483,27 @@ recoveryStopsBefore(XLogRecord *record)
54725483if (record -> xl_rmid != RM_XACT_ID )
54735484return false;
54745485record_info = record -> xl_info & ~XLR_INFO_MASK ;
5486+
54755487if (record_info == XLOG_XACT_COMMIT_COMPACT || record_info == XLOG_XACT_COMMIT )
5488+ {
5489+ isCommit = true;
5490+ recordXid = record -> xl_xid ;
5491+ }
5492+ if (record_info == XLOG_XACT_COMMIT_PREPARED )
5493+ {
54765494isCommit = true;
5495+ recordXid = ((xl_xact_commit_prepared * )XLogRecGetData (record ))-> xid ;
5496+ }
54775497else if (record_info == XLOG_XACT_ABORT )
5498+ {
5499+ isCommit = false;
5500+ recordXid = record -> xl_xid ;
5501+ }
5502+ else if (record_info == XLOG_XACT_ABORT_PREPARED )
5503+ {
54785504isCommit = false;
5505+ recordXid = ((xl_xact_abort_prepared * )XLogRecGetData (record ))-> xid ;
5506+ }
54795507else
54805508return false;
54815509
@@ -5490,7 +5518,7 @@ recoveryStopsBefore(XLogRecord *record)
54905518 * they complete. A higher numbered xid will complete before you about
54915519 * 50% of the time...
54925520 */
5493- stopsHere = (record -> xl_xid == recoveryTargetXid );
5521+ stopsHere = (recordXid == recoveryTargetXid );
54945522}
54955523
54965524if (recoveryTarget == RECOVERY_TARGET_TIME &&
@@ -5510,7 +5538,7 @@ recoveryStopsBefore(XLogRecord *record)
55105538if (stopsHere )
55115539{
55125540recoveryStopAfter = false;
5513- recoveryStopXid = record -> xl_xid ;
5541+ recoveryStopXid = recordXid ;
55145542recoveryStopTime = recordXtime ;
55155543recoveryStopName [0 ]= '\0' ;
55165544
@@ -5576,12 +5604,24 @@ recoveryStopsAfter(XLogRecord *record)
55765604if (record -> xl_rmid == RM_XACT_ID &&
55775605(record_info == XLOG_XACT_COMMIT_COMPACT ||
55785606record_info == XLOG_XACT_COMMIT ||
5579- record_info == XLOG_XACT_ABORT ))
5607+ record_info == XLOG_XACT_COMMIT_PREPARED ||
5608+ record_info == XLOG_XACT_ABORT ||
5609+ record_info == XLOG_XACT_ABORT_PREPARED ))
55805610{
5611+ TransactionId recordXid ;
5612+
55815613/* Update the last applied transaction timestamp */
55825614if (getRecordTimestamp (record ,& recordXtime ))
55835615SetLatestXTime (recordXtime );
55845616
5617+ /* Extract the XID of the committed/aborted transaction */
5618+ if (record_info == XLOG_XACT_COMMIT_PREPARED )
5619+ recordXid = ((xl_xact_commit_prepared * )XLogRecGetData (record ))-> xid ;
5620+ else if (record_info == XLOG_XACT_ABORT_PREPARED )
5621+ recordXid = ((xl_xact_abort_prepared * )XLogRecGetData (record ))-> xid ;
5622+ else
5623+ recordXid = record -> xl_xid ;
5624+
55855625/*
55865626 * There can be only one transaction end record with this exact
55875627 * transactionid
@@ -5592,21 +5632,24 @@ recoveryStopsAfter(XLogRecord *record)
55925632 * 50% of the time...
55935633 */
55945634if (recoveryTarget == RECOVERY_TARGET_XID && recoveryTargetInclusive &&
5595- record -> xl_xid == recoveryTargetXid )
5635+ recordXid == recoveryTargetXid )
55965636{
55975637recoveryStopAfter = true;
5598- recoveryStopXid = record -> xl_xid ;
5638+ recoveryStopXid = recordXid ;
55995639recoveryStopTime = recordXtime ;
56005640recoveryStopName [0 ]= '\0' ;
56015641
5602- if (record_info == XLOG_XACT_COMMIT_COMPACT || record_info == XLOG_XACT_COMMIT )
5642+ if (record_info == XLOG_XACT_COMMIT_COMPACT ||
5643+ record_info == XLOG_XACT_COMMIT ||
5644+ record_info == XLOG_XACT_COMMIT_PREPARED )
56035645{
56045646ereport (LOG ,
56055647(errmsg ("recovery stopping after commit of transaction %u, time %s" ,
56065648recoveryStopXid ,
56075649timestamptz_to_str (recoveryStopTime ))));
56085650}
5609- else if (record_info == XLOG_XACT_ABORT )
5651+ else if (record_info == XLOG_XACT_ABORT ||
5652+ record_info == XLOG_XACT_ABORT_PREPARED )
56105653{
56115654ereport (LOG ,
56125655(errmsg ("recovery stopping after abort of transaction %u, time %s" ,
@@ -5719,7 +5762,8 @@ recoveryApplyDelay(XLogRecord *record)
57195762record_info = record -> xl_info & ~XLR_INFO_MASK ;
57205763if (!(record -> xl_rmid == RM_XACT_ID &&
57215764 (record_info == XLOG_XACT_COMMIT_COMPACT ||
5722- record_info == XLOG_XACT_COMMIT )))
5765+ record_info == XLOG_XACT_COMMIT ||
5766+ record_info == XLOG_XACT_COMMIT_PREPARED )))
57235767return false;
57245768
57255769if (!getRecordTimestamp (record ,& xtime ))