Fix for consume_xids advancing XIDs incorrectly

From: Yushi Ogiwara <btogiwarayuushi(at)oss(dot)nttdata(dot)com>
To: Pgsql Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Fix for consume_xids advancing XIDs incorrectly
Date: 2024-10-15 01:51:33
Message-ID: 2a62f138c9dcb6fcf5889b076d123aa2@oss.nttdata.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

I found that the consume_xids function incorrectly advances XIDs as
shown:

postgres=# select txid_current();
txid_current
--------------
746
(1 row)

postgres=# select consume_xids('100');
consume_xids
--------------
847
(1 row)

In the example, the consume_xids function consumes 100 XIDs when XID =
746, so the desired outcome from consume_xids should be 746 + 100 = 846,
which differs from the actual outcome, 847.

Behavior inside a transaction block:

postgres=# select txid_current();
txid_current
--------------
1410
(1 row)

postgres=# begin;
BEGIN
postgres=*# select consume_xids('100');
consume_xids
--------------
1511
(1 row)
postgres=*# select consume_xids('100');
consume_xids
--------------
1521
(1 row)

Here, the first call inside the transaction block consumes 100+1 XIDs
(incorrect), while the second call consumes exactly 100 XIDs (as
expected)

Summary:

The function performs incorrectly when:
- Outside of a transaction block
- The first call inside a transaction block
But works correctly when:
- After the second call inside a transaction block

The issue arises because consume_xids does not correctly count the
consumed XIDs when it calls the GetTopTransactionId function, which
allocates a new XID when none has been assigned.

With the attached patch, the consume_xids works as expected, both inside
and outside of transaction blocks as shown below:

postgres=# select txid_current();
txid_current
--------------
1546
(1 row)

postgres=# select consume_xids('100');
consume_xids
--------------
1646
(1 row)

postgres=# begin;
BEGIN
postgres=*# select consume_xids('100');
consume_xids
--------------
1746
(1 row)

postgres=*# select consume_xids('100');
consume_xids
--------------
1846
(1 row)

Regards,
Yushi

Attachment Content-Type Size
skip_id_correctly.diff text/x-diff 909 bytes

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message David Rowley 2024-10-15 02:20:31 Re: Changing the default random_page_cost value
Previous Message Corey Huinker 2024-10-15 01:46:58 Re: Statistics Import and Export