Thread

Commits

  1. Fix bogus logic for reporting which hash partition conflicts.

  1. BUG #17076: Server crashes on composing an error message about invalid modulus for a new table partition

    The Post Office <noreply@postgresql.org> — 2021-06-28T16:00:00Z

    The following bug has been logged on the website:
    
    Bug reference:      17076
    Logged by:          Alexander Lakhin
    Email address:      exclusion@gmail.com
    PostgreSQL version: 14beta2
    Operating system:   Ubuntu 20.04
    Description:        
    
    When executing the following query (based on create_table.sql):
    CREATE TABLE hash_parted (a int) PARTITION BY HASH (a);
    CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 10,
    REMAINDER 0);
    CREATE TABLE hpart_3 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 200,
    REMAINDER 2);
    CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS
    150, REMAINDER 3);
    
    Server crashes with the following stack:
    Core was generated by `postgres: law regression [local] CREATE TABLE        
                            '.
    Program terminated with signal SIGABRT, Aborted.
    #0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
    50      ../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:50
    #1  0x00007f032f726859 in __GI_abort () at abort.c:79
    #2  0x00005577bdce1ea3 in ExceptionalCondition
    (conditionName=conditionName@entry=0x5577bdef056c "strvalue != NULL", 
        errorType=errorType@entry=0x5577bdd4100b "FailedAssertion",
    fileName=0x7ffe0bcd1ac0 "\204\036\316\275wU", 
        fileName@entry=0x5577bdef0561 "snprintf.c",
    lineNumber=lineNumber@entry=442) at assert.c:69
    #3  0x00005577bdd3f04c in dopr (target=target@entry=0x7ffe0bcd20a0,
    format=0x5577bde49b5f "\".", 
        format@entry=0x5577bde49b10 "The new modulus %d is not a factor of %d,
    the modulus of existing partition \"%s\".", 
        args=0x7ffe0bcd2150) at snprintf.c:442
    #4  0x00005577bdd3f71f in pg_vsnprintf (str=<optimized out>,
    count=<optimized out>, count@entry=1024, 
        fmt=fmt@entry=0x5577bde49b10 "The new modulus %d is not a factor of %d,
    the modulus of existing partition \"%s\".", 
        args=args@entry=0x7ffe0bcd2150) at snprintf.c:195
    #5  0x00005577bdd359f6 in pvsnprintf (buf=<optimized out>,
    len=len@entry=1024, 
        fmt=fmt@entry=0x5577bde49b10 "The new modulus %d is not a factor of %d,
    the modulus of existing partition \"%s\".", 
        args=args@entry=0x7ffe0bcd2150) at psprintf.c:110
    #6  0x00005577bdd36de4 in appendStringInfoVA (str=str@entry=0x7ffe0bcd2130,
    
        fmt=fmt@entry=0x5577bde49b10 "The new modulus %d is not a factor of %d,
    the modulus of existing partition \"%s\".", 
        args=args@entry=0x7ffe0bcd2150) at stringinfo.c:149
    #7  0x00005577bdce7042 in errdetail (
        fmt=fmt@entry=0x5577bde49b10 "The new modulus %d is not a factor of %d,
    the modulus of existing partition \"%s\".")
        at elog.c:1051
    #8  0x00005577bdaec445 in check_new_partition_bound
    (relname=relname@entry=0x7ffe0bcd24a0 "fail_part", 
        parent=parent@entry=0x7f03223053b0, spec=spec@entry=0x5577bf9e9458,
    pstate=pstate@entry=0x5577bf9e8188)
        at partbounds.c:2902
    #9  0x00005577bd9b068b in DefineRelation (stmt=stmt@entry=0x5577bf8fb3c8,
    relkind=relkind@entry=114 'r', ownerId=10, 
        ownerId@entry=0, typaddress=typaddress@entry=0x0, 
        queryString=queryString@entry=0x5577bf8fa670 "CREATE TABLE fail_part
    PARTITION OF hash_parted FOR VALUES WITH (MODULUS 150, REMAINDER 3);") at
    tablecmds.c:1059
    #10 0x00005577bdbad002 in ProcessUtilitySlow
    (pstate=pstate@entry=0x5577bf91bf80, pstmt=pstmt@entry=0x5577bf8fb770, 
        queryString=queryString@entry=0x5577bf8fa670 "CREATE TABLE fail_part
    PARTITION OF hash_parted FOR VALUES WITH (MODULUS 150, REMAINDER 3);",
    context=context@entry=PROCESS_UTILITY_TOPLEVEL, params=params@entry=0x0, 
        queryEnv=queryEnv@entry=0x0, dest=0x5577bf8fb840, qc=0x7ffe0bcd2ad0) at
    utility.c:1146
    #11 0x00005577bdbacd34 in standard_ProcessUtility (pstmt=0x5577bf8fb770, 
        queryString=0x5577bf8fa670 "CREATE TABLE fail_part PARTITION OF
    hash_parted FOR VALUES WITH (MODULUS 150, REMAINDER 3);",
    readOnlyTree=<optimized out>, context=PROCESS_UTILITY_TOPLEVEL, params=0x0,
    queryEnv=0x0, dest=0x5577bf8fb840, 
        qc=0x7ffe0bcd2ad0) at utility.c:1049
    #12 0x00005577bdbace1d in ProcessUtility (pstmt=pstmt@entry=0x5577bf8fb770,
    queryString=<optimized out>, 
        readOnlyTree=<optimized out>,
    context=context@entry=PROCESS_UTILITY_TOPLEVEL, params=<optimized out>, 
        queryEnv=<optimized out>, dest=0x5577bf8fb840, qc=0x7ffe0bcd2ad0) at
    utility.c:527
    #13 0x00005577bdbaa343 in PortalRunUtility
    (portal=portal@entry=0x5577bf969570, pstmt=pstmt@entry=0x5577bf8fb770, 
        isTopLevel=isTopLevel@entry=true,
    setHoldSnapshot=setHoldSnapshot@entry=false, dest=dest@entry=0x5577bf8fb840,
    
        qc=qc@entry=0x7ffe0bcd2ad0) at pquery.c:1147
    #14 0x00005577bdbaa645 in PortalRunMulti
    (portal=portal@entry=0x5577bf969570, isTopLevel=isTopLevel@entry=true, 
        setHoldSnapshot=setHoldSnapshot@entry=false,
    dest=dest@entry=0x5577bf8fb840, altdest=altdest@entry=0x5577bf8fb840, 
        qc=qc@entry=0x7ffe0bcd2ad0) at pquery.c:1304
    #15 0x00005577bdbaaa79 in PortalRun (portal=portal@entry=0x5577bf969570,
    count=count@entry=9223372036854775807, 
        isTopLevel=isTopLevel@entry=true, run_once=run_once@entry=true,
    dest=dest@entry=0x5577bf8fb840, 
        altdest=altdest@entry=0x5577bf8fb840, qc=0x7ffe0bcd2ad0) at
    pquery.c:786
    #16 0x00005577bdba6cc6 in exec_simple_query (
        query_string=query_string@entry=0x5577bf8fa670 "CREATE TABLE fail_part
    PARTITION OF hash_parted FOR VALUES WITH (MODULUS 150, REMAINDER 3);") at
    postgres.c:1214
    #17 0x00005577bdba8c98 in PostgresMain (argc=argc@entry=1,
    argv=argv@entry=0x7ffe0bcd2cc0, dbname=<optimized out>, 
        username=<optimized out>) at postgres.c:4486
    #18 0x00005577bdb03b65 in BackendRun (port=port@entry=0x5577bf91dee0) at
    postmaster.c:4507
    #19 0x00005577bdb06d7a in BackendStartup (port=port@entry=0x5577bf91dee0) at
    postmaster.c:4229
    #20 0x00005577bdb06fc1 in ServerLoop () at postmaster.c:1745
    #21 0x00005577bdb0850e in PostmasterMain (argc=3, argv=<optimized out>) at
    postmaster.c:1417
    #22 0x00005577bda49158 in main (argc=3, argv=0x5577bf8f4930) at main.c:209
    
    
  2. Re: BUG #17076: Server crashes on composing an error message about invalid modulus for a new table partition

    Tom Lane <tgl@sss.pgh.pa.us> — 2021-06-28T21:08:09Z

    PG Bug reporting form <noreply@postgresql.org> writes:
    > When executing the following query (based on create_table.sql):
    > CREATE TABLE hash_parted (a int) PARTITION BY HASH (a);
    > CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 10,
    > REMAINDER 0);
    > CREATE TABLE hpart_3 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 200,
    > REMAINDER 2);
    > CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS
    > 150, REMAINDER 3);
    
    > Server crashes with the following stack:
    
    So this is evidently the fault of efbfb6424, which isn't accounting
    for the possibility that the next remainder has no associated partition.
    That results in boundinfo->indexes[offset + 1] being -1, whereupon we
    pass garbage to get_rel_name() and get back a NULL.
    
    I think the patch has got more problems than that too, as it's far
    from clear why the next remainder would have anything to do with the
    next larger modulus.  IOW I suspect that when it does manage to print
    a partition name without crashing, it's very likely to print the
    wrong partition.
    
    I'm inclined to think we should just revert efbfb6424, and maybe
    try again some other time.
    
    			regards, tom lane
    
    
    
    
  3. Re: BUG #17076: Server crashes on composing an error message about invalid modulus for a new table partition

    Tom Lane <tgl@sss.pgh.pa.us> — 2021-06-28T22:30:32Z

    I wrote:
    > I think the patch has got more problems than that too, as it's far
    > from clear why the next remainder would have anything to do with the
    > next larger modulus.  IOW I suspect that when it does manage to print
    > a partition name without crashing, it's very likely to print the
    > wrong partition.
    
    Concretely, this variant of the test case:
    
    drop table hash_parted;
    CREATE TABLE hash_parted (
    	a int
    ) PARTITION BY HASH (a);
    CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 50, REMAINDER 0);
    CREATE TABLE hpart_2 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 10, REMAINDER 1);
    CREATE TABLE hpart_3 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 200, REMAINDER 2);
    
    CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 25, REMAINDER 3);
    
    prints
    
    ERROR:  every hash partition modulus must be a factor of the next larger modulus
    DETAIL:  The new modulus 25 is not divisible by 10, the modulus of existing partition "hpart_1".
    
    which is obviously wrong.
    
    I think that rescuing this might require scanning through the list of
    partitions for one that has the desired modulus.  There could be more
    than one match, but I'd be content to take the first one.
    
    			regards, tom lane
    
    
    
    
  4. Re: BUG #17076: Server crashes on composing an error message about invalid modulus for a new table partition

    Amit Langote <amitlangote09@gmail.com> — 2021-06-29T07:11:51Z

    On Tue, Jun 29, 2021 at 7:30 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > I wrote:
    > > I think the patch has got more problems than that too, as it's far
    > > from clear why the next remainder would have anything to do with the
    > > next larger modulus.  IOW I suspect that when it does manage to print
    > > a partition name without crashing, it's very likely to print the
    > > wrong partition.
    >
    > Concretely, this variant of the test case:
    >
    > drop table hash_parted;
    > CREATE TABLE hash_parted (
    >         a int
    > ) PARTITION BY HASH (a);
    > CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 50, REMAINDER 0);
    > CREATE TABLE hpart_2 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 10, REMAINDER 1);
    > CREATE TABLE hpart_3 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 200, REMAINDER 2);
    >
    > CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 25, REMAINDER 3);
    >
    > prints
    >
    > ERROR:  every hash partition modulus must be a factor of the next larger modulus
    > DETAIL:  The new modulus 25 is not divisible by 10, the modulus of existing partition "hpart_1".
    >
    > which is obviously wrong.
    
    Yes.  Though, I think the problem is that the code uses
    boundinfo->indexes[<offset>] as an index into partdesc->oids[] array
    to get the existing partition to show in the error message.  The
    correct thing here would be to use <offset> directly.  That is because
    the hash partition bounds as laid out in boudinfo->datums[] correspond
    one-to-one with the partition OIDs laid out in partdesc->oids[].
    boundinfo->indexes should only be consulted to get the partition OID
    from a remainder value, as get_partition_for_tuple() does.
    
    (OTOH, range and list partition bound offsets, because there may be
    more than one bound assigned to each partition (considering
    de-duplication of pairs of matching upper and next lower bound in the
    range case), do not correspond one-to-one with those of partition
    OIDs.)
    
    > I think that rescuing this might require scanning through the list of
    > partitions for one that has the desired modulus.  There could be more
    > than one match, but I'd be content to take the first one.
    
    Hmm, the bound offset that the code comes up with to show in the error
    message seems fine to me.
    
    I have attached a patch containing the above mentioned fix.  The patch
    also adjusts the relevant test cases in create_table.sql to cover
    these cases.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
  5. Re: BUG #17076: Server crashes on composing an error message about invalid modulus for a new table partition

    Tom Lane <tgl@sss.pgh.pa.us> — 2021-06-29T18:36:52Z

    Amit Langote <amitlangote09@gmail.com> writes:
    > On Tue, Jun 29, 2021 at 7:30 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    >>> I think the patch has got more problems than that too, as it's far
    >>> from clear why the next remainder would have anything to do with the
    >>> next larger modulus.
    
    > Yes.  Though, I think the problem is that the code uses
    > boundinfo->indexes[<offset>] as an index into partdesc->oids[] array
    > to get the existing partition to show in the error message.  The
    > correct thing here would be to use <offset> directly.  That is because
    > the hash partition bounds as laid out in boudinfo->datums[] correspond
    > one-to-one with the partition OIDs laid out in partdesc->oids[].
    
    Got it.  Pushed your fix, along with some twiddling of the nearby
    comments which seemed a bit vague.
    
    			regards, tom lane