PostgreSQL DBA(177) - Serializability Isolation(Index vs NonIndex)
发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,PostgreSQL 9.1或以上版本,提供了真正意义的Serializability Isolation,本节主要介绍了Serializability Isolation下有索引与没有索引的区别。N
千家信息网最后更新 2026年10月31日PostgreSQL DBA(177) - Serializability Isolation(Index vs NonIndex)
PostgreSQL 9.1或以上版本,提供了真正意义的Serializability Isolation,本节主要介绍了Serializability Isolation下有索引与没有索引的区别。
NonIndex
在没有索引的情况下,对relation进行w(写)操作,PG会对整个relation加SIReadLock,因为加锁粒度是Relation级别,因此如果其他session也对这个表进行w操作,那么两个session之间会出现rw依赖循环,其中一个session会被终止。
-- Session 1[local:/data/run/pg12]:5120 pg12@testdb=# show default_transaction_isolation; default_transaction_isolation------------------------------- serializable(1 row)[local:/data/run/pg12]:5120 pg12@testdb=# begin;BEGIN[local:/data/run/pg12]:5120 pg12@testdb=#* select * from tbl where id = 1; id | c1----+---------------------- 1 | x(1 row)查询锁信息,在relation上加SIReadLock
[local:/data/run/pg12]:5120 pg12@testdb=# select pid,locktype,relation::regclass,page,tuple,transactionid,mode,granted,fastpath from pg_locks where pid = 22365; pid | locktype | relation | page | tuple | transactionid | mode | granted | fastpath-------+------------+----------+------+-------+---------------+-----------------+---------+---------- 22365 | relation | tbl | | | | AccessShareLock | t | t 22365 | virtualxid | | | | | ExclusiveLock | t | t 22365 | relation | tbl | | | | SIReadLock | t | f(3 rows)-- Session 1[local:/data/run/pg12]:5120 pg12@testdb=#* update tbl set c1='x' where id = 1;UPDATE 1[local:/data/run/pg12]:5120 pg12@testdb=#* commit;COMMIT[local:/data/run/pg12]:5120 pg12@testdb=#-- Session 2[local:/data/run/pg12]:5120 pg12@testdb=# begin;BEGIN[local:/data/run/pg12]:5120 pg12@testdb=#* update tbl set c1 = 'x' where id = 2;UPDATE 1[local:/data/run/pg12]:5120 pg12@testdb=#* commit;ERROR: could not serialize access due to read/write dependencies among transactionsDETAIL: Reason code: Canceled on identification as a pivot, during commit attempt.HINT: The transaction might succeed if retried.[local:/data/run/pg12]:5120 pg12@testdb=#操作过程如下:
| 时间点 | T1 | T2 |
|---|---|---|
| t1 | begin; | |
| t2 | begin; | |
| t3 | update tbl set c1 = 'x' where id = 1; | |
| t4 | begin; | |
| t5 | update tbl set c1 = 'x' where id = 2; | |
| t6 | commit; | |
| t7 | commit; |
Index
在存在索引的情况下,对relation进行w(写)操作,PG会对page加SIReadLock,只会影响到tuple所在的page。
[local:/data/run/pg12]:5120 pg12@testdb=# create table tbl_index(id int ,c1 varchar);CREATE TABLE [local:/data/run/pg12]:5120 pg12@testdb=# insert into tbl_index select x,x from generate_series(1,100000) x;INSERT 0 100000[local:/data/run/pg12]:5120 pg12@testdb=# create index idx_tbl_index_id on tbl_index(id);CREATE INDEX[local:/data/run/pg12]:5120 pg12@testdb=# select id,ctid from tbl_index where id in(1,20000); id | ctid-------+---------- 1 | (0,1) 20000 | (107,24)(2 rows)id为1和20000的tuple位于不同的page中,下面对这两条记录进行更新
-- session 1[local:/data/run/pg12]:5120 pg12@testdb=# begin;BEGIN[local:/data/run/pg12]:5120 pg12@testdb=#* update tbl_index set c1='x' where id = 1;UPDATE 1[local:/data/run/pg12]:5120 pg12@testdb=#*-- session 2[local:/data/run/pg12]:5120 pg12@testdb=# begin;BEGIN[local:/data/run/pg12]:5120 pg12@testdb=#* update tbl_index set c1='x' where id = 20000;UPDATE 1[local:/data/run/pg12]:5120 pg12@testdb=#* select pg_backend_pid(); pg_backend_pid---------------- 22425(1 row)[local:/data/run/pg12]:5120 pg12@testdb=#*锁信息,注意:锁定的page是index的page而不是heap page
[local:/data/run/pg12]:5120 pg12@testdb=# select pid,locktype,relation::regclass,page,tuple,transactionid,mode,granted,fastpath from pg_locks where pid = 22365; pid | locktype | relation | page | tuple | transactionid | mode | granted | fastpath-------+---------------+------------------+------+-------+---------------+------------------+---------+---------- 22365 | relation | idx_tbl_index_id | | | | RowExclusiveLock | t | t 22365 | relation | tbl_index | | | | RowExclusiveLock | t | t 22365 | virtualxid | | | | | ExclusiveLock | t | t 22365 | transactionid | | | | 423265 | ExclusiveLock | t | f 22365 | page | idx_tbl_index_id | 1 | | | SIReadLock | t | f(5 rows)[local:/data/run/pg12]:5120 pg12@testdb=# select pid,locktype,relation::regclass,page,tuple,transactionid,mode,granted,fastpath from pg_locks where pid = 22425; pid | locktype | relation | page | tuple | transactionid | mode | granted | fastpath-------+---------------+------------------+------+-------+---------------+------------------+---------+---------- 22425 | relation | idx_tbl_index_id | | | | RowExclusiveLock | t | t 22425 | relation | tbl_index | | | | RowExclusiveLock | t | t 22425 | virtualxid | | | | | ExclusiveLock | t | t 22425 | transactionid | | | | 423266 | ExclusiveLock | t | f 22425 | page | idx_tbl_index_id | 56 | | | SIReadLock | t | f(5 rows)提交事务,两个session均成功
-- session 1[local:/data/run/pg12]:5120 pg12@testdb=#* commit;COMMIT-- session 2[local:/data/run/pg12]:5120 pg12@testdb=#* commit;COMMIT
索引
两个
信息
情况
不同
成功
下有
之间
事务
意义
所在
时间
版本
粒度
级别
过程
影响
循环
更新
查询
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
上海卓越科技互联网
中国互联网科技工作委员会毛军
北京互联网科技有限公司
中国 科技 互联网
上海挚品互联网科技
奇酷互联网科技公司
互联网科技革命
深圳齐家互联网科技
银优互联网科技有限公司
互联网前沿科技
联恩商钥互联网科技有限公司
济南华为互联网科技产业总部基地
成都铂石互联网科技做什么的
武汉健翔互联网络科技有限公司
语蝶互联网科技有限公司
宜昌元轩互联网科技有限公司
辽宁互联网新科技
互联网行业科技股
富国互联网科技002692
容联科技互联网电商
科技与互联网
互联网金融公司科技
致聘互联网科技
互联网科技网站
长亮科技互联网金融
居家互联网科技有限公司
厦门千工互联网科技有限公司
雨阳互联网卡科技有限公司
深圳无忧互联网科技
互联网科技博主张洲