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

Commit3424bff

Browse files
committed
Prevent index-only scans from returning wrong answers under Hot Standby.
The alternative of disallowing index-only scans in HS operation wasdiscussed, but the consensus was that it was better to treat markinga page all-visible as a recovery conflict for snapshots that could stillfail to see XIDs on that page. We may in the future try to soften this,so that we simply force index scans to do heap fetches in cases wherethis may be an issue, rather than throwing a hard conflict.
1 parent92df220 commit3424bff

File tree

7 files changed

+36
-11
lines changed

7 files changed

+36
-11
lines changed

‎src/backend/access/heap/heapam.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4368,14 +4368,16 @@ log_heap_freeze(Relation reln, Buffer buffer,
43684368
* and dirtied.
43694369
*/
43704370
XLogRecPtr
4371-
log_heap_visible(RelFileNodernode,BlockNumberblock,Buffervm_buffer)
4371+
log_heap_visible(RelFileNodernode,BlockNumberblock,Buffervm_buffer,
4372+
TransactionIdcutoff_xid)
43724373
{
43734374
xl_heap_visiblexlrec;
43744375
XLogRecPtrrecptr;
43754376
XLogRecDatardata[2];
43764377

43774378
xlrec.node=rnode;
43784379
xlrec.block=block;
4380+
xlrec.cutoff_xid=cutoff_xid;
43794381

43804382
rdata[0].data= (char*)&xlrec;
43814383
rdata[0].len=SizeOfHeapVisible;
@@ -4708,6 +4710,17 @@ heap_xlog_visible(XLogRecPtr lsn, XLogRecord *record)
47084710
return;
47094711
page= (Page)BufferGetPage(buffer);
47104712

4713+
/*
4714+
* If there are any Hot Standby transactions running that have an xmin
4715+
* horizon old enough that this page isn't all-visible for them, they
4716+
* might incorrectly decide that an index-only scan can skip a heap fetch.
4717+
*
4718+
* NB: It might be better to throw some kind of "soft" conflict here that
4719+
* forces any index-only scan that is in flight to perform heap fetches,
4720+
* rather than killing the transaction outright.
4721+
*/
4722+
ResolveRecoveryConflictWithSnapshot(xlrec->cutoff_xid,xlrec->node);
4723+
47114724
LockBuffer(buffer,BUFFER_LOCK_EXCLUSIVE);
47124725

47134726
/*
@@ -4760,7 +4773,8 @@ heap_xlog_visible(XLogRecPtr lsn, XLogRecord *record)
47604773
* harm is done; and the next VACUUM will fix it.
47614774
*/
47624775
if (!XLByteLE(lsn,PageGetLSN(BufferGetPage(vmbuffer))))
4763-
visibilitymap_set(reln,xlrec->block,lsn,vmbuffer);
4776+
visibilitymap_set(reln,xlrec->block,lsn,vmbuffer,
4777+
xlrec->cutoff_xid);
47644778

47654779
ReleaseBuffer(vmbuffer);
47664780
FreeFakeRelcacheEntry(reln);

‎src/backend/access/heap/visibilitymap.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,15 +229,17 @@ visibilitymap_pin_ok(BlockNumber heapBlk, Buffer buf)
229229
* recptr is the LSN of the XLOG record we're replaying, if we're in recovery,
230230
* or InvalidXLogRecPtr in normal running. The page LSN is advanced to the
231231
* one provided; in normal running, we generate a new XLOG record and set the
232-
* page LSN to that value.
232+
* page LSN to that value. cutoff_xid is the largest xmin on the page being
233+
* marked all-visible; it is needed for Hot Standby, and can be
234+
* InvalidTransactionId if the page contains no tuples.
233235
*
234236
* You must pass a buffer containing the correct map page to this function.
235237
* Call visibilitymap_pin first to pin the right one. This function doesn't do
236238
* any I/O.
237239
*/
238240
void
239241
visibilitymap_set(Relationrel,BlockNumberheapBlk,XLogRecPtrrecptr,
240-
Bufferbuf)
242+
Bufferbuf,TransactionIdcutoff_xid)
241243
{
242244
BlockNumbermapBlock=HEAPBLK_TO_MAPBLOCK(heapBlk);
243245
uint32mapByte=HEAPBLK_TO_MAPBYTE(heapBlk);
@@ -269,7 +271,8 @@ visibilitymap_set(Relation rel, BlockNumber heapBlk, XLogRecPtr recptr,
269271
if (RelationNeedsWAL(rel))
270272
{
271273
if (XLogRecPtrIsInvalid(recptr))
272-
recptr=log_heap_visible(rel->rd_node,heapBlk,buf);
274+
recptr=log_heap_visible(rel->rd_node,heapBlk,buf,
275+
cutoff_xid);
273276
PageSetLSN(page,recptr);
274277
PageSetTLI(page,ThisTimeLineID);
275278
}

‎src/backend/commands/vacuumlazy.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
448448
boolall_visible_according_to_vm;
449449
boolall_visible;
450450
boolhas_dead_tuples;
451+
TransactionIdvisibility_cutoff_xid=InvalidTransactionId;
451452

452453
if (blkno==next_not_all_visible_block)
453454
{
@@ -627,7 +628,8 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
627628
{
628629
PageSetAllVisible(page);
629630
MarkBufferDirty(buf);
630-
visibilitymap_set(onerel,blkno,InvalidXLogRecPtr,vmbuffer);
631+
visibilitymap_set(onerel,blkno,InvalidXLogRecPtr,vmbuffer,
632+
InvalidTransactionId);
631633
}
632634

633635
UnlockReleaseBuffer(buf);
@@ -759,6 +761,10 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
759761
all_visible= false;
760762
break;
761763
}
764+
765+
/* Track newest xmin on page. */
766+
if (TransactionIdFollows(xmin,visibility_cutoff_xid))
767+
visibility_cutoff_xid=xmin;
762768
}
763769
break;
764770
caseHEAPTUPLE_RECENTLY_DEAD:
@@ -853,7 +859,8 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
853859
PageSetAllVisible(page);
854860
MarkBufferDirty(buf);
855861
}
856-
visibilitymap_set(onerel,blkno,InvalidXLogRecPtr,vmbuffer);
862+
visibilitymap_set(onerel,blkno,InvalidXLogRecPtr,vmbuffer,
863+
visibility_cutoff_xid);
857864
}
858865

