← 中文资源

简体中文版本

跨并行数据库分片测试提速

给每个测试分片独立 schema 或数据库,并发执行分片,根除串行运行器掩盖的跨测试干扰。

阅读英文原文

目标

共享数据库的测试没法并行:干扰之所以看不见,只是串行执行把它藏了起来。每个分片一个 schema 给每条并行车道一个私有世界,套件拆成并发安全的块。这份纪律的回报超出提速——任何“靠执行顺序才通过”的测试都变成看得见、修得掉的失败。

步骤要点

  1. setup 阶段按 SHARD_INDEX 建 test_shard_N 私有 schema 并跑迁移,DATABASE_URL 指向该 schema。
  2. CI matrix 起 4 个并行 job,各跑 1/4 用例,墙钟时间相应下降。
  3. 隔离验证:同一测试在两个分片同时跑都通过,状态不串。
  4. afterAll 里 DROP SCHEMA CASCADE,失败重跑也从干净状态开始。
  5. 用历史时长记录做负载均衡,四个分片几乎同时完成,没有掉队者定义总时长。

排错提示

分片后仍互相干扰,说明还有共享外部状态(全局 Redis、固定文件路径),把这些也按分片索引隔离;迁移跑四遍太慢就先建模板 schema 再克隆,比逐 job 重放迁移便宜得多;某个分片总在最后失败,因为它吃了最重的用例,按实测时长重新分桶让各分片接近均值。

适用边界

并行成倍放大数据库负载,CI 库要能吃下分片数倍的用量;每分片 schema 也成倍增加连接数,要按分片收紧连接池。

代码示例

// One private world per shard
const schema = `test_shard_${process.env.SHARD_INDEX}`;
await db.exec(`CREATE SCHEMA IF NOT EXISTS ${schema}`);
await runMigrations(schema);
process.env.DATABASE_URL = urlWithSchema(schema);