Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9ff6903

Browse files
committed
Fixing possible losing data changes:
1. New flag - BM_JUST_DIRTIED - added for BufferDesc;2. All data "dirtiers" (WriteBuffer and WriteNoReleaseBuffer) set this flag (and BM_DIRTY too);3. All data "flushers" (FlushBuffer, BufferSync and BufferReplace) turn this flag off just before calling smgr[blind]write/smgrflush and check this flag after flushing buffer: if it turned ON then BM_DIRTY will stay ON.
1 parentdeef313 commit9ff6903

File tree

1 file changed

+62
-15
lines changed

1 file changed

+62
-15
lines changed

‎src/backend/storage/buffer/bufmgr.c

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.8 1997/01/16 08:11:41 vadim Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.9 1997/01/20 04:36:48 vadim Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -474,7 +474,19 @@ BufferAlloc(Relation reln,
474474
else
475475
{
476476
BufferFlushCount++;
477-
buf->flags &= ~BM_DIRTY;
477+
/*
478+
* BM_JUST_DIRTIED cleared by BufferReplace and shouldn't
479+
* be setted by anyone. - vadim 01/17/97
480+
*/
481+
if (buf->flags&BM_JUST_DIRTIED )
482+
{
483+
elog (FATAL,"BufferAlloc: content of block %u (%s) changed while flushing",
484+
buf->tag.blockNum,buf->sb_relname);
485+
}
486+
else
487+
{
488+
buf->flags &= ~BM_DIRTY;
489+
}
478490
}
479491

480492
/*
@@ -488,7 +500,8 @@ BufferAlloc(Relation reln,
488500
* no reason to think that we have an immediate disaster on
489501
* our hands.
490502
*/
491-
if (buf&&buf->refcount>1) {
503+
if (buf&&buf->refcount>1 )
504+
{
492505
inProgress= FALSE;
493506
buf->flags &= ~BM_IO_IN_PROGRESS;
494507
#ifdefHAS_TEST_AND_SET
@@ -643,7 +656,7 @@ WriteBuffer(Buffer buffer)
643656

644657
SpinAcquire(BufMgrLock);
645658
Assert(bufHdr->refcount>0);
646-
bufHdr->flags |=BM_DIRTY;
659+
bufHdr->flags |=(BM_DIRTY |BM_JUST_DIRTIED);
647660
UnpinBuffer(bufHdr);
648661
SpinRelease(BufMgrLock);
649662
}
@@ -733,19 +746,36 @@ FlushBuffer(Buffer buffer, bool release)
733746
bufrel=RelationIdCacheGetRelation (bufHdr->tag.relId.relId);
734747
Assert (bufrel!= (Relation)NULL);
735748

749+
/* To check if block content changed while flushing. - vadim 01/17/97 */
750+
SpinAcquire(BufMgrLock);
751+
bufHdr->flags &= ~BM_JUST_DIRTIED;
752+
SpinRelease(BufMgrLock);
753+
736754
status=smgrflush(bufHdr->bufsmgr,bufrel,bufHdr->tag.blockNum,
737755
(char*)MAKE_PTR(bufHdr->data));
738756

739757
if (status==SM_FAIL)
740758
{
741-
elog(WARN,"FlushBuffer: cannot flush block %u of the relation %.*s",
742-
bufHdr->tag.blockNum,
743-
NAMEDATALEN,bufrel->rd_rel->relname.data);
759+
elog(WARN,"FlushBuffer: cannot flush block %u of the relation %s",
760+
bufHdr->tag.blockNum,bufHdr->sb_relname);
744761
return (STATUS_ERROR);
745762
}
746763

747764
SpinAcquire(BufMgrLock);
748-
bufHdr->flags &= ~BM_DIRTY;
765+
/*
766+
* If this buffer was marked by someone as DIRTY while
767+
* we were flushing it out we must not clear DIRTY flag
768+
* - vadim 01/17/97
769+
*/
770+
if (bufHdr->flags&BM_JUST_DIRTIED )
771+
{
772+
elog (NOTICE,"FlusfBuffer: content of block %u (%s) changed while flushing",
773+
bufHdr->tag.blockNum,bufHdr->sb_relname);
774+
}
775+
else
776+
{
777+
bufHdr->flags &= ~BM_DIRTY;
778+
}
749779
if (release )
750780
UnpinBuffer(bufHdr);
751781
SpinRelease(BufMgrLock);
@@ -779,7 +809,7 @@ WriteNoReleaseBuffer(Buffer buffer)
779809
bufHdr=&BufferDescriptors[buffer-1];
780810

781811
SpinAcquire(BufMgrLock);
782-
bufHdr->flags |=BM_DIRTY;
812+
bufHdr->flags |=(BM_DIRTY |BM_JUST_DIRTIED);
783813
SpinRelease(BufMgrLock);
784814
}
785815
return(STATUS_OK);
@@ -878,13 +908,19 @@ BufferSync()
878908
UnpinBuffer(bufHdr);
879909
if (bufHdr->flags&BM_IO_ERROR)
880910
{
881-
elog(WARN,"cannot write %u for %s",
911+
elog(WARN,"BufferSync: write error %u for %s",
882912
bufHdr->tag.blockNum,bufHdr->sb_relname);
883913
}
884914
if (reln!= (Relation)NULL)
885915
RelationDecrementReferenceCount(reln);
886916
continue;
887917
}
918+
919+
/*
920+
* To check if block content changed while flushing
921+
* (see below). - vadim 01/17/97
922+
*/
923+
bufHdr->flags &= ~BM_JUST_DIRTIED;
888924

889925
/*
890926
* If we didn't have the reldesc in our local cache, flush this
@@ -912,15 +948,23 @@ BufferSync()
912948
UnpinBuffer(bufHdr);
913949
if (status==SM_FAIL) {
914950
bufHdr->flags |=BM_IO_ERROR;
915-
elog(WARN,"cannot write %u for %s",
951+
elog(WARN,"BufferSync:cannot write %u for %s",
916952
bufHdr->tag.blockNum,bufHdr->sb_relname);
917953
}
918954
/*
919-
*What if someone has markedthis buffer as DIRTYafter
920-
*smgr[blind]write but before SpinAcquire(BufMgrLock)
921-
*??? - vadim 01/16/97
955+
*If this buffer was markedby someone as DIRTYwhile
956+
*we were flushing it out we must not clear DIRTY flag
957+
* - vadim 01/17/97
922958
*/
923-
bufHdr->flags &= ~BM_DIRTY;
959+
if (bufHdr->flags&BM_JUST_DIRTIED )
960+
{
961+
elog (NOTICE,"BufferSync: content of block %u (%s) changed while flushing",
962+
bufHdr->tag.blockNum,bufHdr->sb_relname);
963+
}
964+
else
965+
{
966+
bufHdr->flags &= ~BM_DIRTY;
967+
}
924968
if (reln!= (Relation)NULL)
925969
RelationDecrementReferenceCount(reln);
926970
}
@@ -1189,6 +1233,9 @@ BufferReplace(BufferDesc *bufHdr, bool bufferLockHeld)
11891233
reln=RelationIdCacheGetRelation(bufrel);
11901234
else
11911235
reln= (Relation)NULL;
1236+
1237+
/* To check if block content changed while flushing. - vadim 01/17/97 */
1238+
bufHdr->flags &= ~BM_JUST_DIRTIED;
11921239

11931240
SpinRelease(BufMgrLock);
11941241

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp