Search Postgresql Archives

Re: Autovacuum daemon terminated by signal 11

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Tom Lane wrote:

> What is happening is that autovacuum_do_vac_analyze contains
> 
> 	old_cxt = MemoryContextSwitchTo(AutovacMemCxt);
> 	...
> 	vacuum(vacstmt, relids);
> 	...
> 	MemoryContextSwitchTo(old_cxt);
> 
> and at the time it is called by process_whole_db, CurrentMemoryContext
> points at TopTransactionContext.  Which gets destroyed because vacuum()
> internally finishes that transaction and starts a new one.  When we
> come out of vacuum(), CurrentMemoryContext again points at
> TopTransactionContext, but *its not the same one*.  The closing
> MemoryContextSwitchTo is installing a stale pointer, which then remains
> active into CommitTransaction.  It's a wonder this code ever works.

Hmm, in retrospect this is pretty obviously buggy.  I can't say that
it's that easy for me to reproduce it though; I definitely can't make it
crash.  Maybe by sheer luck, the new TopTransactionContext pointer
points to the same memory area that the old was stored in.

I think this patch should fix it.  Justin, would you try it and report
back?  I would commit it right away since it seems simple enough, but
since I can't reproduce the crash, I prefer external confirmation first
:-)

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Index: src/backend/postmaster/autovacuum.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/postmaster/autovacuum.c,v
retrieving revision 1.5.2.8
diff -c -p -r1.5.2.8 autovacuum.c
*** src/backend/postmaster/autovacuum.c	17 Jan 2008 23:47:07 -0000	1.5.2.8
--- src/backend/postmaster/autovacuum.c	17 Jan 2009 04:08:44 -0000
*************** autovacuum_do_vac_analyze(List *relids, 
*** 925,937 ****
  						  bool freeze)
  {
  	VacuumStmt *vacstmt;
- 	MemoryContext old_cxt;
  
  	/*
  	 * The node must survive transaction boundaries, so make sure we create it
  	 * in a long-lived context
  	 */
! 	old_cxt = MemoryContextSwitchTo(AutovacMemCxt);
  
  	vacstmt = makeNode(VacuumStmt);
  
--- 925,936 ----
  						  bool freeze)
  {
  	VacuumStmt *vacstmt;
  
  	/*
  	 * The node must survive transaction boundaries, so make sure we create it
  	 * in a long-lived context
  	 */
! 	MemoryContextSwitchTo(AutovacMemCxt);
  
  	vacstmt = makeNode(VacuumStmt);
  
*************** autovacuum_do_vac_analyze(List *relids, 
*** 957,963 ****
  	vacuum(vacstmt, relids);
  
  	pfree(vacstmt);
! 	MemoryContextSwitchTo(old_cxt);
  }
  
  /*
--- 956,964 ----
  	vacuum(vacstmt, relids);
  
  	pfree(vacstmt);
! 
! 	/* Make sure we end up pointing to a valid memory context at exit */
! 	MemoryContextSwitchTo(TopTransactionContext);
  }
  
  /*
-- 
Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux