Tom Lane wrote: > Alvaro Herrera <alvhe...@commandprompt.com> 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 (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers