ykhuang wrote:
recurred through deadlock.
client1:
create table test(a int);
create index id on test using hash(a);
insert into test values(1);
insert into test values(2);
set enable_seqscan=off;
begin;
update test set a=a+1 where a=1;
client2:
set enable_seqscan=off;
begin;
update test set a=a+1 where a=2;
client1:
update test set a=a+1 where a=2;
client2:
update test set a=a+1 where a=1;
I can reproduce this, with --enable-cassert. It crashes when aborting
the transaction, in ReleaseResources_hash. The HashScanList items are
allocated in ExecutorState memory context, but that context has already
been deleted by the time we get to ReleaseResources_hash.
Not sure how to fix this. There's this piece of code in AtAbort_Portals:
/*
* Any resources belonging to the portal will be released in the
* upcoming transaction-wide cleanup; they will be gone before
we run
* PortalDrop.
*/
portal->resowner = NULL;
/*
* Although we can't delete the portal data structure proper,
we can
* release any memory in subsidiary contexts, such as executor
state.
* The cleanup hook was the last thing that might have needed
data
* there.
*/
MemoryContextDeleteChildren(PortalGetHeapMemory(portal));
MemoryContextDeleteChildren is where we free the HashScanList item we
later try to access. It seems like a simple fix would be to call
ResourceOwnerRelease before that, instead of relying on the
transaction-wide cleanup.
Another idea would be to allocate the HashScanList items in a
longer-lived memory context. The IndexScanDesc struct pointed to by the
HashScanList would still be in ExecutorState context, but that's all
right because we don't need to access it in ReleaseResources_hash.
--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com
--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs