0001-Release-SLRU-control-lock-before-reporting-I-O-error.patch
text/x-patch
Filename: 0001-Release-SLRU-control-lock-before-reporting-I-O-error.patch
Type: text/x-patch
Part: 0
Patch
Format: format-patch
Series: patch 0001
Subject: Release SLRU control lock before reporting I/O error
| File | + | − |
|---|---|---|
| src/backend/access/transam/slru.c | 13 | 4 |
From 0b928fb91b5b3aa527372495e9fa4778c5b5bfab Mon Sep 17 00:00:00 2001
From: Craig Ringer <craig@2ndquadrant.com>
Date: Thu, 25 Aug 2016 10:59:57 +0800
Subject: [PATCH 1/4] Release SLRU control lock before reporting I/O error
To allow callers to trap SLRU I/O errors with a PG_TRY() / PG_CATCH() block,
slru.c functions that acquire the SLRU control lock now also release the SLRU
control LWLock before reporting I/O errors.
Many SLRU functions previously took the LWLock and threw exceptions with it
still held.
---
src/backend/access/transam/slru.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index bbae584..f020522 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -366,7 +366,8 @@ SimpleLruWaitIO(SlruCtl ctl, int slotno)
* Return value is the shared-buffer slot number now holding the page.
* The buffer's LRU access info is updated.
*
- * Control lock must be held at entry, and will be held at exit.
+ * Control lock must be held at entry, and will be held at normal exit.
+ * The control lock is released if an exception is thrown.
*/
int
SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok,
@@ -439,7 +440,10 @@ SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok,
/* Now it's okay to ereport if we failed */
if (!ok)
+ {
+ LWLockRelease(shared->ControlLock);
SlruReportIOError(ctl, pageno, xid);
+ }
SlruRecentlyUsed(shared, slotno);
return slotno;
@@ -457,8 +461,9 @@ SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok,
* Return value is the shared-buffer slot number now holding the page.
* The buffer's LRU access info is updated.
*
- * Control lock must NOT be held at entry, but will be held at exit.
- * It is unspecified whether the lock will be shared or exclusive.
+ * Control lock must NOT be held at entry, but will be held at exit
+ * unless an exception is thrown. It is unspecified whether the lock
+ * will be shared or exclusive.
*/
int
SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid)
@@ -498,7 +503,8 @@ SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid)
* the write). However, we *do* attempt a fresh write even if the page
* is already being written; this is for checkpoints.
*
- * Control lock must be held at entry, and will be held at exit.
+ * Control lock must be held at entry, and will be held at normal exit.
+ * The lock is released if an exception is thrown.
*/
static void
SlruInternalWritePage(SlruCtl ctl, int slotno, SlruFlush fdata)
@@ -564,7 +570,10 @@ SlruInternalWritePage(SlruCtl ctl, int slotno, SlruFlush fdata)
/* Now it's okay to ereport if we failed */
if (!ok)
+ {
+ LWLockRelease(shared->ControlLock);
SlruReportIOError(ctl, pageno, InvalidTransactionId);
+ }
}
/*
--
2.5.5