@@ -929,105 +929,122 @@ SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, TransactionId xid,
929929{
930930 int nxact ;
931931
932- bool forced_timetravel = false;
932+ bool needs_snapshot = false;
933+ bool needs_timetravel = false;
933934 bool sub_needs_timetravel = false;
934- bool top_needs_timetravel = false;
935935
936936 TransactionId 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+
947952 if (builder -> state < SNAPBUILD_CONSISTENT )
948953 {
949954 /* ensure that only commits after this are getting replayed */
950955 if (builder -> start_decoding_at <= lsn )
951956 builder -> 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
962968 for (nxact = 0 ; nxact < nsubxacts ; nxact ++ )
963969 {
964970 TransactionId 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+
972984 SnapBuildAddCommittedTxn (builder , subxid );
985+
973986 if (NormalTransactionIdFollows (subxid , xmax ))
974987 xmax = 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-
988997 SnapBuildAddCommittedTxn (builder , subxid );
989-
990998 if (NormalTransactionIdFollows (subxid , xmax ))
991999 xmax = 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;
9991010 SnapBuildAddCommittedTxn (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 */
10081015 SnapBuildAddCommittedTxn (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+
10131021 SnapBuildAddCommittedTxn (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 */
10601077 SnapBuildDistributeNewCatalogSnapshot (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
0 commit comments