Commit 91d20ff7 authored by Tom Lane's avatar Tom Lane

Additional mop-up for sync-to-fsync changes: avoid issuing fsyncs for

temp tables, and avoid WAL-logging truncations of temp tables.  Do issue
fsync on truncated files (not sure this is necessary but it seems like
a good idea).
parent e6747079
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.168 2004/05/31 19:24:05 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.169 2004/05/31 20:31:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -182,7 +182,8 @@ ReadBufferInternal(Relation reln, BlockNumber blockNum, ...@@ -182,7 +182,8 @@ ReadBufferInternal(Relation reln, BlockNumber blockNum,
{ {
/* new buffers are zero-filled */ /* new buffers are zero-filled */
MemSet((char *) MAKE_PTR(bufHdr->data), 0, BLCKSZ); MemSet((char *) MAKE_PTR(bufHdr->data), 0, BLCKSZ);
smgrextend(reln->rd_smgr, blockNum, (char *) MAKE_PTR(bufHdr->data)); smgrextend(reln->rd_smgr, blockNum, (char *) MAKE_PTR(bufHdr->data),
reln->rd_istemp);
} }
else else
{ {
...@@ -915,8 +916,8 @@ BufferGetFileNode(Buffer buffer) ...@@ -915,8 +916,8 @@ BufferGetFileNode(Buffer buffer)
* NOTE: this actually just passes the buffer contents to the kernel; the * NOTE: this actually just passes the buffer contents to the kernel; the
* real write to disk won't happen until the kernel feels like it. This * real write to disk won't happen until the kernel feels like it. This
* is okay from our point of view since we can redo the changes from WAL. * is okay from our point of view since we can redo the changes from WAL.
* However, we will need to force the changes to disk via sync/fsync * However, we will need to force the changes to disk via fsync before
* before we can checkpoint WAL. * we can checkpoint WAL.
* *
* BufMgrLock must be held at entry, and the buffer must be pinned. The * BufMgrLock must be held at entry, and the buffer must be pinned. The
* caller is also responsible for doing StartBufferIO/TerminateBufferIO. * caller is also responsible for doing StartBufferIO/TerminateBufferIO.
...@@ -979,7 +980,8 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln) ...@@ -979,7 +980,8 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
*/ */
smgrwrite(reln, smgrwrite(reln,
buf->tag.blockNum, buf->tag.blockNum,
(char *) MAKE_PTR(buf->data)); (char *) MAKE_PTR(buf->data),
false);
/* Pop the error context stack */ /* Pop the error context stack */
error_context_stack = errcontext.previous; error_context_stack = errcontext.previous;
...@@ -1033,7 +1035,7 @@ RelationTruncate(Relation rel, BlockNumber nblocks) ...@@ -1033,7 +1035,7 @@ RelationTruncate(Relation rel, BlockNumber nblocks)
rel->rd_targblock = InvalidBlockNumber; rel->rd_targblock = InvalidBlockNumber;
/* Do the real work */ /* Do the real work */
smgrtruncate(rel->rd_smgr, nblocks); smgrtruncate(rel->rd_smgr, nblocks, rel->rd_istemp);
} }
/* --------------------------------------------------------------------- /* ---------------------------------------------------------------------
...@@ -1351,7 +1353,8 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock) ...@@ -1351,7 +1353,8 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
smgrwrite(rel->rd_smgr, smgrwrite(rel->rd_smgr,
bufHdr->tag.blockNum, bufHdr->tag.blockNum,
(char *) MAKE_PTR(bufHdr->data)); (char *) MAKE_PTR(bufHdr->data),
true);
bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED); bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
bufHdr->cntxDirty = false; bufHdr->cntxDirty = false;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.54 2004/04/22 07:21:55 neilc Exp $ * $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.55 2004/05/31 20:31:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -111,7 +111,8 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr) ...@@ -111,7 +111,8 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
/* And write... */ /* And write... */
smgrwrite(reln, smgrwrite(reln,
bufHdr->tag.blockNum, bufHdr->tag.blockNum,
(char *) MAKE_PTR(bufHdr->data)); (char *) MAKE_PTR(bufHdr->data),
true);
LocalBufferFlushCount++; LocalBufferFlushCount++;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/smgr/md.c,v 1.105 2004/05/31 03:48:06 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/smgr/md.c,v 1.106 2004/05/31 20:31:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -270,7 +270,7 @@ mdunlink(RelFileNode rnode, bool isRedo) ...@@ -270,7 +270,7 @@ mdunlink(RelFileNode rnode, bool isRedo)
* already. Might as well pass in the position and save a seek. * already. Might as well pass in the position and save a seek.
*/ */
bool bool
mdextend(SMgrRelation reln, BlockNumber blocknum, char *buffer) mdextend(SMgrRelation reln, BlockNumber blocknum, char *buffer, bool isTemp)
{ {
long seekpos; long seekpos;
int nbytes; int nbytes;
...@@ -311,8 +311,11 @@ mdextend(SMgrRelation reln, BlockNumber blocknum, char *buffer) ...@@ -311,8 +311,11 @@ mdextend(SMgrRelation reln, BlockNumber blocknum, char *buffer)
return false; return false;
} }
if (!register_dirty_segment(reln, v)) if (!isTemp)
return false; {
if (!register_dirty_segment(reln, v))
return false;
}
#ifndef LET_OS_MANAGE_FILESIZE #ifndef LET_OS_MANAGE_FILESIZE
Assert(_mdnblocks(v->mdfd_vfd, BLCKSZ) <= ((BlockNumber) RELSEG_SIZE)); Assert(_mdnblocks(v->mdfd_vfd, BLCKSZ) <= ((BlockNumber) RELSEG_SIZE));
...@@ -465,7 +468,7 @@ mdread(SMgrRelation reln, BlockNumber blocknum, char *buffer) ...@@ -465,7 +468,7 @@ mdread(SMgrRelation reln, BlockNumber blocknum, char *buffer)
* mdwrite() -- Write the supplied block at the appropriate location. * mdwrite() -- Write the supplied block at the appropriate location.
*/ */
bool bool
mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer) mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer, bool isTemp)
{ {
long seekpos; long seekpos;
MdfdVec *v; MdfdVec *v;
...@@ -485,8 +488,11 @@ mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer) ...@@ -485,8 +488,11 @@ mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer)
if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ) if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ)
return false; return false;
if (!register_dirty_segment(reln, v)) if (!isTemp)
return false; {
if (!register_dirty_segment(reln, v))
return false;
}
return true; return true;
} }
...@@ -565,7 +571,7 @@ mdnblocks(SMgrRelation reln) ...@@ -565,7 +571,7 @@ mdnblocks(SMgrRelation reln)
* Returns # of blocks or InvalidBlockNumber on error. * Returns # of blocks or InvalidBlockNumber on error.
*/ */
BlockNumber BlockNumber
mdtruncate(SMgrRelation reln, BlockNumber nblocks) mdtruncate(SMgrRelation reln, BlockNumber nblocks, bool isTemp)
{ {
MdfdVec *v; MdfdVec *v;
BlockNumber curnblk; BlockNumber curnblk;
...@@ -624,6 +630,11 @@ mdtruncate(SMgrRelation reln, BlockNumber nblocks) ...@@ -624,6 +630,11 @@ mdtruncate(SMgrRelation reln, BlockNumber nblocks)
if (FileTruncate(v->mdfd_vfd, lastsegblocks * BLCKSZ) < 0) if (FileTruncate(v->mdfd_vfd, lastsegblocks * BLCKSZ) < 0)
return InvalidBlockNumber; return InvalidBlockNumber;
if (!isTemp)
{
if (!register_dirty_segment(reln, v))
return InvalidBlockNumber;
}
v = v->mdfd_chain; v = v->mdfd_chain;
ov->mdfd_chain = NULL; ov->mdfd_chain = NULL;
} }
...@@ -640,6 +651,11 @@ mdtruncate(SMgrRelation reln, BlockNumber nblocks) ...@@ -640,6 +651,11 @@ mdtruncate(SMgrRelation reln, BlockNumber nblocks)
#else #else
if (FileTruncate(v->mdfd_vfd, nblocks * BLCKSZ) < 0) if (FileTruncate(v->mdfd_vfd, nblocks * BLCKSZ) < 0)
return InvalidBlockNumber; return InvalidBlockNumber;
if (!isTemp)
{
if (!register_dirty_segment(reln, v))
return InvalidBlockNumber;
}
#endif #endif
return nblocks; return nblocks;
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.71 2004/05/31 03:48:06 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.72 2004/05/31 20:31:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -40,13 +40,14 @@ typedef struct f_smgr ...@@ -40,13 +40,14 @@ typedef struct f_smgr
bool (*smgr_create) (SMgrRelation reln, bool isRedo); bool (*smgr_create) (SMgrRelation reln, bool isRedo);
bool (*smgr_unlink) (RelFileNode rnode, bool isRedo); bool (*smgr_unlink) (RelFileNode rnode, bool isRedo);
bool (*smgr_extend) (SMgrRelation reln, BlockNumber blocknum, bool (*smgr_extend) (SMgrRelation reln, BlockNumber blocknum,
char *buffer); char *buffer, bool isTemp);
bool (*smgr_read) (SMgrRelation reln, BlockNumber blocknum, bool (*smgr_read) (SMgrRelation reln, BlockNumber blocknum,
char *buffer); char *buffer);
bool (*smgr_write) (SMgrRelation reln, BlockNumber blocknum, bool (*smgr_write) (SMgrRelation reln, BlockNumber blocknum,
char *buffer); char *buffer, bool isTemp);
BlockNumber (*smgr_nblocks) (SMgrRelation reln); BlockNumber (*smgr_nblocks) (SMgrRelation reln);
BlockNumber (*smgr_truncate) (SMgrRelation reln, BlockNumber nblocks); BlockNumber (*smgr_truncate) (SMgrRelation reln, BlockNumber nblocks,
bool isTemp);
bool (*smgr_commit) (void); /* may be NULL */ bool (*smgr_commit) (void); /* may be NULL */
bool (*smgr_abort) (void); /* may be NULL */ bool (*smgr_abort) (void); /* may be NULL */
bool (*smgr_sync) (void); /* may be NULL */ bool (*smgr_sync) (void); /* may be NULL */
...@@ -438,9 +439,10 @@ smgr_internal_unlink(RelFileNode rnode, int which, bool isTemp, bool isRedo) ...@@ -438,9 +439,10 @@ smgr_internal_unlink(RelFileNode rnode, int which, bool isTemp, bool isRedo)
* failure we clean up by truncating. * failure we clean up by truncating.
*/ */
void void
smgrextend(SMgrRelation reln, BlockNumber blocknum, char *buffer) smgrextend(SMgrRelation reln, BlockNumber blocknum, char *buffer, bool isTemp)
{ {
if (! (*(smgrsw[reln->smgr_which].smgr_extend)) (reln, blocknum, buffer)) if (! (*(smgrsw[reln->smgr_which].smgr_extend)) (reln, blocknum, buffer,
isTemp))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not extend relation %u/%u: %m", errmsg("could not extend relation %u/%u: %m",
...@@ -473,12 +475,18 @@ smgrread(SMgrRelation reln, BlockNumber blocknum, char *buffer) ...@@ -473,12 +475,18 @@ smgrread(SMgrRelation reln, BlockNumber blocknum, char *buffer)
* smgrwrite() -- Write the supplied buffer out. * smgrwrite() -- Write the supplied buffer out.
* *
* This is not a synchronous write -- the block is not necessarily * This is not a synchronous write -- the block is not necessarily
* on disk at return, only dumped out to the kernel. * on disk at return, only dumped out to the kernel. However,
* provisions will be made to fsync the write before the next checkpoint.
*
* isTemp indicates that the relation is a temp table (ie, is managed
* by the local-buffer manager). In this case no provisions need be
* made to fsync the write before checkpointing.
*/ */
void void
smgrwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer) smgrwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer, bool isTemp)
{ {
if (! (*(smgrsw[reln->smgr_which].smgr_write)) (reln, blocknum, buffer)) if (! (*(smgrsw[reln->smgr_which].smgr_write)) (reln, blocknum, buffer,
isTemp))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not write block %u of relation %u/%u: %m", errmsg("could not write block %u of relation %u/%u: %m",
...@@ -525,12 +533,9 @@ smgrnblocks(SMgrRelation reln) ...@@ -525,12 +533,9 @@ smgrnblocks(SMgrRelation reln)
* transaction on failure. * transaction on failure.
*/ */
BlockNumber BlockNumber
smgrtruncate(SMgrRelation reln, BlockNumber nblocks) smgrtruncate(SMgrRelation reln, BlockNumber nblocks, bool isTemp)
{ {
BlockNumber newblks; BlockNumber newblks;
XLogRecPtr lsn;
XLogRecData rdata;
xl_smgr_truncate xlrec;
/* /*
* Tell the free space map to forget anything it may have stored * Tell the free space map to forget anything it may have stored
...@@ -540,7 +545,8 @@ smgrtruncate(SMgrRelation reln, BlockNumber nblocks) ...@@ -540,7 +545,8 @@ smgrtruncate(SMgrRelation reln, BlockNumber nblocks)
FreeSpaceMapTruncateRel(&reln->smgr_rnode, nblocks); FreeSpaceMapTruncateRel(&reln->smgr_rnode, nblocks);
/* Do the truncation */ /* Do the truncation */
newblks = (*(smgrsw[reln->smgr_which].smgr_truncate)) (reln, nblocks); newblks = (*(smgrsw[reln->smgr_which].smgr_truncate)) (reln, nblocks,
isTemp);
if (newblks == InvalidBlockNumber) if (newblks == InvalidBlockNumber)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
...@@ -549,20 +555,29 @@ smgrtruncate(SMgrRelation reln, BlockNumber nblocks) ...@@ -549,20 +555,29 @@ smgrtruncate(SMgrRelation reln, BlockNumber nblocks)
reln->smgr_rnode.relNode, reln->smgr_rnode.relNode,
nblocks))); nblocks)));
/* if (!isTemp)
* Make a non-transactional XLOG entry showing the file truncation. It's {
* non-transactional because we should replay it whether the transaction /*
* commits or not; the underlying file change is certainly not reversible. * Make a non-transactional XLOG entry showing the file truncation.
*/ * It's non-transactional because we should replay it whether the
xlrec.blkno = newblks; * transaction commits or not; the underlying file change is certainly
xlrec.rnode = reln->smgr_rnode; * not reversible.
*/
XLogRecPtr lsn;
XLogRecData rdata;
xl_smgr_truncate xlrec;
rdata.buffer = InvalidBuffer; xlrec.blkno = newblks;
rdata.data = (char *) &xlrec; xlrec.rnode = reln->smgr_rnode;
rdata.len = sizeof(xlrec);
rdata.next = NULL;
lsn = XLogInsert(RM_SMGR_ID, XLOG_SMGR_TRUNCATE | XLOG_NO_TRAN, &rdata); rdata.buffer = InvalidBuffer;
rdata.data = (char *) &xlrec;
rdata.len = sizeof(xlrec);
rdata.next = NULL;
lsn = XLogInsert(RM_SMGR_ID, XLOG_SMGR_TRUNCATE | XLOG_NO_TRAN,
&rdata);
}
return newblks; return newblks;
} }
...@@ -725,7 +740,8 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record) ...@@ -725,7 +740,8 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
/* Do the truncation */ /* Do the truncation */
newblks = (*(smgrsw[reln->smgr_which].smgr_truncate)) (reln, newblks = (*(smgrsw[reln->smgr_which].smgr_truncate)) (reln,
xlrec->blkno); xlrec->blkno,
false);
if (newblks == InvalidBlockNumber) if (newblks == InvalidBlockNumber)
ereport(WARNING, ereport(WARNING,
(errcode_for_file_access(), (errcode_for_file_access(),
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/storage/smgr.h,v 1.42 2004/05/31 03:48:10 tgl Exp $ * $PostgreSQL: pgsql/src/include/storage/smgr.h,v 1.43 2004/05/31 20:31:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -55,11 +55,14 @@ extern void smgrclosenode(RelFileNode rnode); ...@@ -55,11 +55,14 @@ extern void smgrclosenode(RelFileNode rnode);
extern void smgrcreate(SMgrRelation reln, bool isTemp, bool isRedo); extern void smgrcreate(SMgrRelation reln, bool isTemp, bool isRedo);
extern void smgrscheduleunlink(SMgrRelation reln, bool isTemp); extern void smgrscheduleunlink(SMgrRelation reln, bool isTemp);
extern void smgrdounlink(SMgrRelation reln, bool isTemp, bool isRedo); extern void smgrdounlink(SMgrRelation reln, bool isTemp, bool isRedo);
extern void smgrextend(SMgrRelation reln, BlockNumber blocknum, char *buffer); extern void smgrextend(SMgrRelation reln, BlockNumber blocknum, char *buffer,
bool isTemp);
extern void smgrread(SMgrRelation reln, BlockNumber blocknum, char *buffer); extern void smgrread(SMgrRelation reln, BlockNumber blocknum, char *buffer);
extern void smgrwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer); extern void smgrwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer,
bool isTemp);
extern BlockNumber smgrnblocks(SMgrRelation reln); extern BlockNumber smgrnblocks(SMgrRelation reln);
extern BlockNumber smgrtruncate(SMgrRelation reln, BlockNumber nblocks); extern BlockNumber smgrtruncate(SMgrRelation reln, BlockNumber nblocks,
bool isTemp);
extern void smgrDoPendingDeletes(bool isCommit); extern void smgrDoPendingDeletes(bool isCommit);
extern int smgrGetPendingDeletes(bool forCommit, RelFileNode **ptr); extern int smgrGetPendingDeletes(bool forCommit, RelFileNode **ptr);
extern void smgrcommit(void); extern void smgrcommit(void);
...@@ -78,11 +81,14 @@ extern bool mdinit(void); ...@@ -78,11 +81,14 @@ extern bool mdinit(void);
extern bool mdclose(SMgrRelation reln); extern bool mdclose(SMgrRelation reln);
extern bool mdcreate(SMgrRelation reln, bool isRedo); extern bool mdcreate(SMgrRelation reln, bool isRedo);
extern bool mdunlink(RelFileNode rnode, bool isRedo); extern bool mdunlink(RelFileNode rnode, bool isRedo);
extern bool mdextend(SMgrRelation reln, BlockNumber blocknum, char *buffer); extern bool mdextend(SMgrRelation reln, BlockNumber blocknum, char *buffer,
bool isTemp);
extern bool mdread(SMgrRelation reln, BlockNumber blocknum, char *buffer); extern bool mdread(SMgrRelation reln, BlockNumber blocknum, char *buffer);
extern bool mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer); extern bool mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer,
bool isTemp);
extern BlockNumber mdnblocks(SMgrRelation reln); extern BlockNumber mdnblocks(SMgrRelation reln);
extern BlockNumber mdtruncate(SMgrRelation reln, BlockNumber nblocks); extern BlockNumber mdtruncate(SMgrRelation reln, BlockNumber nblocks,
bool isTemp);
extern bool mdsync(void); extern bool mdsync(void);
extern void RememberFsyncRequest(RelFileNode rnode, BlockNumber segno); extern void RememberFsyncRequest(RelFileNode rnode, BlockNumber segno);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment