From aaa3dfd26c22be1848c1f613171aca4e588e431c Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 8 Dec 2005 19:19:22 +0000 Subject: [PATCH] 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. --- src/backend/postmaster/bgwriter.c | 19 +++++++++++++++++-- src/backend/utils/resowner/resowner.c | 8 ++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c index 78fecf4dd6..c9a8baf25a 100644 --- a/src/backend/postmaster/bgwriter.c +++ b/src/backend/postmaster/bgwriter.c @@ -37,7 +37,7 @@ * * * 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 "postmaster/bgwriter.h" #include "storage/bufmgr.h" +#include "storage/fd.h" #include "storage/freespace.h" #include "storage/ipc.h" #include "storage/pmsignal.h" @@ -58,6 +59,7 @@ #include "tcop/tcopprot.h" #include "utils/guc.h" #include "utils/memutils.h" +#include "utils/resowner.h" /*---------- @@ -208,6 +210,12 @@ BackgroundWriterMain(void) */ 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 * 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 * 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(); AbortBufferIO(); 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. */ if (ckpt_active) diff --git a/src/backend/utils/resowner/resowner.c b/src/backend/utils/resowner/resowner.c index 19c7f8ea8b..d9c830dfc1 100644 --- a/src/backend/utils/resowner/resowner.c +++ b/src/backend/utils/resowner/resowner.c @@ -14,7 +14,7 @@ * * * 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. * * 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 ResourceOwnerEnlargeBuffers(ResourceOwner owner) @@ -470,7 +470,7 @@ ResourceOwnerEnlargeBuffers(ResourceOwner owner) * Caller must have previously done ResourceOwnerEnlargeBuffers() * * 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 ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer) @@ -487,7 +487,7 @@ ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer) * Forget that a buffer pin is owned by a ResourceOwner * * 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 ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer)