Обсуждение: BUG #5906: assertion failure in AtCleanup_Portals
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)
"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);
}
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
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
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