jepsen测试-分布式系统正确性

场景

  1. 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;
  1. 单行递增计数器(counter)
    一个简单的共享状态,是否可以正确地处理并发写+读,验证线性一致性
UPDATE T SET count = count + ? WHERE id = 0;
  1. set
    insert成功或被第一次select查到过后,以后的select必须都包含它
    并发写入+并发读取,已查到过的数据是否又消失。检查是否脏读、幻读,非单调读取等
INSERT INTO T (id, val, grp) VALUES (?, ?, ?);
SELECT val FROM T where id = 0;
  1. long-fork (长叉)
    并发写+并发读,例如:
    如果我并发写 A 和 B,但某些并发读却只看到 A 或只看到 B,而没有任何一个读能看到完整的 [A,B],那就违反串行化了 —— 这就是“长叉”。

  2. 在线变更(并发)
    并发执行插入、读取的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 
  1. 单值验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 = ?;
  1. 追加文本
    多个表 + 并发单行追加日志(CONCAT)+ 读取。检查是否满足串行化隔离级别。
    使用多表是为了提升到系统压力,而不是单单行锁的竞争,暴露更多系统极限边界行为。
UPDATE T SET txt = CONCAT(txt, ',', ?) WHERE id = ?;
select ...

附加
制造故障环境:时钟偏差、重启/挂起服务进程、网络分区(iptable)

posted @ 2025-04-16 16:01  代码世界faq  阅读(27)  评论(0)    收藏  举报