@@ -929,105 +929,122 @@ SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, TransactionId xid,
929929{
930930int nxact ;
931931
932- bool forced_timetravel = false;
932+ bool needs_snapshot = false;
933+ bool needs_timetravel = false;
933934bool sub_needs_timetravel = false;
934- bool top_needs_timetravel = false;
935935
936936TransactionId xmax = xid ;
937937
938938/*
939- * If we couldn't observe every change of a transaction because it was
940- * already running at the point we started to observe we have to assume it
941- * made catalog changes.
942- *
943- * This has the positive benefit that we afterwards have enough
944- * information to build an exportable snapshot that's usable by pg_dump et
945- * al.
939+ * Transactions preceding BUILDING_SNAPSHOT will neither be decoded, nor
940+ * will they be part of a snapshot. So we don't need to record anything.
946941 */
942+ if (builder -> state == SNAPBUILD_START ||
943+ (builder -> state == SNAPBUILD_BUILDING_SNAPSHOT &&
944+ TransactionIdPrecedes (xid ,SnapBuildNextPhaseAt (builder ))))
945+ {
946+ /* ensure that only commits after this are getting replayed */
947+ if (builder -> start_decoding_at <=lsn )
948+ builder -> start_decoding_at = lsn + 1 ;
949+ return ;
950+ }
951+
947952if (builder -> state < SNAPBUILD_CONSISTENT )
948953{
949954/* ensure that only commits after this are getting replayed */
950955if (builder -> start_decoding_at <=lsn )
951956builder -> start_decoding_at = lsn + 1 ;
952957
953958/*
954- * We could avoid treating !SnapBuildTxnIsRunning transactions as
955- * timetravel ones, but we want to be able to export a snapshot when
956- * we reached consistency.
959+ * If building an exportable snapshot, force xid to be tracked, even
960+ * if the transaction didn't modify the catalog.
957961 */
958- forced_timetravel = true;
959- elog (DEBUG1 ,"forced to assume catalog changes for xid %u because it was running too early" ,xid );
962+ if (builder -> building_full_snapshot )
963+ {
964+ needs_timetravel = true;
965+ }
960966}
961967
962968for (nxact = 0 ;nxact < nsubxacts ;nxact ++ )
963969{
964970TransactionId subxid = subxacts [nxact ];
965971
966972/*
967- *If we're forcing timetravel we also need visibility information
968- *about subtransaction, so keep track of subtransaction's state .
973+ *Add subtransaction to base snapshot if catalog modifying, we don't
974+ *distinguish to toplevel transactions there .
969975 */
970- if (forced_timetravel )
976+ if (ReorderBufferXidHasCatalogChanges ( builder -> reorder , subxid ) )
971977{
978+ sub_needs_timetravel = true;
979+ needs_snapshot = true;
980+
981+ elog (DEBUG1 ,"found subtransaction %u:%u with catalog changes" ,
982+ xid ,subxid );
983+
972984SnapBuildAddCommittedTxn (builder ,subxid );
985+
973986if (NormalTransactionIdFollows (subxid ,xmax ))
974987xmax = subxid ;
975988}
976-
977989/*
978- * Add subtransaction to base snapshot if it DDL, we don't distinguish
979- * to toplevel transactions there.
990+ * If we're forcing timetravel we also need visibility information
991+ * about subtransaction, so keep track of subtransaction's state, even
992+ * if not catalog modifying. Don't need to distribute a snapshot in
993+ * that case.
980994 */
981- else if (ReorderBufferXidHasCatalogChanges ( builder -> reorder , subxid ) )
995+ else if (needs_timetravel )
982996{
983- sub_needs_timetravel = true;
984-
985- elog (DEBUG1 ,"found subtransaction %u:%u with catalog changes." ,
986- xid ,subxid );
987-
988997SnapBuildAddCommittedTxn (builder ,subxid );
989-
990998if (NormalTransactionIdFollows (subxid ,xmax ))
991999xmax = subxid ;
9921000}
9931001}
9941002
995- if (forced_timetravel )
1003+ /* if top-level modified catalog, it'll need a snapshot */
1004+ if (ReorderBufferXidHasCatalogChanges (builder -> reorder ,xid ))
9961005{
997- elog (DEBUG2 ,"forced transaction %u to do timetravel." ,xid );
998-
1006+ elog (DEBUG2 ,"found top level transaction %u, with catalog changes" ,
1007+ xid );
1008+ needs_snapshot = true;
1009+ needs_timetravel = true;
9991010SnapBuildAddCommittedTxn (builder ,xid );
10001011}
1001- /* add toplevel transaction to base snapshot */
1002- else if (ReorderBufferXidHasCatalogChanges (builder -> reorder ,xid ))
1012+ else if (sub_needs_timetravel )
10031013{
1004- elog (DEBUG2 ,"found top level transaction %u, with catalog changes!" ,
1005- xid );
1006-
1007- top_needs_timetravel = true;
1014+ /* track toplevel txn as well, subxact alone isn't meaningful */
10081015SnapBuildAddCommittedTxn (builder ,xid );
10091016}
1010- else if (sub_needs_timetravel )
1017+ else if (needs_timetravel )
10111018{
1012- /* mark toplevel txn as timetravel as well */
1019+ elog (DEBUG2 ,"forced transaction %u to do timetravel" ,xid );
1020+
10131021SnapBuildAddCommittedTxn (builder ,xid );
10141022}
10151023
1016- /* if there's any reason to build a historic snapshot, do so now */
1017- if (forced_timetravel || top_needs_timetravel || sub_needs_timetravel )
1024+ if (!needs_timetravel )
10181025{
1019- /*
1020- * Adjust xmax of the snapshot builder, we only do that for committed,
1021- * catalog modifying, transactions, everything else isn't interesting
1022- * for us since we'll never look at the respective rows.
1023- */
1024- if (!TransactionIdIsValid (builder -> xmax )||
1025- TransactionIdFollowsOrEquals (xmax ,builder -> xmax ))
1026- {
1027- builder -> xmax = xmax ;
1028- TransactionIdAdvance (builder -> xmax );
1029- }
1026+ /* record that we cannot export a general snapshot anymore */
1027+ builder -> committed .includes_all_transactions = false;
1028+ }
1029+
1030+ Assert (!needs_snapshot || needs_timetravel );
10301031
1032+ /*
1033+ * Adjust xmax of the snapshot builder, we only do that for committed,
1034+ * catalog modifying, transactions, everything else isn't interesting
1035+ * for us since we'll never look at the respective rows.
1036+ */
1037+ if (needs_timetravel &&
1038+ (!TransactionIdIsValid (builder -> xmax )||
1039+ TransactionIdFollowsOrEquals (xmax ,builder -> xmax )))
1040+ {
1041+ builder -> xmax = xmax ;
1042+ TransactionIdAdvance (builder -> xmax );
1043+ }
1044+
1045+ /* if there's any reason to build a historic snapshot, do so now */
1046+ if (needs_snapshot )
1047+ {
10311048/*
10321049 * If we haven't built a complete snapshot yet there's no need to hand
10331050 * it out, it wouldn't (and couldn't) be used anyway.
@@ -1059,11 +1076,6 @@ SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, TransactionId xid,
10591076/* add a new Snapshot to all currently running transactions */
10601077SnapBuildDistributeNewCatalogSnapshot (builder ,lsn );
10611078}
1062- else
1063- {
1064- /* record that we cannot export a general snapshot anymore */
1065- builder -> committed .includes_all_transactions = false;
1066- }
10671079}
10681080
10691081