Skip to content

sink/mysql: align DDL time defaults with origin_default#12490

Merged
ti-chi-bot[bot] merged 25 commits intopingcap:masterfrom
haiboumich:fix-handle-alter-add-default_current_timestamp
Jan 30, 2026
Merged

sink/mysql: align DDL time defaults with origin_default#12490
ti-chi-bot[bot] merged 25 commits intopingcap:masterfrom
haiboumich:fix-handle-alter-add-default_current_timestamp

Conversation

@haiboumich
Copy link
Contributor

@haiboumich haiboumich commented Jan 13, 2026

What problem does this PR solve?

DDL statements that reference CURRENT_TIMESTAMP/NOW/LOCALTIME/LOCALTIMESTAMP can evaluate to different values downstream when executed later or in a different time zone. This can lead to inconsistent default values for newly added columns.

Issue Number: close #11368

What is changed and how it works?

  • Set session TIMESTAMP for each DDL execution using the DDL StartTs (fallback to CommitTs).
  • Parse CREATE/ALTER statements to detect CURRENT_TIMESTAMP-style defaults and use the column origin_default from TableInfo to set the session timestamp so defaults match upstream evaluation.
  • Reset session TIMESTAMP after DDL execution and on failures to avoid leaking session state.
  • Add unit tests for origin_default-driven timestamps and StartTs fallback; update existing DDL sink tests to expect the session timestamp set/reset.

Check List

Tests

  • Unit test
  • Manual test
    -- create changefeed
    CREATE DATABASE IF NOT EXISTS test_time_funcs;
    USE test_time_funcs;
    -- Timestamp & Datetime Functions
    -- Test: NOW(), CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP, LOCALTIME(), LOCALTIME, LOCALTIMESTAMP, LOCALTIMESTAMP(), UTC_TIMESTAMP()
    CREATE TABLE t_timestamp (id INT PRIMARY KEY, info VARCHAR(20));
    INSERT INTO t_timestamp VALUES (1, 'initial_row');
    -- pause the changefeed
    ALTER TABLE t_timestamp ADD COLUMN ts_now DATETIME DEFAULT NOW();
    ALTER TABLE t_timestamp ADD COLUMN ts_current_timestamp_func TIMESTAMP DEFAULT CURRENT_TIMESTAMP();
    ALTER TABLE t_timestamp ADD COLUMN ts_current_timestamp_const TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
    ALTER TABLE t_timestamp ADD COLUMN ts_localtime_func TIMESTAMP DEFAULT LOCALTIME();
    ALTER TABLE t_timestamp ADD COLUMN ts_localtime_const TIMESTAMP DEFAULT LOCALTIME;
    ALTER TABLE t_timestamp ADD COLUMN ts_localtimestamp_func TIMESTAMP DEFAULT LOCALTIMESTAMP();
    ALTER TABLE t_timestamp ADD COLUMN ts_localtimestamp_const TIMESTAMP DEFAULT LOCALTIMESTAMP;
    SELECT * FROM test_time_funcs.t_timestamp\G
    -- wait for seconds & resume the changefeed
    SELECT * FROM test_time_funcs.t_timestamp\G

Questions

Will it cause performance regression or break compatibility?

No. The change only affects DDL execution paths and sets a session variable around the DDL, then resets it.

Do you need to update user documentation, design documentation or monitoring documentation?

No.

Release note

Fix MySQL DDL execution to use upstream-evaluated timestamps for CURRENT_TIMESTAMP-style defaults, ensuring consistent default values downstream.

@ti-chi-bot ti-chi-bot bot added do-not-merge/needs-linked-issue first-time-contributor Indicates that the PR was contributed by an external member and is a first-time contributor. release-note Denotes a PR that will be considered when it comes time to generate release notes. labels Jan 13, 2026
@pingcap-cla-assistant
Copy link

pingcap-cla-assistant bot commented Jan 13, 2026

CLA assistant check
All committers have signed the CLA.

@ti-chi-bot ti-chi-bot bot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Jan 13, 2026
@gemini-code-assist
Copy link

Summary of Changes

