vitess的vschema定义keyspace类型与分片表规则:normal keyspace禁用分片表,sharded keyspace需指定sharding_column或algorithm;分片表必须设type=”sharded”并绑定已定义且列类型兼容的primary_vindex,禁止外键和跨keyspace lookup。

Vitess 的 VSchema 是逻辑分片模型的核心配置,它不直接定义物理分片(shard),而是描述 keyspace 的逻辑结构、表的分片属性及关联关系。keyspace 与 sharded table 的定义需严格遵循规范,否则会导致路由错误、查询失败或数据不一致。
keyspace 定义:必须显式声明类型与分片策略
每个 keyspace 必须在 VSchema 中以对象形式声明,并明确指定 type 字段:
-
"type": "normal":表示非分片 keyspace,所有表默认为 unsharded,即使后续定义了 sharded table 也会被忽略(Vitess 不允许在 normal keyspace 内定义 sharded 表) -
"type": "sharded":表示该 keyspace 启用水平分片,所有 sharded table 必须归属于此类型 keyspace;此时还需提供sharding_column(推荐)或sharding_algorithm(v14+ 支持 hash/vrange) - keyspace 名称需与
vttablet启动参数中的--keyspace严格一致,且不能含大写字母或特殊字符(仅支持小写字母、数字、下划线)
sharded table 定义:必须绑定 keyspace + 指定主分片键
分片表需在对应 sharded 类型 keyspace 的 tables 字段下声明,并满足以下硬性要求:
- 必须设置
"type": "sharded"(不可省略,即使父 keyspace 是 sharded) - 必须指定
"primary_vindex",其值为已定义的 vindex 名(如"hash"或自定义 vindex),且该 vindex 的columns必须与表中真实存在的列名完全匹配(大小写敏感) - 若使用复合主分片键(如
["user_id", "tenant_id"]),对应 vindex 必须是consistent_lookup或支持多列的自定义 vindex;标准hashvindex 仅支持单列 - 不允许在 sharded table 中定义外键(foreign key),Vitess 不支持跨分片外键约束
vindex 关联:vindex 定义必须前置且列类型兼容
所有 primary_vindex 引用的 vindex 必须在 VSchema 的顶层 vindexes 字段中预先定义:
- vindex 名称(如
"hash")需与primary_vindex字段值完全一致 - vindex 的
params.column_type(如"INT64")必须与目标表中对应列的实际 mysql 类型兼容(例如:MySQLBIGINT→INT64,VARCHAR(64)→VARBINARY或VARCHAR) - 若使用
lookup类型 vindex,必须确保 lookup 表已存在、结构正确,且在同一个 keyspace 内(不能跨 keyspace)
常见错误与规避方式
以下配置会触发 ApplyVSchema 失败或运行时路由异常:
- 在
normalkeyspace 下定义"type": "sharded"表 → 报错:sharded table not allowed in normal keyspace -
primary_vindex名拼写错误或未在vindexes中定义 → 报错:vindex not found - 分片列在表中不存在,或类型不匹配(如 vindex 设为
INT64,但 MySQL 列是VARCHAR)→ 查询可能路由到错误分片,或 INSERT 失败 - 同一 keyspace 内多个 sharded 表使用不同 vindex,但未对齐分片逻辑(如一个用
hash(user_id),另一个用hash(order_id))→ 关联查询(JOIN)无法下推,强制走 scatter-gather,性能极差