0

0

postgresql表级锁如何避免阻塞_postgresql并发访问机制

舞姬之光

舞姬之光

发布时间:2025-11-24 20:13:02

|

188人浏览过

|

来源于php中文网

原创

PostgreSQL表级锁阻塞可通过合理设计避免,关键在于理解锁类型与触发场景。ACCESS EXCLUSIVE锁由ALTER TABLE等DDL操作触发,易导致阻塞;应尽量避免长时间持有此类强锁。使用CREATE INDEX CONCURRENTLY可避免写阻塞,将DDL安排在低峰期或通过灰度发布减少影响。显式使用ROW EXCLUSIVE等弱锁、缩短事务生命周期、及时提交或回滚有助于降低锁争用。借助MVCC机制,读不阻塞写、写不阻塞读,提升并发性能。通过pg_locks和pg_stat_activity视图监控锁等待,定位阻塞源头。优化核心是减少强锁使用、善用并发操作、利用MVCC特性、保持事务短小精悍,从而显著提升系统并发处理能力。

postgresql表级锁如何避免阻塞_postgresql并发访问机制

PostgreSQL 的表级锁在并发访问中确实可能引发阻塞,但通过合理的设计和使用机制,可以有效避免或减少阻塞。关键在于理解锁的类型、触发场景,并结合事务控制与索引策略进行优化。

理解表级锁的常见类型与触发条件

PostgreSQL 中表级锁由 DDL 操作或显式锁定语句触发,不同操作持有不同强度的锁:

  • ACCESS SHARE:SELECT 使用,兼容性强,一般不阻塞其他查询
  • ROW EXCLUSIVE:INSERT、UPDATE、DELETE 持有,通常不会阻塞 SELECT
  • SHARE ROW EXCLUSIVE:CREATE INDEX CONCURRENTLY 使用,防止并发写入
  • ACCESS EXCLUSIVE:ALTER TABLE、DROP、VACUUM FULL 等,几乎阻塞所有其他操作

其中 ACCESS EXCLUSIVE 锁最容易造成阻塞,例如在一个大表上执行 ALTER TABLE 添加列,会独占该表,导致其他读写操作排队等待。

避免阻塞的关键策略

要减少表级锁带来的阻塞,核心是避免长时间持有强锁,尤其是 ACCESS EXCLUSIVE 类型。

  • 使用 CONCURRENTLY 方式创建或重建索引(CREATE INDEX CONCURRENTLY),虽然耗时更长且不允许在事务块中执行,但不会阻塞写操作
  • 将 DDL 操作安排在低峰期执行,或通过应用层灰度更新表结构
  • 避免在事务中长时间持有表锁,尽量缩短事务生命周期,及时提交或回滚
  • LOCK TABLE ... IN ROW EXCLUSIVE MODE 显式加弱锁,代替默认的强锁行为(如某些批量导入场景)

利用 MVCC 提升并发读写性能

PostgreSQL 基于 MVCC(多版本并发控制)机制,使得读不阻塞写、写也不阻塞读。这是其高并发能力的基础。

Autoppt
Autoppt

Autoppt:打造高效与精美PPT的AI工具

下载
  • 普通 SELECT 不加锁,直接读取事务可见的数据版本
  • UPDATE 和 DELETE 只锁定目标行,而非整个表(除非显式 LOCK TABLE)
  • 合理使用事务隔离级别(READ COMMITTED 是默认且推荐用于大多数场景)

只要不涉及 DDL 或显式表锁,多个事务可以同时对同一张表进行读写,而不会相互阻塞。

监控与诊断锁等待

当出现阻塞时,可通过系统视图快速定位问题:

SELECT blocked_locks.pid     AS blocked_pid,
         blocking_locks.pid    AS blocking_pid,
         blocked_activity.query AS blocked_query,
         blocking_activity.query AS blocking_query
  FROM pg_catalog.pg_locks blocked_locks
  JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
  JOIN pg_catalog.pg_locks blocking_locks 
    ON blocking_locks.locktype = blocked_locks.locktype
   AND blocking_locks.database IS NOT DISTINCT FROM blocked_locks.database
   AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
   AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
   AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
   AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
   AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
   AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
   AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
   AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
   AND blocking_locks.pid != blocked_locks.pid
  JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
  WHERE NOT blocked_locks.granted;

这个查询能列出当前被阻塞的进程及其阻塞源,便于快速干预。

基本上就这些。关键是少用强锁、善用并发操作、借助 MVCC 特性,并保持事务短小精悍。多数阻塞问题都源于不当的 DDL 操作或长事务,针对性优化即可显著提升并发能力。

相关专题

更多
数据库Delete用法
数据库Delete用法

数据库Delete用法:1、删除单条记录;2、删除多条记录;3、删除所有记录;4、删除特定条件的记录。更多关于数据库Delete的内容,大家可以访问下面的文章。

269

2023.11.13

drop和delete的区别
drop和delete的区别

drop和delete的区别:1、功能与用途;2、操作对象;3、可逆性;4、空间释放;5、执行速度与效率;6、与其他命令的交互;7、影响的持久性;8、语法和执行;9、触发器与约束;10、事务处理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

209

2023.12.29

postgresql常用命令
postgresql常用命令

postgresql常用命令psql、createdb、dropdb、createuser、dropuser、l、c、dt、d table_name、du、i file_name、e和q等。本专题为大家提供postgresql相关的文章、下载、课程内容,供大家免费下载体验。

158

2023.10.10

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

970

2023.11.02

postgresql常用命令有哪些
postgresql常用命令有哪些

postgresql常用命令psql、createdb、dropdb、createuser、dropuser、l、c、dt、d table_name、du、i file_name、e和q等。更详细的postgresql常用命令,大家可以访问下面的文章。

196

2023.11.16

postgresql常用命令介绍
postgresql常用命令介绍

postgresql常用命令有l、d、d5、di、ds、dv、df、dn、db、dg、dp、c、pset、show search_path、ALTER TABLE、INSERT INTO、UPDATE、DELETE FROM、SELECT等。想了解更多postgresql的相关内容,可以阅读本专题下面的文章。

268

2023.11.20

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

323

2023.10.09

vb连接access数据库的方法
vb连接access数据库的方法

vb连接access数据库方法:1、使用ADO连接,首先导入System.Data.OleDb模块,然后定义一个连接字符串,接着创建一个OleDbConnection对象并使用Open() 方法打开连接;2、使用DAO连接,首先导入 Microsoft.Jet.OLEDB模块,然后定义一个连接字符串,接着创建一个JetConnection对象并使用Open()方法打开连接即可。

397

2023.10.16

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

72

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
【李炎恢】ThinkPHP8.x 后端框架课程
【李炎恢】ThinkPHP8.x 后端框架课程

共50课时 | 4.5万人学习

Swoft2.x速学之http api篇课程
Swoft2.x速学之http api篇课程

共16课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号