Skip to content

Commit 97c2f13

Browse files
mjonssti-chi-bot
authored andcommitted
This is an automated cherry-pick of pingcap#45877
Signed-off-by: ti-chi-bot <[email protected]>
1 parent fe7bcf1 commit 97c2f13

File tree

12 files changed

+2980
-75
lines changed

12 files changed

+2980
-75
lines changed

ddl/db_partition_test.go

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2377,6 +2377,224 @@ func TestExchangePartitionTableCompatiable(t *testing.T) {
23772377
require.NoError(t, err)
23782378
}
23792379

2380+
<<<<<<< HEAD
2381+
=======
2382+
func TestExchangePartitionMultiTable(t *testing.T) {
2383+
store := testkit.CreateMockStore(t)
2384+
tk1 := testkit.NewTestKit(t, store)
2385+
2386+
dbName := "ExchangeMultiTable"
2387+
tk1.MustExec(`create schema ` + dbName)
2388+
tk1.MustExec(`use ` + dbName)
2389+
tk1.MustExec(`CREATE TABLE t1 (a int)`)
2390+
tk1.MustExec(`CREATE TABLE t2 (a int)`)
2391+
tk1.MustExec(`CREATE TABLE tp (a int) partition by hash(a) partitions 3`)
2392+
tk1.MustExec(`insert into t1 values (0)`)
2393+
tk1.MustExec(`insert into t2 values (3)`)
2394+
tk1.MustExec(`insert into tp values (6)`)
2395+
2396+
tk2 := testkit.NewTestKit(t, store)
2397+
tk2.MustExec(`use ` + dbName)
2398+
tk3 := testkit.NewTestKit(t, store)
2399+
tk3.MustExec(`use ` + dbName)
2400+
tk4 := testkit.NewTestKit(t, store)
2401+
tk4.MustExec(`use ` + dbName)
2402+
waitFor := func(col int, tableName, s string) {
2403+
for {
2404+
tk4 := testkit.NewTestKit(t, store)
2405+
tk4.MustExec(`use test`)
2406+
sql := `admin show ddl jobs where db_name = '` + strings.ToLower(dbName) + `' and table_name = '` + tableName + `' and job_type = 'exchange partition'`
2407+
res := tk4.MustQuery(sql).Rows()
2408+
if len(res) == 1 && res[0][col] == s {
2409+
break
2410+
}
2411+
time.Sleep(10 * time.Millisecond)
2412+
}
2413+
}
2414+
alterChan1 := make(chan error)
2415+
alterChan2 := make(chan error)
2416+
tk3.MustExec(`BEGIN`)
2417+
tk3.MustExec(`insert into tp values (1)`)
2418+
go func() {
2419+
alterChan1 <- tk1.ExecToErr(`alter table tp exchange partition p0 with table t1`)
2420+
}()
2421+
waitFor(11, "t1", "running")
2422+
go func() {
2423+
alterChan2 <- tk2.ExecToErr(`alter table tp exchange partition p0 with table t2`)
2424+
}()
2425+
waitFor(11, "t2", "queueing")
2426+
tk3.MustExec(`rollback`)
2427+
require.NoError(t, <-alterChan1)
2428+
err := <-alterChan2
2429+
tk3.MustQuery(`select * from t1`).Check(testkit.Rows("6"))
2430+
tk3.MustQuery(`select * from t2`).Check(testkit.Rows("0"))
2431+
tk3.MustQuery(`select * from tp`).Check(testkit.Rows("3"))
2432+
require.NoError(t, err)
2433+
}
2434+
2435+
func TestExchangePartitionValidation(t *testing.T) {
2436+
store := testkit.CreateMockStore(t)
2437+
tk := testkit.NewTestKit(t, store)
2438+
2439+
dbName := "ExchangeValidation"
2440+
tk.MustExec(`create schema ` + dbName)
2441+
tk.MustExec(`use ` + dbName)
2442+
tk.MustExec(`CREATE TABLE t1 (
2443+
d date NOT NULL ,
2444+
name varchar(10) NOT NULL,
2445+
UNIQUE KEY (d,name))`)
2446+
2447+
tk.MustExec(`CREATE TABLE t1p (
2448+
d date NOT NULL ,
2449+
name varchar(10) NOT NULL,
2450+
UNIQUE KEY (d,name)
2451+
)
2452+
PARTITION BY RANGE COLUMNS(d)
2453+
(PARTITION p202307 VALUES LESS THAN ('2023-08-01'),
2454+
PARTITION p202308 VALUES LESS THAN ('2023-09-01'),
2455+
PARTITION p202309 VALUES LESS THAN ('2023-10-01'),
2456+
PARTITION p202310 VALUES LESS THAN ('2023-11-01'),
2457+
PARTITION p202311 VALUES LESS THAN ('2023-12-01'),
2458+
PARTITION p202312 VALUES LESS THAN ('2024-01-01'),
2459+
PARTITION pfuture VALUES LESS THAN (MAXVALUE))`)
2460+
2461+
tk.MustExec(`insert into t1 values ("2023-08-06","0000")`)
2462+
tk.MustContainErrMsg(`alter table t1p exchange partition p202307 with table t1 with validation`,
2463+
"[ddl:1737]Found a row that does not match the partition")
2464+
tk.MustExec(`insert into t1 values ("2023-08-06","0001")`)
2465+
}
2466+
2467+
func TestExchangePartitionPlacementPolicy(t *testing.T) {
2468+
store := testkit.CreateMockStore(t)
2469+
tk := testkit.NewTestKit(t, store)
2470+
2471+
tk.MustExec(`create schema ExchangePartWithPolicy`)
2472+
tk.MustExec(`use ExchangePartWithPolicy`)
2473+
tk.MustExec(`CREATE PLACEMENT POLICY rule1 FOLLOWERS=1`)
2474+
tk.MustExec(`CREATE PLACEMENT POLICY rule2 FOLLOWERS=2`)
2475+
tk.MustExec(`CREATE TABLE t1 (
2476+
d date NOT NULL ,
2477+
name varchar(10) NOT NULL,
2478+
UNIQUE KEY (d,name)
2479+
) PLACEMENT POLICY="rule1"`)
2480+
2481+
tk.MustExec(`CREATE TABLE t1p (
2482+
d date NOT NULL ,
2483+
name varchar(10) NOT NULL,
2484+
UNIQUE KEY (d,name)
2485+
) PLACEMENT POLICY="rule2"
2486+
PARTITION BY RANGE COLUMNS(d)
2487+
(PARTITION p202307 VALUES LESS THAN ('2023-08-01'),
2488+
PARTITION p202308 VALUES LESS THAN ('2023-09-01'),
2489+
PARTITION p202309 VALUES LESS THAN ('2023-10-01'),
2490+
PARTITION p202310 VALUES LESS THAN ('2023-11-01'),
2491+
PARTITION p202311 VALUES LESS THAN ('2023-12-01'),
2492+
PARTITION p202312 VALUES LESS THAN ('2024-01-01'),
2493+
PARTITION pfuture VALUES LESS THAN (MAXVALUE))`)
2494+
2495+
tk.MustContainErrMsg(`alter table t1p exchange partition p202307 with table t1`,
2496+
"[ddl:1736]Tables have different definitions")
2497+
tk.MustExec(`insert into t1 values ("2023-08-06","0000")`)
2498+
}
2499+
2500+
func TestExchangePartitionHook(t *testing.T) {
2501+
store, dom := testkit.CreateMockStoreAndDomain(t)
2502+
tk := testkit.NewTestKit(t, store)
2503+
// why use tkCancel, not tk.
2504+
tkCancel := testkit.NewTestKit(t, store)
2505+
2506+
tk.MustExec("set @@tidb_enable_exchange_partition=1")
2507+
defer tk.MustExec("set @@tidb_enable_exchange_partition=0")
2508+
2509+
tk.MustExec("use test")
2510+
tk.MustExec(`create table pt (a int) partition by range(a) (
2511+
partition p0 values less than (3),
2512+
partition p1 values less than (6),
2513+
PARTITION p2 VALUES LESS THAN (9),
2514+
PARTITION p3 VALUES LESS THAN (MAXVALUE)
2515+
);`)
2516+
tk.MustExec(`create table nt(a int);`)
2517+
2518+
tk.MustExec(`insert into pt values (0), (4), (7)`)
2519+
tk.MustExec("insert into nt values (1)")
2520+
2521+
hook := &callback.TestDDLCallback{Do: dom}
2522+
dom.DDL().SetHook(hook)
2523+
2524+
hookFunc := func(job *model.Job) {
2525+
if job.Type == model.ActionExchangeTablePartition && job.SchemaState != model.StateNone {
2526+
tkCancel.MustExec("use test")
2527+
tkCancel.MustGetErrCode("insert into nt values (5)", errno.ErrRowDoesNotMatchGivenPartitionSet)
2528+
}
2529+
}
2530+
hook.OnJobUpdatedExported.Store(&hookFunc)
2531+
2532+
tk.MustExec("alter table pt exchange partition p0 with table nt")
2533+
tk.MustQuery("select * from pt partition(p0)").Check(testkit.Rows("1"))
2534+
}
2535+
2536+
func TestExchangePartitionAutoID(t *testing.T) {
2537+
store := testkit.CreateMockStore(t)
2538+
tk := testkit.NewTestKit(t, store)
2539+
2540+
tk.MustExec("set @@tidb_enable_exchange_partition=1")
2541+
defer tk.MustExec("set @@tidb_enable_exchange_partition=0")
2542+
2543+
tk.MustExec("use test")
2544+
tk.MustExec(`create table pt (a int primary key auto_increment) partition by range(a) (
2545+
partition p0 values less than (3),
2546+
partition p1 values less than (6),
2547+
PARTITION p2 values less than (9),
2548+
PARTITION p3 values less than (50000000)
2549+
);`)
2550+
tk.MustExec(`create table nt(a int primary key auto_increment);`)
2551+
tk.MustExec(`insert into pt values (0), (4)`)
2552+
tk.MustExec("insert into nt values (1)")
2553+
2554+
require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/exchangePartitionAutoID", `return(true)`))
2555+
defer func() {
2556+
require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/exchangePartitionAutoID"))
2557+
}()
2558+
2559+
tk.MustExec("alter table pt exchange partition p0 with table nt")
2560+
tk.MustExec("insert into nt values (NULL)")
2561+
tk.MustQuery("select count(*) from nt where a >= 4000000").Check(testkit.Rows("1"))
2562+
tk.MustQuery("select count(*) from pt where a >= 4000000").Check(testkit.Rows("1"))
2563+
}
2564+
2565+
func TestTiDBEnableExchangePartition(t *testing.T) {
2566+
store := testkit.CreateMockStore(t)
2567+
tk := testkit.NewTestKit(t, store)
2568+
2569+
tk.MustExec("use test")
2570+
tk.MustExec(`create table pt (a int primary key auto_increment) partition by range(a) (
2571+
partition p0 values less than (3),
2572+
partition p1 values less than (6),
2573+
PARTITION p2 values less than (9)
2574+
);`)
2575+
// default
2576+
tk.MustQuery("select @@tidb_enable_exchange_partition").Check(testkit.Rows("1"))
2577+
tk.MustExec(`create table nt(a int primary key auto_increment);`)
2578+
tk.MustExec("alter table pt exchange partition p0 with table nt")
2579+
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 after the exchange, please analyze related table of the exchange to update statistics"))
2580+
2581+
// set tidb_enable_exchange_partition = 0
2582+
tk.MustExec("set @@tidb_enable_exchange_partition=0")
2583+
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 tidb_enable_exchange_partition is always turned on. This variable has been deprecated and will be removed in the future releases"))
2584+
tk.MustQuery("select @@tidb_enable_exchange_partition").Check(testkit.Rows("1"))
2585+
tk.MustExec("alter table pt exchange partition p0 with table nt")
2586+
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 after the exchange, please analyze related table of the exchange to update statistics"))
2587+
2588+
// set tidb_enable_exchange_partition = 1
2589+
tk.MustExec("set @@tidb_enable_exchange_partition=1")
2590+
tk.MustQuery("show warnings").Check(testkit.Rows())
2591+
tk.MustQuery("select @@tidb_enable_exchange_partition").Check(testkit.Rows("1"))
2592+
tk.MustExec("alter table pt exchange partition p0 with table nt")
2593+
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 after the exchange, please analyze related table of the exchange to update statistics"))
2594+
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 after the exchange, please analyze related table of the exchange to update statistics"))
2595+
}
2596+
2597+
>>>>>>> c7c7000165a (ddl: Exchange partition rollback (#45877))
23802598
func TestExchangePartitionExpressIndex(t *testing.T) {
23812599
restore := config.RestoreFunc()
23822600
defer restore()

ddl/ddl_api.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3988,7 +3988,6 @@ func checkExchangePartition(pt *model.TableInfo, nt *model.TableInfo) error {
39883988
return errors.Trace(dbterror.ErrPartitionExchangeForeignKey.GenWithStackByArgs(nt.Name))
39893989
}
39903990

3991-
// NOTE: if nt is temporary table, it should be checked
39923991
return nil
39933992
}
39943993

ddl/ddl_worker.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,7 @@ func updateSchemaVersion(_ *ddlCtx, t *meta.Meta, job *model.Job) (int64, error)
11491149
diff.OldSchemaID = oldSchemaIDs[0]
11501150
diff.AffectedOpts = affects
11511151
case model.ActionExchangeTablePartition:
1152+
<<<<<<< HEAD
11521153
var (
11531154
ptSchemaID int64
11541155
ptTableID int64
@@ -1157,14 +1158,30 @@ func updateSchemaVersion(_ *ddlCtx, t *meta.Meta, job *model.Job) (int64, error)
11571158
if err != nil {
11581159
return 0, errors.Trace(err)
11591160
}
1161+
=======
1162+
>>>>>>> c7c7000165a (ddl: Exchange partition rollback (#45877))
11601163
diff.OldTableID = job.TableID
1161-
affects := make([]*model.AffectedOption, 1)
1162-
affects[0] = &model.AffectedOption{
1163-
SchemaID: ptSchemaID,
1164-
TableID: ptTableID,
1165-
OldTableID: ptTableID,
1164+
diff.OldSchemaID = job.SchemaID
1165+
if job.SchemaState != model.StatePublic {
1166+
diff.TableID = job.TableID
1167+
diff.SchemaID = job.SchemaID
1168+
} else {
1169+
// Update the partitioned table (it is only done in the last state)
1170+
var (
1171+
ptSchemaID int64
1172+
ptTableID int64
1173+
ptDefID int64 // Not needed, will reload the whole table
1174+
partName string // Not used
1175+
withValidation bool // Not used
1176+
)
1177+
// See ddl.ExchangeTablePartition
1178+
err = job.DecodeArgs(&ptDefID, &ptSchemaID, &ptTableID, &partName, &withValidation)
1179+
if err != nil {
1180+
return 0, errors.Trace(err)
1181+
}
1182+
diff.SchemaID = ptSchemaID
1183+
diff.TableID = ptTableID
11661184
}
1167-
diff.AffectedOpts = affects
11681185
case model.ActionTruncateTablePartition:
11691186
diff.TableID = job.TableID
11701187
if len(job.CtxVars) > 0 {

ddl/failtest/fail_db_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,13 @@ func TestHalfwayCancelOperations(t *testing.T) {
132132
tk.MustExec("insert into pt values(1), (3), (5)")
133133
tk.MustExec("create table nt(a int)")
134134
tk.MustExec("insert into nt values(7)")
135+
<<<<<<< HEAD:ddl/failtest/fail_db_test.go
135136
tk.MustExec("set @@tidb_enable_exchange_partition=1")
136137
defer tk.MustExec("set @@tidb_enable_exchange_partition=0")
137138
_, err = tk.Exec("alter table pt exchange partition p1 with table nt")
139+
=======
140+
err = tk.ExecToErr("alter table pt exchange partition p1 with table nt")
141+
>>>>>>> c7c7000165a (ddl: Exchange partition rollback (#45877)):ddl/tests/fail/fail_db_test.go
138142
require.Error(t, err)
139143

140144
tk.MustQuery("select * from pt").Check(testkit.Rows("1", "3", "5"))

0 commit comments

Comments
 (0)