Skip to content

*: br,lightning,import use meta service group#69780

Open
ystaticy wants to merge 6 commits into
pingcap:masterfrom
ystaticy:msg_br_lighting_import
Open

*: br,lightning,import use meta service group#69780
ystaticy wants to merge 6 commits into
pingcap:masterfrom
ystaticy:msg_br_lighting_import

Conversation

@ystaticy

@ystaticy ystaticy commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: ref #68338

Problem Summary:

What changed and how does it work?

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No need to test
    • I checked and no code files have been changed.

Side effects

  • Performance regression: Consumes more CPU
  • Performance regression: Consumes more Memory
  • Breaking backward compatibility

Documentation

  • Affects user behaviors
  • Contains syntax changes
  • Contains variable changes
  • Contains experimental features
  • Changes MySQL compatibility

Release note

Please refer to Release Notes Language Style Guide to write a quality release note.

None

Summary by CodeRabbit

Summary of updates

  • New Features

    • Keyspace-aware etcd connectivity now resolves metadata service group endpoints and uses the correct keyspace namespace during dialing, including for local-backend paths.
    • etcd dialing is metadata-driven and supports TLS during endpoint resolution.
  • Bug Fixes

    • Improved PD endpoint parsing/normalization to correctly handle unix:// endpoints for metadata-driven dialing.
  • Tests

    • Added/expanded integration tests to verify correct meta-service-group dialing and namespace/key placement (restore, import, allocator rebase).
  • Chores

    • Updated Bazel deps and test shard counts for the new coverage.

Signed-off-by: ystaticy <y_static_y@sina.com>
@ti-chi-bot ti-chi-bot Bot added do-not-merge/needs-linked-issue do-not-merge/needs-tests-checked release-note-none Denotes a PR that doesn't merit a release note. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Jul 12, 2026
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

BR, Lightning, executor importer, and store etcd paths now resolve metaservice endpoints and keyspace namespaces from PD metadata. Shared utilities centralize endpoint parsing and namespaced client creation, with integration tests covering Unix endpoints and keyspace-scoped writes.

Changes

Keyspace-aware etcd resolution

Layer / File(s) Summary
Service URL and metaservice resolution
pkg/util/..., pkg/metaservice/...
Adds service URL parsing and normalization, PD-backed endpoint resolution, keyspace namespace derivation, and centralized etcd client creation.
BR task and operator dialing
br/pkg/task/..., br/pkg/task/operator/...
BR task and CRR checkpoint clients use metaservice dialing and test namespaced writes.
Lightning importer dialing
lightning/pkg/importer/...
Precheck and local-backend flows use PD and keyspace metadata for etcd clients and validate namespaced writes.
Executor allocator dialing
pkg/executor/importer/...
Allocator rebase uses TiKV storage metadata to create a namespaced etcd client.
Store and mockstore validation
pkg/store/..., pkg/store/mockstore/unistore/...
Store tests verify namespace placement, while mock PD discovery normalizes addresses, supports Unix endpoints, and returns injected members.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller as BR or Lightning caller
  participant Meta as metaservice.DialEtcdClient
  participant PD as PD client
  participant Etcd as etcd client
  Caller->>Meta: Request etcd client with keyspace name
  Meta->>PD: Load keyspace metadata and members
  Meta->>Meta: Resolve endpoints and namespace
  Meta->>Etcd: Create namespaced client
  Meta-->>Caller: Return configured etcd client
  Caller->>Etcd: Write keyspace-scoped task data
Loading

Possibly related PRs

Suggested labels: component/pd, ok-to-test, approved, lgtm

Suggested reviewers: d3hunter, yangkeao

Poem

I’m a rabbit with keys in my paw,
Guiding etcd by metadata law.
Through PD paths I hop and roam,
Namespaced writes arrive safely home.
BR and Lightning share the trail!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The template is present, but the Problem Summary and What changed sections are empty, so the description is too incomplete. Add a Problem Summary and a clear What changed/how it works section, and fill out any applicable side effects and documentation items.
Docstring Coverage ⚠️ Warning Docstring coverage is 42.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change by stating BR, Lightning, and Import now use the meta service group.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
pkg/store/etcd_test.go (1)

83-84: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider using metaservice.GroupIDKey and metaservice.GroupAddrsKey constants instead of string literals.

The Lightning test (lightning/pkg/importer/meta_service_group_test.go:64-65) uses the metaservice package constants for these config keys, while this test uses raw string literals. If the constant values ever change, this test would break silently. Using the constants would require adding //pkg/metaservice to the store_test BUILD.bazel deps.

♻️ Optional refactor for consistency
 		Config: map[string]string{
 			"gc_management_type":       "keyspace_level",
-			"meta_service_group_id":    "group1",
-			"meta_service_group_addrs": strings.Join(metaCluster.Client(0).Endpoints(), ","),
+			metaservice.GroupIDKey:     "group1",
+			metaservice.GroupAddrsKey:   strings.Join(metaCluster.Client(0).Endpoints(), ","),
 		}

This would also require adding the import and BUILD.bazel dependency:

+	"github.com/pingcap/tidb/pkg/metaservice"

In pkg/store/BUILD.bazel:

+        "//pkg/metaservice",
🤖 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/store/etcd_test.go` around lines 83 - 84, Replace the raw
"meta_service_group_id" and "meta_service_group_addrs" keys in the test
configuration with metaservice.GroupIDKey and metaservice.GroupAddrsKey. Add the
metaservice import and declare the corresponding //pkg/metaservice dependency in
the store_test BUILD.bazel target.
🤖 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.

Nitpick comments:
In `@pkg/store/etcd_test.go`:
- Around line 83-84: Replace the raw "meta_service_group_id" and
"meta_service_group_addrs" keys in the test configuration with
metaservice.GroupIDKey and metaservice.GroupAddrsKey. Add the metaservice import
and declare the corresponding //pkg/metaservice dependency in the store_test
BUILD.bazel target.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1b1a3e6e-bb12-4902-80ab-d18c8dda4ab3

📥 Commits

Reviewing files that changed from the base of the PR and between b94006d and d6df859.

📒 Files selected for processing (10)
  • br/pkg/task/BUILD.bazel
  • br/pkg/task/common.go
  • br/pkg/task/meta_service_group_test.go
  • lightning/pkg/importer/BUILD.bazel
  • lightning/pkg/importer/meta_service_group_test.go
  • lightning/pkg/importer/precheck_impl.go
  • pkg/metaservice/BUILD.bazel
  • pkg/metaservice/etcd.go
  • pkg/store/BUILD.bazel
  • pkg/store/etcd_test.go

@codecov

codecov Bot commented Jul 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 64.28571% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.3634%. Comparing base (b94006d) to head (04be59c).
⚠️ Report is 6 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #69780        +/-   ##
================================================
+ Coverage   76.3194%   76.3634%   +0.0439%     
================================================
  Files          2041       2042         +1     
  Lines        560102     562363      +2261     
================================================
+ Hits         427467     429440      +1973     
- Misses       131734     131797        +63     
- Partials        901       1126       +225     
Flag Coverage Δ
integration 45.4671% <64.2857%> (+5.7618%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
dumpling 60.4471% <ø> (ø)
parser ∅ <ø> (∅)
br 63.9807% <64.2857%> (+1.2594%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

ystaticy added 2 commits July 12, 2026 21:45
Signed-off-by: ystaticy <y_static_y@sina.com>
Signed-off-by: ystaticy <y_static_y@sina.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
br/pkg/task/common.go (1)

222-222: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider updating the log message to reflect post-connection state.

With grpc.WithBlock() in the dial options, DialEtcdClient blocks until the etcd connection is established. By the time line 222 executes, the connection is already active, so "trying to connect to etcd" is slightly misleading. Consider "connected to etcd" for accuracy.

✏️ Proposed tweak
-	log.Info("trying to connect to etcd", zap.Strings("addr", etcdCLI.Endpoints()))
+	log.Info("connected to etcd", zap.Strings("addr", etcdCLI.Endpoints()))
🤖 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 `@br/pkg/task/common.go` at line 222, Update the log message in DialEtcdClient
after the blocking etcd dial to state that the client is connected rather than
still trying to connect, while preserving the existing endpoint fields.
🤖 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/metaservice/etcd.go`:
- Around line 77-126: Update the missing-metadata error in DialEtcdClient to
include the keyspaceName value, while preserving the existing error path and
message meaning.

---

Nitpick comments:
In `@br/pkg/task/common.go`:
- Line 222: Update the log message in DialEtcdClient after the blocking etcd
dial to state that the client is connected rather than still trying to connect,
while preserving the existing endpoint fields.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 78a32d2f-21e3-4bf3-899e-1665759aa001

