Re: backend dies suddenly after a lot of error messages
От | Tom Lane |
---|---|
Тема | Re: backend dies suddenly after a lot of error messages |
Дата | |
Msg-id | 14059.926644574@sss.pgh.pa.us обсуждение исходный текст |
Ответ на | backend dies suddenly after a lot of error messages (Mirko Kaffka <mirko@interface-business.de>) |
Список | pgsql-general |
Mirko Kaffka <mirko@interface-business.de> wrote: > We have problems with backend processes that close the channel because of > palloc() failures. When an INSERT statement fails, the backend reports an > error (e.g. `Cannot insert a duplicate key into a unique index') and > allocates a few bytes more memory. The next SQL statement that fails > causes the backend to allocate more memory again, etc. until we have no > more virtual memory left. Is this a bug? > We are using postgres 6.4.2 on FreeBSD 2.2.8. I have found the primary cause of memory leakage after an error --- basically, the backend forgets to free *any* of the temporary memory allocated up to the point of the error :-(. If your applications tend to provoke many SQL errors then you will see a backend process that eats up more and more memory until it hits your local system's process size limit, whereupon it crashes. I have repaired this problem in the 6.5 development sources. Attached is a patch for 6.4.2, which I suggest you apply if this sounds like a problem you are having. The patch does not completely eliminate memory leaks after errors, but they seem to be reduced to the few-hundred-bytes-per-error range instead of the kilobytes (potentially lots of kilobytes) range. I am working on curing the problem more completely for 6.5. regards, tom lane *** src/backend/access/transam/xact.c.orig Thu Oct 8 14:29:15 1998 --- src/backend/access/transam/xact.c Thu May 13 18:53:05 1999 *************** *** 767,776 **** static void AtAbort_Memory() { /* ---------------- ! * after doing an abort transaction, make certain the ! * system uses the top memory context rather then the ! * portal memory context (until the next transaction). * ---------------- */ MemoryContextSwitchTo(TopMemoryContext); --- 767,791 ---- static void AtAbort_Memory() { + Portal portal; + MemoryContext portalContext; + /* ---------------- ! * Release memory in the blank portal. ! * Since EndPortalAllocMode implicitly works on the current context, ! * first make real sure that the blank portal is the selected context. ! * (This is ESSENTIAL in case we aborted from someplace where it wasn't.) ! * ---------------- ! */ ! portal = GetPortalByName(NULL); ! portalContext = (MemoryContext) PortalGetHeapMemory(portal); ! MemoryContextSwitchTo(portalContext); ! EndPortalAllocMode(); ! ! /* ---------------- ! * Now that we're "out" of a transaction, have the ! * system allocate things in the top memory context instead ! * of the blank portal memory context. * ---------------- */ MemoryContextSwitchTo(TopMemoryContext);
В списке pgsql-general по дате отправления: