Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

http: get region's info #2774

Merged
merged 51 commits into from
Mar 17, 2017
Merged

http: get region's info #2774

merged 51 commits into from
Mar 17, 2017

Conversation

AndreMouche
Copy link
Contributor

@AndreMouche AndreMouche commented Mar 3, 2017

Hi,all,
This PR is used to list regions for table && get region by ID through http request.

@coocood @disksing @siddontang PTAL

Details:

List table's Regions

Requests

Syntax

GET /tables/${db}/${table}/regions HTTP/1.1
Host: status.tidb.domain
Date: date

Request Parameters

Name Description Required
db database's name YES
table table's name YES

Response

Response Elements

Parent Name Type Description
name string table's name
id int table's ID
record_regions []object regions which table's record key convered
indices []object list of table's indices
indices[] name string index's name
indices[] id int index's ID
indices[] regions []object regions which current index covered

Response Sample

HTTP/1.1 200 OK
Content-Length:244
Content-Type:application/json
Date:Tue, 07 Mar 2017 07:50:31 GMT
{
    "name": "mcc_access",
    "id": 19,
    "record_regions": [
        {
            "region_id": 7,
            "leader": {
                "id": 10,
                "store_id": 1
            },
            "peers": [
                {
                    "id": 8,
                    "store_id": 2
                },
                {
                    "id": 10,
                    "store_id": 1
                }
            ],
            "region_epoch": {
                "conf_ver": 2,
                "version": 2
            }
        }
    ],
    "indices": [
        {
            "name": "access_key",
            "id": 1,
            "regions": [
                {
                    "region_id": 7,
                    "leader": {
                        "id": 10,
                        "store_id": 1
                    },
                    "peers": [
                        {
                            "id": 8,
                            "store_id": 2
                        },
                        {
                            "id": 10,
                            "store_id": 1
                        }
                    ],
                    "region_epoch": {
                        "conf_ver": 2,
                        "version": 2
                    }
                }
            ]
        }
    ]
}

GET Region By ID

Requests

Syntax

GET /regions/${regionID} HTTP/1.1
Host: status.tidb.domain
Date: date

Request Parameters

Name Description Required
regionID ID of region to get YES

Response

Response Elements

Parent Name Type Description
region_id int region's id
start_key string region's start_key
-- end_key string region's end_key
frames []object list of frames current region covered
frames[] table_name string table's name
frames[] table_id int table's ID
frames[] is_record bool whether current frame is a record
frames[] index_name string index's name
frames[] index_id int index's ID

Response Sample

HTTP/1.1 200 OK
Content-Length:244
Content-Type:application/json
Date:Tue, 07 Mar 2017 07:50:31 GMT
{
  region_id: 7,
  start_key: "bURETEpvYkj/af9zdG9yeQD/AAD8AAAAAAD/AABoAAAAAAD/AAAG/wAAAAD/AAAAAPcAAAD8",
  end_key: "",
  frames: [
      {
      db_name: "INFORMATION_SCHEMA",
      table_name: "STATISTICS",
      table_id: 9223372036854776000,
      is_record: true
      },
      {
        db_name: "test",
        table_name: "mcc_access",
        table_id: 19,
        is_record: false,
        index_name: "access_key",
        index_id: 1
      }
  ]
}

@AndreMouche AndreMouche changed the title Shirly/regions Http: list regions for table Mar 4, 2017
server/server.go Outdated
@@ -250,6 +251,18 @@ func (s *Server) startStatusHTTP() {
})
// HTTP path for prometheus.
http.Handle("/metrics", prometheus.Handler())
// default path for regions status info
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use /regions

@AndreMouche AndreMouche changed the title Http: list regions for table http: list regions for table Mar 4, 2017
@shenli
Copy link
Member

shenli commented Mar 5, 2017

@AndreMouche CI failed.

Copy link
Member

@coocood coocood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need test for region handler.

"github.com/pingcap/tidb/store/tikv"
"github.com/pingcap/tidb/tablecodec"
"github.com/pingcap/tidb/util/codec"
gContext "golang.org/x/net/context"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

goctx "context"

gContext "golang.org/x/net/context"
"math"
"net/http"
"time"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Take a look at how other files in TiDB organize import paths.

server/server.go Outdated
@@ -39,6 +39,7 @@ import (
// For pprof
_ "net/http/pprof"

"github.com/gorilla/mux"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds a dependency, we should add this repo in vendor.

}
}

func (req *RegionsHTTPRequest) showResponse(data interface{}, err error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not name it writeResponse?

@@ -163,6 +182,23 @@ func (c *RegionCache) GroupKeysByRegion(bo *Backoffer, keys [][]byte) (map[Regio
return groups, first, nil
}

// ListRegionIDsInKeyRange lists ids of regions in [start_key,end_key].
func (c *RegionCache) ListRegionIDsInKeyRange(bo *Backoffer, startKey, endKey []byte) (regions []uint64, err error) {
regions = make([]uint64, 0, 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why make a slice with zero capacity?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable name should be regionIDs.


pdCli, err := pd.NewClient(etcdAddrs)
if err != nil {
if strings.Contains(err.Error(), "i/o timeout") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be removed, it is useful only for server initialization.

@@ -24,6 +24,7 @@ import (
"github.com/pingcap/kvproto/pkg/kvrpcpb"
"github.com/pingcap/kvproto/pkg/metapb"
"github.com/pingcap/pd/pd-client"
"strings"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import path ordering.

TableName: tableName,
TableID: tableID,
RowRegions: nil,
Indices: make([]IndexRegions, len(table.Indices()), len(table.Indices())),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The third parameter in make is not needed.

@AndreMouche AndreMouche changed the title http: list regions for table [WIP]http: list regions for table Mar 6, 2017
server/server.go Outdated
request.Handle()
router.Handle("/metrics", prometheus.Handler())

router.HandleFunc("/tables/{db}/{table}/regions", func(w http.ResponseWriter, req *http.Request) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer /regions/db/table

@AndreMouche AndreMouche changed the title [WIP]http: list regions for table http: regions Mar 7, 2017
@AndreMouche
Copy link
Contributor Author

PTAL

}

// HTTPListTableRegionsHandler is the handler for list table's regions.
type HTTPListTableRegionsHandler struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TableRegionsHandler

// HTTPRegionHandler is the common field for http region handler. It contains
// some common functions which would be used in HTTPListTableRegionsHandler and
// HTTPGetRegionByIDHandler.
type HTTPRegionHandler struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use RegionHandler to handle /regions/{regionID} and TableRegionsHandler to handle /tables/db/table

@AndreMouche
Copy link
Contributor Author

@coocood PTAL

// get from table's ID directly. Above all, here do dot process like
// `for id in [frameRange.firstTableID,frameRange.endTableID]`
// on [frameRange.firstTableID,frameRange.endTableID] is small enough.
for _, db := range tool.infoSchema.AllSchemas() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we will add all databases and tables? this may cost lots of memory.

Copy link
Contributor Author

@AndreMouche AndreMouche Mar 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@siddontang Since we need a database's name for each frame, and a table's database name can not get from table's ID directly. So here do dot process like

for id in [frameRange.firstTableID,frameRange.endTableID]
      ...

on [frameRange.firstTableID,frameRange.endTableID] is small enough.

Above all, it seems iterate all databases and tables cannot be avoided. While with infoSchema already have all databases with tables in memory, there is no additional memory cost.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a function like GetTableByID in infoshema? @coocood

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@siddontang We have GetTableByID, but the table doesn't know about the DB name.

@coocood
Copy link
Member

coocood commented Mar 16, 2017

LGTM

@siddontang
Copy link
Member

PTAL @disksing

@@ -163,6 +192,22 @@ func (c *RegionCache) GroupKeysByRegion(bo *Backoffer, keys [][]byte) (map[Regio
return groups, first, nil
}

// ListRegionIDsInKeyRange lists ids of regions in [start_key,end_key].
func (c *RegionCache) ListRegionIDsInKeyRange(bo *Backoffer, startKey, endKey []byte) (regionIDs []uint64, err error) {
for err == nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

err will never be nil.

// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !race
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why disable race detector?

}

// addIndex insert a index into RegionDetail.
func (rt *RegionDetail) addIndex(dbName, tName string, tID int64, indexName string, indexID int64) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the methods to the place next to the structure.

// TableRegionsHandler is the handler for list table's regions.
type TableRegionsHandler struct {
RegionHandler
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need TableRegionsHandler. How about define 2 methods on RegionHandler and use HandleFunc to register them to router?

}
}

func (rh TableRegionsHandler) getRegionsMetaWithRegionIds(rIDs []uint64) ([]RegionMeta, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Id should be ID. Also I think just getRegionMetas(regionIDs []uint64) is ok.

// prepare checks and prepares for region request. It returns
// regionHandlerTool on success while return an err on any
// error happens.
func (rh *RegionHandler) prepare() (tool *regionHandlerTool, err error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems regionHandlerTool is redundant. I think it would be more clear to return infoSchema, regionCache, error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may cause too many params for the func? And make regionHandlerTool as they are common tools used in region handler. @disksing

if rh.pdClient == nil {
err = fmt.Errorf("Invalid PdClient: nil")
return
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose it won't be nil.

store/tikv/kv.go Outdated
func ParsePath(path string) (etcdAddrs []string, disableGC bool, err error) {
return parsePath(path)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just rename 'parsePath' to 'ParsePath'?

Copy link
Contributor Author

@AndreMouche AndreMouche Mar 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because too many function are using parsePath. I also think ParsePath is not a good name used as public function and would like to change someday. @disksing

@@ -22,6 +22,7 @@ import (
"github.com/pingcap/tidb/util/codec"
"github.com/pingcap/tidb/util/testleak"
"github.com/pingcap/tidb/util/types"
"math"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The imports are not in good order. We should separate std packages from 3rd-party packages.


regionIDs, err := s.cache.ListRegionIDsInKeyRange(s.bo, []byte("a"), []byte("z"))
c.Assert(err, IsNil)
c.Assert(len(regionIDs), Equals, 2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why only check length? I suppose you can check the IDs are correct.
c.Assert(regionIDs, DeeqEquals, []uint64{s.region1, region2})

resp, err := http.Get("http://127.0.0.1:10090/tables/information_schema/SCHEMATA/regions")
c.Assert(err, IsNil)

//c.Assert(resp.StatusCode,Equals,http.StatusOK)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why comment it?

err = decoder.Decode(&data)
c.Assert(err, IsNil)

c.Assert(len(data.RecordRegions) > 0, IsTrue)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c.Assert(len(data.RecordRegions), Greater, 0)

@AndreMouche
Copy link
Contributor Author

@BusyJay PTAL

@disksing
Copy link
Contributor

LGTM, PTAL @siddontang

@disksing disksing merged commit e791b9a into master Mar 17, 2017
@disksing disksing deleted the shirly/regions branch March 17, 2017 04:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants