jepsen测试-分布式系统正确性
场景
- bank-contention(银行竞争——并发)
通过并发的场景,开展并发银行业务,通过账户加总验证结果是否正确。
转账
事务模拟(A减少,B增加)启动多个并发客户端,中途kill节点,或断网,重启服务等,查看账户是否一致。使用余额加总检查事务一致性。
BEGIN TXN;
UPDATE T SET balance = balance + x WHERE id = ?;
UPDATE T SET balance = balance - x WHERE id = ?;
COMMIT;
开户+入账
事务:新用户开户+从已有用户转账,原子性+持久性
BEGIN TXN;
INSERT INTO T (id, balance) VALUES (?, ?);
UPDATE T SET balance = balance - x WHERE id = ?;
COMMIT;
销户
事务:查看余额+转账其他人+删除账户 ,原子性+一致性
BEGIN TXN;
SELECT balance FROM T WHERE id = ?;
UPDATE T SET balance = balance + x WHERE id = ?;
DELETE FROM T WHERE id = ?;
COMMIT;
- 单行递增计数器(counter)
一个简单的共享状态,是否可以正确地处理并发写+读,验证线性一致性
UPDATE T SET count = count + ? WHERE id = 0;
- set
insert成功或被第一次select查到过后,以后的select必须都包含它
并发写入+并发读取,已查到过的数据是否又消失。检查是否脏读、幻读,非单调读取等
INSERT INTO T (id, val, grp) VALUES (?, ?, ?);
SELECT val FROM T where id = 0;
-
long-fork (长叉)
并发写+并发读,例如:
如果我并发写 A 和 B,但某些并发读却只看到 A 或只看到 B,而没有任何一个读能看到完整的 [A,B],那就违反串行化了 —— 这就是“长叉”。 -
在线变更(并发)
并发执行插入、读取的DML操作时,进行字段添加、更改,索引添加等DDL操作。
潜在问题:1. 可能锁表、死锁、数据丢失。2. DML 没有带这个字段,数据库有没有按预期填充默认值? 3. SELECT * 的时候有没有报错?结果格式是否统一?
insert ...
select...
alter table T add V Default 0.
alter table T drop COLUMN V.
create table T
DROP TABLE
- 单值验ACID
同一个 key 上多个线程并发执行 CAS、UPDATE、SELECT,一个行多线程,对多行进行key检验。
select val from T where ID =1;
update T set val where ID = 1;
update T set val = ? where ID = 1 and val = ?;
7.多值验ACID(两个主键,复合键)
INSERT INTO T VALUES (k1, k2, val) ON CONFLICT DO UPDATE SET val = ?;
SELECT k1, value FROM T where k2 = ? and k1 = ?;
- 追加文本
多个表 + 并发单行追加日志(CONCAT)+ 读取。检查是否满足串行化隔离级别。
使用多表是为了提升到系统压力,而不是单单行锁的竞争,暴露更多系统极限边界行为。
UPDATE T SET txt = CONCAT(txt, ',', ?) WHERE id = ?;
select ...
附加
制造故障环境:时钟偏差、重启/挂起服务进程、网络分区(iptable)

浙公网安备 33010602011771号