diff --git a/docs/tidb_http_api.md b/docs/tidb_http_api.md index ca05f16ff2581..fb15087cd4789 100644 --- a/docs/tidb_http_api.md +++ b/docs/tidb_http_api.md @@ -261,16 +261,18 @@ timezone.* 1. Scatter regions of the specified table, add a `scatter-range` scheduler for the PD and the range is same as the table range. ```shell - curl -X POST http://{TiDBIP}:10080/tables/{db}/{table}/scatter + curl http://{TiDBIP}:10080/tables/{db}/{table}/scatter ``` + *Hint: On a partitioned table, use the `table(partition)` pattern as the table name, `test(p1)` for example.* **Note**: The `scatter-range` scheduler may conflict with the global scheduler, do not use it for long periods on the larger table. 1. Stop scatter the regions, disable the `scatter-range` scheduler for the specified table. ```shell - curl -X POST http://{TiDBIP}:10080/tables/{db}/{table}/stop-scatter + curl http://{TiDBIP}:10080/tables/{db}/{table}/stop-scatter ``` + *Hint: On a partitioned table, use the `table(partition)` pattern as the table name, `test(p1)` for example.* 1. Get TiDB server settings diff --git a/server/http_handler.go b/server/http_handler.go index 9bd661f3d78fe..106878aec05e9 100644 --- a/server/http_handler.go +++ b/server/http_handler.go @@ -309,9 +309,13 @@ func (t *tikvHandlerTool) getTable(dbName, tableName string) (table.PhysicalTabl if err != nil { return nil, errors.Trace(err) } + return t.getPartition(tableVal, partitionName) +} + +func (t *tikvHandlerTool) getPartition(tableVal table.Table, partitionName string) (table.PhysicalTable, error) { if pt, ok := tableVal.(table.PartitionedTable); ok { if partitionName == "" { - return nil, errors.New("work on partitioned table, please specify the table name like this: table(partition)") + return tableVal.(table.PhysicalTable), errors.New("work on partitioned table, please specify the table name like this: table(partition)") } tblInfo := pt.Meta() pid, err := tables.FindPartitionByName(tblInfo, partitionName) @@ -321,7 +325,7 @@ func (t *tikvHandlerTool) getTable(dbName, tableName string) (table.PhysicalTabl return pt.GetPartition(pid), nil } if partitionName != "" { - return nil, fmt.Errorf("%s is not a partitionted table", tableName) + return nil, fmt.Errorf("%s is not a partitionted table", tableVal.Meta().Name) } return tableVal.(table.PhysicalTable), nil } @@ -939,22 +943,33 @@ func (h tableHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { writeError(w, err) return } - // get table's schema. + + tableName, partitionName := extractTableAndPartitionName(tableName) tableVal, err := schema.TableByName(model.NewCIStr(dbName), model.NewCIStr(tableName)) if err != nil { writeError(w, err) return } - switch h.op { case opTableRegions: h.handleRegionRequest(schema, tableVal, w, req) case opTableDiskUsage: h.handleDiskUsageRequest(tableVal, w) case opTableScatter: - h.handleScatterTableRequest(schema, tableVal, w, req) + // supports partition table, only get one physical table, prevent too many scatter schedulers. + ptbl, err := h.getPartition(tableVal, partitionName) + if err != nil { + writeError(w, err) + return + } + h.handleScatterTableRequest(schema, ptbl, w, req) case opStopTableScatter: - h.handleStopScatterTableRequest(schema, tableVal, w, req) + ptbl, err := h.getPartition(tableVal, partitionName) + if err != nil { + writeError(w, err) + return + } + h.handleStopScatterTableRequest(schema, ptbl, w, req) default: writeError(w, errors.New("method not found")) } @@ -1113,13 +1128,13 @@ func (h tableHandler) deleteScatterSchedule(name string) error { return nil } -func (h tableHandler) handleScatterTableRequest(schema infoschema.InfoSchema, tbl table.Table, w http.ResponseWriter, req *http.Request) { +func (h tableHandler) handleScatterTableRequest(schema infoschema.InfoSchema, tbl table.PhysicalTable, w http.ResponseWriter, req *http.Request) { // for record - tableID := tbl.Meta().ID + tableID := tbl.GetPhysicalID() startKey, endKey := tablecodec.GetTableHandleKeyRange(tableID) startKey = codec.EncodeBytes([]byte{}, startKey) endKey = codec.EncodeBytes([]byte{}, endKey) - tableName := tbl.Meta().Name.String() + tableName := fmt.Sprintf("%s-%d", tbl.Meta().Name.String(), tableID) err := h.addScatterSchedule(startKey, endKey, tableName) if err != nil { writeError(w, errors.Annotate(err, "scatter record error")) @@ -1142,9 +1157,9 @@ func (h tableHandler) handleScatterTableRequest(schema infoschema.InfoSchema, tb writeData(w, "success!") } -func (h tableHandler) handleStopScatterTableRequest(schema infoschema.InfoSchema, tbl table.Table, w http.ResponseWriter, req *http.Request) { +func (h tableHandler) handleStopScatterTableRequest(schema infoschema.InfoSchema, tbl table.PhysicalTable, w http.ResponseWriter, req *http.Request) { // for record - tableName := tbl.Meta().Name.String() + tableName := fmt.Sprintf("%s-%d", tbl.Meta().Name.String(), tbl.GetPhysicalID()) err := h.deleteScatterSchedule(tableName) if err != nil { writeError(w, errors.Annotate(err, "stop scatter record error"))