@@ -911,105 +911,122 @@ SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, TransactionId xid,
911911{
912912 int nxact ;
913913
914- bool forced_timetravel = false;
914+ bool needs_snapshot = false;
915+ bool needs_timetravel = false;
915916 bool sub_needs_timetravel = false;
916- bool top_needs_timetravel = false;
917917
918918 TransactionId 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+
929934 if (builder -> state < SNAPBUILD_CONSISTENT )
930935 {
931936 /* ensure that only commits after this are getting replayed */
932937 if (builder -> start_decoding_at <= lsn )
933938 builder -> 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
944950 for (nxact = 0 ; nxact < nsubxacts ; nxact ++ )
945951 {
946952 TransactionId 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+
954966 SnapBuildAddCommittedTxn (builder , subxid );
967+
955968 if (NormalTransactionIdFollows (subxid , xmax ))
956969 xmax = 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-
970979 SnapBuildAddCommittedTxn (builder , subxid );
971-
972980 if (NormalTransactionIdFollows (subxid , xmax ))
973981 xmax = 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;
981992 SnapBuildAddCommittedTxn (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 */
990997 SnapBuildAddCommittedTxn (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+
9951003 SnapBuildAddCommittedTxn (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 */
10421059 SnapBuildDistributeNewCatalogSnapshot (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
0 commit comments