func (s *testSuite) TestAdmin(c *C) { defer testleak.AfterTest(c)() tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists admin_test") tk.MustExec("create table admin_test (c1 int, c2 int, c3 int default 1, index (c1))") tk.MustExec("insert admin_test (c1) values (1),(2),(NULL)") r, err := tk.Exec("admin show ddl") c.Assert(err, IsNil) row, err := r.Next() c.Assert(err, IsNil) c.Assert(row.Data, HasLen, 6) txn, err := s.store.Begin() c.Assert(err, IsNil) ddlInfo, err := inspectkv.GetDDLInfo(txn) c.Assert(err, IsNil) c.Assert(row.Data[0].GetInt64(), Equals, ddlInfo.SchemaVer) rowOwnerInfos := strings.Split(row.Data[1].GetString(), ",") ownerInfos := strings.Split(ddlInfo.Owner.String(), ",") c.Assert(rowOwnerInfos[0], Equals, ownerInfos[0]) c.Assert(row.Data[2].GetString(), Equals, "") bgInfo, err := inspectkv.GetBgDDLInfo(txn) c.Assert(err, IsNil) c.Assert(row.Data[3].GetInt64(), Equals, bgInfo.SchemaVer) rowOwnerInfos = strings.Split(row.Data[4].GetString(), ",") ownerInfos = strings.Split(bgInfo.Owner.String(), ",") c.Assert(rowOwnerInfos[0], Equals, ownerInfos[0]) c.Assert(row.Data[5].GetString(), Equals, "") row, err = r.Next() c.Assert(err, IsNil) c.Assert(row, IsNil) // check table test tk.MustExec("create table admin_test1 (c1 int, c2 int default 1, index (c1))") tk.MustExec("insert admin_test1 (c1) values (21),(22)") r, err = tk.Exec("admin check table admin_test, admin_test1") c.Assert(err, IsNil) c.Assert(r, IsNil) // error table name r, err = tk.Exec("admin check table admin_test_error") c.Assert(err, NotNil) // different index values ctx := tk.Se.(context.Context) domain := sessionctx.GetDomain(ctx) is := domain.InfoSchema() c.Assert(is, NotNil) tb, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("admin_test")) c.Assert(err, IsNil) c.Assert(tb.Indices(), HasLen, 1) _, err = tb.Indices()[0].Create(txn, types.MakeDatums(int64(10)), 1) c.Assert(err, IsNil) err = txn.Commit() c.Assert(err, IsNil) r, err = tk.Exec("admin check table admin_test") c.Assert(err, NotNil) }
// Next implements Executor Next interface. func (e *ShowDDLExec) Next() (*Row, error) { if e.done { return nil, nil } txn, err := e.ctx.GetTxn(false) if err != nil { return nil, errors.Trace(err) } ddlInfo, err := inspectkv.GetDDLInfo(txn) if err != nil { return nil, errors.Trace(err) } bgInfo, err := inspectkv.GetBgDDLInfo(txn) if err != nil { return nil, errors.Trace(err) } var ddlOwner, ddlJob string if ddlInfo.Owner != nil { ddlOwner = ddlInfo.Owner.String() } if ddlInfo.Job != nil { ddlJob = ddlInfo.Job.String() } var bgOwner, bgJob string if bgInfo.Owner != nil { bgOwner = bgInfo.Owner.String() } if bgInfo.Job != nil { bgJob = bgInfo.Job.String() } row := &Row{} row.Data = types.MakeDatums( ddlInfo.SchemaVer, ddlOwner, ddlJob, bgInfo.SchemaVer, bgOwner, bgJob, ) for i, f := range e.fields { f.Expr.SetValue(row.Data[i].GetValue()) } e.done = true return row, nil }
// Stat returns the DDL statistics. func (d *ddl) Stats() (map[string]interface{}, error) { m := make(map[string]interface{}) m[serverID] = d.uuid var ddlInfo, bgInfo *inspectkv.DDLInfo err := kv.RunInNewTxn(d.store, false, func(txn kv.Transaction) error { var err1 error ddlInfo, err1 = inspectkv.GetDDLInfo(txn) if err1 != nil { return errors.Trace(err1) } bgInfo, err1 = inspectkv.GetBgDDLInfo(txn) return errors.Trace(err1) }) if err != nil { return nil, errors.Trace(err) } m[ddlSchemaVersion] = ddlInfo.SchemaVer if ddlInfo.Owner != nil { m[ddlOwnerID] = ddlInfo.Owner.OwnerID // LastUpdateTS uses nanosecond. m[ddlOwnerLastUpdateTS] = ddlInfo.Owner.LastUpdateTS / 1e9 } if ddlInfo.Job != nil { m[ddlJobID] = ddlInfo.Job.ID m[ddlJobAction] = ddlInfo.Job.Type.String() m[ddlJobLastUpdateTS] = ddlInfo.Job.LastUpdateTS / 1e9 m[ddlJobState] = ddlInfo.Job.State.String() m[ddlJobError] = ddlInfo.Job.Error m[ddlJobSchemaState] = ddlInfo.Job.SchemaState.String() m[ddlJobSchemaID] = ddlInfo.Job.SchemaID m[ddlJobTableID] = ddlInfo.Job.TableID m[ddlJobSnapshotVer] = ddlInfo.Job.SnapshotVer m[ddlJobReorgHandle] = ddlInfo.ReorgHandle m[ddlJobArgs] = ddlInfo.Job.Args } // background DDL info m[bgSchemaVersion] = bgInfo.SchemaVer if bgInfo.Owner != nil { m[bgOwnerID] = bgInfo.Owner.OwnerID // LastUpdateTS uses nanosecond. m[bgOwnerLastUpdateTS] = bgInfo.Owner.LastUpdateTS / 1e9 } if bgInfo.Job != nil { m[bgJobID] = bgInfo.Job.ID m[bgJobAction] = bgInfo.Job.Type.String() m[bgJobLastUpdateTS] = bgInfo.Job.LastUpdateTS / 1e9 m[bgJobState] = bgInfo.Job.State.String() m[bgJobError] = bgInfo.Job.Error m[bgJobSchemaState] = bgInfo.Job.SchemaState.String() m[bgJobSchemaID] = bgInfo.Job.SchemaID m[bgJobTableID] = bgInfo.Job.TableID m[bgJobSnapshotVer] = bgInfo.Job.SnapshotVer m[bgJobReorgHandle] = bgInfo.ReorgHandle m[bgJobArgs] = bgInfo.Job.Args } return m, nil }