Re: BUG #17821: Assertion failed in heap_update() due to heap pruning

From: Alexander Lakhin <exclusion(at)gmail(dot)com>
To: pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #17821: Assertion failed in heap_update() due to heap pruning
Date: 2023-03-04 06:00:00
Message-ID: 13d30799-0107-6502-c81c-39ff5f1e7eb0@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

02.03.2023 16:00, PG Bug reporting form wrote:
> #5 0x0000556725c44981 in ExceptionalCondition
> (conditionName=conditionName(at)entry=0x556725dc6b00 "ItemIdIsNormal(lp)",
> fileName=fileName(at)entry=0x556725dc48e0 "heapam.c",
> lineNumber=lineNumber(at)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 Content-Type Size
server.log text/x-log 4.7 KB
page.bin application/octet-stream 8.0 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Andres Freund 2023-03-04 16:48:32 Re: BUG #17821: Assertion failed in heap_update() due to heap pruning
Previous Message Tom Lane 2023-03-03 19:33:34 Re: BUG #17817: DISABLE TRIGGER ALL on a partitioned table with foreign key fails