mirror of
https://github.com/postgres/postgres.git
synced 2025-09-02 04:21:28 +03:00
Per previous discussions, get rid of use of sync(2) in favor of
explicitly fsync'ing every (non-temp) file we have written since the last checkpoint. In the vast majority of cases, the burden of the fsyncs should fall on the bgwriter process not on backends. (To this end, we assume that an fsync issued by the bgwriter will force out blocks written to the same file by other processes using other file descriptors. Anyone have a problem with that?) This makes the world safe for WIN32, which ain't even got sync(2), and really makes the world safe for Unixen as well, because sync(2) never had the semantics we need: it offers no way to wait for the requested I/O to finish. Along the way, fix a bug I recently introduced in xlog recovery: file truncation replay failed to clear bufmgr buffers for the dropped blocks, which could result in 'PANIC: heap_delete_redo: no block' later on in xlog replay.
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.70 2004/02/11 22:55:25 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.71 2004/05/31 03:48:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -56,7 +56,7 @@ typedef struct f_smgr
|
||||
static const f_smgr smgrsw[] = {
|
||||
/* magnetic disk */
|
||||
{mdinit, NULL, mdclose, mdcreate, mdunlink, mdextend,
|
||||
mdread, mdwrite, mdnblocks, mdtruncate, mdcommit, mdabort, mdsync
|
||||
mdread, mdwrite, mdnblocks, mdtruncate, NULL, NULL, mdsync
|
||||
}
|
||||
};
|
||||
|
||||
@@ -407,7 +407,7 @@ smgr_internal_unlink(RelFileNode rnode, int which, bool isTemp, bool isRedo)
|
||||
* Get rid of any leftover buffers for the rel (shouldn't be any in the
|
||||
* commit case, but there can be in the abort case).
|
||||
*/
|
||||
DropRelFileNodeBuffers(rnode, isTemp);
|
||||
DropRelFileNodeBuffers(rnode, isTemp, 0);
|
||||
|
||||
/*
|
||||
* Tell the free space map to forget this relation. It won't be accessed
|
||||
@@ -638,7 +638,7 @@ smgrcommit(void)
|
||||
if (smgrsw[i].smgr_commit)
|
||||
{
|
||||
if (! (*(smgrsw[i].smgr_commit)) ())
|
||||
elog(FATAL, "transaction commit failed on %s: %m",
|
||||
elog(ERROR, "transaction commit failed on %s: %m",
|
||||
DatumGetCString(DirectFunctionCall1(smgrout,
|
||||
Int16GetDatum(i))));
|
||||
}
|
||||
@@ -658,7 +658,7 @@ smgrabort(void)
|
||||
if (smgrsw[i].smgr_abort)
|
||||
{
|
||||
if (! (*(smgrsw[i].smgr_abort)) ())
|
||||
elog(FATAL, "transaction abort failed on %s: %m",
|
||||
elog(ERROR, "transaction abort failed on %s: %m",
|
||||
DatumGetCString(DirectFunctionCall1(smgrout,
|
||||
Int16GetDatum(i))));
|
||||
}
|
||||
@@ -678,7 +678,7 @@ smgrsync(void)
|
||||
if (smgrsw[i].smgr_sync)
|
||||
{
|
||||
if (! (*(smgrsw[i].smgr_sync)) ())
|
||||
elog(PANIC, "storage sync failed on %s: %m",
|
||||
elog(ERROR, "storage sync failed on %s: %m",
|
||||
DatumGetCString(DirectFunctionCall1(smgrout,
|
||||
Int16GetDatum(i))));
|
||||
}
|
||||
@@ -707,6 +707,13 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
|
||||
|
||||
reln = smgropen(xlrec->rnode);
|
||||
|
||||
/*
|
||||
* First, force bufmgr to drop any buffers it has for the to-be-
|
||||
* truncated blocks. We must do this, else subsequent XLogReadBuffer
|
||||
* operations will not re-extend the file properly.
|
||||
*/
|
||||
DropRelFileNodeBuffers(xlrec->rnode, false, xlrec->blkno);
|
||||
|
||||
/* Can't use smgrtruncate because it would try to xlog */
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user