OSDN Git Service

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

index 4689a2f..cd860e0 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 <commands/sequence.h>
 #include <libpq/be-fsstubs.h>
 
+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 446917a..e81b2df 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);