pingcap / pingcap/tidb-operator
TiCDC rolling updates resign the next owner too early and skip drain after query failures
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 1.3k
- Forks
- 540
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 18
Description
Bug Report
What version of TiDB Operator are you using?
v1.6.3. The same affected code remains in v1.6.6 and release-1.x.
What did you do?
Roll two TiCDC Pods in descending ordinal order: a first, then b, with b initially the owner.
What did you expect to see?
Drain a → restart a and wait for readiness → resign b → drain b → restart b. Failed maintenance queries should return an error for the existing controller retry mechanism. Query failures must not cause drain to be skipped. The existing Pod maintenance timeout policy remains unchanged.
What did you see instead?
- After draining a, Operator asks b to resign before allowing a to restart. Since a is already
Stoppingand cannot become owner, b can repeatedly resign and win election again until maintenance times out. - A captures HTTP 500 or response decode failure can become an empty capture list without an error. Maintenance then skips drain and can allow Pod replacement without migrating its work.
Related issues in Operator v2 (code inspection)
Checked main (7fe7fa7e), release-2.0 (85bda3ea), and release-2.1 (c5f44a09). The following problems remain in all three branches:
- Captures queries and drain requests still target the Pod being maintained, so they depend on that Pod forwarding requests after owner handoff. This retains the failure path where the old owner cannot resolve or reach the new owner.
- A drain response that fails JSON decoding returns
0, nil. An empty object or missing/nullcurrent_table_countalso produces zero, allowing maintenance to proceed without confirmation that drain completed. Client implementation. - The preStop hook exits its polling loop on a resign/drain API error. It does not retry that failure before returning; Pod termination is already underway at this point. preStop implementation.
The two v1 behaviors reported above have different handling in v2: the pre-delete check maintains only the current Pod, and a captures HTTP 500 propagates an error that blocks that deletion attempt. Pre-delete check.
These v2 findings are based on code inspection; a v2 cluster reproduction has not been run.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with pkg/ticdcapi/v1/client.go and trace the rolling-update maintenance flow, then inspect cmd/prestop-checker/main.go and pkg/controllers/ticdc/tasks/pod.go. Compare the affected v1 behavior with the v2 findings and existing retry or timeout handling. Done means resignation and draining follow the stated order, query and decode failures remain errors, and maintenance cannot proceed without confirmed draining.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, kubernetes
- Domain
- devops, infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100