dm: fix spurious online-DDL replay for ghost→real RENAME without gh-ost comment#12565
dm: fix spurious online-DDL replay for ghost→real RENAME without gh-ost comment#12565Takashi-kun wants to merge 1 commit intopingcap:masterfrom
Conversation
…st comment When an operator manually renames a ghost table (e.g. RENAME TABLE _t1_gho TO will_be_deleted) without the /* gh-ost */ cutover comment, DM was incorrectly treating it as a gh-ost cutover and replaying stored ALTER TABLE DDLs against the destination table. Fix: in processOneDDL, bypass Apply() for ghost→real RENAMEs that lack the gh-ost comment and pass the statement through as-is instead. close pingcap#12564
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Hi @Takashi-kun. Thanks for your PR. I'm waiting for a pingcap member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions 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. |
|
Welcome @Takashi-kun! |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request resolves an issue where DM would erroneously attempt to replay stored DDLs during manual Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request correctly fixes an issue where manual renames of gh-ost ghost tables were incorrectly treated as gh-ost cutovers, leading to DDL replay errors. The approach of checking for the /* gh-ost */ comment in the RENAME TABLE statement is a solid and reliable way to distinguish between automated cutovers and manual operations. The implementation is clean, and the addition of TestGhostTableRenameWithoutGhostComment provides good test coverage for both the new and existing logic paths. I have one suggestion to improve code readability.
| if _, ok := ddlInfo.stmtCache.(*ast.RenameTableStmt); ok && | ||
| len(ddlInfo.sourceTables) == parserpkg.SingleRenameTableNameNum && | ||
| ddl.onlineDDL.TableType(ddlInfo.sourceTables[0].Name) == onlineddl.GhostTable && | ||
| ddl.onlineDDL.TableType(ddlInfo.sourceTables[1].Name) == onlineddl.RealTable && | ||
| !ghostCommentRegexp.MatchString(qec.originSQL) { | ||
| return []string{ddlInfo.originDDL}, nil | ||
| } |
There was a problem hiding this comment.
This if condition is a bit long and combines several checks, which can be hard to parse. To improve readability, consider breaking down the logic into a few named boolean variables that describe each part of the condition.
| if _, ok := ddlInfo.stmtCache.(*ast.RenameTableStmt); ok && | |
| len(ddlInfo.sourceTables) == parserpkg.SingleRenameTableNameNum && | |
| ddl.onlineDDL.TableType(ddlInfo.sourceTables[0].Name) == onlineddl.GhostTable && | |
| ddl.onlineDDL.TableType(ddlInfo.sourceTables[1].Name) == onlineddl.RealTable && | |
| !ghostCommentRegexp.MatchString(qec.originSQL) { | |
| return []string{ddlInfo.originDDL}, nil | |
| } | |
| if _, ok := ddlInfo.stmtCache.(*ast.RenameTableStmt); ok { | |
| isGhostToRealRename := len(ddlInfo.sourceTables) == parserpkg.SingleRenameTableNameNum && | |
| ddl.onlineDDL.TableType(ddlInfo.sourceTables[0].Name) == onlineddl.GhostTable && | |
| ddl.onlineDDL.TableType(ddlInfo.sourceTables[1].Name) == onlineddl.RealTable | |
| isManualRename := isGhostToRealRename && !ghostCommentRegexp.MatchString(qec.originSQL) | |
| if isManualRename { | |
| return []string{ddlInfo.originDDL}, nil | |
| } | |
| } |
What problem does this PR solve?
Issue Number: close #12564
When a gh-ost migration leaves behind a ghost table (e.g.
_t_gho), an operator may manually rename it for cleanup:Because DM identifies gh-ost tables purely by table-name regex, it treats any
GhostTable → RealTablerename as a gh-ost cutover and tries to replay storedALTER TABLEstatements against the destination. Since that table doesn't exist in TiDB, the apply fails and blocks replication.What is changed and how it works?
gh-ost always embeds a
/* gh-ost */comment in its atomic cutoverRENAME TABLE:This comment is preserved in the MySQL binlog QUERY event (
qec.originSQL). InprocessOneDDL, before callingApply(), we now check for its presence on ghost→realRENAME TABLEstatements. Without the comment the rename is a manual operation and is passed through as-is, so the operator can observe any resulting error rather than DM silently mishandling the event.Check List
Tests
TestGhostTableRenameWithoutGhostComment)/* gh-ost */comment — stored ALTER is applied to the real table (existing behavior preserved)Questions
Will it cause performance regression or break compatibility?
No. The added regexp check only runs on
RENAME TABLEstatements whenonlineDDLis enabled.Do you need to update user documentation, design documentation or monitoring documentation?
No.
Release note