📥 Commits

Reviewing files that changed from the base of the PR and between d6df859 and 5580cdb.

📒 Files selected for processing (9)
  • br/pkg/task/BUILD.bazel
  • br/pkg/task/common.go
  • br/pkg/task/meta_service_group_test.go
  • lightning/pkg/importer/BUILD.bazel
  • lightning/pkg/importer/meta_service_group_test.go
  • lightning/pkg/importer/precheck_impl.go
  • pkg/metaservice/BUILD.bazel
  • pkg/metaservice/etcd.go
  • pkg/store/etcd_test.go
💤 Files with no reviewable changes (2)
  • lightning/pkg/importer/BUILD.bazel
  • br/pkg/task/BUILD.bazel
🚧 Files skipped from review as they are similar to previous changes (4)
  • lightning/pkg/importer/meta_service_group_test.go
  • br/pkg/task/meta_service_group_test.go
  • pkg/store/etcd_test.go
  • lightning/pkg/importer/precheck_impl.go

Comment thread pkg/metaservice/etcd.go
Comment on lines +77 to +126
// DialEtcdClient resolves the target meta service group and returns a namespaced etcd client.
func DialEtcdClient(
ctx context.Context,
keyspaceName string,
pdAddrs []string,
security pd.SecurityOption,
pdClientFactory PDClientFactory,
callerComponent caller.Component,
pdClientOpts []opt.ClientOption,
etcdCfg clientv3.Config,
) (*clientv3.Client, error) {
if pdClientFactory == nil {
pdClientFactory = pd.NewClientWithAPIContext
}

pdCli, err := pdClientFactory(
ctx, keyspace.BuildAPIContext(keyspaceName), callerComponent, pdAddrs, security, pdClientOpts...,
)
if err != nil {
return nil, err
}
defer pdCli.Close()

var keyspaceMeta *keyspacepb.KeyspaceMeta
if keyspaceName != "" {
keyspaceMeta, err = pdCli.LoadKeyspace(ctx, keyspaceName)
if err != nil {
return nil, err
}
if keyspaceMeta == nil {
return nil, errors.New("keyspace meta not found")
}
}

dialInfo, err := ResolveEtcdDialInfo(ctx, pdCli, keyspaceMeta)
if err != nil {
return nil, err
}

etcdCfg.Context = ctx
etcdCfg.Endpoints = dialInfo.Endpoints
etcdCli, err := clientv3.New(etcdCfg)
if err != nil {
return nil, err
}
if dialInfo.Namespace != "" {
etcd.SetEtcdCliByNamespace(etcdCli, dialInfo.Namespace)
}
return etcdCli, nil
}

Copy link
Copy Markdown

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

Include keyspace name in the "not found" error message.

The error at line 107 (errors.New("keyspace meta not found")) is actionable but lacks context — when multiple keyspaces are in play, the operator cannot tell which keyspace failed to resolve. Adding the keyspace name makes triage significantly easier.