Hello @haiboumich, 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 addresses a critical issue where DDL statements containing CURRENT_TIMESTAMP-style default values could lead to inconsistent data downstream due to varying evaluation times or timezones. The solution involves dynamically setting the MySQL session TIMESTAMP variable to the upstream-evaluated timestamp (derived from StartTs or CommitTs and the column's origin_default) just before executing such DDLs. This ensures that newly added columns with these defaults are populated with values consistent with the source system, thereby maintaining data integrity across replication.

Highlights

  • DDL Timestamp Alignment: Ensures that DDL statements involving CURRENT_TIMESTAMP-style defaults (like NOW(), LOCALTIME()) evaluate to consistent values downstream by setting the session TIMESTAMP during execution.
  • Origin Default Value Utilization: Parses CREATE and ALTER statements to identify columns with CURRENT_TIMESTAMP-style defaults and uses the origin_default value from the table schema to determine the precise timestamp for session setting.
  • Session State Management: Implements robust session state handling by setting the TIMESTAMP before DDL execution and resetting it to DEFAULT afterwards, or upon any failure, to prevent state leakage.
  • Comprehensive Testing: Adds new unit tests specifically for the origin_default-driven timestamp logic and updates existing DDL sink tests to verify the correct setting and resetting of the session timestamp.

🧠 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 Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a mechanism to align DDL timestamp defaults with the upstream by setting the session TIMESTAMP variable. This is achieved by parsing the DDL to identify columns with CURRENT_TIMESTAMP defaults and using the origin_default value from TableInfo. The implementation correctly handles setting and resetting the session timestamp, including in error scenarios. The added tests cover the main logic well. My review focuses on improving logging and error handling to make the new logic more robust and easier to debug. Specifically, I've pointed out a few places where the wrong error is logged on rollback failures and a case where a DDL parsing error is silently ignored.

zap.Error(err))
if rbErr := tx.Rollback(); rbErr != nil {
log.Error("Failed to rollback", zap.String("namespace", m.id.Namespace),
zap.String("changefeed", m.id.ID), zap.Error(err))

Choose a reason for hiding this comment

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

medium

The log message "Failed to rollback" suggests that the error from the rollback operation (rbErr) should be logged. However, the original error err (from setSessionTimestamp) is being logged instead. This can be misleading during debugging. This pattern of logging the wrong error on rollback failure appears in a few other places in this file.

Suggested change
zap.String("changefeed", m.id.ID), zap.Error(err))
zap.String("changefeed", m.id.ID), zap.Error(rbErr))

log.Error("Failed to reset session timestamp after DDL execution", zap.Error(err))
if rbErr := tx.Rollback(); rbErr != nil {
log.Error("Failed to rollback", zap.String("namespace", m.id.Namespace),
zap.String("changefeed", m.id.ID), zap.Error(err))

Choose a reason for hiding this comment

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

medium

Similar to another comment, the log for "Failed to rollback" is logging err from resetSessionTimestamp instead of rbErr from the rollback operation.

Suggested change
zap.String("changefeed", m.id.ID), zap.Error(err))
zap.String("changefeed", m.id.ID), zap.Error(rbErr))

Comment on lines +315 to +318
targetColumns, err := extractCurrentTimestampDefaultColumns(ddl.Query)
if err != nil || len(targetColumns) == 0 {
return 0, false
}

Choose a reason for hiding this comment

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

medium

The error from extractCurrentTimestampDefaultColumns is silently ignored. If DDL parsing fails, it could indicate an issue with an unsupported DDL statement, and the system would fall back to the old behavior without aligning timestamps. This could lead to data inconsistency without any warning. It's better to log this error.

        targetColumns, err := extractCurrentTimestampDefaultColumns(ddl.Query)
        if err != nil {
                log.Warn("Failed to extract columns with CURRENT_TIMESTAMP default from DDL, "+
                        "it may cause data inconsistency.",
                        zap.String("query", ddl.Query),
                        zap.Error(err))
                return 0, false
        }
        if len(targetColumns) == 0 {
                return 0, false
        }

@ti-chi-bot
Copy link
Contributor

ti-chi-bot bot commented Jan 14, 2026

@Debra-He: adding LGTM is restricted to approvers and reviewers in OWNERS files.

Details

In response to this:

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.

@ti-chi-bot
Copy link
Contributor

ti-chi-bot bot commented Jan 14, 2026

@zier-one: adding LGTM is restricted to approvers and reviewers in OWNERS files.

Details

In response to this:

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.

@haiboumich
Copy link
Contributor Author

/retest-required

1 similar comment
@haiboumich
Copy link
Contributor Author

/retest-required

@haiboumich
Copy link
Contributor Author

/retest-required

1 similar comment
@haiboumich
Copy link
Contributor Author

/retest-required

@wk989898
Copy link
Collaborator

Please add an integration test to cover it.

…ailures only when the downstream returns specific “bad value / unknown var” errors
…... DEFAULT CURRENT_TIMESTAMP existing‑rows divergence by forcing a fixed session timestamp
… reset failures only when the downstream returns specific “bad value / unknown var” errors"

This reverts commit 5ba109a.
run_sql "INSERT INTO ${DB_NAME}.t VALUES (1, 10), (2, 20), (3, 30);" ${UP_TIDB_HOST} ${UP_TIDB_PORT}

run_sql "SET @@timestamp = 1000000000.123456; ALTER TABLE ${DB_NAME}.t ADD COLUMN c DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6);" ${UP_TIDB_HOST} ${UP_TIDB_PORT}

Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you add more dml before and after adding the column?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thx, i just added some more dml, PTAL

