Tom Lane wrote:
> Alvaro Herrera <[email protected]> writes:
> > Some time ago I noticed that in postmaster.c there's a corner case which
> > probably causes postmaster to exit in out-of-memory condition. See
> > BackendStartup, near the bottom, there's a call to DLNewElem(). The
> > problem is that this function calls palloc() and thus can elog(ERROR) on
> > OOM, but postmaster has no way to defend itself from this and would die.
>
> So? There are probably hundreds of palloc calls that are reachable from
> the postmaster main loop. If this were allocating more than a few bytes
> of memory, it might be worth worrying about.
Hundreds? I think you'd be hard pressed to find as much as a dozen :-)
I mean stuff that's called inside ServerLoop, of course. There are a
few places calling alloc-type functions, but as far as I see they use
calloc or malloc, and behave "sanely" (i.e. not elog(ERROR)) in OOM.
Note that BackendStartup itself is very careful about allocating a
Backend struct, even when it's just ~10 bytes on 32 bits machines.
I think a patch to solve this is as simple as the attached.
--
Alvaro Herrera http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/postmaster/postmaster.c,v
retrieving revision 1.551.2.1
diff -c -p -r1.551.2.1 postmaster.c
*** src/backend/postmaster/postmaster.c 27 Jun 2008 01:53:31 -0000 1.551.2.1
--- src/backend/postmaster/postmaster.c 6 Apr 2009 23:14:00 -0000
*************** BackendStartup(Port *port)
*** 2774,2779 ****
--- 2774,2780 ----
{
Backend *bn; /* for backend cleanup */
pid_t pid;
+ Dlelem *newel;
/*
* Compute the cancel key that will be assigned to this backend. The
*************** BackendStartup(Port *port)
*** 2794,2799 ****
--- 2795,2818 ----
errmsg("out of memory")));
return STATUS_ERROR;
}
+ PG_TRY();
+ {
+ newel = DLNewElem(bn);
+ elog(ERROR, "out of luck :-(");
+ }
+ PG_CATCH();
+ {
+ /*
+ * it would be great if we could just reduce the error severity of the
+ * current error
+ */
+ FlushErrorState();
+ ereport(LOG,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+ return STATUS_ERROR;
+ }
+ PG_END_TRY();
/* Pass down canAcceptConnections state (kluge for EXEC_BACKEND case) */
port->canAcceptConnections = canAcceptConnections();
*************** BackendStartup(Port *port)
*** 2857,2863 ****
bn->cancel_key = MyCancelKey;
bn->is_autovacuum = false;
bn->dead_end = (port->canAcceptConnections != CAC_OK);
! DLAddHead(BackendList, DLNewElem(bn));
#ifdef EXEC_BACKEND
if (!bn->dead_end)
ShmemBackendArrayAdd(bn);
--- 2876,2883 ----
bn->cancel_key = MyCancelKey;
bn->is_autovacuum = false;
bn->dead_end = (port->canAcceptConnections != CAC_OK);
!
! DLAddHead(BackendList, newel);
#ifdef EXEC_BACKEND
if (!bn->dead_end)
ShmemBackendArrayAdd(bn);
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers