Thread: BUG #16134: Assertion fails on CREATE gist INDEX over intarray

BUG #16134: Assertion fails on CREATE gist INDEX over intarray

From
PG Bug reporting form
Date:
The following bug has been logged on the website:

Bug reference:      16134
Logged by:          Alexander Lakhin
Email address:      exclusion@gmail.com
PostgreSQL version: 12.1
Operating system:   Ubuntu 18.04
Description:

When running the following script (repeated to improve reproducing):
echo "
CREATE EXTENSION IF NOT EXISTS intarray;
DROP TABLE IF EXISTS test__int;
CREATE TABLE test__int( a int[] );
\copy test__int from 'contrib/intarray/data/test__int.data'
INSERT INTO test__int SELECT * FROM test__int;
INSERT INTO test__int SELECT * FROM test__int;
INSERT INTO test__int SELECT * FROM test__int;
INSERT INTO test__int SELECT * FROM test__int;
CREATE INDEX test_idx on test__int using gist ( a gist__int_ops );
" >/tmp/test_gist_intarray.sql

for i in `seq 1 10`; do
echo "iteration $i"
psql -f /tmp/test_gist_intarray.sql || break
done

Server (compiled with cassert) crashes:
...
iteration 3
psql:/tmp/test_gist_intarray.sql:2: NOTICE:  extension "intarray" already
exists, skipping
CREATE EXTENSION
DROP TABLE
CREATE TABLE
COPY 7000
INSERT 0 7000
INSERT 0 14000
INSERT 0 28000
INSERT 0 56000
psql:/tmp/test_gist_intarray.sql:10: server closed the connection
unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
psql:/tmp/test_gist_intarray.sql:10: fatal: connection to server was lost
...