@ti-chi-bot ti-chi-bot bot added lgtm and removed needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Jan 22, 2026
@ti-chi-bot
Copy link
Contributor

ti-chi-bot bot commented Jan 22, 2026

[LGTM Timeline notifier]

Timeline:

  • 2026-01-19 08:46:00.814916563 +0000 UTC m=+397188.428873409: ☑️ agreed by wk989898.
  • 2026-01-22 13:58:05.35973673 +0000 UTC m=+675112.973693576: ☑️ agreed by lidezhu.

@haiboumich
Copy link
Contributor Author

/retest-required

@ti-chi-bot
Copy link
Contributor

ti-chi-bot bot commented Jan 26, 2026

@flowbehappy: adding LGTM is restricted to approvers and reviewers in OWNERS files.

Details

In response to this:

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.

@ti-chi-bot
Copy link
Contributor

ti-chi-bot bot commented Jan 26, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Debra-He, flowbehappy, lidezhu, wk989898, zier-one

The full list of commands accepted by this bot can be found here.

The pull request process is described 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

@haiboumich
Copy link
Contributor Author

/test pull-error-log-review

@haiboumich
Copy link
Contributor Author

/retest-required

@haiboumich
Copy link
Contributor Author

/test pull-dm-integration-test

@hongyunyan
Copy link
Collaborator

/retest

@haiboumich
Copy link
Contributor Author

/test pull-cdc-integration-kafka-test

@haiboumich
Copy link
Contributor Author

/test tide

@ti-chi-bot
Copy link
Contributor

ti-chi-bot bot commented Jan 29, 2026

@haiboumich: The specified target(s) for /test were not found.
The following commands are available to trigger required jobs:

/test pull-cdc-integration-kafka-test
/test pull-cdc-integration-mysql-test
/test pull-cdc-integration-pulsar-test
/test pull-cdc-integration-storage-test
/test pull-dm-compatibility-test
/test pull-dm-integration-test
/test pull-error-log-review
/test pull-syncdiff-integration-test
/test pull-verify
/test wip-pull-build
/test wip-pull-check
/test wip-pull-unit-test-cdc
/test wip-pull-unit-test-dm
/test wip-pull-unit-test-engine

Use /test all to run the following jobs that were automatically triggered:

pingcap/tiflow/ghpr_verify
pingcap/tiflow/pull_cdc_integration_kafka_test
pingcap/tiflow/pull_cdc_integration_pulsar_test
pingcap/tiflow/pull_cdc_integration_storage_test
pingcap/tiflow/pull_cdc_integration_test
pingcap/tiflow/pull_dm_compatibility_test
pingcap/tiflow/pull_dm_integration_test
pingcap/tiflow/pull_syncdiff_integration_test
pull-error-log-review
Details

In response to this:

/test tide

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.

@haiboumich
Copy link
Contributor Author

/test pull-cdc-integration-pulsar-test

@haiboumich
Copy link
Contributor Author

/retest-required

@haiboumich
Copy link
Contributor Author

/test pull-dm-integration-test

@haiboumich
Copy link
Contributor Author

/test pull-cdc-integration-kafka-test

5 similar comments
@haiboumich
Copy link
Contributor Author

/test pull-cdc-integration-kafka-test

@haiboumich
Copy link
Contributor Author

/test pull-cdc-integration-kafka-test

@haiboumich
Copy link
Contributor Author

/test pull-cdc-integration-kafka-test

@haiboumich
Copy link
Contributor Author

/test pull-cdc-integration-kafka-test

@haiboumich
Copy link
Contributor Author

/test pull-cdc-integration-kafka-test

@ti-chi-bot ti-chi-bot bot merged commit 142713c into pingcap:master Jan 30, 2026
24 checks passed
haiboumich added a commit to haiboumich/tiflow that referenced this pull request Feb 2, 2026
@wk989898 wk989898 added the needs-cherry-pick-release-8.5 Should cherry pick this PR to release-8.5 branch. label Feb 4, 2026
ti-chi-bot pushed a commit to ti-chi-bot/tiflow that referenced this pull request Feb 4, 2026
Signed-off-by: ti-chi-bot <ti-community-prow-bot@tidb.io>
@ti-chi-bot
Copy link
Member

In response to a cherrypick label: new pull request created to branch release-8.5: #12516.
But this PR has conflicts, please resolve them!

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

Labels

approved first-time-contributor Indicates that the PR was contributed by an external member and is a first-time contributor. lgtm needs-cherry-pick-release-8.5 Should cherry pick this PR to release-8.5 branch. release-note Denotes a PR that will be considered when it comes time to generate release notes. 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.

[Limitation] TiCDC can't not handle DDL as alter table xx add column xx datetime default current_timestamp properly

8 participants