Skip to content

sink: add async ddl timeout for add index - #5836

Open
wk989898 wants to merge 7 commits into
pingcap:masterfrom
wk989898:async-ddl
Open

sink: add async ddl timeout for add index#5836
wk989898 wants to merge 7 commits into
pingcap:masterfrom
wk989898:async-ddl

Conversation

@wk989898

@wk989898 wk989898 commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

What problem does this PR solve?

Issue Number: close #5711 close #1926

What is changed and how it works?

The change adds a dedicated timeout path for TiDB async DDL, specifically ADD INDEX.
Added a new MySQL sink option async-ddl-timeout, the default value is 10s. It can be set in sink URI: mysql://.../?async-ddl-timeout=30m

  • The sink now uses separate DB pools:
    • dmlDB: DML writes.
    • controlDB: normal DDL, DDL-ts, syncpoint, progress metadata, etc.
    • controlAsyncDB: only for TiDB ADD INDEX. controlAsyncDB is created only when the downstream is confirmed to be TiDB.
  • DDL execution now chooses the DB based on DDL type:
    • TiDB ADD INDEX uses controlAsyncDB and async-ddl-timeout.
    • All other DDLs use controlDB and the normal read-timeout.

Check List

Tests

  • Unit test
  • Integration test

Questions

Will it cause performance regression or break compatibility?
Do you need to update user documentation, design documentation or monitoring documentation?

Release note

Please refer to [Release Notes Language Style Guide](https://pingcap.github.io/tidb-dev-guide/contribute-to-tidb/release-notes-style-guide.html) to write a quality release note.

If you don't think this PR needs a release note then fill it with `None`.

Summary by CodeRabbit

  • New Features

    • Added configurable asynchronous DDL timeouts for TiDB downstreams.
    • TiDB ADD INDEX operations now use a dedicated asynchronous connection with its own timeout.
    • Async DDL timeout settings are supported through sink configuration, API, and configuration files.
  • Bug Fixes

    • Improved timeout handling while preserving existing settings for other DDL operations.
    • MySQL operations continue using the standard control connection.
    • Invalid asynchronous DDL timeout values are rejected with validation errors.

Signed-off-by: wk989898 <nhsmwk@gmail.com>
@ti-chi-bot

ti-chi-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@ti-chi-bot ti-chi-bot Bot added release-note Denotes a PR that will be considered when it comes time to generate release notes. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. labels Jul 31, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign nongfushanquan for approval. For more information see the Code Review Process.
Please ensure that each of them provides their approval before proceeding.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ti-chi-bot ti-chi-bot Bot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Jul 31, 2026
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b65517a8-bb27-4b9a-9d26-148cb1457616

📥 Commits

Reviewing files that changed from the base of the PR and between 69c95ab and 957a17b.

📒 Files selected for processing (3)
  • api/v2/model.go
  • api/v2/model_test.go
  • cmd/cdc/cli/cli_changefeed_create_test.go

📝 Walkthrough

Walkthrough

MySQL sink configuration now supports asynchronous DDL timeouts and a separate TiDB control pool. Sink construction manages the pool lifecycle. TiDB ADD INDEX DDLs use the asynchronous pool. Other DDLs retain the regular control pool.

Changes

TiDB asynchronous DDL execution

Layer / File(s) Summary
Async pool configuration and creation
pkg/config/sink.go, pkg/sink/mysql/config.go, pkg/sink/mysql/config_test.go, api/v2/model.go, api/v2/model_test.go, cmd/cdc/cli/cli_changefeed_create_test.go
Adds AsyncDDLTimeout, API conversion, timeout precedence and validation, DSN read-timeout rewriting, and TiDB-only asynchronous pool creation.
Sink pool ownership and wiring
downstreamadapter/sink/mysql/sink.go, downstreamadapter/sink/mysql/sink_test.go
Passes the asynchronous pool through sink construction, disables it for MySQL, reuses or derives it for TiDB, and closes independently owned pools.
ADD INDEX DDL routing
pkg/sink/mysql/mysql_writer.go, pkg/sink/mysql/mysql_writer_ddl.go, pkg/sink/mysql/mysql_writer_test.go
Routes TiDB ADD INDEX execution through controlAsyncDB with AsyncDDLTimeout. Other DDL paths use the regular control database and ReadTimeout.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SinkConfig
  participant TiDBSink
  participant DDLWriter
  participant ControlDB
  participant ControlAsyncDB
  SinkConfig->>TiDBSink: create DML, control, and async control pools
  TiDBSink->>DDLWriter: set ControlAsyncDB
  DDLWriter->>ControlDB: retrieve DDL timestamp
  DDLWriter->>ControlAsyncDB: execute TiDB ADD INDEX
  ControlAsyncDB-->>DDLWriter: commit transaction
Loading

Possibly related PRs

  • pingcap/ticdc#5397: Extends the split DML/control pool design with a TiDB-only asynchronous control pool.

Suggested reviewers: 3aceshowhand, hongyunyan, asddongmen

Poem

A rabbit checks the async gate,
TiDB indexes need not wait.
One pool routes the DDL flow,
Regular DDLs keep their row.
Clean shutdown closes what we own.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.08% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: adding an asynchronous DDL timeout for ADD INDEX operations.
Description check ✅ Passed The description includes linked issues, implementation details, and test coverage; blank checklist questions and the placeholder release note are non-critical.
Linked Issues check ✅ Passed The changes add a separate async timeout and pool for TiDB ADD INDEX, avoiding the default synchronous wait and addressing both linked issue objectives [#5711, #1926].
Out of Scope Changes check ✅ Passed All changes support async DDL timeout handling, connection-pool separation, configuration propagation, and related tests.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

wk989898 added 2 commits July 31, 2026 15:22
Signed-off-by: wk989898 <nhsmwk@gmail.com>
Signed-off-by: wk989898 <nhsmwk@gmail.com>
@wk989898

wk989898 commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

/test all

Signed-off-by: wk989898 <nhsmwk@gmail.com>
@wk989898
wk989898 marked this pull request as ready for review August 3, 2026 08:30
@ti-chi-bot ti-chi-bot Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Aug 3, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/sink/mysql/config.go`:
- Around line 285-293: Validate the config-supplied AsyncDDLTimeout before
assigning it in mergeConfig alongside the other MySQLConfig duration fields.
Ensure invalid duration strings return an error, while valid values are
converted and assigned consistently; keep Apply’s query-parameter handling and
non-TiDB behavior unchanged.
- Around line 356-389: Extract the duplicated dmlDB-then-controlDB cleanup and
warning logic from the TiDB error paths in the surrounding connection setup
function into a small helper, parameterized by the failure-context message
suffix. Replace both inline cleanup blocks after setDSNReadTimeout and
CreateMysqlDBConn failures with calls to that helper, preserving the existing
close order, warning fields, and returned errors.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1a57d499-b353-4971-b15f-2a2e63969a86

📥 Commits

Reviewing files that changed from the base of the PR and between af33cc1 and 1714741.

📒 Files selected for processing (8)
  • downstreamadapter/sink/mysql/sink.go
  • downstreamadapter/sink/mysql/sink_test.go
  • pkg/config/sink.go
  • pkg/sink/mysql/config.go
  • pkg/sink/mysql/config_test.go
  • pkg/sink/mysql/mysql_writer.go
  • pkg/sink/mysql/mysql_writer_ddl.go
  • pkg/sink/mysql/mysql_writer_test.go

Comment thread pkg/sink/mysql/config.go Outdated
Comment on lines +285 to +293
if cfg != nil &&
cfg.SinkConfig != nil &&
cfg.SinkConfig.MySQLConfig != nil &&
cfg.SinkConfig.MySQLConfig.AsyncDDLTimeout != nil {
c.AsyncDDLTimeout = *cfg.SinkConfig.MySQLConfig.AsyncDDLTimeout
}
if err = getDuration(query, "async-ddl-timeout", &c.AsyncDDLTimeout); err != nil {
return err
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
ast-grep run --pattern 'func getDuration($$$) $$$' --lang go pkg/sink/mysql

Repository: pingcap/ticdc

Length of output: 768


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- config.go relevant sections ---\n'
sed -n '250,300p' pkg/sink/mysql/config.go
printf '\n--- NewMysqlConfigAndDBs / apply timeout sections ---\n'
sed -n '320,410p' pkg/sink/mysql/config.go
printf '\n--- mergeConfig / duration setters ---\n'
sed -n '170,250p' pkg/sink/mysql/config.go
printf '\n--- setDSNReadTimeout usages ---\n'
rg -n "setDSNReadTimeout|IsTiDB|AsyncDDLTimeout|DialTimeout|WriteTimeout|ReadTimeout" pkg/sink/mysql/config.go

Repository: pingcap/ticdc

Length of output: 242


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- config.go relevant sections ---'
sed -n '250,300p' pkg/sink/mysql/config.go
printf '%s\n' ''
printf '%s\n' '--- NewMysqlConfigAndDBs timeout sections ---'
sed -n '320,410p' pkg/sink/mysql/config.go
printf '%s\n' ''
printf '%s\n' '--- mergeConfig and duration setters ---'
sed -n '170,250p' pkg/sink/mysql/config.go
printf '%s\n' ''
printf '%s\n' '--- setDSNReadTimeout usages ---'
rg -n "setDSNReadTimeout|IsTiDB|AsyncDDLTimeout|DialTimeout|WriteTimeout|ReadTimeout" pkg/sink/mysql/config.go

Repository: pingcap/ticdc

Length of output: 9965


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- setDSNReadTimeout implementation ---'
sed -n '460,500p' pkg/sink/mysql/config.go
printf '%s\n' ''
printf '%s\n' '--- Apply merge and duration helpers area ---'
sed -n '200,295p' pkg/sink/mysql/config.go
printf '%s\n' ''
printf '%s\n' '--- getDuration helper ---'
sed -n '700,735p' pkg/sink/mysql/config.go

Repository: pingcap/ticdc

Length of output: 5849


Validate AsyncDDLTimeout when it is copied from config.

Apply() copies cfg.SinkConfig.MySQLConfig.AsyncDDLTimeout directly, then calls getDuration("async-ddl-timeout", ...) which only checks URI query params. setDSNReadTimeout() validates cfg.AsyncDDLTimeout only for TiDB downstreams. A config-supplied invalid duration passes Apply() for non-TiDB MySQL downstreams. Validate the config string before assigning it, ideally in mergeConfig with the other MySQLConfig duration fields.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/sink/mysql/config.go` around lines 285 - 293, Validate the
config-supplied AsyncDDLTimeout before assigning it in mergeConfig alongside the
other MySQLConfig duration fields. Ensure invalid duration strings return an
error, while valid values are converted and assigned consistently; keep Apply’s
query-parameter handling and non-TiDB behavior unchanged.

Comment thread pkg/sink/mysql/config.go
@wk989898

wk989898 commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

/test all

Signed-off-by: wk989898 <nhsmwk@gmail.com>
Signed-off-by: wk989898 <nhsmwk@gmail.com>
@wk989898

wk989898 commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator Author

/test all

Signed-off-by: wk989898 <nhsmwk@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adding an index may result in increased lag when the timeout is large Optimize ADD INDEX Operations in MySQL Sink

1 participant