🛡️ Proposed fix
 	if keyspaceMeta == nil {
-		return nil, errors.New("keyspace meta not found")
+		return nil, errors.Errorf("keyspace meta not found for keyspace %q", keyspaceName)
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// DialEtcdClient resolves the target meta service group and returns a namespaced etcd client.
func DialEtcdClient(
ctx context.Context,
keyspaceName string,
pdAddrs []string,
security pd.SecurityOption,
pdClientFactory PDClientFactory,
callerComponent caller.Component,
pdClientOpts []opt.ClientOption,
etcdCfg clientv3.Config,
) (*clientv3.Client, error) {
if pdClientFactory == nil {
pdClientFactory = pd.NewClientWithAPIContext
}
pdCli, err := pdClientFactory(
ctx, keyspace.BuildAPIContext(keyspaceName), callerComponent, pdAddrs, security, pdClientOpts...,
)
if err != nil {
return nil, err
}
defer pdCli.Close()
var keyspaceMeta *keyspacepb.KeyspaceMeta
if keyspaceName != "" {
keyspaceMeta, err = pdCli.LoadKeyspace(ctx, keyspaceName)
if err != nil {
return nil, err
}
if keyspaceMeta == nil {
return nil, errors.New("keyspace meta not found")
}
}
dialInfo, err := ResolveEtcdDialInfo(ctx, pdCli, keyspaceMeta)
if err != nil {
return nil, err
}
etcdCfg.Context = ctx
etcdCfg.Endpoints = dialInfo.Endpoints
etcdCli, err := clientv3.New(etcdCfg)
if err != nil {
return nil, err
}
if dialInfo.Namespace != "" {
etcd.SetEtcdCliByNamespace(etcdCli, dialInfo.Namespace)
}
return etcdCli, nil
}
if keyspaceMeta == nil {
return nil, errors.Errorf("keyspace meta not found for keyspace %q", keyspaceName)
}
🤖 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/metaservice/etcd.go` around lines 77 - 126, Update the missing-metadata
error in DialEtcdClient to include the keyspaceName value, while preserving the
existing error path and message meaning.

@ystaticy

Copy link
Copy Markdown
Contributor Author

/retest-required

Signed-off-by: ystaticy <y_static_y@sina.com>
@ti-chi-bot ti-chi-bot Bot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Jul 13, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jul 13, 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 d3hunter, leavrth 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

@ystaticy

Copy link
Copy Markdown
Contributor Author

/retest-required

Signed-off-by: ystaticy <y_static_y@sina.com>
@ystaticy

Copy link
Copy Markdown
Contributor Author

/retest-required

Signed-off-by: ystaticy <y_static_y@sina.com>
@ti-chi-bot

ti-chi-bot Bot commented Jul 14, 2026

Copy link
Copy Markdown

@ystaticy: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
idc-jenkins-ci-tidb/check_dev 04be59c link true /test check-dev
pull-lightning-integration-test 04be59c link true /test pull-lightning-integration-test

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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/metaservice/etcd.go`:
- Around line 194-202: Update GetPDAddrs so malformed ClientUrls entries are
skipped rather than returned as errors: continue iterating members when
util.ParseServiceURL fails, while preserving valid endpoints. Keep the existing
len(pdAddrs) == 0 fallback/error behavior so the call succeeds only when at
least one usable address is found.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 50b2f62f-5cd7-4642-ac45-63c350000b30

📥 Commits

Reviewing files that changed from the base of the PR and between e180fcd and 04be59c.

📒 Files selected for processing (8)
  • pkg/metaservice/BUILD.bazel
  • pkg/metaservice/etcd.go
  • pkg/store/mockstore/unistore/BUILD.bazel
  • pkg/store/mockstore/unistore/pd.go
  • pkg/store/mockstore/unistore/pd_test.go
  • pkg/util/BUILD.bazel
  • pkg/util/service_url.go
  • pkg/util/service_url_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • pkg/store/mockstore/unistore/BUILD.bazel
  • pkg/store/mockstore/unistore/pd_test.go
  • pkg/metaservice/BUILD.bazel
  • pkg/store/mockstore/unistore/pd.go

Comment thread pkg/metaservice/etcd.go
Comment on lines 194 to 202
for _, member := range members.GetMembers() {
if len(member.ClientUrls) > 0 {
prefix, hostPort, err := ParseURL(member.ClientUrls[0])
endpoint, err := util.ParseServiceURL(member.ClientUrls[0])
if err != nil {
return nil, fmt.Errorf("parse client url from pd members %q: %w", member.ClientUrls[0], err)
}
var pdAddr string
if withSchema {
pdAddr = prefix + hostPort // http://ip:port
} else {
pdAddr = hostPort // ip:port
}

pdAddrs = append(pdAddrs, pdAddr)
pdAddrs = append(pdAddrs, endpoint.Endpoint(withSchema))
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Single malformed PD member URL aborts the whole GetPDAddrs call.

A parse failure on one member's ClientUrls[0] returns immediately, even though the trailing len(pdAddrs) == 0 check (lines 203-205) implies the intended contract is "succeed if at least one member yields a usable URL." This is stricter than the mock counterpart, normalizeMockPDAddrs in pkg/store/mockstore/unistore/pd.go, which calls util.NormalizeServiceURL with util.URLSchemeHTTP and drops entries that fail normalization instead of failing outright. A single member reporting a malformed ClientUrls[0] would now break etcd dialing for BR/Lightning/executor-importer even if other members are healthy.

🛡️ Proposed fix to skip malformed entries instead of failing outright
 		for _, member := range members.GetMembers() {
 			if len(member.ClientUrls) > 0 {
 				endpoint, err := util.ParseServiceURL(member.ClientUrls[0])
 				if err != nil {
-					return nil, fmt.Errorf("parse client url from pd members %q: %w", member.ClientUrls[0], err)
+					// Skip this member; other members may still provide a usable client URL,
+					// matching the len(pdAddrs) == 0 fallback check below.
+					continue
 				}
 				pdAddrs = append(pdAddrs, endpoint.Endpoint(withSchema))
 			}
 		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for _, member := range members.GetMembers() {
if len(member.ClientUrls) > 0 {
prefix, hostPort, err := ParseURL(member.ClientUrls[0])
endpoint, err := util.ParseServiceURL(member.ClientUrls[0])
if err != nil {
return nil, fmt.Errorf("parse client url from pd members %q: %w", member.ClientUrls[0], err)
}
var pdAddr string
if withSchema {
pdAddr = prefix + hostPort // http://ip:port
} else {
pdAddr = hostPort // ip:port
}
pdAddrs = append(pdAddrs, pdAddr)
pdAddrs = append(pdAddrs, endpoint.Endpoint(withSchema))
}
}
for _, member := range members.GetMembers() {
if len(member.ClientUrls) > 0 {
endpoint, err := util.ParseServiceURL(member.ClientUrls[0])
if err != nil {
// Skip this member; other members may still provide a usable client URL,
// matching the len(pdAddrs) == 0 fallback check below.
continue
}
pdAddrs = append(pdAddrs, endpoint.Endpoint(withSchema))
}
}
🤖 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/metaservice/etcd.go` around lines 194 - 202, Update GetPDAddrs so
malformed ClientUrls entries are skipped rather than returned as errors:
continue iterating members when util.ParseServiceURL fails, while preserving
valid endpoints. Keep the existing len(pdAddrs) == 0 fallback/error behavior so
the call succeeds only when at least one usable address is found.

Source: Linked repositories

})
}
return metaservice.DialEtcdClient(
ctx, cfg.TikvImporter.KeyspaceName, addrs, tlsCfg.ToPDSecurityOption(),

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.

This precheck should use the runtime keyspace passed through ControllerParam.KeyspaceName, rather than cfg.TikvImporter.KeyspaceName.

NewImportControllerWithPauser constructs the PD client, codec, local backend, and Controller using p.KeyspaceName, but NewPrecheckItemBuilder does not receive that value. Therefore, an embedded caller can import into one keyspace while the CDC/PiTR precheck connects to the global group or a different keyspace configured in cfg.TikvImporter.KeyspaceName.

In that case, the precheck may incorrectly report that no CDC or PiTR task exists and allow a local-backend import that should have been rejected.

Could we pass p.KeyspaceName through PrecheckItemBuilder and CDCPITRCheckItem, or explicitly validate and synchronize these two values? Please also add a test where ControllerParam.KeyspaceName is non-empty but cfg.TikvImporter.KeyspaceName is empty or different.

Comment thread pkg/metaservice/etcd.go

// ResolveEtcdDialInfo resolves the etcd endpoints and namespace for a keyspace.
func ResolveEtcdDialInfo(ctx context.Context, pdCli pd.Client, keyspaceMeta *keyspacepb.KeyspaceMeta) (EtcdDialInfo, error) {
_, endpoints, err := GetInfoAndGroupAddrs(ctx, pdCli, keyspaceMeta)

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.

Calling GetInfoAndGroupAddrs here makes dedicated meta-service-group resolution unnecessarily depend on the PD members' advertised client URLs.

GetInfoAndGroupAddrs calls MetaServiceManager.FetchInfo, which first invokes GetPDAddrs and only then reads the dedicated group information from keyspaceMeta. As a result, even when keyspaceMeta already contains valid meta_service_group_id and meta_service_group_addrs, this function can still fail because a PD member has missing, malformed, or unreachable advertised client URLs.

This is especially problematic for deployments where the caller connects to PD through a load balancer, proxy, NAT, or Kubernetes Service, while the advertised member addresses are not directly reachable. It may also change the global-group fallback behavior by replacing the caller-provided endpoints with PD-advertised addresses. Additionally, GetPDAddrs currently only uses member.ClientUrls[0], so a valid secondary URL is ignored.

Could we avoid calling GetInfoAndGroupAddrs for this purpose and resolve the dedicated group directly from keyspaceMeta? For the global-group fallback, it would be safer to preserve the caller-provided endpoints. If advertised URLs are still required, all ClientUrls should be considered rather than only the first one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note-none Denotes a PR that doesn't merit a release note. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants