跳转到主要内容

pg_lease

SQL leases with TTL expiry and monotonically increasing fencing epochs

pg_lease : SQL leases with TTL expiry and monotonically increasing fencing epochs

Overview

ID Extension Package Version Category License Language
4145 pg_lease pg_lease 0.1.0 UTIL MIT SQL
Attribute Has Binary Has Library Need Load Has DDL Relocatable Trusted
----dt- No No No Yes no yes
Relationships
Schemas lease
See Also 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.

Packages

Type Repo Version PG Major Compatibility Package Pattern Dependencies
EXT PIGSTY 0.1.0 18 17 16 15 14 pg_lease -
RPM PIGSTY 0.1.0 18 17 16 15 14 pg_lease_$v -
Linux / PG PG18 PG17 PG16 PG15 PG14
el8.x86_64 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0
el8.aarch64 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0
el9.x86_64 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0
el9.aarch64 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0
el10.x86_64 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0
el10.aarch64 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0 PIGSTY 0.1.0
d12.x86_64 N/A N/A N/A N/A N/A
d12.aarch64 N/A N/A N/A N/A N/A
d13.x86_64 N/A N/A N/A N/A N/A
d13.aarch64 N/A N/A N/A N/A N/A
u22.x86_64 N/A N/A N/A N/A N/A
u22.aarch64 N/A N/A N/A N/A N/A
u24.x86_64 N/A N/A N/A N/A N/A
u24.aarch64 N/A N/A N/A N/A N/A
u26.x86_64 N/A N/A N/A N/A N/A
u26.aarch64 N/A N/A N/A N/A N/A
Package Version OS ORG SIZE File URL
pg_lease_18 0.1.0 el8.x86_64 pigsty 23.0 KiB pg_lease_18-0.1.0-1PGSTY.el8.noarch.rpm
pg_lease_18 0.1.0 el8.aarch64 pigsty 23.0 KiB pg_lease_18-0.1.0-1PGSTY.el8.noarch.rpm
pg_lease_18 0.1.0 el9.x86_64 pigsty 22.8 KiB pg_lease_18-0.1.0-1PGSTY.el9.noarch.rpm
pg_lease_18 0.1.0 el9.aarch64 pigsty 22.8 KiB pg_lease_18-0.1.0-1PGSTY.el9.noarch.rpm
pg_lease_18 0.1.0 el10.x86_64 pigsty 22.9 KiB pg_lease_18-0.1.0-1PGSTY.el10.noarch.rpm
pg_lease_18 0.1.0 el10.aarch64 pigsty 22.9 KiB pg_lease_18-0.1.0-1PGSTY.el10.noarch.rpm
Package Version OS ORG SIZE File URL
pg_lease_17 0.1.0 el8.x86_64 pigsty 23.0 KiB pg_lease_17-0.1.0-1PGSTY.el8.noarch.rpm
pg_lease_17 0.1.0 el8.aarch64 pigsty 23.0 KiB pg_lease_17-0.1.0-1PGSTY.el8.noarch.rpm
pg_lease_17 0.1.0 el9.x86_64 pigsty 22.8 KiB pg_lease_17-0.1.0-1PGSTY.el9.noarch.rpm
pg_lease_17 0.1.0 el9.aarch64 pigsty 22.8 KiB pg_lease_17-0.1.0-1PGSTY.el9.noarch.rpm
pg_lease_17 0.1.0 el10.x86_64 pigsty 22.9 KiB pg_lease_17-0.1.0-1PGSTY.el10.noarch.rpm
pg_lease_17 0.1.0 el10.aarch64 pigsty 22.9 KiB pg_lease_17-0.1.0-1PGSTY.el10.noarch.rpm
Package Version OS ORG SIZE File URL
pg_lease_16 0.1.0 el8.x86_64 pigsty 23.0 KiB pg_lease_16-0.1.0-1PGSTY.el8.noarch.rpm
pg_lease_16 0.1.0 el8.aarch64 pigsty 23.0 KiB pg_lease_16-0.1.0-1PGSTY.el8.noarch.rpm
pg_lease_16 0.1.0 el9.x86_64 pigsty 22.8 KiB pg_lease_16-0.1.0-1PGSTY.el9.noarch.rpm
pg_lease_16 0.1.0 el9.aarch64 pigsty 22.8 KiB pg_lease_16-0.1.0-1PGSTY.el9.noarch.rpm
pg_lease_16 0.1.0 el10.x86_64 pigsty 22.9 KiB pg_lease_16-0.1.0-1PGSTY.el10.noarch.rpm
pg_lease_16 0.1.0 el10.aarch64 pigsty 22.9 KiB pg_lease_16-0.1.0-1PGSTY.el10.noarch.rpm
Package Version OS ORG SIZE File URL
pg_lease_15 0.1.0 el8.x86_64 pigsty 23.0 KiB pg_lease_15-0.1.0-1PGSTY.el8.noarch.rpm
pg_lease_15 0.1.0 el8.aarch64 pigsty 23.0 KiB pg_lease_15-0.1.0-1PGSTY.el8.noarch.rpm
pg_lease_15 0.1.0 el9.x86_64 pigsty 22.8 KiB pg_lease_15-0.1.0-1PGSTY.el9.noarch.rpm
pg_lease_15 0.1.0 el9.aarch64 pigsty 22.8 KiB pg_lease_15-0.1.0-1PGSTY.el9.noarch.rpm
pg_lease_15 0.1.0 el10.x86_64 pigsty 22.9 KiB pg_lease_15-0.1.0-1PGSTY.el10.noarch.rpm
pg_lease_15 0.1.0 el10.aarch64 pigsty 22.9 KiB pg_lease_15-0.1.0-1PGSTY.el10.noarch.rpm
Package Version OS ORG SIZE File URL
pg_lease_14 0.1.0 el8.x86_64 pigsty 23.0 KiB pg_lease_14-0.1.0-1PGSTY.el8.noarch.rpm
pg_lease_14 0.1.0 el8.aarch64 pigsty 23.0 KiB pg_lease_14-0.1.0-1PGSTY.el8.noarch.rpm
pg_lease_14 0.1.0 el9.x86_64 pigsty 22.8 KiB pg_lease_14-0.1.0-1PGSTY.el9.noarch.rpm
pg_lease_14 0.1.0 el9.aarch64 pigsty 22.8 KiB pg_lease_14-0.1.0-1PGSTY.el9.noarch.rpm
pg_lease_14 0.1.0 el10.x86_64 pigsty 22.9 KiB pg_lease_14-0.1.0-1PGSTY.el10.noarch.rpm
pg_lease_14 0.1.0 el10.aarch64 pigsty 22.9 KiB pg_lease_14-0.1.0-1PGSTY.el10.noarch.rpm

