diff --git a/pkg/ddl/partition.go b/pkg/ddl/partition.go index 580acf932b..4410fc3761 100644 --- a/pkg/ddl/partition.go +++ b/pkg/ddl/partition.go @@ -3869,6 +3869,7 @@ func (w *reorgPartitionWorker) BackfillData(handleRange reorgBackfillTask) (task taskCtx.nextKey = nextKey taskCtx.done = taskDone + failpoint.InjectCall("PartitionBackfillData", len(w.rowRecords) > 0) isClustered := w.reorgedTbl.Meta().IsCommonHandle || w.reorgedTbl.Meta().PKIsHandle if !isClustered { // non-clustered table, we need to replace the _tidb_rowid handles since diff --git a/pkg/ddl/tests/partition/multi_domain_test.go b/pkg/ddl/tests/partition/multi_domain_test.go index 60d2985b19..4e6f9562ec 100644 --- a/pkg/ddl/tests/partition/multi_domain_test.go +++ b/pkg/ddl/tests/partition/multi_domain_test.go @@ -811,6 +811,9 @@ func TestMultiSchemaDropUniqueIndex(t *testing.T) { //} func runMultiSchemaTest(t *testing.T, createSQL, alterSQL string, initFn func(*testkit.TestKit), postFn func(*testkit.TestKit, kv.Storage), loopFn func(tO, tNO *testkit.TestKit)) { + runMultiSchemaTestWithBackfillDML(t, createSQL, alterSQL, "", initFn, postFn, loopFn) +} +func runMultiSchemaTestWithBackfillDML(t *testing.T, createSQL, alterSQL, backfillDML string, initFn func(*testkit.TestKit), postFn func(*testkit.TestKit, kv.Storage), loopFn func(tO, tNO *testkit.TestKit)) { // When debugging, increase the lease, so the schema does not auto reload :) distCtx := testkit.NewDistExecutionContextWithLease(t, 2, 15*time.Second) store := distCtx.Store @@ -873,8 +876,21 @@ func runMultiSchemaTest(t *testing.T, createSQL, alterSQL string, initFn func(*t testfailpoint.EnableCall(t, "github.com/pingcap/tidb/pkg/ddl/afterRunOneJobStep", hookFunc) alterChan := make(chan error) go func() { + if backfillDML != "" { + // This can be used for testing concurrent writes during backfill. + testfailpoint.EnableCall(t, "github.com/pingcap/tidb/pkg/ddl/PartitionBackfillData", func(b bool) { + if b { + logutil.BgLogger().Info("XXXXXXXXXXX Concurrent UPDATE!") + tkO.MustExec(backfillDML) + } + }) + } + logutil.BgLogger().Info("XXXXXXXXXXX DDL starting!", zap.String("alterSQL", alterSQL)) err := tkDDLOwner.ExecToErr(alterSQL) logutil.BgLogger().Info("XXXXXXXXXXX DDL done!", zap.String("alterSQL", alterSQL)) + if backfillDML != "" { + testfailpoint.Disable(t, "github.com/pingcap/tidb/pkg/ddl/PartitionBackfillData") + } alterChan <- err }() // Skip the first state, since we want to compare before vs after in the loop @@ -1022,45 +1038,163 @@ func HaveEntriesForTableIndex(t *testing.T, tk *testkit.TestKit, tableID, indexI } return false } +func TestMultiSchemaReorganizePK(t *testing.T) { + createSQL := `create table t (c1 INT primary key, c2 CHAR(255), c3 CHAR(255), c4 CHAR(255), c5 CHAR(255)) partition by range (c1) (partition p1 values less than (200), partition pMax values less than (maxvalue))` + i := 1 + initFn := func(tkO *testkit.TestKit) { + tkO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',%d,%d)`, i, "init O", 4185725186-i, 7483634197-i)) + i++ + tkO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',%d,%d)`, i, "init O", 4185725186-i, 7483634197-i)) + i++ + } + alterSQL := `alter table t reorganize partition p1 into (partition p0 values less than (100), partition p1 values less than (200))` + loopFn := func(tkO, tkNO *testkit.TestKit) { + res := tkO.MustQuery(`select schema_state from information_schema.DDL_JOBS where table_name = 't' order by job_id desc limit 1`) + schemaState := res.Rows()[0][0].(string) + tkO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',%d,%d)`, i, schemaState+" O", 4185725186-i, 7483634197-i)) + i++ + tkNO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',%d,%d)`, i, schemaState+" NO", 4185725186-i, 7483634197-i)) + i++ + } + postFn := func(tkO *testkit.TestKit, _ kv.Storage) { + require.Equal(t, int(7*2+1), i) + tkO.MustQuery(`select c1,c2 from t`).Sort().Check(testkit.Rows(""+ + "1 init O", + "10 delete reorganization NO", + "11 public O", + "12 public NO", + "13 none O", + "14 none NO", + "2 init O", + "3 delete only O", + "4 delete only NO", + "5 write only O", + "6 write only NO", + "7 write reorganization O", + "8 write reorganization NO", + "9 delete reorganization O")) + } + runMultiSchemaTest(t, createSQL, alterSQL, initFn, postFn, loopFn) +} + +func TestMultiSchemaReorganizePKBackfillDML(t *testing.T) { + createSQL := `create table t (c1 INT primary key, c2 CHAR(255), c3 CHAR(255), c4 CHAR(255), c5 CHAR(255)) partition by range (c1) (partition p1 values less than (200), partition pMax values less than (maxvalue))` + i := 1 + initFn := func(tkO *testkit.TestKit) { + tkO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',%d,%d)`, i, "init O", 4185725186-i, 7483634197-i)) + i++ + tkO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',%d,%d)`, i, "init O", 4185725186-i, 7483634197-i)) + i++ + } + alterSQL := `alter table t reorganize partition p1 into (partition p0 values less than (100), partition p1 values less than (200))` + loopFn := func(tkO, tkNO *testkit.TestKit) { + res := tkO.MustQuery(`select schema_state from information_schema.DDL_JOBS where table_name = 't' order by job_id desc limit 1`) + schemaState := res.Rows()[0][0].(string) + tkO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',%d,%d)`, i, schemaState+" O", 4185725186-i, 7483634197-i)) + i++ + tkNO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',%d,%d)`, i, schemaState+" NO", 4185725186-i, 7483634197-i)) + i++ + } + postFn := func(tkO *testkit.TestKit, _ kv.Storage) { + tkO.MustQuery(`select c1,c2,c3 from t`).Sort().Check(testkit.Rows(""+ + "1 init O updated", + "10 delete reorganization NO Original", + "11 public O Original", + "12 public NO Original", + "13 none O Original", + "14 none NO Original", + "2 init O updated", + "3 delete only O updated", + "4 delete only NO updated", + "5 write only O updated", + "6 write only NO updated", + "7 write reorganization O Original", + "8 write reorganization NO Original", + "9 delete reorganization O Original")) + } + runMultiSchemaTestWithBackfillDML(t, createSQL, alterSQL, "update t set c3 = 'updated'", initFn, postFn, loopFn) +} func TestMultiSchemaReorganizeNoPK(t *testing.T) { createSQL := `create table t (c1 INT, c2 CHAR(255), c3 CHAR(255), c4 CHAR(255), c5 CHAR(255)) partition by range (c1) (partition p1 values less than (200), partition pMax values less than (maxvalue))` i := 1 initFn := func(tkO *testkit.TestKit) { - tkO.MustExec(fmt.Sprintf(`insert into t values (%d,repeat('%d', 25),repeat('%d', 25),repeat('%d', 25),repeat('%d', 25))`, i, 9786756453-i, 6821527184-i, 4185725186-i, 7483634197-i)) + tkO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',repeat('%d', 25),repeat('%d', 25))`, i, "init O", 4185725186-i, 7483634197-i)) i++ - tkO.MustExec(fmt.Sprintf(`insert into t values (%d,repeat('%d', 25),repeat('%d', 25),repeat('%d', 25),repeat('%d', 25))`, i, 9786756453-i, 6821527184-i, 4185725186-i, 7483634197-i)) + tkO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',repeat('%d', 25),repeat('%d', 25))`, i, "init O", 4185725186-i, 7483634197-i)) i++ } alterSQL := `alter table t reorganize partition p1 into (partition p0 values less than (100), partition p1 values less than (200))` loopFn := func(tkO, tkNO *testkit.TestKit) { res := tkO.MustQuery(`select schema_state from information_schema.DDL_JOBS where table_name = 't' order by job_id desc limit 1`) schemaState := res.Rows()[0][0].(string) - tkO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s',concat('O-', repeat('%d', 25)),repeat('%d', 25),repeat('%d', 25))`, i, schemaState, 6821527184-i, 4185725186-i, 7483634197-i)) + tkO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',repeat('%d', 25),repeat('%d', 25))`, i, schemaState+" O", 4185725186-i, 7483634197-i)) i++ - tkNO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s',concat('NO-',repeat('%d', 25)),repeat('%d', 25),repeat('%d', 25))`, i, schemaState, 6821527184-i, 4185725186-i, 7483634197-i)) + tkNO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',repeat('%d', 25),repeat('%d', 25))`, i, schemaState+" NO", 4185725186-i, 7483634197-i)) i++ } postFn := func(tkO *testkit.TestKit, _ kv.Storage) { - tkO.MustQuery(`select * from t`).Sort().Check(testkit.Rows(""+ - "1 9786756452978675645297867564529786756452978675645297867564529786756452978675645297867564529786756452978675645297867564529786756452978675645297867564529786756452978675645297867564529786756452978675645297867564529786756452978675645297867564529786756452 6821527183682152718368215271836821527183682152718368215271836821527183682152718368215271836821527183682152718368215271836821527183682152718368215271836821527183682152718368215271836821527183682152718368215271836821527183682152718368215271836821527183 4185725185418572518541857251854185725185418572518541857251854185725185418572518541857251854185725185418572518541857251854185725185418572518541857251854185725185418572518541857251854185725185418572518541857251854185725185418572518541857251854185725185 7483634196748363419674836341967483634196748363419674836341967483634196748363419674836341967483634196748363419674836341967483634196748363419674836341967483634196748363419674836341967483634196748363419674836341967483634196748363419674836341967483634196", - "10 delete reorganization NO-6821527174682152717468215271746821527174682152717468215271746821527174682152717468215271746821527174682152717468215271746821527174682152717468215271746821527174682152717468215271746821527174682152717468215271746821527174682152717468215271746821527174 4185725176418572517641857251764185725176418572517641857251764185725176418572517641857251764185725176418572517641857251764185725176418572517641857251764185725176418572517641857251764185725176418572517641857251764185725176418572517641857251764185725176 7483634187748363418774836341877483634187748363418774836341877483634187748363418774836341877483634187748363418774836341877483634187748363418774836341877483634187748363418774836341877483634187748363418774836341877483634187748363418774836341877483634187", - "11 public O-6821527173682152717368215271736821527173682152717368215271736821527173682152717368215271736821527173682152717368215271736821527173682152717368215271736821527173682152717368215271736821527173682152717368215271736821527173682152717368215271736821527173 4185725175418572517541857251754185725175418572517541857251754185725175418572517541857251754185725175418572517541857251754185725175418572517541857251754185725175418572517541857251754185725175418572517541857251754185725175418572517541857251754185725175 7483634186748363418674836341867483634186748363418674836341867483634186748363418674836341867483634186748363418674836341867483634186748363418674836341867483634186748363418674836341867483634186748363418674836341867483634186748363418674836341867483634186", - "12 public NO-6821527172682152717268215271726821527172682152717268215271726821527172682152717268215271726821527172682152717268215271726821527172682152717268215271726821527172682152717268215271726821527172682152717268215271726821527172682152717268215271726821527172 4185725174418572517441857251744185725174418572517441857251744185725174418572517441857251744185725174418572517441857251744185725174418572517441857251744185725174418572517441857251744185725174418572517441857251744185725174418572517441857251744185725174 7483634185748363418574836341857483634185748363418574836341857483634185748363418574836341857483634185748363418574836341857483634185748363418574836341857483634185748363418574836341857483634185748363418574836341857483634185748363418574836341857483634185", - "13 none O-6821527171682152717168215271716821527171682152717168215271716821527171682152717168215271716821527171682152717168215271716821527171682152717168215271716821527171682152717168215271716821527171682152717168215271716821527171682152717168215271716821527171 4185725173418572517341857251734185725173418572517341857251734185725173418572517341857251734185725173418572517341857251734185725173418572517341857251734185725173418572517341857251734185725173418572517341857251734185725173418572517341857251734185725173 7483634184748363418474836341847483634184748363418474836341847483634184748363418474836341847483634184748363418474836341847483634184748363418474836341847483634184748363418474836341847483634184748363418474836341847483634184748363418474836341847483634184", - "14 none NO-6821527170682152717068215271706821527170682152717068215271706821527170682152717068215271706821527170682152717068215271706821527170682152717068215271706821527170682152717068215271706821527170682152717068215271706821527170682152717068215271706821527170 4185725172418572517241857251724185725172418572517241857251724185725172418572517241857251724185725172418572517241857251724185725172418572517241857251724185725172418572517241857251724185725172418572517241857251724185725172418572517241857251724185725172 7483634183748363418374836341837483634183748363418374836341837483634183748363418374836341837483634183748363418374836341837483634183748363418374836341837483634183748363418374836341837483634183748363418374836341837483634183748363418374836341837483634183", - "2 9786756451978675645197867564519786756451978675645197867564519786756451978675645197867564519786756451978675645197867564519786756451978675645197867564519786756451978675645197867564519786756451978675645197867564519786756451978675645197867564519786756451 6821527182682152718268215271826821527182682152718268215271826821527182682152718268215271826821527182682152718268215271826821527182682152718268215271826821527182682152718268215271826821527182682152718268215271826821527182682152718268215271826821527182 4185725184418572518441857251844185725184418572518441857251844185725184418572518441857251844185725184418572518441857251844185725184418572518441857251844185725184418572518441857251844185725184418572518441857251844185725184418572518441857251844185725184 7483634195748363419574836341957483634195748363419574836341957483634195748363419574836341957483634195748363419574836341957483634195748363419574836341957483634195748363419574836341957483634195748363419574836341957483634195748363419574836341957483634195", - "3 delete only O-6821527181682152718168215271816821527181682152718168215271816821527181682152718168215271816821527181682152718168215271816821527181682152718168215271816821527181682152718168215271816821527181682152718168215271816821527181682152718168215271816821527181 4185725183418572518341857251834185725183418572518341857251834185725183418572518341857251834185725183418572518341857251834185725183418572518341857251834185725183418572518341857251834185725183418572518341857251834185725183418572518341857251834185725183 7483634194748363419474836341947483634194748363419474836341947483634194748363419474836341947483634194748363419474836341947483634194748363419474836341947483634194748363419474836341947483634194748363419474836341947483634194748363419474836341947483634194", - "4 delete only NO-6821527180682152718068215271806821527180682152718068215271806821527180682152718068215271806821527180682152718068215271806821527180682152718068215271806821527180682152718068215271806821527180682152718068215271806821527180682152718068215271806821527180 4185725182418572518241857251824185725182418572518241857251824185725182418572518241857251824185725182418572518241857251824185725182418572518241857251824185725182418572518241857251824185725182418572518241857251824185725182418572518241857251824185725182 7483634193748363419374836341937483634193748363419374836341937483634193748363419374836341937483634193748363419374836341937483634193748363419374836341937483634193748363419374836341937483634193748363419374836341937483634193748363419374836341937483634193", - "5 write only O-6821527179682152717968215271796821527179682152717968215271796821527179682152717968215271796821527179682152717968215271796821527179682152717968215271796821527179682152717968215271796821527179682152717968215271796821527179682152717968215271796821527179 4185725181418572518141857251814185725181418572518141857251814185725181418572518141857251814185725181418572518141857251814185725181418572518141857251814185725181418572518141857251814185725181418572518141857251814185725181418572518141857251814185725181 7483634192748363419274836341927483634192748363419274836341927483634192748363419274836341927483634192748363419274836341927483634192748363419274836341927483634192748363419274836341927483634192748363419274836341927483634192748363419274836341927483634192", - "6 write only NO-6821527178682152717868215271786821527178682152717868215271786821527178682152717868215271786821527178682152717868215271786821527178682152717868215271786821527178682152717868215271786821527178682152717868215271786821527178682152717868215271786821527178 4185725180418572518041857251804185725180418572518041857251804185725180418572518041857251804185725180418572518041857251804185725180418572518041857251804185725180418572518041857251804185725180418572518041857251804185725180418572518041857251804185725180 7483634191748363419174836341917483634191748363419174836341917483634191748363419174836341917483634191748363419174836341917483634191748363419174836341917483634191748363419174836341917483634191748363419174836341917483634191748363419174836341917483634191", - "7 write reorganization O-6821527177682152717768215271776821527177682152717768215271776821527177682152717768215271776821527177682152717768215271776821527177682152717768215271776821527177682152717768215271776821527177682152717768215271776821527177682152717768215271776821527177 4185725179418572517941857251794185725179418572517941857251794185725179418572517941857251794185725179418572517941857251794185725179418572517941857251794185725179418572517941857251794185725179418572517941857251794185725179418572517941857251794185725179 7483634190748363419074836341907483634190748363419074836341907483634190748363419074836341907483634190748363419074836341907483634190748363419074836341907483634190748363419074836341907483634190748363419074836341907483634190748363419074836341907483634190", - "8 write reorganization NO-6821527176682152717668215271766821527176682152717668215271766821527176682152717668215271766821527176682152717668215271766821527176682152717668215271766821527176682152717668215271766821527176682152717668215271766821527176682152717668215271766821527176 4185725178418572517841857251784185725178418572517841857251784185725178418572517841857251784185725178418572517841857251784185725178418572517841857251784185725178418572517841857251784185725178418572517841857251784185725178418572517841857251784185725178 7483634189748363418974836341897483634189748363418974836341897483634189748363418974836341897483634189748363418974836341897483634189748363418974836341897483634189748363418974836341897483634189748363418974836341897483634189748363418974836341897483634189", - "9 delete reorganization O-6821527175682152717568215271756821527175682152717568215271756821527175682152717568215271756821527175682152717568215271756821527175682152717568215271756821527175682152717568215271756821527175682152717568215271756821527175682152717568215271756821527175 4185725177418572517741857251774185725177418572517741857251774185725177418572517741857251774185725177418572517741857251774185725177418572517741857251774185725177418572517741857251774185725177418572517741857251774185725177418572517741857251774185725177 7483634188748363418874836341887483634188748363418874836341887483634188748363418874836341887483634188748363418874836341887483634188748363418874836341887483634188748363418874836341887483634188748363418874836341887483634188748363418874836341887483634188")) + require.Equal(t, int(7*2+1), i) + tkO.MustQuery(`select c1,_tidb_rowid,c2 from t`).Sort().Check(testkit.Rows(""+ + "1 60001 init O", + "10 30004 delete reorganization NO", + "11 7 public O", + "12 30005 public NO", + "13 8 none O", + "14 30006 none NO", + "2 60002 init O", + "3 60003 delete only O", + "4 60004 delete only NO", + "5 4 write only O", + // Before, there were a DUPLICATE ROW here!!! + //"5 60004 write only O", + "6 60005 write only NO", + "7 5 write reorganization O", + "8 30003 write reorganization NO", + "9 6 delete reorganization O")) } runMultiSchemaTest(t, createSQL, alterSQL, initFn, postFn, loopFn) } +func TestMultiSchemaReorganizeNoPKBackfillDML(t *testing.T) { + createSQL := `create table t (c1 INT, c2 CHAR(255), c3 CHAR(255), c4 CHAR(255), c5 CHAR(255)) partition by range (c1) (partition p1 values less than (200), partition pMax values less than (maxvalue))` + i := 1 + initFn := func(tkO *testkit.TestKit) { + tkO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',repeat('%d', 25),repeat('%d', 25))`, i, "init O", 4185725186-i, 7483634197-i)) + i++ + tkO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',repeat('%d', 25),repeat('%d', 25))`, i, "init O", 4185725186-i, 7483634197-i)) + i++ + } + alterSQL := `alter table t reorganize partition p1 into (partition p0 values less than (100), partition p1 values less than (200))` + loopFn := func(tkO, tkNO *testkit.TestKit) { + res := tkO.MustQuery(`select schema_state from information_schema.DDL_JOBS where table_name = 't' order by job_id desc limit 1`) + schemaState := res.Rows()[0][0].(string) + tkO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',repeat('%d', 25),repeat('%d', 25))`, i, schemaState+" O", 4185725186-i, 7483634197-i)) + i++ + tkNO.MustExec(fmt.Sprintf(`insert into t values (%d,'%s','Original',repeat('%d', 25),repeat('%d', 25))`, i, schemaState+" NO", 4185725186-i, 7483634197-i)) + i++ + } + postFn := func(tkO *testkit.TestKit, _ kv.Storage) { + require.Equal(t, int(7*2+1), i) + tkO.MustQuery(`select c1,_tidb_rowid,c2,c3 from t`).Sort().Check(testkit.Rows(""+ + "1 1 init O updated", + "10 30004 delete reorganization NO Original", + "11 7 public O Original", + "12 30005 public NO Original", + "13 8 none O Original", + "14 30006 none NO Original", + "2 2 init O updated", + "3 3 delete only O updated", + "4 30001 delete only NO updated", + "5 4 write only O updated", + "6 30002 write only NO updated", + "7 5 write reorganization O Original", + "8 30003 write reorganization NO Original", + "9 6 delete reorganization O Original")) + } + runMultiSchemaTestWithBackfillDML(t, createSQL, alterSQL, "update t set c3 = 'updated'", initFn, postFn, loopFn) +} + // TestMultiSchemaTruncatePartitionWithGlobalIndex to show behavior when // truncating a partition with a global index func TestMultiSchemaTruncatePartitionWithGlobalIndex(t *testing.T) {