From 08d0d42e64f93f6a5099d87f1025f4edd1a62076 Mon Sep 17 00:00:00 2001 From: jiyfhust Date: Fri, 21 Apr 2023 09:50:52 +0800 Subject: [PATCH 1/5] split and scatter region for truncate partition --- ddl/ddl_api.go | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index f9d5039b41351..d6ec2876c7f3b 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -4219,30 +4219,34 @@ func (d *ddl) TruncateTablePartition(ctx sessionctx.Context, ident ast.Ident, sp return errors.Trace(dbterror.ErrPartitionMgmtOnNonpartitioned) } - var pids []int64 - if spec.OnAllPartitions { - pids = make([]int64, len(meta.GetPartitionInfo().Definitions)) - for i, def := range meta.GetPartitionInfo().Definitions { - pids[i] = def.ID + fn := func(pi *model.PartitionInfo) (*model.PartitionInfo, error) { + if spec.OnAllPartitions { + return pi, nil } - } else { + var defs []model.PartitionDefinition // MySQL allows duplicate partition names in truncate partition // so we filter them out through a hash - pidMap := make(map[int64]bool) + posMap := make(map[int]bool) for _, name := range spec.PartitionNames { - pid, err := tables.FindPartitionByName(meta, name.L) - if err != nil { - return errors.Trace(err) + pos := pi.FindPartitionDefinitionByName(name.L) + if pos < 0 { + return nil, errors.Trace(table.ErrUnknownPartition.GenWithStackByArgs(name.L, ident.Name.O)) + } + if _, ok := posMap[pos]; !ok { + defs = append(defs, pi.Definitions[pos]) + posMap[pos] = true } - pidMap[pid] = true - } - // linter makezero does not handle changing pids to zero length, - // so create a new var and then assign to pids... - newPids := make([]int64, 0, len(pidMap)) - for pid := range pidMap { - newPids = append(newPids, pid) } - pids = newPids + pi.Definitions = defs + return pi, nil + } + var pids []int64 + pi, err := fn(meta.GetPartitionInfo().Clone()) + if err != nil { + return err + } + for i := range pi.Definitions { + pids = append(pids, pi.Definitions[i].ID) } job := &model.Job{ @@ -4256,11 +4260,16 @@ func (d *ddl) TruncateTablePartition(ctx sessionctx.Context, ident ast.Ident, sp } err = d.DoDDLJob(ctx, job) + err = d.callHookOnChanged(job, err) if err != nil { return errors.Trace(err) } - err = d.callHookOnChanged(job, err) - return errors.Trace(err) + if _, tb, err := d.getSchemaAndTableByIdent(ctx, ident); err == nil { + if p, err := fn(tb.Meta().GetPartitionInfo().Clone()); err == nil { + d.preSplitAndScatter(ctx, tb.Meta(), p) + } + } + return nil } func (d *ddl) DropTablePartition(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) error { From 8e429c9a4b81dbc149977821eab82857d1b93074 Mon Sep 17 00:00:00 2001 From: jiyfhust Date: Fri, 21 Apr 2023 17:08:26 +0800 Subject: [PATCH 2/5] fix --- ddl/db_partition_test.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/ddl/db_partition_test.go b/ddl/db_partition_test.go index d2f0a0f13f845..d8cfde01bf94a 100644 --- a/ddl/db_partition_test.go +++ b/ddl/db_partition_test.go @@ -1537,6 +1537,39 @@ func TestAlterTableTruncatePartitionByListColumns(t *testing.T) { tk.MustQuery("select * from t").Check(testkit.Rows()) } +func TestAlterTableTruncatePartitionPreSplitRegion(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + atomic.StoreUint32(&ddl.EnableSplitTableRegion, 1) + tk.MustExec("set @@global.tidb_scatter_region=1;") + tk.MustExec("use test;") + + tk.MustExec("drop table if exists t1;") + tk.MustExec(`CREATE TABLE t1 (id int, c varchar(128), key c(c)) partition by range (id) ( + partition p0 values less than (10), + partition p1 values less than MAXVALUE)`) + re := tk.MustQuery("show table t1 regions") + rows := re.Rows() + require.Len(t, rows, 2) + tk.MustExec(`alter table t1 truncate partition p0`) + re = tk.MustQuery("show table t1 regions") + rows = re.Rows() + require.Len(t, rows, 2) + + tk.MustExec("drop table if exists t2;") + tk.MustExec(`CREATE TABLE t2(id bigint(20) NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) NONCLUSTERED) SHARD_ROW_ID_BITS=4 PRE_SPLIT_REGIONS=3 PARTITION BY RANGE (id) ( + PARTITION p1 VALUES LESS THAN (10), + PARTITION p2 VALUES LESS THAN (20), + PARTITION p3 VALUES LESS THAN (MAXVALUE))`) + re = tk.MustQuery("show table t2 regions") + rows = re.Rows() + require.Len(t, rows, 24) + tk.MustExec(`alter table t2 truncate partition p3`) + re = tk.MustQuery("show table t2 regions") + rows = re.Rows() + require.Len(t, rows, 24) +} + func TestCreateTableWithKeyPartition(t *testing.T) { store := testkit.CreateMockStore(t, mockstore.WithDDLChecker()) From 4feb4af0cf6f73a71020b1829a80da69294be651 Mon Sep 17 00:00:00 2001 From: jiyfhust Date: Wed, 26 Apr 2023 17:36:45 +0800 Subject: [PATCH 3/5] fix --- ddl/ddl_api.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index d6ec2876c7f3b..17aaf8e1b5e66 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -4221,7 +4221,7 @@ func (d *ddl) TruncateTablePartition(ctx sessionctx.Context, ident ast.Ident, sp fn := func(pi *model.PartitionInfo) (*model.PartitionInfo, error) { if spec.OnAllPartitions { - return pi, nil + return pi.Clone(), nil } var defs []model.PartitionDefinition // MySQL allows duplicate partition names in truncate partition @@ -4237,11 +4237,12 @@ func (d *ddl) TruncateTablePartition(ctx sessionctx.Context, ident ast.Ident, sp posMap[pos] = true } } + pi = pi.Clone() pi.Definitions = defs return pi, nil } var pids []int64 - pi, err := fn(meta.GetPartitionInfo().Clone()) + pi, err := fn(meta.GetPartitionInfo()) if err != nil { return err } @@ -4265,7 +4266,7 @@ func (d *ddl) TruncateTablePartition(ctx sessionctx.Context, ident ast.Ident, sp return errors.Trace(err) } if _, tb, err := d.getSchemaAndTableByIdent(ctx, ident); err == nil { - if p, err := fn(tb.Meta().GetPartitionInfo().Clone()); err == nil { + if p, err := fn(tb.Meta().GetPartitionInfo()); err == nil { d.preSplitAndScatter(ctx, tb.Meta(), p) } } From 53173bbfa161b85a9936d00b8c9ed0caa6a471cd Mon Sep 17 00:00:00 2001 From: jiyfhust Date: Thu, 11 May 2023 15:05:03 +0800 Subject: [PATCH 4/5] fix --- ddl/ddl_api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 17aaf8e1b5e66..0c76913be9a1b 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -4241,11 +4241,11 @@ func (d *ddl) TruncateTablePartition(ctx sessionctx.Context, ident ast.Ident, sp pi.Definitions = defs return pi, nil } - var pids []int64 pi, err := fn(meta.GetPartitionInfo()) if err != nil { return err } + pids := make([]int64, 0, len(pi.Definitions)) for i := range pi.Definitions { pids = append(pids, pi.Definitions[i].ID) } From d22b4ce229ab60f181fe481f3871ea779e055196 Mon Sep 17 00:00:00 2001 From: jiyfhust Date: Fri, 12 May 2023 09:21:05 +0800 Subject: [PATCH 5/5] fix --- ddl/ddl_api.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 42df4bd150d84..1320add92a8cf 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -4232,7 +4232,7 @@ func (d *ddl) TruncateTablePartition(ctx sessionctx.Context, ident ast.Ident, sp return errors.Trace(dbterror.ErrPartitionMgmtOnNonpartitioned) } - fn := func(pi *model.PartitionInfo) (*model.PartitionInfo, error) { + getTruncatedParts := func(pi *model.PartitionInfo) (*model.PartitionInfo, error) { if spec.OnAllPartitions { return pi.Clone(), nil } @@ -4254,7 +4254,7 @@ func (d *ddl) TruncateTablePartition(ctx sessionctx.Context, ident ast.Ident, sp pi.Definitions = defs return pi, nil } - pi, err := fn(meta.GetPartitionInfo()) + pi, err := getTruncatedParts(meta.GetPartitionInfo()) if err != nil { return err } @@ -4279,7 +4279,7 @@ func (d *ddl) TruncateTablePartition(ctx sessionctx.Context, ident ast.Ident, sp return errors.Trace(err) } if _, tb, err := d.getSchemaAndTableByIdent(ctx, ident); err == nil { - if p, err := fn(tb.Meta().GetPartitionInfo()); err == nil { + if p, err := getTruncatedParts(tb.Meta().GetPartitionInfo()); err == nil { d.preSplitAndScatter(ctx, tb.Meta(), p) } }