]> granicus.if.org Git - postgresql/commitdiff
Additional mop-up for sync-to-fsync changes: avoid issuing fsyncs for
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 31 May 2004 20:31:33 +0000 (20:31 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 31 May 2004 20:31:33 +0000 (20:31 +0000)
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).

src/backend/storage/buffer/bufmgr.c
src/backend/storage/buffer/localbuf.c
src/backend/storage/smgr/md.c
src/backend/storage/smgr/smgr.c
src/include/storage/smgr.h

index bc6c0f6993cbd029a991d1810bdce63ca4a3bacc..400fbcf1ff7d1bb9bae4cb59488f0c8b2fa2db3b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * 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,
        {
                /* new buffers are zero-filled */
                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
        {
@@ -915,8 +916,8 @@ BufferGetFileNode(Buffer buffer)
  * 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
  * 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
- * before we can checkpoint WAL.
+ * However, we will need to force the changes to disk via fsync before
+ * we can checkpoint WAL.
  *
  * BufMgrLock must be held at entry, and the buffer must be pinned.  The
  * caller is also responsible for doing StartBufferIO/TerminateBufferIO.
@@ -979,7 +980,8 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
         */
        smgrwrite(reln,
                          buf->tag.blockNum,
-                         (char *) MAKE_PTR(buf->data));
+                         (char *) MAKE_PTR(buf->data),
+                         false);
 
        /* Pop the error context stack */
        error_context_stack = errcontext.previous;
@@ -1033,7 +1035,7 @@ RelationTruncate(Relation rel, BlockNumber nblocks)
        rel->rd_targblock = InvalidBlockNumber;
 
        /* 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)
 
                                        smgrwrite(rel->rd_smgr,
                                                          bufHdr->tag.blockNum,
-                                                         (char *) MAKE_PTR(bufHdr->data));
+                                                         (char *) MAKE_PTR(bufHdr->data),
+                                                         true);
 
                                        bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
                                        bufHdr->cntxDirty = false;
index ba4be8750cb491e37709b41a0f8ab20c62481c1e..95e86e955d19a5cddefca88828c4e9a6f4a7bd02 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * 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)
                /* And write... */
                smgrwrite(reln,
                                  bufHdr->tag.blockNum,
-                                 (char *) MAKE_PTR(bufHdr->data));
+                                 (char *) MAKE_PTR(bufHdr->data),
+                                 true);
 
                LocalBufferFlushCount++;
        }
index 5ac5868f690b32196f7eca791674d2de3c6ca4b0..1a0218c4e58def73447acf5e0077b413270d8ba3 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * 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)
  * already.  Might as well pass in the position and save a seek.
  */
 bool
-mdextend(SMgrRelation reln, BlockNumber blocknum, char *buffer)
+mdextend(SMgrRelation reln, BlockNumber blocknum, char *buffer, bool isTemp)
 {
        long            seekpos;
        int                     nbytes;
@@ -311,8 +311,11 @@ mdextend(SMgrRelation reln, BlockNumber blocknum, char *buffer)
                return false;
        }
 
-       if (!register_dirty_segment(reln, v))
-               return false;
+       if (!isTemp)
+       {
+               if (!register_dirty_segment(reln, v))
+                       return false;
+       }
 
 #ifndef LET_OS_MANAGE_FILESIZE
        Assert(_mdnblocks(v->mdfd_vfd, BLCKSZ) <= ((BlockNumber) RELSEG_SIZE));
@@ -465,7 +468,7 @@ mdread(SMgrRelation reln, BlockNumber blocknum, char *buffer)
  *     mdwrite() -- Write the supplied block at the appropriate location.
  */
 bool
-mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer)
+mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer, bool isTemp)
 {
        long            seekpos;
        MdfdVec    *v;
@@ -485,8 +488,11 @@ mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer)
        if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ)
                return false;
 
-       if (!register_dirty_segment(reln, v))
-               return false;
+       if (!isTemp)
+       {
+               if (!register_dirty_segment(reln, v))
+                       return false;
+       }
 
        return true;
 }
@@ -565,7 +571,7 @@ mdnblocks(SMgrRelation reln)
  *             Returns # of blocks or InvalidBlockNumber on error.
  */
 BlockNumber
-mdtruncate(SMgrRelation reln, BlockNumber nblocks)
+mdtruncate(SMgrRelation reln, BlockNumber nblocks, bool isTemp)
 {
        MdfdVec    *v;
        BlockNumber curnblk;
@@ -624,6 +630,11 @@ mdtruncate(SMgrRelation reln, BlockNumber nblocks)
 
                        if (FileTruncate(v->mdfd_vfd, lastsegblocks * BLCKSZ) < 0)
                                return InvalidBlockNumber;
+                       if (!isTemp)
+                       {
+                               if (!register_dirty_segment(reln, v))
+                                       return InvalidBlockNumber;
+                       }
                        v = v->mdfd_chain;
                        ov->mdfd_chain = NULL;
                }
