public inbox for [email protected]
help / color / mirror / Atom feedFrom: =?utf-8?B?Wml6aHVhbkxpdSBYLU1BTg==?= <[email protected]>
To: =?utf-8?B?Q2hhbyBMaQ==?= <[email protected]>
To: =?utf-8?B?UG9zdGdyZXMgaGFja2Vycw==?= <[email protected]>
Subject: Re: Adjust pg_stat_get_lock() prorows to match lock types
Date: Sat, 6 Jun 2026 11:30:26 +0800
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
References: <[email protected]>
<[email protected]>
>From: Chao Li <[email protected]>
>Date: 2026-05-15 16:34
>To: Postgres hackers <[email protected]>
>Subject: Re: Adjust pg_stat_get_lock() prorows to match lock types
>
>
>
>> On May 4, 2026, at 10:23, Chao Li <[email protected]> wrote:
>>
>> Hi,
>>
>> I read the code of pg_stat_lock() and played a bit with it. I happened to notice one thing: the function always returns 12 rows, but the planner estimates 10 rows:
>>
>> ```
>> evantest=# EXPLAIN ANALYZE SELECT * FROM pg_catalog.pg_stat_lock;
>> QUERY PLAN
>> -----------------------------------------------------------------------------------------------------------------------
>> Function Scan on pg_stat_get_lock l (cost=0.00..0.10 rows=10 width=64) (actual time=0.067..0.071 rows=12.00 loops=1)
>> Planning Time: 0.121 ms
>> Execution Time: 0.126 ms
>> (3 rows)
>> ```
>>
>> Then I found that, in pg_proc.dat, the function's prorows is defined as 10. Since the function returns one row per lock type, and lock types are not something that change frequently, I think it is better to give the planner a more accurate row count. After changing prorows to 12, the plan looks like this:
>>
>> ```
>> evantest=# EXPLAIN ANALYZE SELECT * FROM pg_catalog.pg_stat_lock;
>> QUERY PLAN
>> -----------------------------------------------------------------------------------------------------------------------
>> Function Scan on pg_stat_get_lock l (cost=0.00..0.12 rows=12 width=64) (actual time=0.134..0.138 rows=12.00 loops=1)
>> Planning:
>> Buffers: shared hit=13
>> Planning Time: 0.313 ms
>> Execution Time: 0.228 ms
>> (5 rows)
>> ```
>>
>> While there, I also made two small tweaks to two function comments in pgstat_lock.c. If those are not considered worth changing, I am okay with removing them from the patch.
>>
>> Please see the attached patch for details.
>>
>> Best regards,
>> --
>> Chao Li (Evan)
>> HighGo Software Co., Ltd.
>> https://www.highgo.com/
>>
>>
>>
>>
>> <v1-0001-Adjust-pg_stat_get_lock-row-estimate-and-comments.patch>
>
>Rebased.
>
>Best regards,
>--
>Chao Li (Evan)
>HighGo Software Co., Ltd.
>https://www.highgo.com/
Hi Chao,
After testing with GDB, I found that before your patch, the catalog data of pg_stat_get_lock shows (proowner = 10):
{oid = 6509, proname = {data = "pg_stat_get_lock", '\000' <repeats 47 times>}, pronamespace = 11, proowner = 10, prolang = 12, procost = 1, prorows = 10, provariadic = 0, prosupport = 0, prokind = 102 'f', prosecdef = false, proleakproof = false, proisstrict = true, proretset = true, provolatile = 118 'v', proparallel = 114 'r', pronargs = 0, pronargdefaults = 0, prorettype = 2249, proargtypes = {vl_len_ = 96, ndim = 1, dataoffset = 0, elemtype = 26, dim1 = 0, lbound1 = 0, values = 0x7f09190754e0}}
`
With your v2 patch applied, the data becomes (proowner = 12):
{oid = 6509, proname = {data = "pg_stat_get_lock", '\000' <repeats 47 times>}, pronamespace = 11, proowner = 10, prolang = 12, procost = 1,
prorows = 12, provariadic = 0, prosupport = 0, prokind = 102 'f', prosecdef = false, proleakproof = false, proisstrict = true, proretset = true,
provolatile = 118 'v', proparallel = 114 'r', pronargs = 0, pronargdefaults = 0, prorettype = 2249, proargtypes = {vl_len_ = 96, ndim = 1,
dataoffset = 0, elemtype = 26, dim1 = 0, lbound1 = 0, values = 0x7f013c201788}}
`
The estimated row count 12 of pg_stat_get_lock matches the number of lockable object types:
relation, extend, frozenid, page, tuple, transactionid, virtualxid, spectoken, object, userlock, advisory, and applytransaction.
This is exactly as mentioned in the documentation "Table 27.11. Wait Events of Type Lock", as shown below.
`
xman=# explain select * from pg_catalog.pg_stat_lock;
QUERY PLAN
-------------------------------------------------------------------------
Function Scan on pg_stat_get_lock l (cost=0.00..0.12 rows=12 width=64)
(1 row)
xman=# explain analyze select * from pg_catalog.pg_stat_lock;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
Function Scan on pg_stat_get_lock l (cost=0.00..0.12 rows=12 width=64) (actual time=0.115..0.124 rows=12.00 loops=1)
Planning Time: 4941.026 ms
Execution Time: 0.240 ms
(3 rows)
xman=# select * from pg_catalog.pg_stat_lock;
locktype | waits | wait_time | fastpath_exceeded | stats_reset
------------------+-------+-----------+-------------------+-------------------------------
relation | 0 | 0 | 0 | 2026-06-06 10:59:06.350828+08
extend | 0 | 0 | 0 | 2026-06-06 10:59:06.350828+08
frozenid | 0 | 0 | 0 | 2026-06-06 10:59:06.350828+08
page | 0 | 0 | 0 | 2026-06-06 10:59:06.350828+08
tuple | 0 | 0 | 0 | 2026-06-06 10:59:06.350828+08
transactionid | 0 | 0 | 0 | 2026-06-06 10:59:06.350828+08
virtualxid | 0 | 0 | 0 | 2026-06-06 10:59:06.350828+08
spectoken | 0 | 0 | 0 | 2026-06-06 10:59:06.350828+08
object | 0 | 0 | 0 | 2026-06-06 10:59:06.350828+08
userlock | 0 | 0 | 0 | 2026-06-06 10:59:06.350828+08
advisory | 0 | 0 | 0 | 2026-06-06 10:59:06.350828+08
applytransaction | 0 | 0 | 0 | 2026-06-06 10:59:06.350828+08
(12 rows)
`
Thanks for the patch.
regards,
--
ZizhuanLiu (X-MAN)
[email protected]
view thread (4+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected]
Subject: Re: Adjust pg_stat_get_lock() prorows to match lock types
In-Reply-To: <[email protected]>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox