parallel-workload 是 Materialize 的并行压力测试框架,通过多线程并发执行随机 SQL 动作来发现 panic 和意外查询错误,不校验结果正确性,也不用于性能测试(性能见 mz-benchmark)。
适用场景:并发操作下的 panic、本应成功或优雅失败的查询报出意外错误、特定 DDL/DML 组合引发的崩溃或连接中断。
工作原理:编排器启动 N 个 worker 线程,每个线程按配置的 Complexity 分配动作列表(read、fetch、write、dml_nontrans、ddl),用加权随机选择循环执行直到运行时间结束。动作抛出 QueryError 时,若匹配 errors_to_ignore(exe) 则记录并忽略,否则测试失败。所有线程共享 Database 对象,以线程安全锁跟踪已创建的表、视图、集群等。
新增动作:在 action.py 中继承 Action 并实现 run(),返回 False 表示跳过(前置条件不满足),成功执行后返回 True;必要时重写 errors_to_ignore() 扩展可忽略错误;最后在对应 ActionList 中注册类与权重。列表选择:read_action_list(SELECT、SUBSCRIBE、COPY TO)、fetch_action_list(DECLARE CURSOR/FETCH)、write_action_list(INSERT、COPY FROM)、dml_nontrans_action_list(DELETE、UPDATE、INSERT RETURNING)、ddl_action_list(CREATE/DROP/ALTER/RENAME)。
常见模式:在 exe.db.lock 下短暂选取对象,再用对象级锁操作;遵守 database.py 中的上限(如 MAX_TABLES=5、MAX_VIEWS=15);创建对象后追加到对应列表,删除后移除;使用 self.rng 而非 random.choice 以保证 --seed 可复现。
运行命令:bin/mzcompose --find parallel-workload run default,可加 --complexity、--scenario、--runtime、--seed。complexity 可选 read、dml、ddl、ddl-only、random;scenario 可选 regression、cancel、kill、rename、backup-restore、0dt-deploy、random。
设计规则:尽量减少锁持有时间;前置条件不满足时返回 False 而非抛异常;处理 rng.choice 的 IndexError;跟踪状态变化。