跳转到主要内容

pg_lease

提供 TTL 过期与单调递增隔离令牌的 SQL 租约

概览

扩展包名版本分类许可证语言
pg_lease0.1.0UTILMITSQL
ID扩展名BinLibLoadCreateTrustReloc模式
4145pg_lease否否否是是否lease
相关扩展pglock pg_retry pgmq

PGXN testing release. Requires PG14+; upstream tests PG14/15, local EL9 aarch64 regression and isolation tests pass PG14-18. No failover fencing guarantee; owner strings are application identities. PGXN-listed GitHub repository azghr/pg-primitive returned 404 on 2026-10-23; PGXN hosts the verified source.

版本

类型仓库版本PG 大版本包名依赖
EXTPIGSTY0.1.01817161514pg_lease-
RPMPIGSTY0.1.01817161514pg_lease_$v-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64
el8.aarch64
el9.x86_64
el9.aarch64
el10.x86_64
el10.aarch64
d12.x86_64N/AN/AN/AN/AN/A
d12.aarch64N/AN/AN/AN/AN/A
d13.x86_64N/AN/AN/AN/AN/A
d13.aarch64N/AN/AN/AN/AN/A
u22.x86_64N/AN/AN/AN/AN/A
u22.aarch64N/AN/AN/AN/AN/A
u24.x86_64N/AN/AN/AN/AN/A
u24.aarch64N/AN/AN/AN/AN/A
u26.x86_64N/AN/AN/AN/AN/A
u26.aarch64N/AN/AN/AN/AN/A

构建

您可以使用 pig build 命令构建 pg_lease 扩展的 RPM 包:

pig build pkg pg_lease         # 构建 RPM 包

安装

您可以直接安装 pg_lease 扩展包的预置二进制包,首先确保 PGDG 和 PIGSTY 仓库已经添加并启用:

pig repo add pgsql -u          # 添加仓库并更新缓存

使用 pig 或者是 apt/yum/dnf 安装扩展:

安装
pig install pg_lease;          # 当前活跃 PG 版本安装
pig
pig ext install -y pg_lease -v 18  # PG 18
pig ext install -y pg_lease -v 17  # PG 17
pig ext install -y pg_lease -v 16  # PG 16
pig ext install -y pg_lease -v 15  # PG 15
pig ext install -y pg_lease -v 14  # PG 14
dnf
dnf install -y pg_lease_18       # PG 18
dnf install -y pg_lease_17       # PG 17
dnf install -y pg_lease_16       # PG 16
dnf install -y pg_lease_15       # PG 15
dnf install -y pg_lease_14       # PG 14

创建扩展:

CREATE EXTENSION pg_lease;

用法

来源:

pg_lease 为具名资源提供可过期的所有权与递增的隔离令牌。它是纯 SQL/PL/pgSQL 扩展,采用惰性过期,无后台工作进程,也不需要预加载。PGXN 将 0.1.0 标为 testing;上游要求 PostgreSQL 14 或更高版本,文档记录了 PostgreSQL 14 和 15 的兼容性测试。

核心流程

扩展标为可信:拥有数据库内创建权限的角色可以安装。它创建固定的 lease 模式,不能迁移到其他模式。

CREATE EXTENSION pg_lease;

SELECT acquired, epoch, expires_at
FROM lease.acquire('job-42', 'worker-a', interval '30 seconds');

SELECT status, expires_at
FROM lease.renew('job-42', 'worker-a', 1, interval '30 seconds');

SELECT status FROM lease.release('job-42', 'worker-a', 1);
SELECT held, owner, epoch, expires_at FROM lease.inspect('job-42');

示例使用首次获取租约返回的令牌 1。应用必须把实际取得的令牌传给后续续租、释放操作以及外部资源的校验逻辑。成功释放会推进令牌,再次获取后必须使用新返回值。

操作接口

操作行为
lease.acquire(key, owner, ttl, wait)获取空闲或已过期的资源。等待时间默认零,资源被占用时返回失败;正值表示轮询直到成功或超时。
lease.renew(key, owner, epoch, ttl)延长有效租约,保持令牌不变。
lease.release(key, owner, epoch)释放有效租约并推进令牌。
lease.inspect(key)查询所有权、到期时间与当前令牌;未知资源不返回记录。

续租与释放返回 ok、not_owner、lapsed 或 epoch_mismatch。无效输入抛出 SQLSTATE 22023;阻塞等待超时抛出 57014。同一持有者再次获取尚未过期的租约是幂等操作,不延长到期时间。

事务与边界

阻塞获取应使用 READ COMMITTED。状态变更属于调用者事务,回滚会撤销变更。过期判断使用数据库服务器时钟;会话结束不会立即释放租约。函数采用固定搜索路径的 SECURITY DEFINER,并撤销公众直接访问 lease.leases 的权限。

持有者字符串由应用提供,不是经过认证的数据库身份。应用必须限制租约接口的访问,并在受保护资源处检查隔离令牌。扩展不保证主备切换或独立数据库之间的安全性。删除扩展会丢失租约状态,重新安装会重置令牌历史;0.1.0 没有为租约表注册扩展配置转储。

这个页面对您有帮助吗?