Robert Haas escribió:
> On Wed, Nov 6, 2013 at 9:40 AM, Alvaro Herrera <alvhe...@2ndquadrant.com> 
> wrote:
> > Noah Misch wrote:
> >> Incomplete list:
> >>
> >> - If smgrDoPendingDeletes() finds files to delete, mdunlink() and its 
> >> callee
> >>   relpathbackend() call palloc(); this is true in all supported branches.  
> >> In
> >>   9.3, due to commit 279628a0, smgrDoPendingDeletes() itself calls 
> >> palloc().
> >>   (In fact, it does so even when the pending list is empty -- this is the 
> >> only
> >>   palloc() during a trivial transaction commit.)  palloc() failure there
> >>   yields a PANIC during commit.
> >
> > I think we should fix this routine to avoid the palloc when not necessary.
> > That initial palloc is pointless.

Here's a trivial patch we could apply to 9.3 immediately.  Anything else
such as the ideas proposed below would require more effort than anyone
can probably spend here soon.


> > Also, there have been previous discussions about having relpathbackend
> > not use palloc at all.  That was only because we wanted to use it in
> > pg_xlogdump which didn't have palloc support at the time, so it's no
> > longer as pressing; but perhaps it's still worthy of consideration.
> 
> +1, but I'd like it better if we could find a way of avoiding the
> palloc in all cases.  Panicking because we run out of memory at the
> wrong time isn't really very nice.  Maybe the information needs to be
> maintained in the format in which it ultimately needs to be returned,
> so that we needn't rejigger it in the middle of a critical section.

-- 
Álvaro Herrera                http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
*** a/src/backend/catalog/storage.c
--- b/src/backend/catalog/storage.c
***************
*** 314,321 **** smgrDoPendingDeletes(bool isCommit)
  	PendingRelDelete *next;
  	int			nrels = 0,
  				i = 0,
! 				maxrels = 8;
! 	SMgrRelation *srels = palloc(maxrels * sizeof(SMgrRelation));
  
  	prev = NULL;
  	for (pending = pendingDeletes; pending != NULL; pending = next)
--- 314,321 ----
  	PendingRelDelete *next;
  	int			nrels = 0,
  				i = 0,
! 				maxrels = 0;
! 	SMgrRelation *srels = NULL;
  
  	prev = NULL;
  	for (pending = pendingDeletes; pending != NULL; pending = next)
***************
*** 340,347 **** smgrDoPendingDeletes(bool isCommit)
  
  				srel = smgropen(pending->relnode, pending->backend);
  
! 				/* extend the array if needed (double the size) */
! 				if (maxrels <= nrels)
  				{
  					maxrels *= 2;
  					srels = repalloc(srels, sizeof(SMgrRelation) * maxrels);
--- 340,352 ----
  
  				srel = smgropen(pending->relnode, pending->backend);
  
! 				/* allocate the initial array, or extend it, if needed */
! 				if (maxrels == 0)
! 				{
! 					maxrels = 8;
! 					srels = palloc(sizeof(SMgrRelation) * maxrels );
! 				}
! 				else if (maxrels <= nrels)
  				{
  					maxrels *= 2;
  					srels = repalloc(srels, sizeof(SMgrRelation) * maxrels);
***************
*** 361,370 **** smgrDoPendingDeletes(bool isCommit)
  
  		for (i = 0; i < nrels; i++)
  			smgrclose(srels[i]);
- 	}
- 
- 	pfree(srels);
  
  }
  
  /*
--- 366,374 ----
  
  		for (i = 0; i < nrels; i++)
  			smgrclose(srels[i]);
  
+ 		pfree(srels);
+ 	}
  }
  
  /*
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to