@@ -929,105 +929,122 @@ SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, TransactionId xid,
929
929
{
930
930
int nxact ;
931
931
932
- bool forced_timetravel = false;
932
+ bool needs_snapshot = false;
933
+ bool needs_timetravel = false;
933
934
bool sub_needs_timetravel = false;
934
- bool top_needs_timetravel = false;
935
935
936
936
TransactionId xmax = xid ;
937
937
938
938
/*
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.
946
941
*/
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
+
947
952
if (builder -> state < SNAPBUILD_CONSISTENT )
948
953
{
949
954
/* ensure that only commits after this are getting replayed */
950
955
if (builder -> start_decoding_at <= lsn )
951
956
builder -> start_decoding_at = lsn + 1 ;
952
957
953
958
/*
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.
957
961
*/
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
+ }
960
966
}
961
967
962
968
for (nxact = 0 ; nxact < nsubxacts ; nxact ++ )
963
969
{
964
970
TransactionId subxid = subxacts [nxact ];
965
971
966
972
/*
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 .
969
975
*/
970
- if (forced_timetravel )
976
+ if (ReorderBufferXidHasCatalogChanges ( builder -> reorder , subxid ) )
971
977
{
978
+ sub_needs_timetravel = true;
979
+ needs_snapshot = true;
980
+
981
+ elog (DEBUG1 , "found subtransaction %u:%u with catalog changes" ,
982
+ xid , subxid );
983
+
972
984
SnapBuildAddCommittedTxn (builder , subxid );
985
+
973
986
if (NormalTransactionIdFollows (subxid , xmax ))
974
987
xmax = subxid ;
975
988
}
976
-
977
989
/*
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.
980
994
*/
981
- else if (ReorderBufferXidHasCatalogChanges ( builder -> reorder , subxid ) )
995
+ else if (needs_timetravel )
982
996
{
983
- sub_needs_timetravel = true;
984
-
985
- elog (DEBUG1 , "found subtransaction %u:%u with catalog changes." ,
986
- xid , subxid );
987
-
988
997
SnapBuildAddCommittedTxn (builder , subxid );
989
-
990
998
if (NormalTransactionIdFollows (subxid , xmax ))
991
999
xmax = subxid ;
992
1000
}
993
1001
}
994
1002
995
- if (forced_timetravel )
1003
+ /* if top-level modified catalog, it'll need a snapshot */
1004
+ if (ReorderBufferXidHasCatalogChanges (builder -> reorder , xid ))
996
1005
{
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;
999
1010
SnapBuildAddCommittedTxn (builder , xid );
1000
1011
}
1001
- /* add toplevel transaction to base snapshot */
1002
- else if (ReorderBufferXidHasCatalogChanges (builder -> reorder , xid ))
1012
+ else if (sub_needs_timetravel )
1003
1013
{
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 */
1008
1015
SnapBuildAddCommittedTxn (builder , xid );
1009
1016
}
1010
- else if (sub_needs_timetravel )
1017
+ else if (needs_timetravel )
1011
1018
{
1012
- /* mark toplevel txn as timetravel as well */
1019
+ elog (DEBUG2 , "forced transaction %u to do timetravel" , xid );
1020
+
1013
1021
SnapBuildAddCommittedTxn (builder , xid );
1014
1022
}
1015
1023
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 )
1018
1025
{
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 );
1030
1031
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
+ {
1031
1048
/*
1032
1049
* If we haven't built a complete snapshot yet there's no need to hand
1033
1050
* it out, it wouldn't (and couldn't) be used anyway.
@@ -1059,11 +1076,6 @@ SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, TransactionId xid,
1059
1076
/* add a new Snapshot to all currently running transactions */
1060
1077
SnapBuildDistributeNewCatalogSnapshot (builder , lsn );
1061
1078
}
1062
- else
1063
- {
1064
- /* record that we cannot export a general snapshot anymore */
1065
- builder -> committed .includes_all_transactions = false;
1066
- }
1067
1079
}
1068
1080
1069
1081
0 commit comments