@@ -911,105 +911,122 @@ SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, TransactionId xid,
911911{
912912int nxact ;
913913
914- bool forced_timetravel = false;
914+ bool needs_snapshot = false;
915+ bool needs_timetravel = false;
915916bool sub_needs_timetravel = false;
916- bool top_needs_timetravel = false;
917917
918918TransactionId xmax = xid ;
919919
920920/*
921- * If we couldn't observe every change of a transaction because it was
922- * already running at the point we started to observe we have to assume it
923- * made catalog changes.
924- *
925- * This has the positive benefit that we afterwards have enough
926- * information to build an exportable snapshot that's usable by pg_dump et
927- * al.
921+ * Transactions preceding BUILDING_SNAPSHOT will neither be decoded, nor
922+ * will they be part of a snapshot. So we don't need to record anything.
928923 */
924+ if (builder -> state == SNAPBUILD_START ||
925+ (builder -> state == SNAPBUILD_BUILDING_SNAPSHOT &&
926+ TransactionIdPrecedes (xid ,SnapBuildNextPhaseAt (builder ))))
927+ {
928+ /* ensure that only commits after this are getting replayed */
929+ if (builder -> start_decoding_at <=lsn )
930+ builder -> start_decoding_at = lsn + 1 ;
931+ return ;
932+ }
933+
929934if (builder -> state < SNAPBUILD_CONSISTENT )
930935{
931936/* ensure that only commits after this are getting replayed */
932937if (builder -> start_decoding_at <=lsn )
933938builder -> start_decoding_at = lsn + 1 ;
934939
935940/*
936- * We could avoid treating !SnapBuildTxnIsRunning transactions as
937- * timetravel ones, but we want to be able to export a snapshot when
938- * we reached consistency.
941+ * If building an exportable snapshot, force xid to be tracked, even
942+ * if the transaction didn't modify the catalog.
939943 */
940- forced_timetravel = true;
941- elog (DEBUG1 ,"forced to assume catalog changes for xid %u because it was running too early" ,xid );
944+ if (builder -> building_full_snapshot )
945+ {
946+ needs_timetravel = true;
947+ }
942948}
943949
944950for (nxact = 0 ;nxact < nsubxacts ;nxact ++ )
945951{
946952TransactionId subxid = subxacts [nxact ];
947953
948954/*
949- *If we're forcing timetravel we also need visibility information
950- *about subtransaction, so keep track of subtransaction's state .
955+ *Add subtransaction to base snapshot if catalog modifying, we don't
956+ *distinguish to toplevel transactions there .
951957 */
952- if (forced_timetravel )
958+ if (ReorderBufferXidHasCatalogChanges ( builder -> reorder , subxid ) )
953959{
960+ sub_needs_timetravel = true;
961+ needs_snapshot = true;
962+
963+ elog (DEBUG1 ,"found subtransaction %u:%u with catalog changes" ,
964+ xid ,subxid );
965+
954966SnapBuildAddCommittedTxn (builder ,subxid );
967+
955968if (NormalTransactionIdFollows (subxid ,xmax ))
956969xmax = subxid ;
957970}
958-
959971/*
960- * Add subtransaction to base snapshot if it DDL, we don't distinguish
961- * to toplevel transactions there.
972+ * If we're forcing timetravel we also need visibility information
973+ * about subtransaction, so keep track of subtransaction's state, even
974+ * if not catalog modifying. Don't need to distribute a snapshot in
975+ * that case.
962976 */
963- else if (ReorderBufferXidHasCatalogChanges ( builder -> reorder , subxid ) )
977+ else if (needs_timetravel )
964978{
965- sub_needs_timetravel = true;
966-
967- elog (DEBUG1 ,"found subtransaction %u:%u with catalog changes." ,
968- xid ,subxid );
969-
970979SnapBuildAddCommittedTxn (builder ,subxid );
971-
972980if (NormalTransactionIdFollows (subxid ,xmax ))
973981xmax = subxid ;
974982}
975983}
976984
977- if (forced_timetravel )
985+ /* if top-level modified catalog, it'll need a snapshot */
986+ if (ReorderBufferXidHasCatalogChanges (builder -> reorder ,xid ))
978987{
979- elog (DEBUG2 ,"forced transaction %u to do timetravel." ,xid );
980-
988+ elog (DEBUG2 ,"found top level transaction %u, with catalog changes" ,
989+ xid );
990+ needs_snapshot = true;
991+ needs_timetravel = true;
981992SnapBuildAddCommittedTxn (builder ,xid );
982993}
983- /* add toplevel transaction to base snapshot */
984- else if (ReorderBufferXidHasCatalogChanges (builder -> reorder ,xid ))
994+ else if (sub_needs_timetravel )
985995{
986- elog (DEBUG2 ,"found top level transaction %u, with catalog changes!" ,
987- xid );
988-
989- top_needs_timetravel = true;
996+ /* track toplevel txn as well, subxact alone isn't meaningful */
990997SnapBuildAddCommittedTxn (builder ,xid );
991998}
992- else if (sub_needs_timetravel )
999+ else if (needs_timetravel )
9931000{
994- /* mark toplevel txn as timetravel as well */
1001+ elog (DEBUG2 ,"forced transaction %u to do timetravel" ,xid );
1002+
9951003SnapBuildAddCommittedTxn (builder ,xid );
9961004}
9971005
998- /* if there's any reason to build a historic snapshot, do so now */
999- if (forced_timetravel || top_needs_timetravel || sub_needs_timetravel )
1006+ if (!needs_timetravel )
10001007{
1001- /*
1002- * Adjust xmax of the snapshot builder, we only do that for committed,
1003- * catalog modifying, transactions, everything else isn't interesting
1004- * for us since we'll never look at the respective rows.
1005- */
1006- if (!TransactionIdIsValid (builder -> xmax )||
1007- TransactionIdFollowsOrEquals (xmax ,builder -> xmax ))
1008- {
1009- builder -> xmax = xmax ;
1010- TransactionIdAdvance (builder -> xmax );
1011- }
1008+ /* record that we cannot export a general snapshot anymore */
1009+ builder -> committed .includes_all_transactions = false;
1010+ }
1011+
1012+ Assert (!needs_snapshot || needs_timetravel );
10121013
1014+ /*
1015+ * Adjust xmax of the snapshot builder, we only do that for committed,
1016+ * catalog modifying, transactions, everything else isn't interesting
1017+ * for us since we'll never look at the respective rows.
1018+ */
1019+ if (needs_timetravel &&
1020+ (!TransactionIdIsValid (builder -> xmax )||
1021+ TransactionIdFollowsOrEquals (xmax ,builder -> xmax )))
1022+ {
1023+ builder -> xmax = xmax ;
1024+ TransactionIdAdvance (builder -> xmax );
1025+ }
1026+
1027+ /* if there's any reason to build a historic snapshot, do so now */
1028+ if (needs_snapshot )
1029+ {
10131030/*
10141031 * If we haven't built a complete snapshot yet there's no need to hand
10151032 * it out, it wouldn't (and couldn't) be used anyway.
@@ -1041,11 +1058,6 @@ SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, TransactionId xid,
10411058/* add a new Snapshot to all currently running transactions */
10421059SnapBuildDistributeNewCatalogSnapshot (builder ,lsn );
10431060}
1044- else
1045- {
1046- /* record that we cannot export a general snapshot anymore */
1047- builder -> committed .includes_all_transactions = false;
1048- }
10491061}
10501062
10511063