@@ -3057,3 +3057,84 @@ func TestPointGetKeyPartitioning(t *testing.T) {
3057
3057
tk .MustExec (`INSERT INTO t VALUES ('Aa', 'Ab', 'Ac'), ('Ba', 'Bb', 'Bc')` )
3058
3058
tk .MustQuery (`SELECT * FROM t WHERE b = 'Ab'` ).Check (testkit .Rows ("Aa Ab Ac" ))
3059
3059
}
3060
+
3061
+ // Issue TiDB #51090.
3062
+ func TestAlterTablePartitionRollback (t * testing.T ) {
3063
+ store := testkit .CreateMockStore (t )
3064
+
3065
+ tk := testkit .NewTestKit (t , store )
3066
+ tk2 := testkit .NewTestKit (t , store )
3067
+ tk3 := testkit .NewTestKit (t , store )
3068
+ tk4 := testkit .NewTestKit (t , store )
3069
+ tk5 := testkit .NewTestKit (t , store )
3070
+ tk .MustExec (`use test;` )
3071
+ tk2 .MustExec (`use test;` )
3072
+ tk3 .MustExec (`use test;` )
3073
+ tk4 .MustExec (`use test;` )
3074
+ tk5 .MustExec (`use test;` )
3075
+ tk .MustExec (`create table t(a int);` )
3076
+ tk .MustExec (`insert into t values(1), (2), (3);` )
3077
+
3078
+ alterChan := make (chan error )
3079
+ alterPartition := func () {
3080
+ err := tk4 .ExecToErr (`alter table t partition by hash(a) partitions 3;` )
3081
+ alterChan <- err
3082
+ }
3083
+ waitFor := func (s string ) {
3084
+ for {
3085
+ select {
3086
+ case alterErr := <- alterChan :
3087
+ require .Fail (t , "Alter completed unexpectedly" , "With error %v" , alterErr )
3088
+ default :
3089
+ // Alter still running
3090
+ }
3091
+ res := tk5 .MustQuery (`admin show ddl jobs where db_name = 'test' and table_name = 't' and job_type = 'alter table partition by'` ).Rows ()
3092
+ if len (res ) > 0 && res [0 ][4 ] == s {
3093
+ logutil .BgLogger ().Info ("Got state" , zap .String ("State" , s ))
3094
+ break
3095
+ }
3096
+ gotime .Sleep (10 * gotime .Millisecond )
3097
+ }
3098
+ dom := domain .GetDomain (tk5 .Session ())
3099
+ // Make sure the table schema is the new schema.
3100
+ require .NoError (t , dom .Reload ())
3101
+ }
3102
+
3103
+ testFunc := func (states []string ) {
3104
+ for i , s := range states {
3105
+ if i % 2 == 0 {
3106
+ tk2 .MustExec (`begin;` )
3107
+ tk2 .MustExec (`select 1 from t;` )
3108
+ if i > 0 {
3109
+ tk3 .MustExec (`commit;` )
3110
+ }
3111
+ } else {
3112
+ tk3 .MustExec (`begin;` )
3113
+ tk3 .MustExec (`select 1 from t;` )
3114
+ tk2 .MustExec (`commit;` )
3115
+ }
3116
+ if i == 0 {
3117
+ go alterPartition ()
3118
+ }
3119
+ waitFor (s )
3120
+ if i == len (states )- 1 {
3121
+ break
3122
+ }
3123
+ }
3124
+ res := tk .MustQuery (`admin show ddl jobs where table_name = 't' and job_type = 'alter table partition by'` ).Rows ()
3125
+ tk .MustExec (fmt .Sprintf ("admin cancel ddl jobs %v" , res [0 ][0 ]))
3126
+ tk2 .MustExec (`commit;` )
3127
+ tk3 .MustExec (`commit;` )
3128
+ require .ErrorContains (t , <- alterChan , "[ddl:8214]Cancelled DDL job" )
3129
+ tk .MustQuery (`show create table t;` ).Check (testkit .Rows (
3130
+ "t CREATE TABLE `t` (\n " +
3131
+ " `a` int(11) DEFAULT NULL\n " +
3132
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin" ))
3133
+ tk .MustQuery (`select a from t order by a;` ).Check (testkit .Rows ("1" , "2" , "3" ))
3134
+ }
3135
+
3136
+ states := []string {"delete only" , "write only" , "write reorganization" , "delete reorganization" }
3137
+ for i := range states {
3138
+ testFunc (states [:i + 1 ])
3139
+ }
3140
+ }
0 commit comments