@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $ Header : / cvsroot / pgsql / src / backend / storage / buffer / bufmgr . c , v 1.107 2001 / 02 / 18 04 : 39 : 42 tgl Exp $
* $ Header : / cvsroot / pgsql / src / backend / storage / buffer / bufmgr . c , v 1.108 2001 / 03 / 21 10 : 13 : 29 vadim Exp $
*
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
*/
@ -727,7 +727,6 @@ BufferSync()
RelFileNode rnode ;
RelFileNode rnode ;
XLogRecPtr recptr ;
XLogRecPtr recptr ;
Relation reln = NULL ;
Relation reln = NULL ;
bool dirty = false ;
for ( i = 0 , bufHdr = BufferDescriptors ; i < NBuffers ; i + + , bufHdr + + )
for ( i = 0 , bufHdr = BufferDescriptors ; i < NBuffers ; i + + , bufHdr + + )
{
{
@ -741,16 +740,44 @@ BufferSync()
}
}
/*
/*
* Pin buffer and ensure that no one reads it from disk
* We can check bufHdr - > cntxDirty here * without * holding any lock
* on buffer context as long as we set this flag in access methods
* * before * logging changes with XLogInsert ( ) : if someone will set
* cntxDirty just after our check we don ' t worry because of our
* checkpoint . redo points before log record for upcoming changes
* and so we are not required to write such dirty buffer .
*/
if ( ! ( bufHdr - > flags & BM_DIRTY ) & & ! ( bufHdr - > cntxDirty ) )
{
SpinRelease ( BufMgrLock ) ;
continue ;
}
/*
* IO synchronization . Note that we do it with unpinned buffer
* to avoid conflicts with FlushRelationBuffers .
*/
*/
PinBuffer ( bufHdr ) ;
/* Synchronize with BufferAlloc */
if ( bufHdr - > flags & BM_IO_IN_PROGRESS )
if ( bufHdr - > flags & BM_IO_IN_PROGRESS )
{
WaitIO ( bufHdr , BufMgrLock ) ;
WaitIO ( bufHdr , BufMgrLock ) ;
if ( ! ( bufHdr - > flags & BM_VALID ) | |
( ! ( bufHdr - > flags & BM_DIRTY ) & & ! ( bufHdr - > cntxDirty ) ) )
{
SpinRelease ( BufMgrLock ) ;
continue ;
}
}
/*
* Here : no one doing IO for this buffer and it ' s dirty .
* Pin buffer now and set IO state for it * before * acquiring
* shlock to avoid conflicts with FlushRelationBuffers .
*/
PinBuffer ( bufHdr ) ;
StartBufferIO ( bufHdr , false ) ; /* output IO start */
buffer = BufferDescriptorGetBuffer ( bufHdr ) ;
buffer = BufferDescriptorGetBuffer ( bufHdr ) ;
rnode = bufHdr - > tag . rnode ;
rnode = bufHdr - > tag . rnode ;
dirty = bufHdr - > flags & BM_DIRTY ;
SpinRelease ( BufMgrLock ) ;
SpinRelease ( BufMgrLock ) ;
@ -764,17 +791,6 @@ BufferSync()
*/
*/
LockBuffer ( buffer , BUFFER_LOCK_SHARE ) ;
LockBuffer ( buffer , BUFFER_LOCK_SHARE ) ;
if ( ! dirty & & ! ( bufHdr - > cntxDirty ) )
{
LockBuffer ( buffer , BUFFER_LOCK_UNLOCK ) ;
SpinAcquire ( BufMgrLock ) ;
UnpinBuffer ( bufHdr ) ;
SpinRelease ( BufMgrLock ) ;
if ( reln ! = ( Relation ) NULL )
RelationDecrementReferenceCount ( reln ) ;
continue ;
}
/*
/*
* Force XLOG flush for buffer ' LSN
* Force XLOG flush for buffer ' LSN
*/
*/
@ -782,18 +798,13 @@ BufferSync()
XLogFlush ( recptr ) ;
XLogFlush ( recptr ) ;
/*
/*
* Now it ' s safe to write buffer to disk
* Now it ' s safe to write buffer to disk . Note that no one else
* ( if no one else already )
* should not be able to write it while we were busy with locking
* and log flushing because of we setted IO flag .
*/
*/
SpinAcquire ( BufMgrLock ) ;
SpinAcquire ( BufMgrLock ) ;
if ( bufHdr - > flags & BM_IO_IN_PROGRESS )
Assert ( bufHdr - > flags & BM_DIRTY | | bufHdr - > cntxDirty ) ;
WaitIO ( bufHdr , BufMgrLock ) ;
if ( bufHdr - > flags & BM_DIRTY | | bufHdr - > cntxDirty )
{
bufHdr - > flags & = ~ BM_JUST_DIRTIED ;
bufHdr - > flags & = ~ BM_JUST_DIRTIED ;
StartBufferIO ( bufHdr , false ) ; /* output IO start */
SpinRelease ( BufMgrLock ) ;
SpinRelease ( BufMgrLock ) ;
if ( reln = = ( Relation ) NULL )
if ( reln = = ( Relation ) NULL )
@ -842,13 +853,6 @@ BufferSync()
bufHdr - > flags & = ~ BM_DIRTY ;
bufHdr - > flags & = ~ BM_DIRTY ;
UnpinBuffer ( bufHdr ) ;
UnpinBuffer ( bufHdr ) ;
SpinRelease ( BufMgrLock ) ;
SpinRelease ( BufMgrLock ) ;
}
else
{
UnpinBuffer ( bufHdr ) ;
SpinRelease ( BufMgrLock ) ;
LockBuffer ( buffer , BUFFER_LOCK_UNLOCK ) ;
}
/* drop refcnt obtained by RelationNodeCacheGetRelation */
/* drop refcnt obtained by RelationNodeCacheGetRelation */
if ( reln ! = ( Relation ) NULL )
if ( reln ! = ( Relation ) NULL )
@ -2079,6 +2083,12 @@ LockBuffer(Buffer buffer, int mode)
buf - > w_lock = true ;
buf - > w_lock = true ;
* buflock | = BL_W_LOCK ;
* buflock | = BL_W_LOCK ;
/*
* This is not the best place to set cntxDirty flag ( eg indices
* do not always change buffer they lock in excl mode ) . But please
* remember that it ' s critical to set cntxDirty * before * logging
* changes with XLogInsert ( ) - see comments in BufferSync ( ) .
*/
buf - > cntxDirty = true ;
buf - > cntxDirty = true ;
if ( * buflock & BL_RI_LOCK )
if ( * buflock & BL_RI_LOCK )