Re: Faulty HEAP_XMAX_LOCK_ONLY & HEAP_KEYS_UPDATED hintbit combination - Mailing list pgsql-hackers

From Mahendra Singh Thalor
Subject Re: Faulty HEAP_XMAX_LOCK_ONLY & HEAP_KEYS_UPDATED hintbit combination
Date
Msg-id CAKYtNAr+x3UbfngDTA+eyWiUdAPVY22DdTAK23uRuUNGUV_6EQ@mail.gmail.com
Whole thread Raw
In response to Faulty HEAP_XMAX_LOCK_ONLY & HEAP_KEYS_UPDATED hintbit combination  (Julien Rouhaud <rjuju123@gmail.com>)
Responses Re: Faulty HEAP_XMAX_LOCK_ONLY & HEAP_KEYS_UPDATED hintbit combination  (Julien Rouhaud <rjuju123@gmail.com>)
List pgsql-hackers
On Sun, 24 Jan 2021 at 11:48, Julien Rouhaud <rjuju123@gmail.com> wrote:
>
> Hi,
>
> While working on pg14 compatibility for an extension relying on an apparently
> uncommon combination of FOR UPDATE and stored function calls, I hit some new
> Asserts introduced in 866e24d47db (Extend amcheck to check heap pages):
>
> +       /*
> +        * Do not allow tuples with invalid combinations of hint bits to be placed
> +        * on a page.  These combinations are detected as corruption by the
> +        * contrib/amcheck logic, so if you disable one or both of these
> +        * assertions, make corresponding changes there.
> +        */
> +       Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
> +                        (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
>
>
> I attach a simple self contained script to reproduce the problem, the last
> UPDATE triggering the Assert.
>
> I'm not really familiar with this part of the code, so it's not exactly clear
> to me if some logic is missing in compute_new_xmax_infomask() /
> heap_prepare_insert(), or if this should actually be an allowed combination of
> hint bit.

Thanks Juliean for reporting this. I am also able to reproduce this assert.

Small test case to reproduce:
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(id integer, val text);
INSERT INTO t1 SELECT i, 'val' FROM generate_series(1, 2) i;

BEGIN;
SAVEPOINT s1;
SELECT 1 FROM t1 WHERE id = 2 FOR UPDATE;
UPDATE t1 SET val = 'hoho' WHERE id = 2;
release s1;
SELECT 1 FROM t1 WHERE id = 2 FOR UPDATE;
UPDATE t1 SET val = 'hoho' WHERE id = 2;

If we remove the "release s1;" step from the test case, then we are not getting this assert failure.

Stack trace:
warning: Unexpected size of section `.reg-xstate/123318' in core file.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `postgres: mahendrathalor postgres [local] UPDATE                              '.
Program terminated with signal SIGABRT, Aborted.

warning: Unexpected size of section `.reg-xstate/123318' in core file.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007fb50a7c88b1 in __GI_abort () at abort.c:79
#2  0x00005612a63f7c84 in ExceptionalCondition (
    conditionName=0x5612a64da470 "!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))",
    errorType=0x5612a64da426 "FailedAssertion", fileName=0x5612a64da420 "hio.c", lineNumber=57) at assert.c:69
#3  0x00005612a597e76b in RelationPutHeapTuple (relation=0x7fb50ce37fc0, buffer=163, tuple=0x5612a795de18, token=false) at hio.c:56
#4  0x00005612a5955d32 in heap_update (relation=0x7fb50ce37fc0, otid=0x7ffc8b5e30d2, newtup=0x5612a795de18, cid=0, crosscheck=0x0, wait=true, tmfd=0x7ffc8b5e3060,
    lockmode=0x7ffc8b5e3028) at heapam.c:3791
#5  0x00005612a596ebdc in heapam_tuple_update (relation=0x7fb50ce37fc0, otid=0x7ffc8b5e30d2, slot=0x5612a794d348, cid=3, snapshot=0x5612a793d620, crosscheck=0x0, wait=true,
    tmfd=0x7ffc8b5e3060, lockmode=0x7ffc8b5e3028, update_indexes=0x7ffc8b5e3025) at heapam_handler.c:327
#6  0x00005612a5da745d in table_tuple_update (rel=0x7fb50ce37fc0, otid=0x7ffc8b5e30d2, slot=0x5612a794d348, cid=3, snapshot=0x5612a793d620, crosscheck=0x0, wait=true,
    tmfd=0x7ffc8b5e3060, lockmode=0x7ffc8b5e3028, update_indexes=0x7ffc8b5e3025) at ../../../src/include/access/tableam.h:1422
#7  0x00005612a5dab6ef in ExecUpdate (mtstate=0x5612a794bc20, resultRelInfo=0x5612a794be58, tupleid=0x7ffc8b5e30d2, oldtuple=0x0, slot=0x5612a794d348, planSlot=0x5612a794d1f8,
    epqstate=0x5612a794bd18, estate=0x5612a794b9b0, canSetTag=true) at nodeModifyTable.c:1498
#8  0x00005612a5dadb17 in ExecModifyTable (pstate=0x5612a794bc20) at nodeModifyTable.c:2254
#9  0x00005612a5d4fdc5 in ExecProcNodeFirst (node=0x5612a794bc20) at execProcnode.c:450
#10 0x00005612a5d3bd3a in ExecProcNode (node=0x5612a794bc20) at ../../../src/include/executor/executor.h:247
#11 0x00005612a5d40764 in ExecutePlan (estate=0x5612a794b9b0, planstate=0x5612a794bc20, use_parallel_mode=false, operation=CMD_UPDATE, sendTuples=false, numberTuples=0,
    direction=ForwardScanDirection, dest=0x5612a7946d38, execute_once=true) at execMain.c:1542
#12 0x00005612a5d3c8e2 in standard_ExecutorRun (queryDesc=0x5612a79468c0, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:364
#13 0x00005612a5d3c5aa in ExecutorRun (queryDesc=0x5612a79468c0, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:308
#14 0x00005612a612d78a in ProcessQuery (plan=0x5612a7946c48, sourceText=0x5612a787b570 "UPDATE t1 SET val = 'hoho' WHERE id = 2;", params=0x0, queryEnv=0x0,
    dest=0x5612a7946d38, qc=0x7ffc8b5e3570) at pquery.c:160
#15 0x00005612a61306f6 in PortalRunMulti (portal=0x5612a78dd5f0, isTopLevel=true, setHoldSnapshot=false, dest=0x5612a7946d38, altdest=0x5612a7946d38, qc=0x7ffc8b5e3570)
    at pquery.c:1267
#16 0x00005612a612f256 in PortalRun (portal=0x5612a78dd5f0, count=9223372036854775807, isTopLevel=true, run_once=true, dest=0x5612a7946d38, altdest=0x5612a7946d38,
    qc=0x7ffc8b5e3570) at pquery.c:779
#17 0x00005612a612266f in exec_simple_query (query_string=0x5612a787b570 "UPDATE t1 SET val = 'hoho' WHERE id = 2;") at postgres.c:1240
#18 0x00005612a612b8dd in PostgresMain (argc=1, argv=0x7ffc8b5e3790, dbname=0x5612a78a74f0 "postgres", username=0x5612a78a74c8 "mahendrathalor") at postgres.c:4394
#19 0x00005612a5fd5bf0 in BackendRun (port=0x5612a789ec00) at postmaster.c:4484
#20 0x00005612a5fd4f46 in BackendStartup (port=0x5612a789ec00) at postmaster.c:4206
#21 0x00005612a5fcd301 in ServerLoop () at postmaster.c:1730
#22 0x00005612a5fcc4fe in PostmasterMain (argc=5, argv=0x5612a7873e70) at postmaster.c:1402
#23 0x00005612a5e16d9a in main (argc=5, argv=0x5612a7873e70) at main.c:209


I am also trying to understand infomask and all.

Thanks and Regards
Mahendra Singh Thalor
EnterpriseDB: http://www.enterprisedb.com

pgsql-hackers by date:

Previous
From: Alvaro Herrera
Date:
Subject: Re: Faulty HEAP_XMAX_LOCK_ONLY & HEAP_KEYS_UPDATED hintbit combination
Next
From: Julien Rouhaud
Date:
Subject: Re: Faulty HEAP_XMAX_LOCK_ONLY & HEAP_KEYS_UPDATED hintbit combination