diff --git a/ddl/db_partition_test.go b/ddl/db_partition_test.go index 52d04e67c1883..f9703d0d8aec1 100644 --- a/ddl/db_partition_test.go +++ b/ddl/db_partition_test.go @@ -1279,6 +1279,23 @@ func (s *testIntegrationSuite1) TestPartitionAddIndex(c *C) { hired date not null ) partition by hash( year(hired) ) partitions 4;`) testPartitionAddIndex(tk, c) + + // Test hash partition for pr 10475. + tk.MustExec("drop table if exists t1") + defer tk.MustExec("drop table if exists t1") + tk.MustExec("set @@session.tidb_enable_table_partition = '1';") + tk.MustExec("create table t1 (a int,b int, primary key(a)) partition by hash(a) partitions 5;") + tk.MustExec("insert into t1 values (0,0),(1,1),(2,2),(3,3);") + tk.MustExec("alter table t1 add index idx(a)") + tk.MustExec("admin check table t1;") + + // Test range partition for pr 10475. + tk.MustExec("drop table t1") + tk.MustExec("create table t1 (a int,b int, primary key(a)) partition by range (a) (partition p0 values less than (10), partition p1 values less than (20));") + tk.MustExec("insert into t1 values (0,0);") + tk.MustExec("alter table t1 add index idx(a)") + tk.MustExec("admin check table t1;") + } func testPartitionAddIndex(tk *testkit.TestKit, c *C) { diff --git a/ddl/index.go b/ddl/index.go index 9e43ce42a4c5c..a613d06026138 100644 --- a/ddl/index.go +++ b/ddl/index.go @@ -312,7 +312,16 @@ func (w *worker) onCreateIndex(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int return ver, errors.Trace(err) } - err = w.runReorgJob(t, reorgInfo, d.lease, func() error { + err = w.runReorgJob(t, reorgInfo, d.lease, func() (addIndexErr error) { + defer func() { + r := recover() + if r != nil { + buf := util.GetStack() + logutil.Logger(ddlLogCtx).Error("[ddl] add table index panic", zap.Any("panic", r), zap.String("stack", string(buf))) + metrics.PanicCounter.WithLabelValues(metrics.LabelDDL).Inc() + addIndexErr = errCancelledDDLJob.GenWithStack("add table `%v` index `%v` panic", tblInfo.Name, indexInfo.Name) + } + }() return w.addTableIndex(tbl, indexInfo, reorgInfo) }) if err != nil { @@ -1200,7 +1209,7 @@ func (w *worker) addTableIndex(t table.Table, idx *model.IndexInfo, reorgInfo *r for !finish { p := tbl.GetPartition(reorgInfo.PhysicalTableID) if p == nil { - return errors.Errorf("Can not find partition id %d for table %d", reorgInfo.PhysicalTableID, t.Meta().ID) + return errCancelledDDLJob.GenWithStack("Can not find partition id %d for table %d", reorgInfo.PhysicalTableID, t.Meta().ID) } err = w.addPhysicalTableIndex(p, idx, reorgInfo) if err != nil { diff --git a/meta/meta.go b/meta/meta.go index 8e47b1201766f..09cc9c3a89a92 100644 --- a/meta/meta.go +++ b/meta/meta.go @@ -733,9 +733,9 @@ func (m *Meta) GetDDLReorgHandle(job *model.Job) (startHandle, endHandle, physic err = errors.Trace(err) return } - // endHandle or physicalTableID may be 0, because older version TiDB (without table partition) doesn't store them. + // physicalTableID may be 0, because older version TiDB (without table partition) doesn't store them. // update them to table's in this case. - if endHandle == 0 || physicalTableID == 0 { + if physicalTableID == 0 { if job.ReorgMeta != nil { endHandle = job.ReorgMeta.EndHandle } else { diff --git a/table/tables/partition.go b/table/tables/partition.go index c48086914dd1c..a03764d30dd33 100644 --- a/table/tables/partition.go +++ b/table/tables/partition.go @@ -313,7 +313,13 @@ func (t *partitionedTable) locateHashPartition(ctx sessionctx.Context, pi *model // GetPartition returns a Table, which is actually a partition. func (t *partitionedTable) GetPartition(pid int64) table.PhysicalTable { - return t.partitions[pid] + // Attention, can't simply use `return t.partitions[pid]` here. + // Because A nil of type *partition is a kind of `table.PhysicalTable` + p, ok := t.partitions[pid] + if !ok { + return nil + } + return p } // GetPartitionByRow returns a Table, which is actually a Partition.