Bgwriter should PANIC if it runs out of memory for pending-fsyncs

hash table.  This is a pretty unlikely scenario, since the table
should be tiny, but we can't guarantee continued correct operation
if it does occur.  Spotted by Qingqing Zhou.
This commit is contained in:
Tom Lane 2005-05-28 17:21:32 +00:00
parent 6d9ee03148
commit f8a051604f
1 changed files with 14 additions and 2 deletions

View File

@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.15 2005/03/04 20:21:06 tgl Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.16 2005/05/28 17:21:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -616,7 +616,7 @@ ForwardFsyncRequest(RelFileNode rnode, BlockNumber segno)
* *
* This is exported because it must be called during CreateCheckPoint; * This is exported because it must be called during CreateCheckPoint;
* we have to be sure we have accepted all pending requests *after* we * we have to be sure we have accepted all pending requests *after* we
* establish the checkpoint redo pointer. Since CreateCheckPoint * establish the checkpoint REDO pointer. Since CreateCheckPoint
* sometimes runs in non-bgwriter processes, do nothing if not bgwriter. * sometimes runs in non-bgwriter processes, do nothing if not bgwriter.
*/ */
void void
@ -629,6 +629,15 @@ AbsorbFsyncRequests(void)
if (!am_bg_writer) if (!am_bg_writer)
return; 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 * We try to avoid holding the lock for a long time by copying the
* request array. * request array.
@ -647,6 +656,9 @@ AbsorbFsyncRequests(void)
for (request = requests; n > 0; request++, n--) for (request = requests; n > 0; request++, n--)
RememberFsyncRequest(request->rnode, request->segno); RememberFsyncRequest(request->rnode, request->segno);
if (requests) if (requests)
pfree(requests); pfree(requests);
END_CRIT_SECTION();
} }