Avoid disk writes for read-only transactions.
authorVadim B. Mikheev
Tue, 29 Jun 1999 04:54:49 +0000 (04:54 +0000)
committerVadim B. Mikheev
Tue, 29 Jun 1999 04:54:49 +0000 (04:54 +0000)
src/backend/access/transam/xact.c
src/backend/storage/buffer/bufmgr.c

index 4689a2f82ea0047cdbebd46c369435313ed33fa7..cd860e0450bc5098a7713cf9e7db1d9c2b9b6fab 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.41 1999/06/10 14:17:06 vadim Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.42 1999/06/29 04:54:46 vadim Exp $
  *
  * NOTES
  *     Transaction aborts can now occur two ways:
 #include 
 #include 
 
+extern bool    SharedBufferChanged;
+
 static void AbortTransaction(void);
 static void AtAbort_Cache(void);
 static void AtAbort_Locks(void);
@@ -618,30 +620,36 @@ RecordTransactionCommit()
     */
    xid = GetCurrentTransactionId();
 
-   /* ----------------
+   /* 
     *  flush the buffer manager pages.  Note: if we have stable
     *  main memory, dirty shared buffers are not flushed
     *  plai 8/7/90
-    * ----------------
     */
    leak = BufferPoolCheckLeak();
-   FlushBufferPool(!TransactionFlushEnabled());
-   if (leak)
-       ResetBufferPool();
 
-   /* ----------------
-    *  have the transaction access methods record the status
-    *  of this transaction id in the pg_log / pg_time relations.
-    * ----------------
+   /*
+    * If no one shared buffer was changed by this transaction then
+    * we don't flush shared buffers and don't record commit status.
     */
-   TransactionIdCommit(xid);
+   if (SharedBufferChanged)
+   {
+       FlushBufferPool(!TransactionFlushEnabled());
+       if (leak)
+           ResetBufferPool();
+
+       /*
+        *  have the transaction access methods record the status
+        *  of this transaction id in the pg_log relation.
+        */
+       TransactionIdCommit(xid);
+
+       /*
+        *  Now write the log info to the disk too.
+        */
+       leak = BufferPoolCheckLeak();
+       FlushBufferPool(!TransactionFlushEnabled());
+   }
 
-   /* ----------------
-    *  Now write the log/time info to the disk too.
-    * ----------------
-    */
-   leak = BufferPoolCheckLeak();
-   FlushBufferPool(!TransactionFlushEnabled());
    if (leak)
        ResetBufferPool();
 }
@@ -731,19 +739,14 @@ RecordTransactionAbort()
     */
    xid = GetCurrentTransactionId();
 
-   /* ----------------
-    *  have the transaction access methods record the status
-    *  of this transaction id in the pg_log / pg_time relations.
-    * ----------------
+   /* 
+    * Have the transaction access methods record the status of
+    * this transaction id in the pg_log relation. We skip it
+    * if no one shared buffer was changed by this transaction.
     */
-   TransactionIdAbort(xid);
+   if (SharedBufferChanged)
+       TransactionIdAbort(xid);
 
-   /* ----------------
-    *  flush the buffer manager pages.  Note: if we have stable
-    *  main memory, dirty shared buffers are not flushed
-    *  plai 8/7/90
-    * ----------------
-    */
    ResetBufferPool();
 }
 
@@ -965,6 +968,7 @@ CommitTransaction()
     * ----------------
     */
    s->state = TRANS_DEFAULT;
+   SharedBufferChanged = false;    /* safest place to do it */
 
 }
 
@@ -1028,6 +1032,7 @@ AbortTransaction()
     * ----------------
     */
    s->state = TRANS_DEFAULT;
+   SharedBufferChanged = false;    /* safest place to do it */
 }
 
 /* --------------------------------
index 446917a4c5008d96d34f4cabc17b6dde2d627ccc..e81b2dfb96bab059578282f33570d8a2c30a7160 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.55 1999/06/11 09:00:02 vadim Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.56 1999/06/29 04:54:47 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -78,6 +78,15 @@ extern long int LocalBufferHitCount;
 extern long int BufferFlushCount;
 extern long int LocalBufferFlushCount;
 
+/*
+ * It's used to avoid disk writes for read-only transactions
+ * (i.e. when no one shared buffer was changed by transaction).
+ * We set it to true in WriteBuffer/WriteNoReleaseBuffer when
+ * marking shared buffer as dirty. We set it to false in xact.c
+ * after transaction is committed/aborted.
+ */
+bool           SharedBufferChanged = false;
+
 static int WriteMode = BUFFER_LATE_WRITE;      /* Delayed write is
                                                 * default */
 
@@ -699,6 +708,8 @@ WriteBuffer(Buffer buffer)
 
        bufHdr = &BufferDescriptors[buffer - 1];
 
+       SharedBufferChanged = true;
+
        SpinAcquire(BufMgrLock);
        Assert(bufHdr->refcount > 0);
        bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
@@ -810,6 +821,8 @@ FlushBuffer(Buffer buffer, bool release)
    bufrel = RelationIdCacheGetRelation(bufHdr->tag.relId.relId);
    Assert(bufrel != (Relation) NULL);
 
+   SharedBufferChanged = true;
+
    /* To check if block content changed while flushing. - vadim 01/17/97 */
    SpinAcquire(BufMgrLock);
    bufHdr->flags &= ~BM_JUST_DIRTIED;
@@ -875,6 +888,8 @@ WriteNoReleaseBuffer(Buffer buffer)
 
        bufHdr = &BufferDescriptors[buffer - 1];
 
+       SharedBufferChanged = true;
+
        SpinAcquire(BufMgrLock);
        bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
        SpinRelease(BufMgrLock);