diff --git a/docs/tidb_http_api.md b/docs/tidb_http_api.md index 084d6ecd05323..f5659927c308f 100644 --- a/docs/tidb_http_api.md +++ b/docs/tidb_http_api.md @@ -52,6 +52,12 @@ curl http://{TiDBIP}:10080/schema?table_id={tableID} ``` +1. Get database information, table information and tidb info schema version by tableID. + + ```shell + curl http://{TiDBIP}:10080/db-table/{tableID} + ``` + 1. Get disk-usage info about db.table ```shell diff --git a/infoschema/infoschema.go b/infoschema/infoschema.go index 79da4b273b2b0..d8bdf96b10682 100644 --- a/infoschema/infoschema.go +++ b/infoschema/infoschema.go @@ -70,6 +70,7 @@ type InfoSchema interface { TableByName(schema, table model.CIStr) (table.Table, error) TableExists(schema, table model.CIStr) bool SchemaByID(id int64) (*model.DBInfo, bool) + SchemaByTable(tableInfo *model.TableInfo) (*model.DBInfo, bool) TableByID(id int64) (table.Table, bool) AllocByID(id int64) (autoid.Allocator, bool) AllSchemaNames() []string @@ -194,6 +195,20 @@ func (is *infoSchema) SchemaByID(id int64) (val *model.DBInfo, ok bool) { return nil, false } +func (is *infoSchema) SchemaByTable(tableInfo *model.TableInfo) (val *model.DBInfo, ok bool) { + if tableInfo == nil { + return nil, false + } + for _, v := range is.schemaMap { + if tbl, ok := v.tables[tableInfo.Name.L]; ok { + if tbl.Meta().ID == tableInfo.ID { + return v.dbInfo, true + } + } + } + return nil, false +} + func (is *infoSchema) TableByID(id int64) (val table.Table, ok bool) { slice := is.sortedTablesBuckets[tableBucketIdx(id)] idx := slice.searchTable(id) diff --git a/server/http_handler.go b/server/http_handler.go index beb14014d4a75..19ddcb6b70616 100644 --- a/server/http_handler.go +++ b/server/http_handler.go @@ -61,6 +61,7 @@ const ( pRegionID = "regionID" pStartTS = "startTS" pTableName = "table" + pTableID = "tableID" pColumnID = "colID" pColumnTp = "colTp" pColumnFlag = "colFlag" @@ -317,6 +318,10 @@ type schemaHandler struct { *tikvHandlerTool } +type dbTableHandler struct { + *tikvHandlerTool +} + // regionHandler is the common field for http handler. It contains // some common functions for all handlers. type regionHandler struct { @@ -1362,3 +1367,45 @@ func (h allServerInfoHandler) ServeHTTP(w http.ResponseWriter, req *http.Request } writeData(w, clusterInfo) } + +// dbTableInfo is used to report the database, table information and the current schema version. +type dbTableInfo struct { + DBInfo *model.DBInfo `json:"db_info"` + TableInfo *model.TableInfo `json:"table_info"` + SchemaVersion int64 `json:"schema_version"` +} + +//ServeHTTP handles request of database information and table information by tableID. +func (h dbTableHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { + params := mux.Vars(req) + tableID := params[pTableID] + tblID, err := strconv.Atoi(tableID) + if err != nil { + writeError(w, errors.Errorf("Wrong tableID: %v", tableID)) + return + } + + schema, err := h.schema() + if err != nil { + writeError(w, err) + return + } + + dbTblInfo := dbTableInfo{ + SchemaVersion: schema.SchemaMetaVersion(), + } + tbl, ok := schema.TableByID(int64(tblID)) + if !ok { + writeError(w, infoschema.ErrTableNotExists.GenWithStack("Table which ID = %s does not exist.", tableID)) + return + } + dbTblInfo.TableInfo = tbl.Meta() + dbInfo, ok := schema.SchemaByTable(dbTblInfo.TableInfo) + if !ok { + log.Warnf("can not find the database of table id: %v, table name: %v", dbTblInfo.TableInfo.ID, dbTblInfo.TableInfo.Name) + writeData(w, dbTblInfo) + return + } + dbTblInfo.DBInfo = dbInfo + writeData(w, dbTblInfo) +} diff --git a/server/http_handler_test.go b/server/http_handler_test.go index a43a3b5ddad7a..c7ca8d4fe9848 100644 --- a/server/http_handler_test.go +++ b/server/http_handler_test.go @@ -570,6 +570,18 @@ func (ts *HTTPHandlerTestSuite) TestGetSchema(c *C) { _, err = http.Get(fmt.Sprintf("http://127.0.0.1:10090/schema/tidb/abc")) c.Assert(err, IsNil) + + resp, err = http.Get(fmt.Sprintf("http://127.0.0.1:10090/db-table/5")) + c.Assert(err, IsNil) + var dbtbl *dbTableInfo + decoder = json.NewDecoder(resp.Body) + err = decoder.Decode(&dbtbl) + c.Assert(err, IsNil) + c.Assert(dbtbl.TableInfo.Name.L, Equals, "user") + c.Assert(dbtbl.DBInfo.Name.L, Equals, "mysql") + se, err := session.CreateSession(ts.store.(kv.Storage)) + c.Assert(err, IsNil) + c.Assert(dbtbl.SchemaVersion, Equals, domain.GetDomain(se.(sessionctx.Context)).InfoSchema().SchemaMetaVersion()) } func (ts *HTTPHandlerTestSuite) TestAllHistory(c *C) { diff --git a/server/http_status.go b/server/http_status.go index 9026f36d7af7d..72fadb57f737d 100644 --- a/server/http_status.go +++ b/server/http_status.go @@ -60,6 +60,9 @@ func (s *Server) startHTTPServer() { // HTTP path for get server info. router.Handle("/info", serverInfoHandler{tikvHandlerTool}).Name("Info") router.Handle("/info/all", allServerInfoHandler{tikvHandlerTool}).Name("InfoALL") + // HTTP path for get db and table info that is related to the tableID. + router.Handle("/db-table/{tableID}", dbTableHandler{tikvHandlerTool}) + if s.cfg.Store == "tikv" { // HTTP path for tikv. router.Handle("/tables/{db}/{table}/regions", tableHandler{tikvHandlerTool, opTableRegions})