Core was generated by `postgres: law regression [local] CREATE INDEX
                        '.
Program terminated with signal SIGABRT, Aborted.
#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  0x00007fc7965ad801 in __GI_abort () at abort.c:79
#2  0x000055eed7d77022 in ExceptionalCondition (
    conditionName=conditionName@entry=0x55eed7de3c28 "!(((((ItemId)
(&((PageHeader) (page))->pd_linp[(todelete) - 1])))->lp_len != 0))",
errorType=errorType@entry=0x55eed7dce108 "FailedAssertion", 
    fileName=fileName@entry=0x55eed7de3bd0 "gistutil.c",
lineNumber=lineNumber@entry=70) at assert.c:54
#3  0x000055eed7913d48 in gistnospace (page=page@entry=0x7fc78e534d00 "",
itvec=itvec@entry=0x7ffca5b65df0, 
    len=len@entry=2, todelete=todelete@entry=18,
freespace=freespace@entry=819) at gistutil.c:70
#4  0x000055eed7911291 in gistplacetopage (rel=0x7fc7976df500,
freespace=819, 
    giststate=giststate@entry=0x55eed9038ab0, buffer=1859,
itup=itup@entry=0x7ffca5b65df0, ntup=ntup@entry=2, 
    oldoffnum=18, newblkno=0x0, leftchildbuf=1014, splitinfo=0x7ffca5b65d80,
markfollowright=true, 
    heapRel=0x7fc7976e97a0, is_build=true) at gist.c:257
#5  0x000055eed79126a1 in gistinserttuples
(state=state@entry=0x7ffca5b66130, stack=0x7ffca5b66100, 
    giststate=giststate@entry=0x55eed9038ab0,
tuples=tuples@entry=0x7ffca5b65df0, ntup=ntup@entry=2, 
    oldoffnum=<optimized out>, leftchild=1014, rightchild=1011,
unlockbuf=true, unlockleftchild=true) at gist.c:1269
#6  0x000055eed79128df in gistfinishsplit (state=state@entry=0x7ffca5b66130,
stack=stack@entry=0x55eed9038a18, 
    giststate=giststate@entry=0x55eed9038ab0, splitinfo=<optimized out>,
unlockbuf=unlockbuf@entry=true) at gist.c:1377
#7  0x000055eed791276b in gistinserttuples
(state=state@entry=0x7ffca5b66130, stack=0x55eed9038a18, 
    giststate=giststate@entry=0x55eed9038ab0,
tuples=tuples@entry=0x7ffca5b65ee0, ntup=ntup@entry=2, 
    oldoffnum=<optimized out>, leftchild=1028, rightchild=1012,
unlockbuf=true, unlockleftchild=true) at gist.c:1296
#8  0x000055eed79128df in gistfinishsplit (state=state@entry=0x7ffca5b66130,
stack=stack@entry=0x55eed902f258, 
    giststate=giststate@entry=0x55eed9038ab0, splitinfo=<optimized out>,
unlockbuf=unlockbuf@entry=true) at gist.c:1377
#9  0x000055eed791276b in gistinserttuples
(state=state@entry=0x7ffca5b66130, stack=0x55eed902f258, 
    giststate=giststate@entry=0x55eed9038ab0,
tuples=tuples@entry=0x7ffca5b65fd0, ntup=ntup@entry=2, 
    oldoffnum=<optimized out>, leftchild=1016, rightchild=1013,
unlockbuf=true, unlockleftchild=false) at gist.c:1296
#10 0x000055eed79128df in gistfinishsplit (state=state@entry=0x7ffca5b66130,
stack=stack@entry=0x55eed9030c50, 
    giststate=giststate@entry=0x55eed9038ab0, splitinfo=<optimized out>,
unlockbuf=unlockbuf@entry=false)
    at gist.c:1377
#11 0x000055eed791276b in gistinserttuples
(state=state@entry=0x7ffca5b66130, stack=stack@entry=0x55eed9030c50, 
    giststate=giststate@entry=0x55eed9038ab0,
tuples=tuples@entry=0x7ffca5b660c8, ntup=ntup@entry=1, 
    oldoffnum=oldoffnum@entry=12, leftchild=0, rightchild=0,
unlockbuf=false, unlockleftchild=false) at gist.c:1296
#12 0x000055eed7912c2c in gistinserttuple (state=state@entry=0x7ffca5b66130,
stack=stack@entry=0x55eed9030c50, 
    giststate=giststate@entry=0x55eed9038ab0, tuple=<optimized out>,
tuple@entry=0x55eed90326b8, 
    oldoffnum=oldoffnum@entry=12) at gist.c:1222
#13 0x000055eed791322b in gistdoinsert (r=r@entry=0x7fc7976df500,
itup=itup@entry=0x55eed9036c08, 
    freespace=<optimized out>, giststate=0x55eed9038ab0, heapRel=<optimized
out>, is_build=is_build@entry=true)
    at gist.c:789
#14 0x000055eed792161b in gistBuildCallback
(index=index@entry=0x7fc7976df500, htup=htup@entry=0x55eed8f84d50, 
    values=values@entry=0x7ffca5b66280, isnull=isnull@entry=0x7ffca5b66260,
tupleIsAlive=tupleIsAlive@entry=true, 
---Type <return> to continue, or q <return> to quit---
    state=state@entry=0x7ffca5b66640) at gistbuild.c:489
#15 0x000055eed794748b in heapam_index_build_range_scan
(heapRelation=0x7fc7976e97a0, indexRelation=0x7fc7976df500, 
    indexInfo=0x55eed9029ef0, allow_sync=<optimized out>, anyvisible=false,
progress=true, start_blockno=0, 
    numblocks=4294967295, callback=0x55eed79215b0 <gistBuildCallback>,
callback_state=0x7ffca5b66640, 
    scan=0x55eed8f84d00) at heapam_handler.c:1664
#16 0x000055eed7921886 in table_index_build_scan (scan=0x0,
callback_state=0x7ffca5b66640, 
    callback=0x55eed79215b0 <gistBuildCallback>, progress=true,
allow_sync=true, index_info=0x55eed9029ef0, 
    index_rel=0x7fc7976df500, table_rel=0x7fc7976e97a0) at
../../../../src/include/access/tableam.h:1508
#17 gistbuild (heap=0x7fc7976e97a0, index=0x7fc7976df500,
indexInfo=0x55eed9029ef0) at gistbuild.c:196
#18 0x000055eed79c4eba in index_build
(heapRelation=heapRelation@entry=0x7fc7976e97a0, 
    indexRelation=indexRelation@entry=0x7fc7976df500,
indexInfo=indexInfo@entry=0x55eed9029ef0, 
    isreindex=isreindex@entry=false, parallel=parallel@entry=true) at
index.c:2844
#19 0x000055eed79c6716 in index_create
(heapRelation=heapRelation@entry=0x7fc7976e97a0, 
    indexRelationName=indexRelationName@entry=0x55eed9029c68 "test_idx",
indexRelationId=16523, 
    indexRelationId@entry=0, parentIndexRelid=parentIndexRelid@entry=0,
parentConstraintId=parentConstraintId@entry=0, 
    relFileNode=0, indexInfo=0x55eed9029ef0, indexColNames=0x55eed8f84c70,
accessMethodObjectId=783, tableSpaceId=0, 
    collationObjectId=0x55eed8f851d0, classObjectId=0x55eed8f851f0,
coloptions=0x55eed8f85210, reloptions=0, flags=0, 
    constr_flags=0, allow_system_table_mods=false, is_internal=false,
constraintId=0x7ffca5b669b0) at index.c:1222
#20 0x000055eed7a71376 in DefineIndex (relationId=relationId@entry=16517,
stmt=stmt@entry=0x55eed9029bd0, 
    indexRelationId=indexRelationId@entry=0,
parentIndexId=parentIndexId@entry=0, 
    parentConstraintId=parentConstraintId@entry=0,
is_alter_table=is_alter_table@entry=false, check_rights=true, 
    check_not_in_use=true, skip_build=false, quiet=false) at
indexcmds.c:986
#21 0x000055eed7c542b9 in ProcessUtilitySlow
(pstate=pstate@entry=0x55eed9029ab8, pstmt=pstmt@entry=0x55eed8f5e680, 
    queryString=queryString@entry=0x55eed8f5d618 "CREATE INDEX test_idx on
test__int using gist ( a gist__int_ops );", 
    context=context@entry=PROCESS_UTILITY_TOPLEVEL, params=params@entry=0x0,
queryEnv=queryEnv@entry=0x0, 
    dest=0x55eed8f5e778, completionTag=0x7ffca5b66fa0 "") at
utility.c:1372
#22 0x000055eed7c53869 in standard_ProcessUtility (pstmt=0x55eed8f5e680, 
    queryString=0x55eed8f5d618 "CREATE INDEX test_idx on test__int using
gist ( a gist__int_ops );", 
    context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0,
dest=0x55eed8f5e778, completionTag=0x7ffca5b66fa0 "")
    at utility.c:927
#23 0x000055eed7c53917 in ProcessUtility (pstmt=pstmt@entry=0x55eed8f5e680,
queryString=<optimized out>, 
    context=context@entry=PROCESS_UTILITY_TOPLEVEL, params=<optimized out>,
queryEnv=<optimized out>, 
    dest=dest@entry=0x55eed8f5e778, completionTag=0x7ffca5b66fa0 "") at
utility.c:360
#24 0x000055eed7c4fdbe in PortalRunUtility
(portal=portal@entry=0x55eed8fc46d8, pstmt=pstmt@entry=0x55eed8f5e680, 
    isTopLevel=isTopLevel@entry=true,
setHoldSnapshot=setHoldSnapshot@entry=false, dest=dest@entry=0x55eed8f5e778,

    completionTag=completionTag@entry=0x7ffca5b66fa0 "") at pquery.c:1175
#25 0x000055eed7c50a0d in PortalRunMulti
(portal=portal@entry=0x55eed8fc46d8, isTopLevel=isTopLevel@entry=true, 
    setHoldSnapshot=setHoldSnapshot@entry=false,
dest=dest@entry=0x55eed8f5e778, altdest=altdest@entry=0x55eed8f5e778, 
    completionTag=completionTag@entry=0x7ffca5b66fa0 "") at pquery.c:1321
---Type <return> to continue, or q <return> to quit---
#26 0x000055eed7c5177d in PortalRun (portal=portal@entry=0x55eed8fc46d8,
count=count@entry=9223372036854775807, 
    isTopLevel=isTopLevel@entry=true, run_once=run_once@entry=true,
dest=dest@entry=0x55eed8f5e778, 
    altdest=altdest@entry=0x55eed8f5e778, completionTag=0x7ffca5b66fa0 "")
at pquery.c:796
#27 0x000055eed7c4da2d in exec_simple_query (
    query_string=query_string@entry=0x55eed8f5d618 "CREATE INDEX test_idx on
test__int using gist ( a gist__int_ops );") at postgres.c:1215
#28 0x000055eed7c4f9fd in PostgresMain (argc=<optimized out>,
argv=argv@entry=0x55eed8f88870, dbname=<optimized out>, 
    username=<optimized out>) at postgres.c:4236
#29 0x000055eed7bc1e2d in BackendRun (port=port@entry=0x55eed8f7ef90) at
postmaster.c:4437
#30 0x000055eed7bc50f3 in BackendStartup (port=port@entry=0x55eed8f7ef90) at
postmaster.c:4128
#31 0x000055eed7bc540a in ServerLoop () at postmaster.c:1704
#32 0x000055eed7bc67fb in PostmasterMain (argc=3, argv=<optimized out>) at
postmaster.c:1377
#33 0x000055eed7b21d87 in main (argc=3, argv=0x55eed8f579f0) at main.c:228


Re: BUG #16134: Assertion fails on CREATE gist INDEX over intarray

From
Tom Lane
Date:
PG Bug reporting form <noreply@postgresql.org> writes:
> When running the following script (repeated to improve reproducing):
> ...
> Server (compiled with cassert) crashes:

Yup, reproduced here.  What I see is that gistnospace is being told
to account for a "to-be-deleted" tuple that is off the end of the
page's line pointer array.  Tracing back to see where that tuple
number is coming from, it seems to originate in gistfinishsplit:

    gistinserttuples(state, stack->parent, giststate,
                     tuples, 2,
                     stack->downlinkoffnum,
                     left->buf, right->buf,
                     true,        /* Unlock parent */
                     unlockbuf    /* Unlock stack->buffer if caller wants that */
);

That is, the stack->downlinkoffnum tuple index doesn't jibe with the
actual state of the stack->parent page.

What I suspect has happened is that the stack->parent page itself
got split during some recursive split, and the stacked info wasn't
updated.  I don't know this code well enough to be sure though,
and I definitely don't wish to be the one to fix it.

            regards, tom lane