From f8a051604fcf4fe718e84c51704bf9e3d14628fe Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 28 May 2005 17:21:32 +0000
Subject: [PATCH] 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.

---
 src/backend/postmaster/bgwriter.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index 09775bd32ad..0cd694ef529 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.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;
  * 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.
  */
 void
@@ -629,6 +629,15 @@ AbsorbFsyncRequests(void)
 	if (!am_bg_writer)
 		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.
@@ -647,6 +656,9 @@ AbsorbFsyncRequests(void)
 
 	for (request = requests; n > 0; request++, n--)
 		RememberFsyncRequest(request->rnode, request->segno);
+
 	if (requests)
 		pfree(requests);
+
+	END_CRIT_SECTION();
 }
-- 
GitLab