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);