-
Notifications
You must be signed in to change notification settings - Fork 42
for test #4342
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
for test #4342
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,6 +45,10 @@ const ( | |
|
|
||
| defaultMaxBatchSize = 128 | ||
| defaultFlushResolvedTsInterval = 25 * time.Millisecond | ||
| // defaultBootstrapResolvedTsInterval controls the synthetic resolvedTs tick | ||
| // before upstream resolvedTs catches up. | ||
| defaultBootstrapResolvedTsInterval = time.Second | ||
| bootstrapResolvedTsStep = time.Second | ||
|
|
||
| defaultReportDispatcherStatToStoreInterval = time.Second * 10 | ||
|
|
||
|
|
@@ -173,6 +177,10 @@ func newEventBroker( | |
| return c.logUninitializedDispatchers(ctx) | ||
| }) | ||
|
|
||
| g.Go(func() error { | ||
| return c.tickBootstrapResolvedTs(ctx) | ||
| }) | ||
|
|
||
| g.Go(func() error { | ||
| return c.reportDispatcherStatToStore(ctx, defaultReportDispatcherStatToStoreInterval) | ||
| }) | ||
|
|
@@ -297,6 +305,25 @@ func (c *eventBroker) sendResolvedTs(d *dispatcherStat, watermark uint64) { | |
| updateMetricEventServiceSendResolvedTsCount(d.info.GetMode()) | ||
| } | ||
|
|
||
| func (c *eventBroker) sendBootstrapResolvedTs(d *dispatcherStat, watermark uint64) bool { | ||
| remoteID := node.ID(d.info.GetServerID()) | ||
| c.emitSyncPointEventIfNeeded(watermark, d, remoteID) | ||
| re := event.NewResolvedEvent(watermark, d.id, d.epoch) | ||
| re.Seq = d.seq.Load() | ||
| resolvedEvent := newWrapResolvedEvent(remoteID, re) | ||
| ch := c.getMessageCh(d.messageWorkerIndex, common.IsRedoMode(d.info.GetMode())) | ||
| select { | ||
| case ch <- resolvedEvent: | ||
| d.updateSentResolvedTs(watermark) | ||
| updateMetricEventServiceSendResolvedTsCount(d.info.GetMode()) | ||
| return true | ||
| default: | ||
| // Avoid blocking broker tick path. The next ticker round will retry. | ||
| resolvedEvent.reset() | ||
| return false | ||
| } | ||
| } | ||
|
|
||
| func (c *eventBroker) sendNotReusableEvent( | ||
| server node.ID, | ||
| d *dispatcherStat, | ||
|
|
@@ -402,6 +429,48 @@ func (c *eventBroker) logUninitializedDispatchers(ctx context.Context) error { | |
| } | ||
| } | ||
|
|
||
| func (c *eventBroker) tickBootstrapResolvedTs(ctx context.Context) error { | ||
| ticker := time.NewTicker(defaultBootstrapResolvedTsInterval) | ||
| defer ticker.Stop() | ||
|
|
||
| for { | ||
| select { | ||
| case <-ctx.Done(): | ||
| return context.Cause(ctx) | ||
| case <-ticker.C: | ||
| c.dispatchers.Range(func(_, value interface{}) bool { | ||
| dispatcher := value.(*atomic.Pointer[dispatcherStat]).Load() | ||
| c.sendBootstrapResolvedTsIfNeeded(dispatcher) | ||
| return true | ||
| }) | ||
|
Comment on lines
+441
to
+445
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This loop only iterates over
c.dispatchers.Range(func(_, value interface{}) bool {
dispatcher := value.(*atomic.Pointer[dispatcherStat]).Load()
c.sendBootstrapResolvedTsIfNeeded(dispatcher)
return true
})
c.tableTriggerDispatchers.Range(func(_, value interface{}) bool {
dispatcher := value.(*atomic.Pointer[dispatcherStat]).Load()
c.sendBootstrapResolvedTsIfNeeded(dispatcher)
return true
}) |
||
| } | ||
| } | ||
| } | ||
|
|
||
| func (c *eventBroker) sendBootstrapResolvedTsIfNeeded(dispatcher *dispatcherStat) { | ||
| if dispatcher == nil || dispatcher.isRemoved.Load() { | ||
| return | ||
| } | ||
|
|
||
| // For epoch 0 dispatchers, drive the ready/reset handshake first. | ||
| if dispatcher.epoch == 0 { | ||
| c.checkAndSendReady(dispatcher) | ||
| return | ||
| } | ||
|
|
||
| sentResolvedTs := dispatcher.sentResolvedTs.Load() | ||
| receivedResolvedTs := dispatcher.receivedResolvedTs.Load() | ||
| // Stop synthetic advancement once upstream resolved-ts catches up. | ||
| if dispatcher.hasReceivedFirstResolvedTs.Load() && receivedResolvedTs >= sentResolvedTs { | ||
| return | ||
| } | ||
|
|
||
| c.sendHandshakeIfNeed(dispatcher) | ||
| nextResolvedTs := oracle.GoTimeToTS(oracle.GetTimeFromTS(sentResolvedTs).Add(bootstrapResolvedTsStep)) | ||
| c.sendBootstrapResolvedTs(dispatcher, nextResolvedTs) | ||
| log.Debug("fizz send resolvedTs", zap.Any("dispatcherID", dispatcher.id), zap.Any("resolvedTs", nextResolvedTs)) | ||
| } | ||
|
|
||
| // getScanTaskDataRange determines the valid data range for scanning a given task. | ||
| // It checks various conditions (dispatcher status, DDL state, max commit ts of dml event) | ||
| // to decide whether scanning is needed and returns the appropriate time range. | ||
|
|
@@ -1043,6 +1112,10 @@ func (c *eventBroker) addDispatcher(info DispatcherInfo) error { | |
| } | ||
| c.dispatchers.Store(id, dispatcherPtr) | ||
| c.metricsCollector.metricDispatcherCount.Inc() | ||
| if dispatcher.epoch > 0 { | ||
| c.sendHandshakeIfNeed(dispatcher) | ||
| c.sendBootstrapResolvedTs(dispatcher, dispatcher.startTs) | ||
| } | ||
| log.Info("register dispatcher", | ||
| zap.Uint64("clusterID", c.tidbClusterID), | ||
| zap.Stringer("changefeedID", changefeedID), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic in this loop to ensure
sentResolvedTsis monotonic is correct, but it could be simplified for better readability and maintainability. The current implementation with two separateifconditions and modification of theresolvedTsparameter can be made more straightforward.