Re: BUG #17821: Assertion failed in heap_update() due to heap pruning - Mailing list pgsql-bugs

From Alexander Lakhin
Subject Re: BUG #17821: Assertion failed in heap_update() due to heap pruning
Date
Msg-id 13d30799-0107-6502-c81c-39ff5f1e7eb0@gmail.com
Whole thread Raw
In response to BUG #17821: Assertion failed in heap_update() due to heap pruning  (PG Bug reporting form <noreply@postgresql.org>)
Responses Re: BUG #17821: Assertion failed in heap_update() due to heap pruning  (Andres Freund <andres@anarazel.de>)
List pgsql-bugs
02.03.2023 16:00, PG Bug reporting form wrote:
#5  0x0000556725c44981 in ExceptionalCondition
(conditionName=conditionName@entry=0x556725dc6b00 "ItemIdIsNormal(lp)",
fileName=fileName@entry=0x556725dc48e0 "heapam.c",
lineNumber=lineNumber@entry=3024) at assert.c:66
...
2023-03-02 15:22:13.031 MSK|law|test1|640094f5.1ba5ac|LOG: 
ExecuteGrantStmt(): before objectNamesToOids()
2023-03-02 15:22:13.031 MSK|law|test1|640094f5.1ba5ac|STATEMENT:  GRANT ALL
ON pg_class TO public;
2023-03-02 15:22:13.031 MSK|law|test1|640094f5.1ba5ac|LOG: 
heap_page_prune_execute() before ItemIdSetUnused(); buffer: 2012, off: 24
2023-03-02 15:22:13.031 MSK|law|test1|640094f5.1ba5ac|STATEMENT:  GRANT ALL
ON pg_class TO public;
...

So it looks like the session 1ba5ac made linepointer 24 unused while
pruning in the guts of objectNamesToOids(), then got the same
offset (24) from the SearchSysCache1() and finally was surprised
inside heap_update() to see an unused line pointer.
This raises two questions for me.
1) Was it legal to prune that linepointer (what if ExecGrant do not
perform
heap_modify_tuple() in this case, will an unused line pointer be left
behind?)?
2) Should page pruning be reflected in SysCache somehow?

Further investigation gave me a positive answer to the first question.
With more debug logging added I see that when that pruning executed
there was a redirection happened. There was dead items found in a tuple
chain starting from position 22, and redirection 22 -> 25 was performed,
so item 24 became unused.
The fragment of the detailed log is attached, and also you can look at
a dump of the modified page at the moment of the Assert.

SELECT * from heap_page_item_attrs(pg_read_binary_file('page.bin'), 1259::oid, true);
shows:
...
 21 |   3600 |        1 |    225 |    680 |      0 |        0 | (10,21) |          33 |      11011 |     32 | 1111111111111111111111111111111000000000 |       | ...
 22 |     25 |        2 |      0 |        |        |          |         |             |            |        |                                          |       |
 23 |      0 |        3 |      0 |        |        |          |         |             |            |        |                                          |       |
 24 |      0 |        0 |      0 |        |        |          |         |             |            |        |                                          |       |
 25 |   3368 |        1 |    225 | 222501 |      0 |        0 | (10,25) |       32801 |      10499 |     32 | 1111111111111111111111111111111000000000 |       | ...
(25 rows)

So we have only the second question left.

Best regards,
Alexander
Attachment

pgsql-bugs by date:

Previous
From: Tom Lane
Date:
Subject: Re: BUG #17817: DISABLE TRIGGER ALL on a partitioned table with foreign key fails
Next
From: Andres Freund
Date:
Subject: Re: BUG #17821: Assertion failed in heap_update() due to heap pruning