859866
/*

‎src/include/access/heapam.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ extern XLogRecPtr log_heap_freeze(Relation reln, Buffer buffer,
141141
TransactionIdcutoff_xid,
142142
OffsetNumber*offsets,intoffcnt);
143143
externXLogRecPtrlog_heap_visible(RelFileNodernode,BlockNumberblock,
144-
Buffervm_buffer);
144+
Buffervm_buffer,TransactionIdcutoff_xid);
145145
externXLogRecPtrlog_newpage(RelFileNode*rnode,ForkNumberforkNum,
146146
BlockNumberblk,Pagepage);
147147

‎src/include/access/htup.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -788,9 +788,10 @@ typedef struct xl_heap_visible
788788
{
789789
RelFileNodenode;
790790
BlockNumberblock;
791+
TransactionIdcutoff_xid;
791792
}xl_heap_visible;
792793

793-
#defineSizeOfHeapVisible (offsetof(xl_heap_visible,block) + sizeof(BlockNumber))
794+
#defineSizeOfHeapVisible (offsetof(xl_heap_visible,cutoff_xid) + sizeof(TransactionId))
794795

795796
externvoidHeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeadertuple,
796797
TransactionId*latestRemovedXid);

‎src/include/access/visibilitymap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ extern void visibilitymap_pin(Relation rel, BlockNumber heapBlk,
2525
Buffer*vmbuf);
2626
externboolvisibilitymap_pin_ok(BlockNumberheapBlk,Buffervmbuf);
2727
externvoidvisibilitymap_set(Relationrel,BlockNumberheapBlk,
28-
XLogRecPtrrecptr,Buffervmbuf);
28+
XLogRecPtrrecptr,Buffervmbuf,TransactionIdcutoff_xid);
2929
externboolvisibilitymap_test(Relationrel,BlockNumberheapBlk,Buffer*vmbuf);
3030
externBlockNumbervisibilitymap_count(Relationrel);
3131
externvoidvisibilitymap_truncate(Relationrel,BlockNumbernheapblocks);

‎src/include/access/xlog_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ typedef struct XLogContRecord
7171
/*
7272
* Each page of XLOG file has a header like this:
7373
*/
74-
#defineXLOG_PAGE_MAGIC0xD070/* can be used as WAL version indicator */
74+
#defineXLOG_PAGE_MAGIC0xD071/* can be used as WAL version indicator */
7575

7676
typedefstructXLogPageHeaderData
7777
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp