From 49f68a8584b03996cd9e8c080fa665f3e406842e Mon Sep 17 00:00:00 2001 From: "Vadim B. Mikheev" Date: Tue, 29 Jun 1999 04:54:49 +0000 Subject: [PATCH] Avoid disk writes for read-only transactions. --- src/backend/access/transam/xact.c | 61 ++++++++++++++++++++----------------- src/backend/storage/buffer/bufmgr.c | 17 ++++++++++- 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 4689a2f82e..cd860e0450 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -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: @@ -158,6 +158,8 @@ #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 */ } /* -------------------------------- diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 446917a4c5..e81b2dfb96 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -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); -- 2.11.0