@@ -1542,7 +1542,12 @@ func (cf *changeFrontier) Start(ctx context.Context) {
15421542 return
15431543 }
15441544 execCfg := cf .FlowCtx .Cfg .ExecutorConfig .(* sql.ExecutorConfig )
1545- cf .tsWatcher = tableset .NewWatcher (wFilter , execCfg , cf .FlowCtx .Cfg .ChangefeedMonitor , int64 (cf .spec .JobID ))
1545+ cf .tsWatcher , err = tableset .NewWatcher (ctx , wFilter , execCfg , cf .FlowCtx .Cfg .ChangefeedMonitor , int64 (cf .spec .JobID ))
1546+ if err != nil {
1547+ log .Changefeed .Warningf (cf .Ctx (), "moving to draining due to error creating tableset watcher: %v" , err )
1548+ cf .MoveToDraining (err )
1549+ return
1550+ }
15461551
15471552 wctx , cancel := context .WithCancel (ctx )
15481553 cf .tsWatcherCancel = cancel
@@ -1942,36 +1947,33 @@ func (cf *changeFrontier) checkpointJobProgress(
19421947 // writing span-level checkpoints), ensure that no new tables have been
19431948 // added up to the frontier timestamp. This guarantees we don't persist a
19441949 // checkpoint that would cause us to miss data from newly added tables.
1945- var tablesToAdd []tableset.AddedTable
1950+ var tableAdds tableset.TableAdds
1951+ var err error
19461952 // NOTE: cf.tsWatcher is only set for db-level changefeeds.
19471953 if cf .tsWatcher != nil {
19481954 // N.B. this call is not idempotent. If this code changes to be in a
19491955 // place where it might be retried during the lifetime of the watcher,
1950- // things will be wrong. The watcher makes a best-effort attempt to
1951- // catch this error but even so.
1952- unchanged , diffs , err := cf .tsWatcher .PopUnchangedUpTo (ctx , frontier )
1956+ // the watcher will return an error upon such a retry.
1957+ tableAdds , err = cf .tsWatcher .PopUpTo (ctx , frontier )
19531958 if err != nil {
1954- return err
1955- }
1956- if ! unchanged {
1957- tablesToAdd = diffs .Adds ()
1958- // Add new tables to the frontier and persist it, if there are any.
1959- if len (tablesToAdd ) > 0 {
1960- // If there are changes, we'll only advance the frontier to the creation time of the first added table.
1961- frontier = tablesToAdd [0 ].AsOf
1962- for _ , table := range tablesToAdd {
1963- tableKey := cf .FlowCtx .Cfg .ExecutorConfig .(* sql.ExecutorConfig ).Codec .TablePrefix (uint32 (table .Table .ID ))
1964- rs := jobspb.ResolvedSpan {
1965- Timestamp : table .AsOf ,
1966- Span : roachpb.Span {Key : tableKey , EndKey : tableKey .PrefixEnd ()},
1967- }
1968- // Sanity check: table doesn't currently exist in tableFrontier.
1969- if tableFrontier := cf .frontier .GetFrontier (table .Table .ID ); tableFrontier != nil {
1970- return errors .AssertionFailedf ("table %d (%+v) already exists in frontier with timestamp %s" , table .Table .ID , table .Table .NameInfo , tableFrontier .Frontier ())
1971- }
1972- if _ , err := cf .frontier .ForwardResolvedSpan (rs ); err != nil {
1973- return errors .Wrapf (err , "forwarding resolved span for newly added table in db-level feed" )
1974- }
1959+ return errors .Wrapf (err , "error getting tables to add for db-level changefeed, up to %s" , frontier )
1960+ }
1961+ log .Changefeed .VInfof (ctx , 2 , "table adds: %v" , tableAdds )
1962+ // Add new tables to the frontier and persist it, if there are any.
1963+ if len (tableAdds ) > 0 {
1964+ // If there are changes, advance the frontier to the frontier
1965+ // timestamp of the each added table, and set the HWM to the minimum
1966+ // of those, which is the first one.
1967+ frontier = tableAdds .Frontier ()
1968+ for _ , table := range tableAdds {
1969+ tableKey := cf .FlowCtx .Cfg .ExecutorConfig .(* sql.ExecutorConfig ).Codec .TablePrefix (uint32 (table .Table .ID ))
1970+ rs := jobspb.ResolvedSpan {
1971+ Timestamp : table .AsOf ,
1972+ Span : roachpb.Span {Key : tableKey , EndKey : tableKey .PrefixEnd ()},
1973+ }
1974+ // If the table already exists in the frontier, the add is a rename that doesn't affect us. Either way, forwarding it should be safe.
1975+ if _ , err := cf .frontier .ForwardResolvedSpan (rs ); err != nil {
1976+ return errors .Wrapf (err , "forwarding resolved span for newly added table in db-level feed" )
19751977 }
19761978 }
19771979 }
@@ -2016,7 +2018,7 @@ func (cf *changeFrontier) checkpointJobProgress(
20162018 ju .UpdateProgress (progress )
20172019
20182020 // Persist new tables to the frontier.
2019- if len (tablesToAdd ) > 0 {
2021+ if len (tableAdds ) > 0 {
20202022 if err := cf .persistFrontier (ctx , txn ); err != nil {
20212023 return err
20222024 }
@@ -2038,8 +2040,8 @@ func (cf *changeFrontier) checkpointJobProgress(
20382040 cf .localState .SetHighwater (frontier )
20392041 cf .localState .SetCheckpoint (spanLevelCheckpoint )
20402042
2041- if len (tablesToAdd ) > 0 {
2042- return errors .Wrapf (errDatabaseTargetsChanged , "(progress saved) before checkpoint at %s: %v" , frontier , tablesToAdd )
2043+ if len (tableAdds ) > 0 {
2044+ return errors .Wrapf (errDatabaseTargetsChanged , "(progress saved) before checkpoint at %s: %v" , frontier , tableAdds )
20432045 }
20442046
20452047 return nil
0 commit comments