| From: | ZizhuanLiu X-MAN <44973863(at)qq(dot)com> |
|---|---|
| To: | Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com>, Postgres hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: Adjust pg_stat_get_lock() prorows to match lock types |
| Date: | 2026-06-06 03:30:26 |
| Message-ID: | tencent_547DAB599650CB356EC26FB5D1D0824ED80A@qq.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
>From: Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com>
>Date: 2026-05-15 16:34
>To: Postgres hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
>Subject: Re: Adjust pg_stat_get_lock() prorows to match lock types
>
>
>
>> On May 4, 2026, at 10:23, Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com> 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)
44973863(at)qq(dot)com
| From | Date | Subject | |
|---|---|---|---|
| Previous Message | Chao Li | 2026-06-06 03:06:00 | Re: Fix bug of CHECK constraint enforceability recursion |