基本扫描和聚合扫描不需要 SIREAD 锁,因此 SERIALIZABLE 无法避免虚拟写入偏差
作者: mdashti创建于 2026年9月17日更新于 2026年9月17日
- 设置表:
CREATE EXTENSION IF NOT EXISTS pg_search;
CREATE TABLE ssi_doctors (id int PRIMARY KEY, name text, status text);
INSERT INTO ssi_doctors
SELECT g, 'doc' || g, CASE WHEN g <= 2 THEN 'oncall' ELSE 'offcall' END FROM generate_series(1, 10) g;
CREATE INDEX ssi_doctors_idx ON ssi_doctors USING bm25 (id, name, status)
WITH (text_fields = '{"status": {"tokenizer": {"type": "keyword"}, "fast": true}, "name": {"fast": true}}');- 在两个会话中按以下顺序运行此命令:
-- session 1
BEGIN ISOLATION LEVEL SERIALIZABLE;
SET paradedb.enable_aggregate_custom_scan = on;
SELECT count(*) FROM ssi_doctors WHERE status @@@ 'oncall'; -- 2
-- session 2
BEGIN ISOLATION LEVEL SERIALIZABLE;
SET paradedb.enable_aggregate_custom_scan = on;
SELECT count(*) FROM ssi_doctors WHERE status @@@ 'oncall'; -- 2
-- session 1
INSERT INTO ssi_doctors VALUES (101, 'new1', 'oncall');
-- session 2
INSERT INTO ssi_doctors VALUES (102, 'new2', 'oncall');
-- session 1
COMMIT;
-- session 2
COMMIT;会话 2 的 COMMIT 成功,现在有 4 行为 "oncall"。基础扫描执行相同的操作,使用 SET paradedb.enable_aggregate_custom_scan = off 和 SELECT id, name FROM ssi_doctors WHERE status @@@ 'oncall'。在两个会话中都设置为 SET paradedb.enable_custom_scan = off,计划为 "使用 ssi_doctors_idx 的索引扫描",会话 2 的 COMMIT 失败:
ERROR: could not serialize access due to read/write dependencies among transactions在包含 #6378、#6380、#6381、#6382 和 #6383 的 main 的 PG 15 调试版中,这些修复并不涉及锁定。
内容来源: paradedb/paradedb