On Monday 19 July 2010 20:32:49 Andres Freund wrote:
> On Monday 19 July 2010 20:19:35 Heikki Linnakangas wrote:
> > On 19/07/10 20:58, Andres Freund wrote:
> > > On Monday 19 July 2010 19:57:13 Alvaro Herrera wrote:
> > >> Excerpts from Andres Freund's message of lun jul 19 11:58:06 -0400 
2010:
> > >>> It seems easy enough to throw a check_stack_depth() in there -
> > >>> survives make check here.
> > >> 
> > >> I wonder if it would work to deal with the problem non-recursively
> > >> instead.  We don't impose subxact depth restrictions elsewhere, why
> > >> start now?
> > > 
> > > It looks trivial enough, but whats the point?
> > 
> > To support more than <insert abitrary limit here> subtransactions,
> > obviously.
> 
> Well. I got that far. But why is that something worthy of support?
> For one I have a hard time imaging a sensible use case, for another doing
> anything in that deeply nested transactions seems to gets really slow (the
> chain of transactions gets walked at some places for one thing, there seem
> to be others).
> 
> If want I can write a patch for that as well, seems to be trivial enough.
Updated patch attached.


Andres
From 6d8ca934e86e63c3e867ecef355bd373412f6b6a Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Mon, 19 Jul 2010 19:44:45 +0200
Subject: [PATCH] Don't segfault upon too deeply nested subtransactions.

Build a list of parent transactions and iterate it in the correct
order instead of using recursion to avoid a stack overflow.
---
 src/backend/access/transam/xact.c |   24 ++++++++++++++++++++++--
 1 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 6ba6534..be0b448 100644
*** a/src/backend/access/transam/xact.c
--- b/src/backend/access/transam/xact.c
*************** AssignTransactionId(TransactionState s)
*** 409,417 ****
  	/*
  	 * Ensure parent(s) have XIDs, so that a child always has an XID later
  	 * than its parent.
  	 */
! 	if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
! 		AssignTransactionId(s->parent);
  
  	/*
  	 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
--- 409,437 ----
  	/*
  	 * Ensure parent(s) have XIDs, so that a child always has an XID later
  	 * than its parent.
+ 	 * We don't use recursion here to allow arbitrarily deep nesting.
  	 */
! 	if(isSubXact && !TransactionIdIsValid(s->parent->transactionId)){
! 		TransactionState p = s->parent;
! 		TransactionState* parents;
! 		size_t parentOffset = 0;
! 
! 		parents = palloc(sizeof(TransactionState) *  s->nestingLevel);
! 
! 		while(p && !TransactionIdIsValid(p->transactionId)){
! 			parents[parentOffset++] = p;
! 			p = p->parent;
! 		}
! 
! 		while(parentOffset != 0){
! 			/*
! 			 * Note that this won't recurse because p will never have a
! 			 * parent with an invalid transactionId at that point.
! 			 */
! 			AssignTransactionId(parents[--parentOffset]);
! 		}
! 		pfree(parents);
! 	}
  
  	/*
  	 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
-- 
1.7.2.rc1.10.gae32f

-- 
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Reply via email to