@@ -640,6 +651,11 @@ mdtruncate(SMgrRelation reln, BlockNumber nblocks)
 #else
        if (FileTruncate(v->mdfd_vfd, nblocks * BLCKSZ) < 0)
                return InvalidBlockNumber;
+       if (!isTemp)
+       {
+               if (!register_dirty_segment(reln, v))
+                       return InvalidBlockNumber;
+       }
 #endif
 
        return nblocks;
index c204e2796c4b2125b5f83a1a3fb574e2a9bd85a1..5320532be4b5dd61b0b1517543f1d93d7fc8a8e3 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * 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
        bool            (*smgr_create) (SMgrRelation reln, bool isRedo);
        bool            (*smgr_unlink) (RelFileNode rnode, bool isRedo);
        bool            (*smgr_extend) (SMgrRelation reln, BlockNumber blocknum,
-                                                                                       char *buffer);
+                                                               char *buffer, bool isTemp);
        bool            (*smgr_read) (SMgrRelation reln, BlockNumber blocknum,
-                                                                                 char *buffer);
+                                                         char *buffer);
        bool            (*smgr_write) (SMgrRelation reln, BlockNumber blocknum,
-                                                                                  char *buffer);
+                                                          char *buffer, bool isTemp);
        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_abort) (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)
  *             failure we clean up by truncating.
  */
 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,
                                (errcode_for_file_access(),
                                 errmsg("could not extend relation %u/%u: %m",
@@ -473,12 +475,18 @@ smgrread(SMgrRelation reln, BlockNumber blocknum, char *buffer)
  *     smgrwrite() -- Write the supplied buffer out.
  *
  *             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
-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,
                                (errcode_for_file_access(),
                                 errmsg("could not write block %u of relation %u/%u: %m",
@@ -525,12 +533,9 @@ smgrnblocks(SMgrRelation reln)
  *             transaction on failure.
  */
 BlockNumber
-smgrtruncate(SMgrRelation reln, BlockNumber nblocks)
+smgrtruncate(SMgrRelation reln, BlockNumber nblocks, bool isTemp)
 {
        BlockNumber newblks;
-       XLogRecPtr              lsn;
-       XLogRecData             rdata;
-       xl_smgr_truncate xlrec;
 
        /*
         * Tell the free space map to forget anything it may have stored
@@ -540,7 +545,8 @@ smgrtruncate(SMgrRelation reln, BlockNumber nblocks)
        FreeSpaceMapTruncateRel(&reln->smgr_rnode, nblocks);
 
        /* 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)
                ereport(ERROR,
                                (errcode_for_file_access(),
@@ -549,20 +555,29 @@ smgrtruncate(SMgrRelation reln, BlockNumber nblocks)
                                                reln->smgr_rnode.relNode,
                                                nblocks)));
 
-       /*
-        * 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.
-        */
-       xlrec.blkno = newblks;
-       xlrec.rnode = reln->smgr_rnode;
+       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.
+                */
+               XLogRecPtr              lsn;
+               XLogRecData             rdata;
+               xl_smgr_truncate xlrec;
 
-       rdata.buffer = InvalidBuffer;
-       rdata.data = (char *) &xlrec;
-       rdata.len = sizeof(xlrec);
-       rdata.next = NULL;
+               xlrec.blkno = newblks;
+               xlrec.rnode = reln->smgr_rnode;
 
-       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;
 }
@@ -725,7 +740,8 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
 
                /* Do the truncation */
                newblks = (*(smgrsw[reln->smgr_which].smgr_truncate)) (reln,
-                                                                                                                          xlrec->blkno);
+                                                                                                                          xlrec->blkno,
+                                                                                                                          false);
                if (newblks == InvalidBlockNumber)
                        ereport(WARNING,
                                        (errcode_for_file_access(),
index 6a28c3824fad8e6b5f1a90cabb455e8219b8b53f..6999635dc468b2b672ce141f449364a5ce3d43b9 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * 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);
 extern void smgrcreate(SMgrRelation reln, bool isTemp, bool isRedo);
 extern void smgrscheduleunlink(SMgrRelation reln, bool isTemp);
 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 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 smgrtruncate(SMgrRelation reln, BlockNumber nblocks);
+extern BlockNumber smgrtruncate(SMgrRelation reln, BlockNumber nblocks,
+                                                               bool isTemp);
 extern void smgrDoPendingDeletes(bool isCommit);
 extern int     smgrGetPendingDeletes(bool forCommit, RelFileNode **ptr);
 extern void smgrcommit(void);
@@ -78,11 +81,14 @@ extern bool mdinit(void);
 extern bool mdclose(SMgrRelation reln);
 extern bool mdcreate(SMgrRelation reln, 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 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 mdtruncate(SMgrRelation reln, BlockNumber nblocks);
+extern BlockNumber mdtruncate(SMgrRelation reln, BlockNumber nblocks,
+                                                         bool isTemp);
 extern bool mdsync(void);
 
 extern void RememberFsyncRequest(RelFileNode rnode, BlockNumber segno);