diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2014-06-30 10:13:48 +0300 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2014-06-30 10:26:00 +0300 |
commit | 1c6821be31f91ab92547a8ed4246762c8cefb1b3 (patch) | |
tree | de5e845c96e8f37b7073708a5bdf9e6b81c6abc9 /src/backend/postmaster/checkpointer.c | |
parent | a749a23d7af4dba9b3468076ec561d2cbf69af09 (diff) | |
download | postgresql-1c6821be31f91ab92547a8ed4246762c8cefb1b3.tar.gz postgresql-1c6821be31f91ab92547a8ed4246762c8cefb1b3.zip |
Fix and enhance the assertion of no palloc's in a critical section.
The assertion failed if WAL_DEBUG or LWLOCK_STATS was enabled; fix that by
using separate memory contexts for the allocations made within those code
blocks.
This patch introduces a mechanism for marking any memory context as allowed
in a critical section. Previously ErrorContext was exempt as a special case.
Instead of a blanket exception of the checkpointer process, only exempt the
memory context used for the pending ops hash table.
Diffstat (limited to 'src/backend/postmaster/checkpointer.c')
-rw-r--r-- | src/backend/postmaster/checkpointer.c | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c index 2ac3061d974..6c814ba0be8 100644 --- a/src/backend/postmaster/checkpointer.c +++ b/src/backend/postmaster/checkpointer.c @@ -1305,19 +1305,6 @@ AbsorbFsyncRequests(void) if (!AmCheckpointerProcess()) return; - /* - * We have to PANIC if we fail to absorb all the pending requests (eg, - * because our hashtable runs out of memory). This is because the system - * cannot run safely if we are unable to fsync what we have been told to - * fsync. Fortunately, the hashtable is so small that the problem is - * quite unlikely to arise in practice. - */ - START_CRIT_SECTION(); - - /* - * We try to avoid holding the lock for a long time by copying the request - * array. - */ LWLockAcquire(CheckpointerCommLock, LW_EXCLUSIVE); /* Transfer stats counts into pending pgstats message */ @@ -1327,12 +1314,25 @@ AbsorbFsyncRequests(void) CheckpointerShmem->num_backend_writes = 0; CheckpointerShmem->num_backend_fsync = 0; + /* + * We try to avoid holding the lock for a long time by copying the request + * array, and processing the requests after releasing the lock. + * + * Once we have cleared the requests from shared memory, we have to PANIC + * if we then fail to absorb them (eg, because our hashtable runs out of + * memory). This is because the system cannot run safely if we are unable + * to fsync what we have been told to fsync. Fortunately, the hashtable + * is so small that the problem is quite unlikely to arise in practice. + */ n = CheckpointerShmem->num_requests; if (n > 0) { requests = (CheckpointerRequest *) palloc(n * sizeof(CheckpointerRequest)); memcpy(requests, CheckpointerShmem->requests, n * sizeof(CheckpointerRequest)); } + + START_CRIT_SECTION(); + CheckpointerShmem->num_requests = 0; LWLockRelease(CheckpointerCommLock); @@ -1340,10 +1340,10 @@ AbsorbFsyncRequests(void) for (request = requests; n > 0; request++, n--) RememberFsyncRequest(request->rnode, request->forknum, request->segno); + END_CRIT_SECTION(); + if (requests) pfree(requests); - - END_CRIT_SECTION(); } /* |