diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 4689a2f82ea0047cdbebd46c369435313ed33fa7..cd860e0450bc5098a7713cf9e7db1d9c2b9b6fab 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 <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 */ } /* -------------------------------- diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 446917a4c5008d96d34f4cabc17b6dde2d627ccc..e81b2dfb96bab059578282f33570d8a2c30a7160 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);