Subject: Re: [PATCH] Add pg_current_vxact_id() function to expose virtual transaction IDs

From: Henson Choi <[email-masked]>
Date: Fri, 9 Jan 2026 12:15:21 +0900

2026년 1월 9일 (금) AM 9:25, Michael Paquier <[email-masked]>님이 작성:

> On Mon, Dec 08, 2025 at 12:09:58PM +0000, Pavlo Golub wrote:
> > Virtual transaction IDs are fundamental to PostgreSQL's transaction
> > tracking,
> > appearing in pg_locks.virtualtransaction, log output via %v placeholder,
> and
> > internal transaction management. However, there's currently no direct SQL
> > function to retrieve the current VXID, forcing applications to query
> > pg_locks
> > or parse log files to obtain this information.
>
> This is replacing one SQL in a given session by another, as a session
> currently running a transaction can query itself pg_locks and match an
> entry with its own pg_backend_pid().  Hence I don't see the need for
> this function, except simplicity in retrieving a session's state with
> less characters typed at the end?
>

I see this as a tradeoff between minor convenience and negligible
addition cost.

The community should decide whether this tradeoff is worth it.

> Thoughts and opinions from others are welcome.  I'm always OK to be
> outvoted.
> --
> Michael
>

Best regards,
Henson Choi

---

From: Pavlo Golub <[email-masked]>
Date: Thu, 5 Feb 2026 14:13:36 +0100

Hi hackers,

Thank you a lot for the feedback on this patch. And sorry for the
delay with the answer.

I'd like to address Michael's concern that pg_current_vxact_id() is
merely a convenience feature when pg_locks can provide the same
information. I believe there are stronger technical and design reasons
for this function beyond reducing typing.

pg_current_vxact_id() complexity is O(1) with direct memory reads and
no locks, while querying pg_locks requires O(n) where n is the number
of locks, among these operations are constructing tuples then
filtering. For me it's obviously more work. The proposed function is
essentially free compared to pg_locks querying.

As for the usage pattern this is how Postgres codebase is built from
the very beginning. PostgreSQL has many established patterns where
both SQL commands and functions exist for the same purpose, providing
programmatic access even when an alternative exists, e.g. NOTIFY vs
pg_notify(), SHOW vs current_setting(), pg_stat_activity vs
pg_current_xact_id() vs pg_current_xact_id_if_assigned(),
pg_stat_activity vs pg_backend_pid(), etc.

I see a clear pattern where Postgres provides function APIs fir
frequently needed info, even if it's theoretically possible to get
that info through other means.

My main concern though is about semantic clarity. I see a huge problem
that one needs to query pg_locks to get VXID. Why would I want to
query the lock subsystem to get transaction ID? That's very confusing.

pg_current_vxact_id() is semantically precise: "What is my
transaction's VXID?" We immediately have the direct answer from MyProc
without indirection through unrelated subsystems, which is pretty
obvious to anyone reading the code.

Having pg_current_vxact_id() increases API consistency. VXIDs deserve
the same treatment because they're fundamental to Postgres transaction
tracking and they uniquely identify every transaction (unlike XIDs). I
could day VXIDs are universal and that's why I think the current
asymmetry is odd:
- get XID: SELECT pg_current_xact_id()
- get PID: SELECT pg_backend_pid()
- get VXID: SELECT ... FROM pg_locks WHERE ... LIMIT 1  (why?)

Plus taking into account the minimal implementation and support costs
we should apply it. 20 lines of code without new infrastructure or
data structures changes sounds like a solid and maintainable piece. No
runtime overhead, no maintenance burden, simplest function without
locks or side effects.

I've prepared v3 of the patch addrressing Henson's code review:
- Added #define VXID_FMT "%d/%u" to lock.h
- Updated lockfuncs.c, elog.c, and xid8funcs.c to use it
- Use "localXID" (not "localTransactionId") in user docs

I'd appreciate thoughts from others in the community on whether this
reasoning is compelling.

Best regards,
Pavlo Golub

On Fri, Jan 9, 2026 at 4:15 AM Henson Choi <[email-masked]> wrote:
>> > appearing in pg_locks.virtualtransaction, log output via %v placeholder, and