温馨提示×

centos postgresql并发控制方法

小樊
42
2026-01-02 11:11:37
栏目: 云计算

并发控制总体思路

  • MVCC(多版本并发控制) 为基础,读写互不阻塞,写不阻塞读、读不阻塞写在 READ COMMITTED/REPEATABLE READ/可序列化快照 SSI 下均成立。
  • 通过选择合适的事务隔离级别(PostgreSQL 实际实现为三种:READ COMMITTED、REPEATABLE READ、SERIALIZABLE;“READ UNCOMMITTED”与“READ COMMITTED”行为一致)来平衡一致性与并发度。
  • 在需要“当前读”或排他修改时,使用 显式锁定(如 SELECT FOR UPDATE/SHARE、ROW EXCLUSIVE、ACCESS EXCLUSIVE 等)。
  • 对跨事务、跨会话的资源竞争,使用 咨询锁(Advisory Locks) 实现应用级互斥。
  • 通过 保存点(SAVEPOINT) 做部分回滚,降低冲突成本。

事务隔离级别与现象

  • 标准现象与 PostgreSQL 实现要点如下:
隔离级别 脏读 不可重复读 幻读 序列化异常 PostgreSQL 说明
READ UNCOMMITTED 允许,但 PG 中行为与读已提交相同 可能 可能 可能 仅为兼容性保留
READ COMMITTED 不可能 可能 可能 可能 默认级别;每条语句取新快照
REPEATABLE READ 不可能 不可能 允许,但 PG 中通过 SSI 避免 可能 事务级快照,避免不可重复读
SERIALIZABLE 不可能 不可能 不可能 不可能 最严格;在快照基础上做可串行化冲突检测
  • 设置方式:
    • 会话级:BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; …
    • 会话默认:SET default_transaction_isolation = ‘serializable’;
    • 注意:SET TRANSACTION 必须在事务块中使用。

显式锁定与典型用法

  • 常用 SQL 与锁模式映射:
    • SELECT:表级 ACCESS SHARE(与 ACCESS EXCLUSIVE 冲突)。
    • SELECT FOR UPDATE/SHARE:表级 ROW SHARE(与 EXCLUSIVE/ACCESS EXCLUSIVE 冲突),行级获得排他/共享行锁。
    • INSERT/UPDATE/DELETE:表级 ROW EXCLUSIVE(与 SHARE/SHARE ROW EXCLUSIVE/EXCLUSIVE/ACCESS EXCLUSIVE 冲突),行级排他锁。
    • CREATE INDEX(非并发):表级 SHARECREATE INDEX CONCURRENTLYSHARE UPDATE EXCLUSIVE
    • VACUUM(非 FULL)ANALYZE、部分 ALTER TABLESHARE UPDATE EXCLUSIVE
    • DROP/TRUNCATE/REINDEX/CLUSTER/VACUUM FULLACCESS EXCLUSIVE(与所有模式冲突)。
  • 显式加锁示例:
    • LOCK TABLE t IN ACCESS EXCLUSIVE MODE NOWAIT;(不等待,冲突即报错)
  • 冲突与死锁:不同事务对同一对象持有冲突锁会互相等待;PostgreSQL 会检测并终止其中一个事务。避免死锁的常用做法是按固定顺序获取锁、尽量缩短事务、减少持有锁的范围。

监控与诊断

  • 查看当前锁与等待关系:
    • 查询视图 pg_locks,结合 pg_stat_activity 定位阻塞会话与锁模式;必要时对热点对象设置 lock_timeout 或改用 NOWAIT 快速失败。
  • 观察事务与隔离:
    • 使用 txid_current() 查看当前事务 ID;在排查可重复读/序列化问题时,结合 xmin/xmax 理解行版本可见性。
  • 典型诊断路径:
    • 发现长事务或锁等待 → 检查应用是否及时提交/回滚 → 核对是否缺少 FOR UPDATE/SHARE 或锁粒度过大 → 评估是否需要 SERIALIZABLE 或改为 READ COMMITTED 并重构逻辑。

CentOS 上的并发相关配置建议

  • 连接与内存(示例为单机估算,需结合实际负载压测微调):
    • 用连接池(如 PgBouncer)控制活跃连接,避免把 max_connections 设得过大;连接开销高,过多连接会加剧锁等待与上下文切换。
    • 常见起点:shared_buffers ≈ 内存的 25%(不超过约 40%);work_mem 按“每个排序/哈希操作”估算,避免过大导致内存争用;effective_cache_size 设为内存的 50%–75% 供成本估算使用;maintenance_work_mem 在大表创建索引/VACUUM 时适当增大。
  • 操作系统资源限制(/etc/security/limits.conf):
    • 提升数据库专用用户(如 postgres)的 nprocnofile,避免“Too many connections/open files”。
  • I/O 平滑:
    • 调整 vm.dirty_background_ratiovm.dirty_background_bytes,降低大内存机器一次性刷脏带来的 I/O 毛刺。
  • 示例(仅示意,需按硬件与应用调优):
    • shared_buffers = 4GB;work_mem = 64MB;effective_cache_size = 12GB;maintenance_work_mem = 1GB;max_connections = 300(配合连接池使用)。

0