Обсуждение: BUG #5906: assertion failure in AtCleanup_Portals

Поиск
Список
Период
Сортировка

BUG #5906: assertion failure in AtCleanup_Portals

От
"YAMAMOTO Takashi"
Дата:
The following bug has been logged online:

Bug reference:      5906
Logged by:          YAMAMOTO Takashi
Email address:      yamt@mwd.biglobe.ne.jp
PostgreSQL version: 9.1devel
Operating system:   NetBSD current
Description:        assertion failure in AtCleanup_Portals
Details:

i got the following with my application, which uses
PQsendPrepare+PQsendQueryPrepared for nearly everything
including ROLLBACK.

PostgreSQL version is 4c966d920fb75a5d0366b887c2ef28e6d87c1eda.

(gdb) bt
#0  0xbbba4cc7 in _lwp_kill () from /usr/lib/libc.so.12
#1  0xbbba4c85 in raise (s=6) at /siro/nbsd/src/lib/libc/gen/raise.c:48
#2  0xbbba445a in abort () at /siro/nbsd/src/lib/libc/stdlib/abort.c:74
#3  0x0833eae2 in ExceptionalCondition (
    conditionName=0x84bf3b8 "!(portal->cleanup == ((void *)0))",
    errorType=0x8371631 "FailedAssertion", fileName=0x84bf200 "portalmem.c",

    lineNumber=766) at assert.c:57
#4  0x0835d4e3 in AtCleanup_Portals () at portalmem.c:766
#5  0x080c49a8 in CleanupTransaction () at xact.c:2325
#6  0x080c809b in CommitTransactionCommand () at xact.c:2503
#7  0x082845a3 in finish_xact_command () at postgres.c:2450
#8  0x08287b34 in PostgresMain (argc=2, argv=0xbb9126a4,
    username=0xbb9125f8 "takashi") at postgres.c:1980
#9  0x08242306 in ServerLoop () at postmaster.c:3590
#10 0x082430b8 in PostmasterMain (argc=3, argv=0xbfbfe5a8) at
postmaster.c:1110
#11 0x081e1ac9 in main (argc=3, argv=0xbfbfe5a8) at main.c:199
(gdb) fr 4
#4  0x0835d4e3 in AtCleanup_Portals () at portalmem.c:766
766                     Assert(portal->cleanup == NULL);
(gdb) p *portal
$2 = {name = 0xbb9e3d48 "", prepStmtName = 0x99b35838 "41", heap =
0x99b323e8,
  resowner = 0x99b44b8c, cleanup = 0x817dd70 <PortalCleanup>, createSubid =
1,
  sourceText = 0x99b3581c "ROLLBACK", commandTag = 0x8498daf "ROLLBACK",
  stmts = 0x99ba681c, cplan = 0x99ba6868, portalParams = 0x0,
  strategy = PORTAL_MULTI_QUERY, cursorOptions = 4, status = PORTAL_DONE,
  portalPinned = 0 '\0', queryDesc = 0x0, tupDesc = 0x0, formats = 0x0,
  holdStore = 0x0, holdContext = 0x0, atStart = 1 '\001', atEnd = 1 '\001',

  posOverflow = 0 '\0', portalPos = 0, creation_time = 352351237783155,
  visible = 1 '\001'}
(gdb)

Re: BUG #5906: assertion failure in AtCleanup_Portals

От
Tom Lane
Дата:
"YAMAMOTO Takashi" <yamt@mwd.biglobe.ne.jp> writes:
> i got the following with my application, which uses
> PQsendPrepare+PQsendQueryPrepared for nearly everything
> including ROLLBACK.

Can't do anything about that without a test case.

            regards, tom lane

Re: BUG #5906: assertion failure in AtCleanup_Portals

От
yamt@mwd.biglobe.ne.jp (YAMAMOTO Takashi)
Дата:
hi,

> "YAMAMOTO Takashi" <yamt@mwd.biglobe.ne.jp> writes:
>> i got the following with my application, which uses
>> PQsendPrepare+PQsendQueryPrepared for nearly everything
>> including ROLLBACK.
>
> Can't do anything about that without a test case.
>
>             regards, tom lane

here's a small test case.

YAMAMOTO Takashi


#include <stdlib.h>

#include <libpq-fe.h>

int
main()
{
        PGconn *conn;
        PGresult *res;

        conn = PQconnectdb("");
        if (PQstatus(conn) != CONNECTION_OK) {
                exit(1);
        }
        res = PQprepare(conn, "r", "ROLLBACK", 0, NULL);
        if (PQresultStatus(res) != PGRES_COMMAND_OK) {
                exit(1);
        }
        PQclear(res);
        res = PQexec(conn, "BEGIN");
        if (PQresultStatus(res) != PGRES_COMMAND_OK) {
                exit(1);
        }
        PQclear(res);
        res = PQexec(conn, "hoge");
        /* a syntax error made the transaction aborted */
        PQclear(res);
        res = PQexecPrepared(conn, "r", 0, NULL, NULL, NULL, 0);
        if (PQresultStatus(res) != PGRES_COMMAND_OK) {
                exit(1);
        }
        PQclear(res);
        exit(0);
}

Re: BUG #5906: assertion failure in AtCleanup_Portals

От
Itagaki Takahiro
Дата:
On Thu, Mar 3, 2011 at 09:14, YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp> wrote:
>>> i got the following with my application, which uses
>>> PQsendPrepare+PQsendQueryPrepared for nearly everything
>>> including ROLLBACK.
>
> here's a small test case.

I was able to reproduce the assertion failure.

It looks we call CreatePortal for ROLLBACK, but don't invoke
DropPortal nor AtAbort_Portals before AtCleanup_Portals.

--
Itagaki Takahiro

Re: BUG #5906: assertion failure in AtCleanup_Portals

От
Tom Lane
Дата:
Itagaki Takahiro <itagaki.takahiro@gmail.com> writes:
> On Thu, Mar 3, 2011 at 09:14, YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp> wrote:
>> here's a small test case.

> I was able to reproduce the assertion failure.

> It looks we call CreatePortal for ROLLBACK, but don't invoke
> DropPortal nor AtAbort_Portals before AtCleanup_Portals.

Hmm.  The reason why not is that xact.c is already in TBLOCK_ABORT_END
state, ie, it knows it already did AbortTransaction and doesn't see a
need to do it again.  So the portal running ROLLBACK doesn't get
cleaned up by AtAbort_Portals.

We could revert the addition of the "cleanup == NULL" assert in
AtCleanup_Portals, but I'm still feeling that that assertion is a good
thing.  Maybe the cleanest fix is to have PortalRun do something to run
the cleanup hook where it does this:

                /* Prevent portal's commands from being re-executed */
                portal->status = PORTAL_DONE;

That should be a safe-enough place to run cleanup.

            regards, tom lane

Re: BUG #5906: assertion failure in AtCleanup_Portals

От
Tom Lane
Дата:
I wrote:
> We could revert the addition of the "cleanup == NULL" assert in
> AtCleanup_Portals, but I'm still feeling that that assertion is a good
> thing.  Maybe the cleanest fix is to have PortalRun do something to run
> the cleanup hook where it does this:
>                 /* Prevent portal's commands from being re-executed */
>                 portal->status = PORTAL_DONE;

Fixed that way.  Thanks for the report!

            regards, tom lane