From 2c09104e615a3d35efc6d9158952e1df65e98dce Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Sat, 8 Dec 2018 23:24:17 +0800 Subject: [PATCH 01/10] ddl: support alter table .. truncate partition --- ddl/db_test.go | 37 ++++++++++++++++++++++++++++++ ddl/ddl.go | 3 +++ ddl/ddl_api.go | 37 ++++++++++++++++++++++++++++++ ddl/ddl_worker.go | 2 ++ ddl/partition.go | 57 +++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 4 +++- go.sum | 3 +-- 7 files changed, 140 insertions(+), 3 deletions(-) diff --git a/ddl/db_test.go b/ddl/db_test.go index 1406e0b639370..ee8499439904a 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -3055,6 +3055,43 @@ func (s *testDBSuite) TestAlterTableDropPartition(c *C) { s.testErrorCode(c, sql4, tmysql.ErrDropPartitionNonExistent) } +func (s *testDBSuite) TestAlterTableTruncatePartition(c *C) { + s.tk = testkit.NewTestKit(c, s.store) + s.tk.MustExec("use test") + s.tk.MustExec("drop table if exists employees") + s.tk.MustExec("set @@tidb_enable_table_partition = 1") + s.tk.MustExec(`create table employees ( + id int not null, + hired int not null + ) partition by range( hired ) ( + partition p1 values less than (1991), + partition p2 values less than (1996), + partition p3 values less than (2001) + )`) + s.tk.MustExec("insert into employees values (1, 1990)") + s.tk.MustExec("insert into employees values (2, 1995)") + s.tk.MustExec("insert into employees values (3, 2000)") + result := s.tk.MustQuery("select * from employees order by id") + result.Check(testkit.Rows(`1 1990`, `2 1995`, `3 2000`)) + + s.testErrorCode(c, "alter table employees truncate partition xxx", tmysql.ErrUnknownPartition) + + s.tk.MustExec("alter table employees truncate partition p1") + result = s.tk.MustQuery("select * from employees order by id") + result.Check(testkit.Rows(`2 1995`, `3 2000`)) + + s.tk.MustExec("alter table employees truncate partition p3") + result = s.tk.MustQuery("select * from employees") + result.Check(testkit.Rows(`2 1995`)) + + s.tk.MustExec("insert into employees values (1, 1984)") + result = s.tk.MustQuery("select * from employees order by id") + result.Check(testkit.Rows(`1 1984`, `2 1995`)) + + s.tk.MustExec(`create table non_partition (id int)`) + s.testErrorCode(c, "alter table non_partition truncate partition p0", tmysql.ErrPartitionMgmtOnNonpartitioned) +} + func (s *testDBSuite) TestAddPartitionTooManyPartitions(c *C) { s.tk = testkit.NewTestKit(c, s.store) s.tk.MustExec("use test") diff --git a/ddl/ddl.go b/ddl/ddl.go index da6bfaea9051f..6e917921bf841 100644 --- a/ddl/ddl.go +++ b/ddl/ddl.go @@ -83,6 +83,7 @@ var ( errWaitReorgTimeout = terror.ClassDDL.New(codeWaitReorgTimeout, "wait for reorganization timeout") errInvalidStoreVer = terror.ClassDDL.New(codeInvalidStoreVer, "invalid storage current version") + errUnknownPartition = terror.ClassDDL.New(codeUnknownPartition, mysql.MySQLErrName[mysql.ErrUnknownPartition]) // We don't support dropping column with index covered now. errCantDropColWithIndex = terror.ClassDDL.New(codeCantDropColWithIndex, "can't drop column with index") errUnsupportedAddColumn = terror.ClassDDL.New(codeUnsupportedAddColumn, "unsupported add column") @@ -634,6 +635,7 @@ const ( codeWrongExprInPartitionFunc = terror.ErrCode(mysql.ErrWrongExprInPartitionFunc) codeWarnDataTruncated = terror.ErrCode(mysql.WarnDataTruncated) codeCoalesceOnlyOnHashPartition = terror.ErrCode(mysql.ErrCoalesceOnlyOnHashPartition) + codeUnknownPartition = terror.ErrCode(mysql.ErrUnknownPartition) ) func init() { @@ -683,6 +685,7 @@ func init() { codeWrongExprInPartitionFunc: mysql.ErrWrongExprInPartitionFunc, codeWarnDataTruncated: mysql.WarnDataTruncated, codeCoalesceOnlyOnHashPartition: mysql.ErrCoalesceOnlyOnHashPartition, + codeUnknownPartition: mysql.ErrUnknownPartition, } terror.ErrClassToMySQLCodes[terror.ClassDDL] = ddlMySQLErrCodes } diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index ad1c05deeec7d..91ab9c55989bd 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -1112,6 +1112,8 @@ func (d *ddl) AlterTable(ctx sessionctx.Context, ident ast.Ident, specs []*ast.A err = d.DropIndex(ctx, ident, model.NewCIStr(spec.Name)) case ast.AlterTableDropPartition: err = d.DropTablePartition(ctx, ident, spec) + case ast.AlterTableTruncatePartition: + err = d.TruncateTablePartition(ctx, ident, spec) case ast.AlterTableAddConstraint: constr := spec.Constraint switch spec.Constraint.Tp { @@ -1418,6 +1420,41 @@ func (d *ddl) CoalescePartitions(ctx sessionctx.Context, ident ast.Ident, spec * return errors.Trace(err) } +func (d *ddl) TruncateTablePartition(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) error { + is := d.infoHandle.Get() + schema, ok := is.SchemaByName(ident.Schema) + if !ok { + return errors.Trace(infoschema.ErrDatabaseNotExists.GenWithStackByArgs(schema)) + } + t, err := is.TableByName(ident.Schema, ident.Name) + if err != nil { + return errors.Trace(infoschema.ErrTableNotExists.GenWithStackByArgs(ident.Schema, ident.Name)) + } + meta := t.Meta() + if meta.GetPartitionInfo() == nil { + return errors.Trace(ErrPartitionMgmtOnNonpartitioned) + } + + if err := checkPartitionExist(meta, spec.Name); err != nil { + return errors.Trace(err) + } + + job := &model.Job{ + SchemaID: schema.ID, + TableID: meta.ID, + Type: model.ActionTruncateTablePartition, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{spec.Name}, + } + + err = d.doDDLJob(ctx, job) + if err != nil { + return errors.Trace(err) + } + err = d.callHookOnChanged(err) + return errors.Trace(err) +} + func (d *ddl) DropTablePartition(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) error { is := d.infoHandle.Get() schema, ok := is.SchemaByName(ident.Schema) diff --git a/ddl/ddl_worker.go b/ddl/ddl_worker.go index 8f89901582733..330ab2dc352d8 100644 --- a/ddl/ddl_worker.go +++ b/ddl/ddl_worker.go @@ -472,6 +472,8 @@ func (w *worker) runDDLJob(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, ver, err = onDropTable(t, job) case model.ActionDropTablePartition: ver, err = onDropTablePartition(t, job) + case model.ActionTruncateTablePartition: + ver, err = onTruncateTablePartition(t, job) case model.ActionAddColumn: ver, err = onAddColumn(d, t, job) case model.ActionDropColumn: diff --git a/ddl/partition.go b/ddl/partition.go index 2323363c5873b..8d92f4e862d85 100644 --- a/ddl/partition.go +++ b/ddl/partition.go @@ -318,6 +318,17 @@ func checkDropTablePartition(meta *model.TableInfo, partName string) error { return errors.Trace(ErrDropPartitionNonExistent.GenWithStackByArgs(partName)) } +func checkPartitionExist(meta *model.TableInfo, parName string) error { + // TODO: MySQL behavior for hash partition is weird, "create table .. partition by hash partition 4", + // it use p0, p1, p2, p3 as partition names automatically. + for _, def := range meta.Partition.Definitions { + if strings.EqualFold(def.Name.L, strings.ToLower(parName)) { + return nil + } + } + return errors.Trace(errUnknownPartition.GenWithStackByArgs(parName, meta.Name.O)) +} + // removePartitionInfo each ddl job deletes a partition. func removePartitionInfo(tblInfo *model.TableInfo, partName string) int64 { oldDefs := tblInfo.Partition.Definitions @@ -365,6 +376,52 @@ func onDropTablePartition(t *meta.Meta, job *model.Job) (ver int64, _ error) { return ver, nil } +// onDropTablePartition truncates old partition meta. +func onTruncateTablePartition(t *meta.Meta, job *model.Job) (int64, error) { + var ver int64 + var partName string + if err := job.DecodeArgs(&partName); err != nil { + job.State = model.JobStateCancelled + return ver, errors.Trace(err) + } + tblInfo, err := getTableInfo(t, job, job.SchemaID) + if err != nil { + return ver, errors.Trace(err) + } + pi := tblInfo.GetPartitionInfo() + if pi == nil { + return ver, errors.Trace(ErrPartitionMgmtOnNonpartitioned) + } + + oldID := int64(-1) + for i := 0; i < len(pi.Definitions); i++ { + def := &pi.Definitions[i] + if strings.EqualFold(def.Name.L, strings.ToLower(partName)) { + pid, err := t.GenGlobalID() + if err != nil { + return ver, errors.Trace(err) + } + oldID = def.ID + def.ID = pid + break + } + } + if oldID == -1 { + return ver, errUnknownPartition.GenWithStackByArgs(partName, tblInfo.Name.O) + } + + ver, err = updateVersionAndTableInfo(t, job, tblInfo, true) + if err != nil { + return ver, errors.Trace(err) + } + + // Finish this job. + job.FinishTableJob(model.JobStateDone, model.StateNone, ver, tblInfo) + // A background job will be created to delete old partition data. + job.Args = []interface{}{oldID} + return ver, nil +} + func checkAddPartitionTooManyPartitions(piDefs uint64) error { if piDefs > uint64(PartitionCountLimit) { return ErrTooManyPartitions diff --git a/go.mod b/go.mod index caf8b3e57d4c0..7ebaac0bf57a7 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,7 @@ require ( github.com/pingcap/errors v0.11.0 github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e github.com/pingcap/kvproto v0.0.0-20181105061835-1b5d69cd1d26 - github.com/pingcap/parser v0.0.0-20181206123229-b006f4e22d98 + github.com/pingcap/parser v0.0.0-20181208021024-ce789e70c83b github.com/pingcap/pd v2.1.0-rc.4+incompatible github.com/pingcap/tidb-tools v0.0.0-20181112132202-4860a0d5de03 github.com/pingcap/tipb v0.0.0-20181012112600-11e33c750323 @@ -85,3 +85,5 @@ require ( sourcegraph.com/sourcegraph/appdash v0.0.0-20180531100431-4c381bd170b4 sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 ) + +replace github.com/pingcap/parser => github.com/tiancaiamao/parser v0.0.0-20181208150835-2e9241b4e355 diff --git a/go.sum b/go.sum index 97457dbb6fb23..9fb64d5f7c3a8 100644 --- a/go.sum +++ b/go.sum @@ -107,8 +107,6 @@ github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e h1:P73/4dPCL96rG github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw= github.com/pingcap/kvproto v0.0.0-20181105061835-1b5d69cd1d26 h1:JK4VLNYbSn36QSbCnqALi2ySXdH0DfcMssT/zmLf4Ls= github.com/pingcap/kvproto v0.0.0-20181105061835-1b5d69cd1d26/go.mod h1:0gwbe1F2iBIjuQ9AH0DbQhL+Dpr5GofU8fgYyXk+ykk= -github.com/pingcap/parser v0.0.0-20181206123229-b006f4e22d98 h1:KsFKFW+PqU2y8xChYPrxMHQfkcbAe2SzsrVhMNAMRCg= -github.com/pingcap/parser v0.0.0-20181206123229-b006f4e22d98/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA= github.com/pingcap/pd v2.1.0-rc.4+incompatible h1:/buwGk04aHO5odk/+O8ZOXGs4qkUjYTJ2UpCJXna8NE= github.com/pingcap/pd v2.1.0-rc.4+incompatible/go.mod h1:nD3+EoYes4+aNNODO99ES59V83MZSI+dFbhyr667a0E= github.com/pingcap/tidb-tools v0.0.0-20181112132202-4860a0d5de03 h1:xVuo5U+l6XAWHsb+xhkZ8zz3jerIwDfCHAO6kR2Kaog= @@ -148,6 +146,7 @@ github.com/struCoder/pidusage v0.1.2 h1:fFPTThlcWFQyizv3xKs5Lyq1lpG5lZ36arEGNhWz github.com/struCoder/pidusage v0.1.2/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2 h1:mbAskLJ0oJfDRtkanvQPiooDH8HvJ2FBh+iKT/OmiQQ= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2/go.mod h1:2PfKggNGDuadAa0LElHrByyrz4JPZ9fFx6Gs7nx7ZZU= +github.com/tiancaiamao/parser v0.0.0-20181208150835-2e9241b4e355/go.mod h1:vqvanuOAAZ9O2rVI51fUrA9P3nV7HoILjLby0/OKOqA= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 h1:lYIiVDtZnyTWlNwiAxLj0bbpTcx1BWCFhXjfsvmPdNc= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/twinj/uuid v1.0.0 h1:fzz7COZnDrXGTAOHGuUGYd6sG+JMq+AoE7+Jlu0przk= From 0aef44865d1499542399029cbd74c4be62953e85 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Sun, 9 Dec 2018 00:50:34 +0800 Subject: [PATCH 02/10] fix CI --- go.mod | 2 +- go.sum | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 7ebaac0bf57a7..4020389f33f34 100644 --- a/go.mod +++ b/go.mod @@ -86,4 +86,4 @@ require ( sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 ) -replace github.com/pingcap/parser => github.com/tiancaiamao/parser v0.0.0-20181208150835-2e9241b4e355 +replace github.com/pingcap/parser => github.com/tiancaiamao/parser v0.0.0-20181208164110-006feb484d18 diff --git a/go.sum b/go.sum index 9fb64d5f7c3a8..8aed4c38b5bef 100644 --- a/go.sum +++ b/go.sum @@ -146,7 +146,12 @@ github.com/struCoder/pidusage v0.1.2 h1:fFPTThlcWFQyizv3xKs5Lyq1lpG5lZ36arEGNhWz github.com/struCoder/pidusage v0.1.2/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2 h1:mbAskLJ0oJfDRtkanvQPiooDH8HvJ2FBh+iKT/OmiQQ= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2/go.mod h1:2PfKggNGDuadAa0LElHrByyrz4JPZ9fFx6Gs7nx7ZZU= +github.com/tiancaiamao/parser v0.0.0-20181108133527-afafb63df286 h1:796qdQ14HjES75vnLKm1V6qQWQilLtJ5xgQTzeFpiUI= +github.com/tiancaiamao/parser v0.0.0-20181108133527-afafb63df286/go.mod h1:vqvanuOAAZ9O2rVI51fUrA9P3nV7HoILjLby0/OKOqA= +github.com/tiancaiamao/parser v0.0.0-20181208150835-2e9241b4e355 h1:Je+3evETelEDZf/6y74aJhKaPGCenj8FedHqCfdugCE= github.com/tiancaiamao/parser v0.0.0-20181208150835-2e9241b4e355/go.mod h1:vqvanuOAAZ9O2rVI51fUrA9P3nV7HoILjLby0/OKOqA= +github.com/tiancaiamao/parser v0.0.0-20181208164110-006feb484d18 h1:RdlDWP22IHOuC6abVahq+4m9Fl9W+NakecOCTaGsG6g= +github.com/tiancaiamao/parser v0.0.0-20181208164110-006feb484d18/go.mod h1:vqvanuOAAZ9O2rVI51fUrA9P3nV7HoILjLby0/OKOqA= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 h1:lYIiVDtZnyTWlNwiAxLj0bbpTcx1BWCFhXjfsvmPdNc= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/twinj/uuid v1.0.0 h1:fzz7COZnDrXGTAOHGuUGYd6sG+JMq+AoE7+Jlu0przk= From d3a1c36ba067e598badcd2a8e8ba930fdb927079 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Sun, 9 Dec 2018 01:05:20 +0800 Subject: [PATCH 03/10] fix make vet --- ddl/ddl_api.go | 2 +- ddl/partition.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 91ab9c55989bd..5f87fe55c3b7c 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -1435,7 +1435,7 @@ func (d *ddl) TruncateTablePartition(ctx sessionctx.Context, ident ast.Ident, sp return errors.Trace(ErrPartitionMgmtOnNonpartitioned) } - if err := checkPartitionExist(meta, spec.Name); err != nil { + if err = checkPartitionExist(meta, spec.Name); err != nil { return errors.Trace(err) } diff --git a/ddl/partition.go b/ddl/partition.go index 8d92f4e862d85..665d22544d876 100644 --- a/ddl/partition.go +++ b/ddl/partition.go @@ -397,9 +397,9 @@ func onTruncateTablePartition(t *meta.Meta, job *model.Job) (int64, error) { for i := 0; i < len(pi.Definitions); i++ { def := &pi.Definitions[i] if strings.EqualFold(def.Name.L, strings.ToLower(partName)) { - pid, err := t.GenGlobalID() + pid, err1 := t.GenGlobalID() if err != nil { - return ver, errors.Trace(err) + return ver, errors.Trace(err1) } oldID = def.ID def.ID = pid From 34482bb02d95667ff12d10e6352e664d70a65641 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Sun, 9 Dec 2018 09:59:07 +0800 Subject: [PATCH 04/10] go mod tidy --- go.sum | 5 ----- 1 file changed, 5 deletions(-) diff --git a/go.sum b/go.sum index 8aed4c38b5bef..c5387aa32d30b 100644 --- a/go.sum +++ b/go.sum @@ -146,11 +146,6 @@ github.com/struCoder/pidusage v0.1.2 h1:fFPTThlcWFQyizv3xKs5Lyq1lpG5lZ36arEGNhWz github.com/struCoder/pidusage v0.1.2/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2 h1:mbAskLJ0oJfDRtkanvQPiooDH8HvJ2FBh+iKT/OmiQQ= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2/go.mod h1:2PfKggNGDuadAa0LElHrByyrz4JPZ9fFx6Gs7nx7ZZU= -github.com/tiancaiamao/parser v0.0.0-20181108133527-afafb63df286 h1:796qdQ14HjES75vnLKm1V6qQWQilLtJ5xgQTzeFpiUI= -github.com/tiancaiamao/parser v0.0.0-20181108133527-afafb63df286/go.mod h1:vqvanuOAAZ9O2rVI51fUrA9P3nV7HoILjLby0/OKOqA= -github.com/tiancaiamao/parser v0.0.0-20181208150835-2e9241b4e355 h1:Je+3evETelEDZf/6y74aJhKaPGCenj8FedHqCfdugCE= -github.com/tiancaiamao/parser v0.0.0-20181208150835-2e9241b4e355/go.mod h1:vqvanuOAAZ9O2rVI51fUrA9P3nV7HoILjLby0/OKOqA= -github.com/tiancaiamao/parser v0.0.0-20181208164110-006feb484d18 h1:RdlDWP22IHOuC6abVahq+4m9Fl9W+NakecOCTaGsG6g= github.com/tiancaiamao/parser v0.0.0-20181208164110-006feb484d18/go.mod h1:vqvanuOAAZ9O2rVI51fUrA9P3nV7HoILjLby0/OKOqA= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 h1:lYIiVDtZnyTWlNwiAxLj0bbpTcx1BWCFhXjfsvmPdNc= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= From 48c32f923a6fb7412ec418a3bde43816855147b2 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 10 Dec 2018 14:43:03 +0800 Subject: [PATCH 05/10] address comment --- ddl/db_test.go | 15 +++++++++++++++ ddl/ddl_api.go | 6 ++++-- ddl/ddl_worker.go | 2 +- ddl/partition.go | 23 ++++++++++++----------- go.sum | 1 + 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/ddl/db_test.go b/ddl/db_test.go index ee8499439904a..b5b0a69abb877 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -3076,10 +3076,22 @@ func (s *testDBSuite) TestAlterTableTruncatePartition(c *C) { s.testErrorCode(c, "alter table employees truncate partition xxx", tmysql.ErrUnknownPartition) + ctx := s.tk.Se.(sessionctx.Context) + is := domain.GetDomain(ctx).InfoSchema() + oldTblInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("employees")) + c.Assert(err, IsNil) + oldPID := oldTblInfo.Meta().Partition.Definitions[0].ID + s.tk.MustExec("alter table employees truncate partition p1") result = s.tk.MustQuery("select * from employees order by id") result.Check(testkit.Rows(`2 1995`, `3 2000`)) + is = domain.GetDomain(ctx).InfoSchema() + oldTblInfo, err = is.TableByName(model.NewCIStr("test"), model.NewCIStr("employees")) + c.Assert(err, IsNil) + newPID := oldTblInfo.Meta().Partition.Definitions[0].ID + c.Assert(oldPID != newPID, IsTrue) + s.tk.MustExec("alter table employees truncate partition p3") result = s.tk.MustQuery("select * from employees") result.Check(testkit.Rows(`2 1995`)) @@ -3087,6 +3099,9 @@ func (s *testDBSuite) TestAlterTableTruncatePartition(c *C) { s.tk.MustExec("insert into employees values (1, 1984)") result = s.tk.MustQuery("select * from employees order by id") result.Check(testkit.Rows(`1 1984`, `2 1995`)) + s.tk.MustExec("insert into employees values (3, 2000)") + result = s.tk.MustQuery("select * from employees order by id") + result.Check(testkit.Rows(`1 1984`, `2 1995`, `3 2000`)) s.tk.MustExec(`create table non_partition (id int)`) s.testErrorCode(c, "alter table non_partition truncate partition p0", tmysql.ErrPartitionMgmtOnNonpartitioned) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 5f87fe55c3b7c..2c0ac48276d3b 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -1435,7 +1435,9 @@ func (d *ddl) TruncateTablePartition(ctx sessionctx.Context, ident ast.Ident, sp return errors.Trace(ErrPartitionMgmtOnNonpartitioned) } - if err = checkPartitionExist(meta, spec.Name); err != nil { + var pid int64 + pid, err = findPartitionByName(meta, spec.Name) + if err != nil { return errors.Trace(err) } @@ -1444,7 +1446,7 @@ func (d *ddl) TruncateTablePartition(ctx sessionctx.Context, ident ast.Ident, sp TableID: meta.ID, Type: model.ActionTruncateTablePartition, BinlogInfo: &model.HistoryInfo{}, - Args: []interface{}{spec.Name}, + Args: []interface{}{pid}, } err = d.doDDLJob(ctx, job) diff --git a/ddl/ddl_worker.go b/ddl/ddl_worker.go index 330ab2dc352d8..8d818ea0bd635 100644 --- a/ddl/ddl_worker.go +++ b/ddl/ddl_worker.go @@ -285,7 +285,7 @@ func (w *worker) finishDDLJob(t *meta.Meta, job *model.Job) (err error) { // After rolling back an AddIndex operation, we need to use delete-range to delete the half-done index data. err = w.deleteRange(job) - case model.ActionDropSchema, model.ActionDropTable, model.ActionTruncateTable, model.ActionDropIndex, model.ActionDropTablePartition: + case model.ActionDropSchema, model.ActionDropTable, model.ActionTruncateTable, model.ActionDropIndex, model.ActionDropTablePartition, model.ActionTruncateTablePartition: err = w.deleteRange(job) } if err != nil { diff --git a/ddl/partition.go b/ddl/partition.go index 665d22544d876..a5db931b9f5ab 100644 --- a/ddl/partition.go +++ b/ddl/partition.go @@ -318,15 +318,16 @@ func checkDropTablePartition(meta *model.TableInfo, partName string) error { return errors.Trace(ErrDropPartitionNonExistent.GenWithStackByArgs(partName)) } -func checkPartitionExist(meta *model.TableInfo, parName string) error { +func findPartitionByName(meta *model.TableInfo, parName string) (int64, error) { // TODO: MySQL behavior for hash partition is weird, "create table .. partition by hash partition 4", // it use p0, p1, p2, p3 as partition names automatically. + parName = strings.ToLower(parName) for _, def := range meta.Partition.Definitions { - if strings.EqualFold(def.Name.L, strings.ToLower(parName)) { - return nil + if strings.EqualFold(def.Name.L, parName) { + return def.ID, nil } } - return errors.Trace(errUnknownPartition.GenWithStackByArgs(parName, meta.Name.O)) + return -1, errors.Trace(errUnknownPartition.GenWithStackByArgs(parName, meta.Name.O)) } // removePartitionInfo each ddl job deletes a partition. @@ -379,8 +380,8 @@ func onDropTablePartition(t *meta.Meta, job *model.Job) (ver int64, _ error) { // onDropTablePartition truncates old partition meta. func onTruncateTablePartition(t *meta.Meta, job *model.Job) (int64, error) { var ver int64 - var partName string - if err := job.DecodeArgs(&partName); err != nil { + var oldID int64 + if err := job.DecodeArgs(&oldID); err != nil { job.State = model.JobStateCancelled return ver, errors.Trace(err) } @@ -393,21 +394,21 @@ func onTruncateTablePartition(t *meta.Meta, job *model.Job) (int64, error) { return ver, errors.Trace(ErrPartitionMgmtOnNonpartitioned) } - oldID := int64(-1) + var find bool for i := 0; i < len(pi.Definitions); i++ { def := &pi.Definitions[i] - if strings.EqualFold(def.Name.L, strings.ToLower(partName)) { + if def.ID == oldID { pid, err1 := t.GenGlobalID() if err != nil { return ver, errors.Trace(err1) } - oldID = def.ID def.ID = pid + find = true break } } - if oldID == -1 { - return ver, errUnknownPartition.GenWithStackByArgs(partName, tblInfo.Name.O) + if !find { + return ver, errUnknownPartition.GenWithStackByArgs("drop?", tblInfo.Name.O) } ver, err = updateVersionAndTableInfo(t, job, tblInfo, true) diff --git a/go.sum b/go.sum index c5387aa32d30b..46319efa9f705 100644 --- a/go.sum +++ b/go.sum @@ -146,6 +146,7 @@ github.com/struCoder/pidusage v0.1.2 h1:fFPTThlcWFQyizv3xKs5Lyq1lpG5lZ36arEGNhWz github.com/struCoder/pidusage v0.1.2/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2 h1:mbAskLJ0oJfDRtkanvQPiooDH8HvJ2FBh+iKT/OmiQQ= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2/go.mod h1:2PfKggNGDuadAa0LElHrByyrz4JPZ9fFx6Gs7nx7ZZU= +github.com/tiancaiamao/parser v0.0.0-20181208164110-006feb484d18 h1:RdlDWP22IHOuC6abVahq+4m9Fl9W+NakecOCTaGsG6g= github.com/tiancaiamao/parser v0.0.0-20181208164110-006feb484d18/go.mod h1:vqvanuOAAZ9O2rVI51fUrA9P3nV7HoILjLby0/OKOqA= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 h1:lYIiVDtZnyTWlNwiAxLj0bbpTcx1BWCFhXjfsvmPdNc= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= From 43e8baffbfb3b4671f1696725a56dd33ea0001c5 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 10 Dec 2018 18:38:11 +0800 Subject: [PATCH 06/10] go mod tidy --- go.mod | 2 +- go.sum | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index f5d8b4f1721f6..20d9a3e05d634 100644 --- a/go.mod +++ b/go.mod @@ -86,4 +86,4 @@ require ( sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 ) -replace github.com/pingcap/parser => github.com/tiancaiamao/parser v0.0.0-20181210100122-04339aab7f71 +replace github.com/pingcap/parser => github.com/tiancaiamao/parser v0.0.0-20181210101737-48890850a7dd diff --git a/go.sum b/go.sum index e9356de1b8267..ba64a03132a93 100644 --- a/go.sum +++ b/go.sum @@ -107,8 +107,6 @@ github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e h1:P73/4dPCL96rG github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw= github.com/pingcap/kvproto v0.0.0-20181105061835-1b5d69cd1d26 h1:JK4VLNYbSn36QSbCnqALi2ySXdH0DfcMssT/zmLf4Ls= github.com/pingcap/kvproto v0.0.0-20181105061835-1b5d69cd1d26/go.mod h1:0gwbe1F2iBIjuQ9AH0DbQhL+Dpr5GofU8fgYyXk+ykk= -github.com/pingcap/parser v0.0.0-20181210061630-27e9d3e251d4 h1:2rCHDk4h8VZw0fiC2CFJffOlXU3iMuz1kOt5wTMCemY= -github.com/pingcap/parser v0.0.0-20181210061630-27e9d3e251d4/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA= github.com/pingcap/pd v2.1.0-rc.4+incompatible h1:/buwGk04aHO5odk/+O8ZOXGs4qkUjYTJ2UpCJXna8NE= github.com/pingcap/pd v2.1.0-rc.4+incompatible/go.mod h1:nD3+EoYes4+aNNODO99ES59V83MZSI+dFbhyr667a0E= github.com/pingcap/tidb-tools v0.0.0-20181112132202-4860a0d5de03 h1:xVuo5U+l6XAWHsb+xhkZ8zz3jerIwDfCHAO6kR2Kaog= @@ -148,10 +146,7 @@ github.com/struCoder/pidusage v0.1.2 h1:fFPTThlcWFQyizv3xKs5Lyq1lpG5lZ36arEGNhWz github.com/struCoder/pidusage v0.1.2/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2 h1:mbAskLJ0oJfDRtkanvQPiooDH8HvJ2FBh+iKT/OmiQQ= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2/go.mod h1:2PfKggNGDuadAa0LElHrByyrz4JPZ9fFx6Gs7nx7ZZU= -github.com/tiancaiamao/parser v0.0.0-20181208164110-006feb484d18 h1:RdlDWP22IHOuC6abVahq+4m9Fl9W+NakecOCTaGsG6g= -github.com/tiancaiamao/parser v0.0.0-20181208164110-006feb484d18/go.mod h1:vqvanuOAAZ9O2rVI51fUrA9P3nV7HoILjLby0/OKOqA= -github.com/tiancaiamao/parser v0.0.0-20181210100122-04339aab7f71 h1:h6zn4mkL+pJbdyJaC4UxFi2EihcwBfD7TRThdIvyA88= -github.com/tiancaiamao/parser v0.0.0-20181210100122-04339aab7f71/go.mod h1:vqvanuOAAZ9O2rVI51fUrA9P3nV7HoILjLby0/OKOqA= +github.com/tiancaiamao/parser v0.0.0-20181210101737-48890850a7dd/go.mod h1:vqvanuOAAZ9O2rVI51fUrA9P3nV7HoILjLby0/OKOqA= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 h1:lYIiVDtZnyTWlNwiAxLj0bbpTcx1BWCFhXjfsvmPdNc= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/twinj/uuid v1.0.0 h1:fzz7COZnDrXGTAOHGuUGYd6sG+JMq+AoE7+Jlu0przk= From 674ef695d39d5e8e144572e7d92dfb312d0a9d42 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 10 Dec 2018 18:46:57 +0800 Subject: [PATCH 07/10] address comment --- ddl/db_test.go | 4 ++++ ddl/delete_range.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ddl/db_test.go b/ddl/db_test.go index d2706e06b2008..41617c4824f73 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -3087,6 +3087,10 @@ func (s *testDBSuite) TestAlterTableTruncatePartition(c *C) { result = s.tk.MustQuery("select * from employees order by id") result.Check(testkit.Rows(`2 1995`, `3 2000`)) + partitionPrefix := tablecodec.EncodeTablePrefix(oldPID) + hasOldPartitionData := checkPartitionDelRangeDone(c, s, partitionPrefix) + c.Assert(hasOldPartitionData, IsFalse) + is = domain.GetDomain(ctx).InfoSchema() oldTblInfo, err = is.TableByName(model.NewCIStr("test"), model.NewCIStr("employees")) c.Assert(err, IsNil) diff --git a/ddl/delete_range.go b/ddl/delete_range.go index 6a4397c734b83..dfee35efe0ca6 100644 --- a/ddl/delete_range.go +++ b/ddl/delete_range.go @@ -243,7 +243,7 @@ func insertJobIntoDeleteRangeTable(ctx sessionctx.Context, job *model.Job) error startKey = tablecodec.EncodeTablePrefix(tableID) endKey := tablecodec.EncodeTablePrefix(tableID + 1) return doInsert(s, job.ID, tableID, startKey, endKey, now) - case model.ActionDropTablePartition: + case model.ActionDropTablePartition, model.ActionTruncateTablePartition: var physicalTableID int64 if err := job.DecodeArgs(&physicalTableID); err != nil { return errors.Trace(err) From 42b34a4e04e157582722a3579f7f6d6f7f747976 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 10 Dec 2018 19:54:12 +0800 Subject: [PATCH 08/10] remove "replace ..." check from circle CI --- circle.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/circle.yml b/circle.yml index 3912f3ae2fd3c..3af846f7e2ac1 100644 --- a/circle.yml +++ b/circle.yml @@ -13,6 +13,3 @@ jobs: - run: name: "Go mod tidy" command: ./hack/check-tidy.sh - - run: - name: "Check go mod replace is removed" - command: ./hack/check_parser_replace.sh From cb20ade44e70f22952cd213bb651cb4baa7b746c Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 10 Dec 2018 20:04:00 +0800 Subject: [PATCH 09/10] address comment --- .travis.yml | 1 - circle.yml | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d81c12ae3b407..c473d1d6443dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,4 +17,3 @@ before_install: script: - make dev - ./hack/check-tidy.sh - - ./hack/check_parser_replace.sh diff --git a/circle.yml b/circle.yml index 3af846f7e2ac1..3912f3ae2fd3c 100644 --- a/circle.yml +++ b/circle.yml @@ -13,3 +13,6 @@ jobs: - run: name: "Go mod tidy" command: ./hack/check-tidy.sh + - run: + name: "Check go mod replace is removed" + command: ./hack/check_parser_replace.sh From 6b8f24ba5a5b54073dcaaeea1ef6fa8b7e365261 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Tue, 11 Dec 2018 10:58:33 +0800 Subject: [PATCH 10/10] clean go.mod --- go.mod | 2 -- go.sum | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 585b1bef64671..08135b2bc61e1 100644 --- a/go.mod +++ b/go.mod @@ -85,5 +85,3 @@ require ( sourcegraph.com/sourcegraph/appdash v0.0.0-20180531100431-4c381bd170b4 sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 ) - -replace github.com/pingcap/parser => github.com/tiancaiamao/parser v0.0.0-20181210101737-48890850a7dd diff --git a/go.sum b/go.sum index ba64a03132a93..be57fc9899053 100644 --- a/go.sum +++ b/go.sum @@ -107,6 +107,8 @@ github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e h1:P73/4dPCL96rG github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw= github.com/pingcap/kvproto v0.0.0-20181105061835-1b5d69cd1d26 h1:JK4VLNYbSn36QSbCnqALi2ySXdH0DfcMssT/zmLf4Ls= github.com/pingcap/kvproto v0.0.0-20181105061835-1b5d69cd1d26/go.mod h1:0gwbe1F2iBIjuQ9AH0DbQhL+Dpr5GofU8fgYyXk+ykk= +github.com/pingcap/parser v0.0.0-20181211024540-4e6d047fcaae h1:RD98+89F/yakFLnztEL4Pi9f+RkOAm2vgRJcB1p6tTw= +github.com/pingcap/parser v0.0.0-20181211024540-4e6d047fcaae/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA= github.com/pingcap/pd v2.1.0-rc.4+incompatible h1:/buwGk04aHO5odk/+O8ZOXGs4qkUjYTJ2UpCJXna8NE= github.com/pingcap/pd v2.1.0-rc.4+incompatible/go.mod h1:nD3+EoYes4+aNNODO99ES59V83MZSI+dFbhyr667a0E= github.com/pingcap/tidb-tools v0.0.0-20181112132202-4860a0d5de03 h1:xVuo5U+l6XAWHsb+xhkZ8zz3jerIwDfCHAO6kR2Kaog= @@ -146,7 +148,6 @@ github.com/struCoder/pidusage v0.1.2 h1:fFPTThlcWFQyizv3xKs5Lyq1lpG5lZ36arEGNhWz github.com/struCoder/pidusage v0.1.2/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2 h1:mbAskLJ0oJfDRtkanvQPiooDH8HvJ2FBh+iKT/OmiQQ= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2/go.mod h1:2PfKggNGDuadAa0LElHrByyrz4JPZ9fFx6Gs7nx7ZZU= -github.com/tiancaiamao/parser v0.0.0-20181210101737-48890850a7dd/go.mod h1:vqvanuOAAZ9O2rVI51fUrA9P3nV7HoILjLby0/OKOqA= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 h1:lYIiVDtZnyTWlNwiAxLj0bbpTcx1BWCFhXjfsvmPdNc= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/twinj/uuid v1.0.0 h1:fzz7COZnDrXGTAOHGuUGYd6sG+JMq+AoE7+Jlu0przk=