Skip to content

fix: make MySQL structure sync idempotent for already-existing indexes and constraints - #600

Open
The-king-king wants to merge 2 commits into
apecloud:mainfrom
The-king-king:fix/mysql-struct-sync-idempotent
Open

The-king-king wants to merge 2 commits into
apecloud:mainfrom
The-king-king:fix/mysql-struct-sync-idempotent

Conversation

@The-king-king

Copy link
Copy Markdown
Contributor

Summary

  • add ErrorCode::ObjectAlreadyExists (MD003) and map MySQL 1050/1061/1826 to it
  • in the shared structure sinker, skip DDL rejected with ObjectAlreadyExists
    instead of failing the task, matching CREATE TABLE IF NOT EXISTS; other errors
    still follow conflict_policy
  • document the new code in docs/en/error_codes.md and docs/zh/error_codes.md

Fixes #599

Why

Structure sync is meant to be re-runnable, but only the table DDL had
IF NOT EXISTS. On a re-run against a non-empty destination the index DDL
(ALTER TABLE ... ADD INDEX) fails with 1061, and with the default
conflict_policy=interrupt the whole task fails.

Notes

  • Scope is MySQL only; PostgreSQL keeps its current behavior.
  • Tolerating "already exists" does not hide real drift; that is the struct checker's job.

Test plan

  • cargo test -p dt-common --lib (213 passed)
  • cargo test -p dt-connector (131 passed)
  • cargo clippy -p dt-common -p dt-connector --all-targets (no new warnings)
  • cargo fmt --all -- --check

…nstraints

Structure sync only had IF NOT EXISTS on the table DDL. On a re-run against a
non-empty destination, ADD INDEX / ADD CONSTRAINT fail with 1061 / 1826, and the
default conflict_policy=interrupt then fails the whole task.

Classify MySQL 1050/1061/1826 as a dedicated ObjectAlreadyExists (MD003) code and
skip such DDL in the structure sinker, consistent with CREATE TABLE IF NOT EXISTS.
Other errors still follow conflict_policy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@The-king-king

Copy link
Copy Markdown
Contributor Author

验证:键值重复应该跳过而不是直接报错
image

@caiq1nyu

Copy link
Copy Markdown
Collaborator

结构可以先用 sinker.conflict_policy=ignore 来忽略冲突的行为。

这个pr里的实现有些粗暴了,对象存在时忽略我们不希望成为一种默认行为,而是一种针对具体问题可配置的策略。main中新引入的errorcode其实就是期望用来迭代一些基于errorcode的策略行为,比如指定code时重试、忽略、报错。但这是个大工程,比如对象存在忽略的行为,不止是struct sinker会碰到,数据sinker回放ddl时一样会碰到这类问题

btw,使用的话可以先以我们最新的release分支(目前最新的是release-2.0.26.1)代码为基准,main上的有很多alpha的功能代码,在release前可能会有breaking change

@The-king-king

Copy link
Copy Markdown
Contributor Author

结构可以先用 sinker.conflict_policy=ignore 来忽略冲突的行为。

这个pr里的实现有些粗暴了,对象存在时忽略我们不希望成为一种默认行为,而是一种针对具体问题可配置的策略。main中新引入的errorcode其实就是期望用来迭代一些基于errorcode的策略行为,比如指定code时重试、忽略、报错。但这是个大工程,比如对象存在忽略的行为,不止是struct sinker会碰到,数据sinker回放ddl时一样会碰到这类问题

btw,使用的话可以先以我们最新的release分支(目前最新的是release-2.0.26.1)代码为基准,main上的有很多alpha的功能代码,在release前可能会有breaking change

好的,感谢

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Structure sync is not idempotent on MySQL: ADD INDEX / ADD CONSTRAINT fail with 1061/1826 on re-run

2 participants