region定义地理大区并决定容灾级别,zone是其内故障隔离单元;仅支持region survivability,需配locality与分区策略防跨域延迟。

REGION 和 ZONE 在 CockroachDB 里到底管什么
CockroachDB 的 REGION 和 ZONE 不是同级概念,也不是随便打标签的逻辑分组——它们对应真实物理部署约束:REGION 定义地理大区(如 us-east、eu-west),必须显式声明为 PRIMARY 或 SECONDARY;ZONE 是更细粒度的故障隔离单元(比如一个 AZ 内的多个机架或 Kubernetes node),靠 constraints 规则控制副本分布。
常见错误现象:ALTER DATABASE d1 SET REGION = 'us-east' 执行成功,但后续 INSERT 还是跨洲写入慢——因为没配 survival goal,也没把表绑定到 REGION 级别策略。
-
REGION必须在集群启动时或通过ALTER CLUSTER SET PRIMARY REGION初始化,之后才能用SET REGION绑定数据库 - 单
REGION模式下,ZONE约束只影响副本在该大区内的分散度;多REGION模式下,ZONE不能跨REGION生效 -
survival goal只有REGION级别可设(REGION survivability),ZONE级别没有“容灾目标”这回事——它只是副本放置的执行层
怎么选 survival goal:REGION survivability vs ZONE survivability
CockroachDB 实际只支持一种容灾目标:REGION survivability。所谓 ZONE survivability 是旧文档遗留说法,0.0 版本就已移除;当前所有 SURVIVE TWO REGIONS 或 SURVIVE THREE REGIONS 都作用于 REGION 维度。
使用场景很明确:你要扛住整个云厂商区域宕机(比如 AWS us-east-1 整个不可用),就必须用 REGION survivability;如果只防单个可用区断电,那靠 ZONE 约束 + 默认三副本就够了,不用动 survival goal。
- 设
SURVIVE TWO REGIONS后,系统会强制每个 Raft group 至少两个副本落在不同REGION,且自动拒绝在只剩一个REGION在线时接受写入 - 不设
survival goal时,即使你部署了三个REGION,副本也可能全挤在主REGION——因为默认策略是“就近写入优先” -
SHOW CLUSTER SETTING cluster.settings.survival_goal能查当前值,但改它需要ADMIN权限,且变更后需等待所有表完成 rebalance(可能耗时数分钟到小时)
多地域写入延迟高?先检查 partitioning 和 locality
开了多 REGION 却发现 INSERT 延迟翻倍,大概率是没做 LOCALITY 分区,或者误用了 GLOBAL 表。
典型错误:CREATE TABLE orders (...) LOCALITY REGIONAL BY TABLE IN PRIMARY REGION 写对了,但关联的 customers 表漏了分区,导致 JOIN 时跨 REGION 拉数据。
- 只有
REGIONAL BY TABLE或REGIONAL BY ROW表才受REGION约束;GLOBAL表副本永远全量同步到所有REGION,写放大严重 -
REGIONAL BY ROW需配合crdb_region列和INSERT ... SELECT显式指定归属,否则新行默认进PRIMARY REGION - 用
EXPLAIN (VERBOSE) INSERT ...看执行计划里有没有remote步骤,有就说明跨REGION通信已发生
region 级 failover 测试时最常踩的坑
模拟 REGION 故障不是简单 docker stop 几个节点就行——CockroachDB 的故障检测有超时机制,且依赖 heartbeats 和 raft leader lease,硬杀节点容易触发脑裂或长时间不可写。
正确做法是用 cockroach quit --decommission 模拟优雅下线,或直接关掉整个 REGION 的网络出口(如 iptables DROP 所有到该 REGION 的 26257 端口流量)。
- 测试前确认
cluster.settings.kv.raft_log.synchronize是true(默认),否则日志落盘不同步,failover 后可能丢事务 - 用
SELECT * FROM [SHOW RANGES WITH DETAILS]查关键表的副本分布,确保至少两个REGION都有VOTER(不是NON_VOTER) - failover 后立刻跑
SHOW STATUSES CLUSTER,重点看ranges_unavailable和ranges_underreplicated是否归零——不归零说明survival goal未满足,集群仍拒绝写入
真正麻烦的是跨 REGION 事务的语义边界:CockroachDB 不保证跨 REGION 的强一致性读,AS OF SYSTEM TIME 必须显式指定,否则可能读到旧版本。这点很容易被忽略,尤其在迁移老应用时。










