pingcap / pingcap/tidb-operator

TiCDC rolling updates resign the next owner too early and skip drain after query failures

Open
#7,059 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area/controller type/bug
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 Stopping and 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/null current_table_count also 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.