You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中获取LWLock的正确方式及两种方法的区别与适用场景

PostgreSQL 11.4中两种LWLock获取方式的区别与适用场景

第一种方式:命名Tranche预分配批量锁

通过RequestNamedLWLockTranche和GetNamedLWLockTranche组合实现:

extern void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks);
extern LWLockPadded *GetNamedLWLockTranche(const char *tranche_name);

核心流程

  1. 注册锁组:调用RequestNamedLWLockTranche在数据库启动阶段注册一个命名锁组(tranche),指定该组内锁的总数,系统会自动在MainLWLockArray中预分配对应数量的LWLockPadded结构。
  2. 获取锁组:通过GetNamedLWLockTranche传入锁组名称,直接拿到整个锁组的数组,后续通过数组下标即可访问具体锁实例。

特点

  • 固定数量:锁的总数在初始化阶段确定,运行时无法动态调整。
  • 内存自动管理:锁的内存由PostgreSQL统一分配、维护,无需手动处理内存分配逻辑。
  • 可读性高:通过名称直接关联锁组,代码逻辑直观易懂。

适用场景

  • 适用于生命周期贯穿数据库进程、数量固定的系统级锁,比如WAL写入锁、缓冲池页面锁这类内置子系统的锁。
  • 适合在数据库启动时就能明确锁数量的场景,避免运行时动态分配的额外开销。

第二种方式:动态自定义锁

通过LWLockNewTrancheId、LWLockRegisterTranche和LWLockInitialize组合实现:

extern int  LWLockNewTrancheId(void);
extern void LWLockRegisterTranche(int tranche_id, const char *tranche_name);
extern void LWLockInitialize(LWLock *lock, int tranche_id);

核心流程

  1. 获取唯一ID:调用LWLockNewTrancheId拿到一个全局唯一的tranche ID,用于标识一组锁。
  2. 注册锁组名称:通过LWLockRegisterTranche将tranche ID与名称绑定,方便监控、调试时识别锁组。
  3. 初始化锁实例:调用LWLockInitialize初始化具体的LWLock实例(该实例可放置在MainLWLockArray或自定义共享内存区域),并关联到之前获取的tranche ID。

特点

  • 动态灵活:锁的数量、位置可在运行时动态决定,无需提前预分配。
  • 手动内存管理:需要自行负责LWLock结构的内存分配(比如从共享内存中预留空间)。
  • 嵌入式适配:可以将锁直接嵌入到自定义共享数据结构中,而非统一放在预分配的锁组数组里。

适用场景

  • 适用于锁数量不确定、需要运行时动态创建的场景,比如用户扩展模块中的自定义共享资源锁。
  • 适合将锁与特定数据结构绑定的场景,比如共享哈希表的每个桶自带的锁,需随数据结构动态初始化。

核心对比

维度第一种方式(命名预分配)第二种方式(动态自定义)
锁数量灵活性固定,初始化阶段确定动态,运行时可调整
内存管理系统自动分配维护手动分配和初始化
使用复杂度低,直接通过名称获取锁组高,需自行管理锁实例
典型适用场景系统级固定数量锁自定义动态/嵌入式锁

内容的提问来源于stack exchange,提问作者Sri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 21:04:55