aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/storage/buffer/bufmgr.c70
1 files changed, 64 insertions, 6 deletions
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 119cfe92b0d..89087f0fb87 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.135 2003/03/28 20:17:13 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.136 2003/05/10 19:04:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -68,6 +68,7 @@ static void WaitIO(BufferDesc *buf);
static void StartBufferIO(BufferDesc *buf, bool forInput);
static void TerminateBufferIO(BufferDesc *buf);
static void ContinueBufferIO(BufferDesc *buf, bool forInput);
+static void buffer_write_error_callback(void *arg);
/*
* Macro : BUFFER_IS_BROKEN
@@ -699,14 +700,24 @@ BufferSync(void)
{
int i;
BufferDesc *bufHdr;
- Buffer buffer;
- int status;
- RelFileNode rnode;
- XLogRecPtr recptr;
- Relation reln = NULL;
+ ErrorContextCallback errcontext;
+
+ /* Setup error traceback support for ereport() */
+ errcontext.callback = buffer_write_error_callback;
+ errcontext.arg = NULL;
+ errcontext.previous = error_context_stack;
+ error_context_stack = &errcontext;
for (i = 0, bufHdr = BufferDescriptors; i < NBuffers; i++, bufHdr++)
{
+ Buffer buffer;
+ int status;
+ RelFileNode rnode;
+ XLogRecPtr recptr;
+ Relation reln;
+
+ errcontext.arg = bufHdr;
+
LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
if (!(bufHdr->flags & BM_VALID))
@@ -834,6 +845,8 @@ BufferSync(void)
RelationDecrementReferenceCount(reln);
}
+ /* Pop the error context stack */
+ error_context_stack = errcontext.previous;
}
/*
@@ -1011,12 +1024,19 @@ BufferReplace(BufferDesc *bufHdr)
Relation reln;
XLogRecPtr recptr;
int status;
+ ErrorContextCallback errcontext;
/* To check if block content changed while flushing. - vadim 01/17/97 */
bufHdr->flags &= ~BM_JUST_DIRTIED;
LWLockRelease(BufMgrLock);
+ /* Setup error traceback support for ereport() */
+ errcontext.callback = buffer_write_error_callback;
+ errcontext.arg = bufHdr;
+ errcontext.previous = error_context_stack;
+ error_context_stack = &errcontext;
+
/*
* No need to lock buffer context - no one should be able to end
* ReadBuffer
@@ -1043,6 +1063,9 @@ BufferReplace(BufferDesc *bufHdr)
if (reln != (Relation) NULL)
RelationDecrementReferenceCount(reln);
+ /* Pop the error context stack */
+ error_context_stack = errcontext.previous;
+
LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
if (status == SM_FAIL)
@@ -1380,12 +1403,20 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
BufferDesc *bufHdr;
XLogRecPtr recptr;
int status;
+ ErrorContextCallback errcontext;
+
+ /* Setup error traceback support for ereport() */
+ errcontext.callback = buffer_write_error_callback;
+ errcontext.arg = NULL;
+ errcontext.previous = error_context_stack;
+ error_context_stack = &errcontext;
if (rel->rd_istemp)
{
for (i = 0; i < NLocBuffer; i++)
{
bufHdr = &LocalBufferDescriptors[i];
+ errcontext.arg = bufHdr;
if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
{
if (bufHdr->flags & BM_DIRTY || bufHdr->cntxDirty)
@@ -1395,6 +1426,7 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
(char *) MAKE_PTR(bufHdr->data));
if (status == SM_FAIL)
{
+ error_context_stack = errcontext.previous;
elog(WARNING, "FlushRelationBuffers(%s (local), %u): block %u is dirty, could not flush it",
RelationGetRelationName(rel), firstDelBlock,
bufHdr->tag.blockNum);
@@ -1405,6 +1437,7 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
}
if (LocalRefCount[i] > 0)
{
+ error_context_stack = errcontext.previous;
elog(WARNING, "FlushRelationBuffers(%s (local), %u): block %u is referenced (%ld)",
RelationGetRelationName(rel), firstDelBlock,
bufHdr->tag.blockNum, LocalRefCount[i]);
@@ -1414,6 +1447,10 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
bufHdr->tag.rnode.relNode = InvalidOid;
}
}
+
+ /* Pop the error context stack */
+ error_context_stack = errcontext.previous;
+
return 0;
}
@@ -1422,6 +1459,7 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
for (i = 0; i < NBuffers; i++)
{
bufHdr = &BufferDescriptors[i];
+ errcontext.arg = bufHdr;
if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
{
if (bufHdr->flags & BM_DIRTY || bufHdr->cntxDirty)
@@ -1483,6 +1521,7 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
if (!(bufHdr->flags & BM_FREE))
{
LWLockRelease(BufMgrLock);
+ error_context_stack = errcontext.previous;
elog(WARNING, "FlushRelationBuffers(%s, %u): block %u is referenced (private %ld, global %d)",
RelationGetRelationName(rel), firstDelBlock,
bufHdr->tag.blockNum,
@@ -1493,7 +1532,12 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
BufTableDelete(bufHdr);
}
}
+
LWLockRelease(BufMgrLock);
+
+ /* Pop the error context stack */
+ error_context_stack = errcontext.previous;
+
return 0;
}
@@ -2083,3 +2127,17 @@ BufferGetFileNode(Buffer buffer)
return (bufHdr->tag.rnode);
}
+
+/*
+ * Error context callback for errors occurring during buffer writes.
+ */
+static void
+buffer_write_error_callback(void *arg)
+{
+ BufferDesc *bufHdr = (BufferDesc *) arg;
+
+ if (bufHdr != NULL)
+ errcontext("writing block %u of relation %u/%u",
+ bufHdr->tag.blockNum,
+ bufHdr->tag.rnode.tblNode, bufHdr->tag.rnode.relNode);
+}