Repository navigation
Crafted ALTER TABLE statement can cause the connection hang and break the database #62457
Copy link
Copy link
Closed
Labels
affects-6.5This bug affects the 6.5.x(LTS) versions.This bug affects the 6.5.x(LTS) versions.affects-7.1This bug affects the 7.1.x(LTS) versions.This bug affects the 7.1.x(LTS) versions.affects-7.5This bug affects the 7.5.x(LTS) versions.This bug affects the 7.5.x(LTS) versions.affects-8.1This bug affects the 8.1.x(LTS) versions.This bug affects the 8.1.x(LTS) versions.affects-8.5This bug affects the 8.5.x(LTS) versions.This bug affects the 8.5.x(LTS) versions.component/ddlThis issue is related to DDL of TiDB.This issue is related to DDL of TiDB.severity/majortype/bugThe issue is confirmed as a bug.The issue is confirmed as a bug.
Description
Bug Report
A crafted ALTER TABLE statement causes the database connection to hang indefinitely. The query cannot be aborted, and even the KILL statement fails to terminate it.
If restarting the TiDB instance, it will encounter a schema build error and fail to restart.
1. Minimal reproduce step (Required)
CREATE TABLE t (c INT) PARTITION BY RANGE (c) (PARTITION p VALUES LESS THAN (10));
ALTER TABLE t ADD COLUMN c2 INT AS (JSON_EXTRACT(c, '$.number')) VIRTUAL;2. What did you expect to see? (Required)
Should not cause hang or break the database.
3. What did you see instead (Required)
bash # docker run -d --name some-tidb -p 4000:4000 -p 10080:10080 pingcap/tidb:nightly
bash # mysql -h127.0.0.1 -P4000 -uroot test
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CREATE TABLE t (c INT) PARTITION BY RANGE (c) (PARTITION p VALUES LESS THAN (10));
Query OK, 0 rows affected (0.01 sec)
mysql> ALTER TABLE t ADD COLUMN c2 INT AS (JSON_EXTRACT(c, '$.number')) VIRTUAL;
^C^C -- query aborted
^C^C -- query aborted
^C^C -- query aborted
Attempting to restart the database fails — it's no longer connectable:
# docker container restart some-tidb
# mysql -h127.0.0.1 -P4000 -uroot test
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 2
Docker logs output:
[2025/07/16 12:46:20.800 +00:00] [INFO] [tidb.go:93] ["new domain"] [store=30b4a02a-9400-40d1-96bc-19a9beedc02b] ["ddl lease"=45s] ["stats lease"=3s]
[2025/07/16 12:46:20.806 +00:00] [WARN] [controller.go:229] ["[resource group controller] server does not save config, load config failed"]
[2025/07/16 12:46:20.806 +00:00] [INFO] [controller.go:213] ["load resource controller config"] [config="{\"degraded-mode-wait-duration\":\"0s\",\"ltb-max-wait-duration\":\"30s\",\"ltb-token-rpc-max-delay\":\"1s\",\"request-unit\":{\"read-base-cost\":0.125,\"read-per-batch-base-cost\":0.5,\"read-cost-per-byte\":0.0000152587890625,\"write-base-cost\":1,\"write-per-batch-base-cost\":1,\"write-cost-per-byte\":0.0009765625,\"read-cpu-ms-cost\":0.3333333333333333},\"enable-controller-trace-log\":\"false\",\"token-rpc-params\":{\"wait-retry-interval\":\"50ms\",\"wait-retry-times\":20}}"] [ru-config="{\"ReadBaseCost\":0.125,\"ReadPerBatchBaseCost\":0.5,\"ReadBytesCost\":0.0000152587890625,\"WriteBaseCost\":1,\"WritePerBatchBaseCost\":1,\"WriteBytesCost\":0.0009765625,\"CPUMsCost\":0.3333333333333333,\"LTBMaxWaitDuration\":30000000000,\"WaitRetryInterval\":50000000,\"WaitRetryTimes\":20,\"DegradedModeWaitDuration\":0}"] [keyspace-id=4294967295]
[2025/07/16 12:46:20.808 +00:00] [INFO] [mock.go:113] ["owner manager is canceled"] [ownerKey=/tidb/ddl/fg/owner] [ID=716264a2-133f-4b89-beb2-b76e6740b19d]
[2025/07/16 12:46:20.808 +00:00] [INFO] [ddl.go:1050] ["DDL closed"] [category=ddl] [ID=716264a2-133f-4b89-beb2-b76e6740b19d] ["take time"=23.239µs]
[2025/07/16 12:46:20.808 +00:00] [INFO] [ddl.go:768] ["stop DDL"] [category=ddl] [ID=716264a2-133f-4b89-beb2-b76e6740b19d]
[2025/07/16 12:46:20.808 +00:00] [INFO] [domain.go:572] ["domain closed"] ["take time"=58.299µs]
[2025/07/16 12:46:20.808 +00:00] [ERROR] [tidb.go:114] ["init domain failed"] [category=ddl] [error="Build table `test`.`t` schema failed: [expression:3146]Invalid data type for JSON data in argument 1 to function json_extract; a JSON string or JSON type is required."]
4. What is your TiDB version? (Required)
Release Version: v9.0.0-beta.2.pre-118-g6ec4810
Edition: Community
Git Commit Hash: 6ec48101cae75529682a0f9fa8c16cbc42f246d3
Git Branch: HEAD
UTC Build Time: 2025-07-16 11:00:02
GoVersion: go1.23.11
Race Enabled: false
Check Table Before Drop: false
Store: unistore
Kernel Type: Classic
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
affects-6.5This bug affects the 6.5.x(LTS) versions.This bug affects the 6.5.x(LTS) versions.affects-7.1This bug affects the 7.1.x(LTS) versions.This bug affects the 7.1.x(LTS) versions.affects-7.5This bug affects the 7.5.x(LTS) versions.This bug affects the 7.5.x(LTS) versions.affects-8.1This bug affects the 8.1.x(LTS) versions.This bug affects the 8.1.x(LTS) versions.affects-8.5This bug affects the 8.5.x(LTS) versions.This bug affects the 8.5.x(LTS) versions.component/ddlThis issue is related to DDL of TiDB.This issue is related to DDL of TiDB.severity/majortype/bugThe issue is confirmed as a bug.The issue is confirmed as a bug.
Activity
fix: close issue pingcap#62457 check first do not let db down
yihong0618 commentedon Jul 17, 2025
This will also break cloud
joechenrh commentedon Jul 17, 2025
MySQL behavior
TiDB
When we build partition expr, we need to build expressions for all the public columns from table.
tidb/pkg/table/tables/partition.go
Lines 305 to 308 in b615180
Since
c2is not public when do the check during adding column, this operation can succeed. But we can't build table after it becomes public.yihong0618 commentedon Jul 17, 2025
learned it thank you
joechenrh commentedon Jul 17, 2025
/severity major
lance6716 commentedon Jul 17, 2025
@joechenrh please help check affected versions
joechenrh commentedon Jul 17, 2025
/label affects-8.5
/label affects-8.1
/label affects-7.5
/label affects-7.1
/label affects-6.5
5 remaining items
joechenrh commentedon Jul 17, 2025
6.1.7 is ok to restart TiDB after
ALTER COLUMNyihong0618 commentedon Jul 17, 2025
@lance6716 @joechenrh do we need to figure a way if user happen to run this sql without patch, then start db again.
I checked if they happen to run it, and the db can not start again even if the patch
the patch only keeps users not run it, but if they already run it, it not fix it..
ddl: check when `updateVersionAndTableInfo` (#62470)
joechenrh commentedon Jul 17, 2025
Maybe it's hard to deal with such case since the table info stored is corrupted... If we want to make the db start again, we need to add patch to skip some check during parsing table info.
yihong0618 commentedon Jul 17, 2025
got it, thank you
yihong0618 commentedon Jul 18, 2025
checked quite some sql like this, there's no hang error after the patch
joechenrh commentedon Jul 18, 2025
Could you add those SQLs that will cause hang problem and can be fixed by the PR in the PR description? (or just paste it here, both is OK)
yihong0618 commentedon Jul 18, 2025
~/.mysql_history
some of my history
sorry some are wrong
ddl: check when `updateVersionAndTableInfo` (#62470) (#64763)