Source

pig build pkg pg_lease;		# build rpm

Install

Make sure PGDG and PIGSTY repo available:

pig repo add pgsql -u   # add both repo and update cache

Install this extension with pig:

pig install pg_lease;		# install via package name, for the active PG version

pig install pg_lease -v 18;   # install for PG 18
pig install pg_lease -v 17;   # install for PG 17
pig install pg_lease -v 16;   # install for PG 16
pig install pg_lease -v 15;   # install for PG 15
pig install pg_lease -v 14;   # install for PG 14

Create this extension with:

CREATE EXTENSION pg_lease;

Usage

Sources:

pg_lease provides expiring ownership of named resources with increasing fencing epochs. It is a pure SQL/PL/pgSQL extension with lazy expiry, no background worker, and no preload requirement. Version 0.1.0 is marked testing on PGXN; upstream requires PostgreSQL 14 or later and documents its compatibility tests on PostgreSQL 14 and 15.

Core Workflow

The extension is trusted: a role with CREATE privilege on the database can install it. It creates the fixed lease schema and is not relocatable.

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');

The example uses the first epoch, 1. Applications must pass the epoch actually returned by acquisition to later renewal, release, and external resource guards. A successful release advances the epoch; re-acquisition must use the newly returned value.

Operations

Operation Behavior
lease.acquire(key, owner, ttl, wait) Acquires a free or expired key. The optional wait defaults to zero; a busy key returns a denial. Positive waits poll until acquisition or timeout.
lease.renew(key, owner, epoch, ttl) Extends an active lease without changing its epoch.
lease.release(key, owner, epoch) Releases an active lease and advances its epoch.
lease.inspect(key) Observes ownership, expiry, and the current fencing counter; an unknown key returns no rows.

Renewal and release return ok, not_owner, lapsed, or epoch_mismatch. Invalid inputs raise SQLSTATE 22023; an exhausted blocking wait raises 57014. Re-acquiring an unexpired lease with the same owner is idempotent and does not extend its expiry.

Transactions and Boundaries

Use READ COMMITTED for blocking acquisition. State changes follow the caller’s transaction and are undone by rollback. Expiry follows the database server’s clock; session termination does not release a lease immediately. The functions use SECURITY DEFINER with a fixed search path; direct public access to lease.leases is revoked.

Owner strings are application-supplied identifiers, not authenticated database identities. Applications must control access to the lease API and enforce fencing epochs at the resource being protected. The extension provides no safety guarantee across primary promotion or independent databases. Dropping the extension destroys lease state and resets the epoch history on reinstallation; version 0.1.0 does not register its lease table for extension configuration dumps.