-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Adding code to properly split_clone a v3 table. #1634
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
Changes from all commits
d6b64cd
9f39741
c2462e9
e0bda92
8a78ec9
6576771
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ import ( | |
| tabletmanagerdatapb "github.com/youtube/vitess/go/vt/proto/tabletmanagerdata" | ||
| topodatapb "github.com/youtube/vitess/go/vt/proto/topodata" | ||
| "github.com/youtube/vitess/go/vt/topo" | ||
| "github.com/youtube/vitess/go/vt/vtgate/vindexes" | ||
| ) | ||
|
|
||
| // This file defines the interface and implementations of sharding key resolvers. | ||
|
|
@@ -47,15 +48,10 @@ func newV2Resolver(keyspaceInfo *topo.KeyspaceInfo, td *tabletmanagerdatapb.Tabl | |
| if td.Type != tmutils.TableBaseTable { | ||
| return nil, fmt.Errorf("a keyspaceID resolver can only be created for a base table, got %v", td.Type) | ||
| } | ||
|
|
||
| // Find the sharding key column index. | ||
| columnIndex := -1 | ||
| for i, name := range td.Columns { | ||
| if name == keyspaceInfo.ShardingColumnName { | ||
| columnIndex = i | ||
| break | ||
| } | ||
| } | ||
| if columnIndex == -1 { | ||
| columnIndex, ok := tmutils.TableDefinitionGetColumn(td, keyspaceInfo.ShardingColumnName) | ||
| if !ok { | ||
| return nil, fmt.Errorf("table %v doesn't have a column named '%v'", td.Name, keyspaceInfo.ShardingColumnName) | ||
| } | ||
|
|
||
|
|
@@ -79,4 +75,97 @@ func (r *v2Resolver) keyspaceID(row []sqltypes.Value) ([]byte, error) { | |
| } | ||
| } | ||
|
|
||
| // TODO(sougou): implement a V3 keyspaceIDResolver, which takes advantage of a table's primary ColVindex. | ||
| // v3Resolver is the keyspace id resolver that is used by VTGate V3 deployments. | ||
| // In V3, we use the VSchema to find a Unique VIndex of cost 0 or 1 for each | ||
| // table. | ||
| type v3Resolver struct { | ||
| shardingColumnIndex int | ||
| vindex vindexes.Unique | ||
| } | ||
|
|
||
| // newV3ResolverFromTableDefinition returns a keyspaceIDResolver for a v3 table. | ||
| func newV3ResolverFromTableDefinition(keyspaceSchema *vindexes.KeyspaceSchema, td *tabletmanagerdatapb.TableDefinition) (keyspaceIDResolver, error) { | ||
| if td.Type != tmutils.TableBaseTable { | ||
| return nil, fmt.Errorf("a keyspaceID resolver can only be created for a base table, got %v", td.Type) | ||
| } | ||
| tableSchema, ok := keyspaceSchema.Tables[td.Name] | ||
| if !ok { | ||
| return nil, fmt.Errorf("no vschema definition for table %v", td.Name) | ||
| } | ||
| // the primary vindex is most likely the sharding key, and has to | ||
| // be unique. | ||
| if len(tableSchema.ColVindexes) == 0 { | ||
| return nil, fmt.Errorf("no vindex definition for table %v", td.Name) | ||
| } | ||
| colVindex := tableSchema.ColVindexes[0] | ||
| if colVindex.Vindex.Cost() > 1 { | ||
| return nil, fmt.Errorf("primary vindex cost is too high for table %v", td.Name) | ||
| } | ||
| unique, ok := colVindex.Vindex.(vindexes.Unique) | ||
| if !ok { | ||
| return nil, fmt.Errorf("primary vindex is not unique for table %v", td.Name) | ||
| } | ||
|
|
||
| // Find the sharding key column index. | ||
| columnIndex, ok := tmutils.TableDefinitionGetColumn(td, colVindex.Col) | ||
| if !ok { | ||
| return nil, fmt.Errorf("table %v has a Vindex on unknown column %v", td.Name, colVindex.Col) | ||
| } | ||
|
|
||
| return &v3Resolver{ | ||
| shardingColumnIndex: columnIndex, | ||
| vindex: unique, | ||
| }, nil | ||
| } | ||
|
|
||
| // newV3ResolverFromColumnList returns a keyspaceIDResolver for a v3 table. | ||
| func newV3ResolverFromColumnList(keyspaceSchema *vindexes.KeyspaceSchema, name string, columns []string) (keyspaceIDResolver, error) { | ||
| tableSchema, ok := keyspaceSchema.Tables[name] | ||
| if !ok { | ||
| return nil, fmt.Errorf("no vschema definition for table %v", name) | ||
| } | ||
| // the primary vindex is most likely the sharding key, and has to | ||
| // be unique. | ||
| if len(tableSchema.ColVindexes) == 0 { | ||
| return nil, fmt.Errorf("no vindex definition for table %v", name) | ||
| } | ||
| colVindex := tableSchema.ColVindexes[0] | ||
| if colVindex.Vindex.Cost() > 1 { | ||
| return nil, fmt.Errorf("primary vindex cost is too high for table %v", name) | ||
| } | ||
| unique, ok := colVindex.Vindex.(vindexes.Unique) | ||
| if !ok { | ||
| return nil, fmt.Errorf("primary vindex is not unique for table %v", name) | ||
| } | ||
|
|
||
| // Find the sharding key column index. | ||
| columnIndex := -1 | ||
| for i, n := range columns { | ||
| if n == colVindex.Col { | ||
| columnIndex = i | ||
| break | ||
| } | ||
| } | ||
| if columnIndex == -1 { | ||
| return nil, fmt.Errorf("table %v has a Vindex on unknown column %v", name, colVindex.Col) | ||
| } | ||
|
|
||
| return &v3Resolver{ | ||
| shardingColumnIndex: columnIndex, | ||
| vindex: unique, | ||
| }, nil | ||
| } | ||
|
|
||
| // keyspaceID implements the keyspaceIDResolver interface. | ||
| func (r *v3Resolver) keyspaceID(row []sqltypes.Value) ([]byte, error) { | ||
| v := row[r.shardingColumnIndex] | ||
| ids := []interface{}{v} | ||
| ksids, err := r.vindex.Map(nil, ids) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There may be some future use cases where someone may use a lookup based sharding key. If so, we may have to supply a VCursor that's capable of fetching data from db. Not an immediate requirement.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then performance would be really bad, having to do a lookup for each row. We would probably not implement it this way... |
||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| if len(ksids) != 1 { | ||
| return nil, fmt.Errorf("maping row to keyspace id returned an invalid array of keyspace ids: %v", ksids) | ||
| } | ||
| return ksids[0], nil | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: use vindexes.IsUnique instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh. Nvm. Looks like you need the Unique interface var also.