Fix bgwriter's failure to release buffer pins and open files after an

error.  This probably explains bug #2099 and could also account for
mysterious VACUUM hangups.
This commit is contained in:
Tom Lane 2005-12-08 19:19:22 +00:00
parent 96e1fbe396
commit aaa3dfd26c
2 changed files with 21 additions and 6 deletions

View File

@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.21 2005/10/15 02:49:23 momjian Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.22 2005/12/08 19:19:22 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -51,6 +51,7 @@
#include "miscadmin.h" #include "miscadmin.h"
#include "postmaster/bgwriter.h" #include "postmaster/bgwriter.h"
#include "storage/bufmgr.h" #include "storage/bufmgr.h"
#include "storage/fd.h"
#include "storage/freespace.h" #include "storage/freespace.h"
#include "storage/ipc.h" #include "storage/ipc.h"
#include "storage/pmsignal.h" #include "storage/pmsignal.h"
@ -58,6 +59,7 @@
#include "tcop/tcopprot.h" #include "tcop/tcopprot.h"
#include "utils/guc.h" #include "utils/guc.h"
#include "utils/memutils.h" #include "utils/memutils.h"
#include "utils/resowner.h"
/*---------- /*----------
@ -208,6 +210,12 @@ BackgroundWriterMain(void)
*/ */
last_checkpoint_time = time(NULL); last_checkpoint_time = time(NULL);
/*
* Create a resource owner to keep track of our resources (currently
* only buffer pins).
*/
CurrentResourceOwner = ResourceOwnerCreate(NULL, "Background Writer");
/* /*
* Create a memory context that we will do all our work in. We do this so * Create a memory context that we will do all our work in. We do this so
* that we can reset the context during error recovery and thereby avoid * that we can reset the context during error recovery and thereby avoid
@ -240,11 +248,18 @@ BackgroundWriterMain(void)
/* /*
* These operations are really just a minimal subset of * These operations are really just a minimal subset of
* AbortTransaction(). We don't have very many resources to worry * AbortTransaction(). We don't have very many resources to worry
* about in bgwriter, but we do have LWLocks and buffers. * about in bgwriter, but we do have LWLocks, buffers, and temp files.
*/ */
LWLockReleaseAll(); LWLockReleaseAll();
AbortBufferIO(); AbortBufferIO();
UnlockBuffers(); UnlockBuffers();
/* buffer pins are released here: */
ResourceOwnerRelease(CurrentResourceOwner,
RESOURCE_RELEASE_BEFORE_LOCKS,
false, true);
/* we needn't bother with the other ResourceOwnerRelease phases */
AtEOXact_Buffers(false);
AtEOXact_Files();
/* Warn any waiting backends that the checkpoint failed. */ /* Warn any waiting backends that the checkpoint failed. */
if (ckpt_active) if (ckpt_active)

View File

@ -14,7 +14,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/resowner/resowner.c,v 1.16 2005/11/22 18:17:27 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/resowner/resowner.c,v 1.17 2005/12/08 19:19:22 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -437,7 +437,7 @@ UnregisterResourceReleaseCallback(ResourceReleaseCallback callback, void *arg)
* of memory, it's critical to do so *before* acquiring the resource. * of memory, it's critical to do so *before* acquiring the resource.
* *
* We allow the case owner == NULL because the bufmgr is sometimes invoked * We allow the case owner == NULL because the bufmgr is sometimes invoked
* outside any transaction (for example, in the bgwriter). * outside any transaction (for example, during WAL recovery).
*/ */
void void
ResourceOwnerEnlargeBuffers(ResourceOwner owner) ResourceOwnerEnlargeBuffers(ResourceOwner owner)
@ -470,7 +470,7 @@ ResourceOwnerEnlargeBuffers(ResourceOwner owner)
* Caller must have previously done ResourceOwnerEnlargeBuffers() * Caller must have previously done ResourceOwnerEnlargeBuffers()
* *
* We allow the case owner == NULL because the bufmgr is sometimes invoked * We allow the case owner == NULL because the bufmgr is sometimes invoked
* outside any transaction (for example, in the bgwriter). * outside any transaction (for example, during WAL recovery).
*/ */
void void
ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer) ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer)
@ -487,7 +487,7 @@ ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer)
* Forget that a buffer pin is owned by a ResourceOwner * Forget that a buffer pin is owned by a ResourceOwner
* *
* We allow the case owner == NULL because the bufmgr is sometimes invoked * We allow the case owner == NULL because the bufmgr is sometimes invoked
* outside any transaction (for example, in the bgwriter). * outside any transaction (for example, during WAL recovery).
*/ */
void void
ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer) ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer)