Assertion failure in AtCleanup_Portals

From: Pavan Deolasee <pavan(dot)deolasee(at)gmail(dot)com>
To: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Assertion failure in AtCleanup_Portals
Date: 2012-02-03 15:30:14
Message-ID: CABOikdMghBjwbyf6jdb=CSgAb0qERJY0JLK=TLf+CdtN5kThMQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

If I run the following sequence of commands, I get an assertion
failure in current HEAD.

postgres=# BEGIN;
BEGIN
postgres=# SELECT 1/0;
ERROR: division by zero
postgres=# ROLLBACK TO A;
ERROR: no such savepoint
postgres=# \q

The process fails when the session is closed and aborted transaction
gets cleaned at the proc_exit time. The stack trace is as below.

(gdb) bt
#0 0x00c16422 in __kernel_vsyscall ()
#1 0x00244651 in *__GI_raise (sig=6) at
../nptl/sysdeps/unix/sysv/linux/raise.c:64
#2 0x00247a82 in *__GI_abort () at abort.c:92
#3 0x0844b800 in ExceptionalCondition (conditionName=0x86161e8
"!(portal->cleanup == ((void *)0))", errorType=0x8615e94
"FailedAssertion",
fileName=0x8615e88 "portalmem.c", lineNumber=793) at assert.c:57
#4 0x08472a5a in AtCleanup_Portals () at portalmem.c:793
#5 0x080f2535 in CleanupTransaction () at xact.c:2373
#6 0x080f40d7 in AbortOutOfAnyTransaction () at xact.c:3855
#7 0x0845cc5e in ShutdownPostgres (code=0, arg=0) at postinit.c:966
#8 0x08332ba7 in shmem_exit (code=0) at ipc.c:221
#9 0x08332ab3 in proc_exit_prepare (code=0) at ipc.c:181
#10 0x08332a15 in proc_exit (code=0) at ipc.c:96
#11 0x0835b07c in PostgresMain (argc=2, argv=0xa12fa64,
username=0xa12f958 "pavan") at postgres.c:4091

I analyzed this a bit. It seems that the first statement throws an
error, runs AbortCurrentTransaction and puts the transaction block in
TBLOCK_ABORT state. Any commands executed after this would usually
fail with error "current transaction is aborted". But the ROLLBACK TO
gets past this check because IsTransactionExitStmt() returns success
(and rightly so). So we end up creating a portal to run the ROLLBACK
TO command. This command fails because the SAVEPOINT A does not exist
and we throw an error. But since the transaction block is already in
TBLOCK_ABORT state, the AbortCurrentTransaction doesn't do any work.
The cleanup routine for the portal remains unexecuted. Later when the
backend exits and cleanup routines are called, the assertion inside
AtCleanup_Portals fails.

I am not sure what is the right fix for this. I see Tom fixed a
similar complain sometime back.
http://git.postgresql.org/pg/commitdiff/6252c4f9e201f619e5eebda12fa867acd4e4200e

But may its not enough to cover all code paths, as demonstrated by this example.

Thanks,
Pavan

--
Pavan Deolasee
EnterpriseDB     http://www.enterprisedb.com

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Joachim Wieland 2012-02-03 15:43:17 Re: patch for parallel pg_dump
Previous Message Robert Haas 2012-02-03 15:28:05 Re: Should I implement DROP INDEX CONCURRENTLY?