Thread

Commits

  1. Fix crash when a page was split during GiST index creation.

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

    The Post Office <noreply@postgresql.org> — 2019-11-24T07:33:34Z

    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
    
    
  2. Re: BUG #16134: Assertion fails on CREATE gist INDEX over intarray

    Tom Lane <tgl@sss.pgh.pa.us> — 2019-11-24T17:38:50Z

    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