mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Repair possible failure to update hint bits back to disk, per
http://archives.postgresql.org/pgsql-hackers/2004-10/msg00464.php. This fix is intended to be permanent: it moves the responsibility for calling SetBufferCommitInfoNeedsSave() into the tqual.c routines, eliminating the requirement for callers to test whether t_infomask changed. Also, tighten validity checking on buffer IDs in bufmgr.c --- several routines were paranoid about out-of-range shared buffer numbers but not about out-of-range local ones, which seems a tad pointless.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.177 2004/09/06 17:31:32 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.178 2004/10/15 22:39:59 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -477,15 +477,15 @@ write_buffer(Buffer buffer, bool release)
|
||||
{
|
||||
BufferDesc *bufHdr;
|
||||
|
||||
if (!BufferIsValid(buffer))
|
||||
elog(ERROR, "bad buffer id: %d", buffer);
|
||||
|
||||
if (BufferIsLocal(buffer))
|
||||
{
|
||||
WriteLocalBuffer(buffer, release);
|
||||
return;
|
||||
}
|
||||
|
||||
if (BAD_BUFFER_ID(buffer))
|
||||
elog(ERROR, "bad buffer id: %d", buffer);
|
||||
|
||||
bufHdr = &BufferDescriptors[buffer - 1];
|
||||
|
||||
Assert(PrivateRefCount[buffer - 1] > 0);
|
||||
@ -1465,6 +1465,9 @@ ReleaseBuffer(Buffer buffer)
|
||||
{
|
||||
BufferDesc *bufHdr;
|
||||
|
||||
if (!BufferIsValid(buffer))
|
||||
elog(ERROR, "bad buffer id: %d", buffer);
|
||||
|
||||
ResourceOwnerForgetBuffer(CurrentResourceOwner, buffer);
|
||||
|
||||
if (BufferIsLocal(buffer))
|
||||
@ -1474,9 +1477,6 @@ ReleaseBuffer(Buffer buffer)
|
||||
return;
|
||||
}
|
||||
|
||||
if (BAD_BUFFER_ID(buffer))
|
||||
elog(ERROR, "bad buffer id: %d", buffer);
|
||||
|
||||
bufHdr = &BufferDescriptors[buffer - 1];
|
||||
|
||||
Assert(PrivateRefCount[buffer - 1] > 0);
|
||||
@ -1503,17 +1503,16 @@ ReleaseBuffer(Buffer buffer)
|
||||
void
|
||||
IncrBufferRefCount(Buffer buffer)
|
||||
{
|
||||
Assert(BufferIsValid(buffer));
|
||||
ResourceOwnerEnlargeBuffers(CurrentResourceOwner);
|
||||
ResourceOwnerRememberBuffer(CurrentResourceOwner, buffer);
|
||||
if (BufferIsLocal(buffer))
|
||||
{
|
||||
Assert(buffer >= -NLocBuffer);
|
||||
Assert(LocalRefCount[-buffer - 1] > 0);
|
||||
LocalRefCount[-buffer - 1]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert(!BAD_BUFFER_ID(buffer));
|
||||
Assert(PrivateRefCount[buffer - 1] > 0);
|
||||
PrivateRefCount[buffer - 1]++;
|
||||
}
|
||||
@ -1606,9 +1605,12 @@ ReleaseAndReadBuffer_Debug(char *file,
|
||||
*
|
||||
* Mark a buffer dirty when we have updated tuple commit-status bits in it.
|
||||
*
|
||||
* This is similar to WriteNoReleaseBuffer, except that we have not made a
|
||||
* critical change that has to be flushed to disk before xact commit --- the
|
||||
* status-bit update could be redone by someone else just as easily.
|
||||
* This is essentially the same as WriteNoReleaseBuffer. We preserve the
|
||||
* distinction as a way of documenting that the caller has not made a critical
|
||||
* data change --- the status-bit update could be redone by someone else just
|
||||
* as easily. Therefore, no WAL log record need be generated, whereas calls
|
||||
* to WriteNoReleaseBuffer really ought to be associated with a WAL-entry-
|
||||
* creating action.
|
||||
*
|
||||
* This routine might get called many times on the same page, if we are making
|
||||
* the first scan after commit of an xact that added/deleted many tuples.
|
||||
@ -1623,15 +1625,15 @@ SetBufferCommitInfoNeedsSave(Buffer buffer)
|
||||
{
|
||||
BufferDesc *bufHdr;
|
||||
|
||||
if (!BufferIsValid(buffer))
|
||||
elog(ERROR, "bad buffer id: %d", buffer);
|
||||
|
||||
if (BufferIsLocal(buffer))
|
||||
{
|
||||
WriteLocalBuffer(buffer, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (BAD_BUFFER_ID(buffer))
|
||||
elog(ERROR, "bad buffer id: %d", buffer);
|
||||
|
||||
bufHdr = &BufferDescriptors[buffer - 1];
|
||||
|
||||
if ((bufHdr->flags & (BM_DIRTY | BM_JUST_DIRTIED)) !=
|
||||
@ -1662,7 +1664,6 @@ UnlockBuffers(void)
|
||||
if (buflocks == 0)
|
||||
continue;
|
||||
|
||||
Assert(BufferIsValid(i + 1));
|
||||
buf = &(BufferDescriptors[i]);
|
||||
|
||||
HOLD_INTERRUPTS(); /* don't want to die() partway through... */
|
||||
|
Reference in New Issue
Block a user