@@ -911,105 +911,122 @@ SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, TransactionId xid,
911
911
{
912
912
int nxact ;
913
913
914
- bool forced_timetravel = false;
914
+ bool needs_snapshot = false;
915
+ bool needs_timetravel = false;
915
916
bool sub_needs_timetravel = false;
916
- bool top_needs_timetravel = false;
917
917
918
918
TransactionId xmax = xid ;
919
919
920
920
/*
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.
928
923
*/
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
+
929
934
if (builder -> state < SNAPBUILD_CONSISTENT )
930
935
{
931
936
/* ensure that only commits after this are getting replayed */
932
937
if (builder -> start_decoding_at <= lsn )
933
938
builder -> start_decoding_at = lsn + 1 ;
934
939
935
940
/*
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.
939
943
*/
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
+ }
942
948
}
943
949
944
950
for (nxact = 0 ; nxact < nsubxacts ; nxact ++ )
945
951
{
946
952
TransactionId subxid = subxacts [nxact ];
947
953
948
954
/*
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 .
951
957
*/
952
- if (forced_timetravel )
958
+ if (ReorderBufferXidHasCatalogChanges ( builder -> reorder , subxid ) )
953
959
{
960
+ sub_needs_timetravel = true;
961
+ needs_snapshot = true;
962
+
963
+ elog (DEBUG1 , "found subtransaction %u:%u with catalog changes" ,
964
+ xid , subxid );
965
+
954
966
SnapBuildAddCommittedTxn (builder , subxid );
967
+
955
968
if (NormalTransactionIdFollows (subxid , xmax ))
956
969
xmax = subxid ;
957
970
}
958
-
959
971
/*
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.
962
976
*/
963
- else if (ReorderBufferXidHasCatalogChanges ( builder -> reorder , subxid ) )
977
+ else if (needs_timetravel )
964
978
{
965
- sub_needs_timetravel = true;
966
-
967
- elog (DEBUG1 , "found subtransaction %u:%u with catalog changes." ,
968
- xid , subxid );
969
-
970
979
SnapBuildAddCommittedTxn (builder , subxid );
971
-
972
980
if (NormalTransactionIdFollows (subxid , xmax ))
973
981
xmax = subxid ;
974
982
}
975
983
}
976
984
977
- if (forced_timetravel )
985
+ /* if top-level modified catalog, it'll need a snapshot */
986
+ if (ReorderBufferXidHasCatalogChanges (builder -> reorder , xid ))
978
987
{
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;
981
992
SnapBuildAddCommittedTxn (builder , xid );
982
993
}
983
- /* add toplevel transaction to base snapshot */
984
- else if (ReorderBufferXidHasCatalogChanges (builder -> reorder , xid ))
994
+ else if (sub_needs_timetravel )
985
995
{
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 */
990
997
SnapBuildAddCommittedTxn (builder , xid );
991
998
}
992
- else if (sub_needs_timetravel )
999
+ else if (needs_timetravel )
993
1000
{
994
- /* mark toplevel txn as timetravel as well */
1001
+ elog (DEBUG2 , "forced transaction %u to do timetravel" , xid );
1002
+
995
1003
SnapBuildAddCommittedTxn (builder , xid );
996
1004
}
997
1005
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 )
1000
1007
{
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 );
1012
1013
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
+ {
1013
1030
/*
1014
1031
* If we haven't built a complete snapshot yet there's no need to hand
1015
1032
* it out, it wouldn't (and couldn't) be used anyway.
@@ -1041,11 +1058,6 @@ SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, TransactionId xid,
1041
1058
/* add a new Snapshot to all currently running transactions */
1042
1059
SnapBuildDistributeNewCatalogSnapshot (builder , lsn );
1043
1060
}
1044
- else
1045
- {
1046
- /* record that we cannot export a general snapshot anymore */
1047
- builder -> committed .includes_all_transactions = false;
1048
- }
1049
1061
}
1050
1062
1051
1063
0 commit comments