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

Commit1489b1c

Browse files
Standardize rmgrdesc recovery conflict XID output.
Standardize on the name snapshotConflictHorizon for all XID fields fromWAL records that generate recovery conflicts when in hot standby mode.This supersedes the previous latestRemovedXid naming convention.The new naming convention places emphasis on how the values are actuallyused by REDO routines. How the values are generated during originalexecution (details of which vary by record type) is deemphasized. Usersof tools like pg_waldump can now grep for snapshotConflictHorizon to seeall potential sources of recovery conflicts in a standardized way,without necessarily having to consider which specific record types mightbe involved.Also bring a couple of WAL record types that didn't follow any kind ofnaming convention into line. These are heapam's VISIBLE record type andSP-GiST's VACUUM_REDIRECT record type. Now every WAL record whose REDOroutine calls ResolveRecoveryConflictWithSnapshot() passes through thesnapshotConflictHorizon field from its WAL record. This is follow-upwork to the refactoring from commit9e54059 that made FREEZE_PAGE WALrecords use a standard snapshotConflictHorizon style XID cutoff.No bump in XLOG_PAGE_MAGIC, since the underlying format of affected WALrecords doesn't change.Author: Peter Geoghegan <pg@bowt.ie>Reviewed-By: Andres Freund <andres@anarazel.de>Discussion:https://postgr.es/m/CAH2-Wzm2CQUmViUq7Opgk=McVREHSOorYaAjR1ZpLYkRN7_dPw@mail.gmail.com
1 parent6ff5aa1 commit1489b1c

File tree

27 files changed

+179
-150
lines changed

27 files changed

+179
-150
lines changed

‎src/backend/access/gist/gist.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,10 +1665,10 @@ gistprunepage(Relation rel, Page page, Buffer buffer, Relation heapRel)
16651665

16661666
if (ndeletable>0)
16671667
{
1668-
TransactionIdlatestRemovedXid=InvalidTransactionId;
1668+
TransactionIdsnapshotConflictHorizon=InvalidTransactionId;
16691669

16701670
if (XLogStandbyInfoActive()&&RelationNeedsWAL(rel))
1671-
latestRemovedXid=
1671+
snapshotConflictHorizon=
16721672
index_compute_xid_horizon_for_tuples(rel,heapRel,buffer,
16731673
deletable,ndeletable);
16741674

@@ -1694,7 +1694,7 @@ gistprunepage(Relation rel, Page page, Buffer buffer, Relation heapRel)
16941694

16951695
recptr=gistXLogDelete(buffer,
16961696
deletable,ndeletable,
1697-
latestRemovedXid);
1697+
snapshotConflictHorizon);
16981698

16991699
PageSetLSN(page,recptr);
17001700
}

‎src/backend/access/gist/gistxlog.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ gistRedoDeleteRecord(XLogReaderState *record)
195195

196196
XLogRecGetBlockTag(record,0,&rlocator,NULL,NULL);
197197

198-
ResolveRecoveryConflictWithSnapshot(xldata->latestRemovedXid,
198+
ResolveRecoveryConflictWithSnapshot(xldata->snapshotConflictHorizon,
199199
rlocator);
200200
}
201201

@@ -388,14 +388,14 @@ gistRedoPageReuse(XLogReaderState *record)
388388
* PAGE_REUSE records exist to provide a conflict point when we reuse
389389
* pages in the index via the FSM. That's all they do though.
390390
*
391-
*latestRemovedXid was the page's deleteXid. The
391+
*snapshotConflictHorizon was the page's deleteXid. The
392392
* GlobalVisCheckRemovableFullXid(deleteXid) test in gistPageRecyclable()
393393
* conceptually mirrors the PGPROC->xmin > limitXmin test in
394394
* GetConflictingVirtualXIDs(). Consequently, one XID value achieves the
395395
* same exclusion effect on primary and standby.
396396
*/
397397
if (InHotStandby)
398-
ResolveRecoveryConflictWithSnapshotFullXid(xlrec->latestRemovedFullXid,
398+
ResolveRecoveryConflictWithSnapshotFullXid(xlrec->snapshotConflictHorizon,
399399
xlrec->locator);
400400
}
401401

@@ -597,7 +597,7 @@ gistXLogAssignLSN(void)
597597
* Write XLOG record about reuse of a deleted page.
598598
*/
599599
void
600-
gistXLogPageReuse(Relationrel,BlockNumberblkno,FullTransactionIdlatestRemovedXid)
600+
gistXLogPageReuse(Relationrel,BlockNumberblkno,FullTransactionIddeleteXid)
601601
{
602602
gistxlogPageReusexlrec_reuse;
603603

@@ -610,7 +610,7 @@ gistXLogPageReuse(Relation rel, BlockNumber blkno, FullTransactionId latestRemov
610610
/* XLOG stuff */
611611
xlrec_reuse.locator=rel->rd_locator;
612612
xlrec_reuse.block=blkno;
613-
xlrec_reuse.latestRemovedFullXid=latestRemovedXid;
613+
xlrec_reuse.snapshotConflictHorizon=deleteXid;
614614

615615
XLogBeginInsert();
616616
XLogRegisterData((char*)&xlrec_reuse,SizeOfGistxlogPageReuse);
@@ -672,20 +672,21 @@ gistXLogUpdate(Buffer buffer,
672672
*/
673673
XLogRecPtr
674674
gistXLogDelete(Bufferbuffer,OffsetNumber*todelete,intntodelete,
675-
TransactionIdlatestRemovedXid)
675+
TransactionIdsnapshotConflictHorizon)
676676
{
677677
gistxlogDeletexlrec;
678678
XLogRecPtrrecptr;
679679

680-
xlrec.latestRemovedXid=latestRemovedXid;
680+
xlrec.snapshotConflictHorizon=snapshotConflictHorizon;
681681
xlrec.ntodelete=ntodelete;
682682

683683
XLogBeginInsert();
684684
XLogRegisterData((char*)&xlrec,SizeOfGistxlogDelete);
685685

686686
/*
687687
* We need the target-offsets array whether or not we store the whole
688-
* buffer, to allow us to find the latestRemovedXid on a standby server.
688+
* buffer, to allow us to find the snapshotConflictHorizon on a standby
689+
* server.
689690
*/
690691
XLogRegisterData((char*)todelete,ntodelete*sizeof(OffsetNumber));
691692

‎src/backend/access/hash/hash_xlog.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,8 @@ hash_xlog_vacuum_one_page(XLogReaderState *record)
10001000
RelFileLocatorrlocator;
10011001

10021002
XLogRecGetBlockTag(record,0,&rlocator,NULL,NULL);
1003-
ResolveRecoveryConflictWithSnapshot(xldata->latestRemovedXid,rlocator);
1003+
ResolveRecoveryConflictWithSnapshot(xldata->snapshotConflictHorizon,
1004+
rlocator);
10041005
}
10051006

10061007
action=XLogReadBufferForRedoExtended(record,0,RBM_NORMAL, true,&buffer);

‎src/backend/access/hash/hashinsert.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,9 @@ _hash_vacuum_one_page(Relation rel, Relation hrel, Buffer metabuf, Buffer buf)
360360

361361
if (ndeletable>0)
362362
{
363-
TransactionIdlatestRemovedXid;
363+
TransactionIdsnapshotConflictHorizon;
364364

365-
latestRemovedXid=
365+
snapshotConflictHorizon=
366366
index_compute_xid_horizon_for_tuples(rel,hrel,buf,
367367
deletable,ndeletable);
368368

@@ -399,7 +399,7 @@ _hash_vacuum_one_page(Relation rel, Relation hrel, Buffer metabuf, Buffer buf)
399399
xl_hash_vacuum_one_pagexlrec;
400400
XLogRecPtrrecptr;
401401

402-
xlrec.latestRemovedXid=latestRemovedXid;
402+
xlrec.snapshotConflictHorizon=snapshotConflictHorizon;
403403
xlrec.ntuples=ndeletable;
404404

405405
XLogBeginInsert();
@@ -408,8 +408,8 @@ _hash_vacuum_one_page(Relation rel, Relation hrel, Buffer metabuf, Buffer buf)
408408

409409
/*
410410
* We need the target-offsets array whether or not we store the
411-
* whole buffer, to allow us to find thelatestRemovedXid on a
412-
* standby server.
411+
* whole buffer, to allow us to find thesnapshotConflictHorizon
412+
*on astandby server.
413413
*/
414414
XLogRegisterData((char*)deletable,
415415
ndeletable*sizeof(OffsetNumber));

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

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6792,7 +6792,7 @@ heap_freeze_execute_prepared(Relation rel, Buffer buffer,
67926792
Pagepage=BufferGetPage(buffer);
67936793

67946794
Assert(ntuples>0);
6795-
Assert(TransactionIdIsValid(FreezeLimit));
6795+
Assert(TransactionIdIsNormal(FreezeLimit));
67966796

67976797
START_CRIT_SECTION();
67986798

@@ -6815,21 +6815,20 @@ heap_freeze_execute_prepared(Relation rel, Buffer buffer,
68156815
intnplans;
68166816
xl_heap_freeze_pagexlrec;
68176817
XLogRecPtrrecptr;
6818-
TransactionIdlatestRemovedXid;
6818+
TransactionIdsnapshotConflictHorizon;
68196819

68206820
/* Prepare deduplicated representation for use in WAL record */
68216821
nplans=heap_xlog_freeze_plan(tuples,ntuples,plans,offsets);
68226822

68236823
/*
6824-
* latestRemovedXid describes the latest processed XID, whereas
68256824
* FreezeLimit is (approximately) the first XID not frozen by VACUUM.
68266825
* Back up caller's FreezeLimit to avoid false conflicts when
68276826
* FreezeLimit is precisely equal to VACUUM's OldestXmin cutoff.
68286827
*/
6829-
latestRemovedXid=FreezeLimit;
6830-
TransactionIdRetreat(latestRemovedXid);
6828+
snapshotConflictHorizon=FreezeLimit;
6829+
TransactionIdRetreat(snapshotConflictHorizon);
68316830

6832-
xlrec.latestRemovedXid=latestRemovedXid;
6831+
xlrec.snapshotConflictHorizon=snapshotConflictHorizon;
68336832
xlrec.nplans=nplans;
68346833

68356834
XLogBeginInsert();
@@ -7401,24 +7400,30 @@ heap_tuple_would_freeze(HeapTupleHeader tuple, TransactionId cutoff_xid,
74017400
}
74027401

74037402
/*
7404-
* If 'tuple' contains any visible XID greater than latestRemovedXid,
7405-
* ratchet forwards latestRemovedXid to the greatest one found.
7406-
* This is used as the basis for generating Hot Standby conflicts, so
7407-
* if a tuple was never visible then removing it should not conflict
7408-
* with queries.
7403+
* Maintain snapshotConflictHorizon for caller by ratcheting forward its value
7404+
* using any committed XIDs contained in 'tuple', an obsolescent heap tuple
7405+
* that caller is in the process of physically removing, e.g. via HOT pruning
7406+
* or index deletion.
7407+
*
7408+
* Caller must initialize its value to InvalidTransactionId, which is
7409+
* generally interpreted as "definitely no need for a recovery conflict".
7410+
* Final value must reflect all heap tuples that caller will physically remove
7411+
* (or remove TID references to) via its ongoing pruning/deletion operation.
7412+
* ResolveRecoveryConflictWithSnapshot() is passed the final value (taken from
7413+
* caller's WAL record) by REDO routine when it replays caller's operation.
74097414
*/
74107415
void
7411-
HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeadertuple,
7412-
TransactionId*latestRemovedXid)
7416+
HeapTupleHeaderAdvanceConflictHorizon(HeapTupleHeadertuple,
7417+
TransactionId*snapshotConflictHorizon)
74137418
{
74147419
TransactionIdxmin=HeapTupleHeaderGetXmin(tuple);
74157420
TransactionIdxmax=HeapTupleHeaderGetUpdateXid(tuple);
74167421
TransactionIdxvac=HeapTupleHeaderGetXvac(tuple);
74177422

74187423
if (tuple->t_infomask&HEAP_MOVED)
74197424
{
7420-
if (TransactionIdPrecedes(*latestRemovedXid,xvac))
7421-
*latestRemovedXid=xvac;
7425+
if (TransactionIdPrecedes(*snapshotConflictHorizon,xvac))
7426+
*snapshotConflictHorizon=xvac;
74227427
}
74237428

74247429
/*
@@ -7431,11 +7436,9 @@ HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeader tuple,
74317436
(!HeapTupleHeaderXminInvalid(tuple)&&TransactionIdDidCommit(xmin)))
74327437
{
74337438
if (xmax!=xmin&&
7434-
TransactionIdFollows(xmax,*latestRemovedXid))
7435-
*latestRemovedXid=xmax;
7439+
TransactionIdFollows(xmax,*snapshotConflictHorizon))
7440+
*snapshotConflictHorizon=xmax;
74367441
}
7437-
7438-
/* *latestRemovedXid may still be invalid at end */
74397442
}
74407443

74417444
#ifdefUSE_PREFETCH
@@ -7558,7 +7561,7 @@ TransactionId
75587561
heap_index_delete_tuples(Relationrel,TM_IndexDeleteOp*delstate)
75597562
{
75607563
/* Initial assumption is that earlier pruning took care of conflict */
7561-
TransactionIdlatestRemovedXid=InvalidTransactionId;
7564+
TransactionIdsnapshotConflictHorizon=InvalidTransactionId;
75627565
BlockNumberblkno=InvalidBlockNumber;
75637566
Bufferbuf=InvalidBuffer;
75647567
Pagepage=NULL;
@@ -7769,8 +7772,8 @@ heap_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate)
77697772
}
77707773

77717774
/*
7772-
* MaintainlatestRemovedXid value for deletion operation as a whole
7773-
* by advancing current value using heap tuple headers. This is
7775+
* MaintainsnapshotConflictHorizon value for deletion operation as a
7776+
*wholeby advancing current value using heap tuple headers. This is
77747777
* loosely based on the logic for pruning a HOT chain.
77757778
*/
77767779
offnum=ItemPointerGetOffsetNumber(htid);
@@ -7805,12 +7808,12 @@ heap_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate)
78057808
* LP_DEAD item. This is okay because the earlier pruning
78067809
* operation that made the line pointer LP_DEAD in the first place
78077810
* must have considered the original tuple header as part of
7808-
* generating its ownlatestRemovedXid value.
7811+
* generating its ownsnapshotConflictHorizon value.
78097812
*
78107813
* Relying on XLOG_HEAP2_PRUNE records like this is the same
78117814
* strategy that index vacuuming uses in all cases. Index VACUUM
7812-
* WAL records don't even have alatestRemovedXid field of their
7813-
* own for this reason.
7815+
* WAL records don't even have asnapshotConflictHorizon field of
7816+
*theirown for this reason.
78147817
*/
78157818
if (!ItemIdIsNormal(lp))
78167819
break;
@@ -7824,7 +7827,8 @@ heap_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate)
78247827
!TransactionIdEquals(HeapTupleHeaderGetXmin(htup),priorXmax))
78257828
break;
78267829

7827-
HeapTupleHeaderAdvanceLatestRemovedXid(htup,&latestRemovedXid);
7830+
HeapTupleHeaderAdvanceConflictHorizon(htup,
7831+
&snapshotConflictHorizon);
78287832

78297833
/*
78307834
* If the tuple is not HOT-updated, then we are at the end of this
@@ -7856,7 +7860,7 @@ heap_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate)
78567860
Assert(finalndeltids>0||delstate->bottomup);
78577861
delstate->ndeltids=finalndeltids;
78587862

7859-
returnlatestRemovedXid;
7863+
returnsnapshotConflictHorizon;
78607864
}
78617865

78627866
/*
@@ -8232,14 +8236,17 @@ bottomup_sort_and_shrink(TM_IndexDeleteOp *delstate)
82328236
* corresponding visibility map block. Both should have already been modified
82338237
* and dirtied.
82348238
*
8239+
* snapshotConflictHorizon comes from the largest xmin on the page being
8240+
* marked all-visible. REDO routine uses it to generate recovery conflicts.
8241+
*
82358242
* If checksums or wal_log_hints are enabled, we may also generate a full-page
82368243
* image of heap_buffer. Otherwise, we optimize away the FPI (by specifying
82378244
* REGBUF_NO_IMAGE for the heap buffer), in which case the caller should *not*
82388245
* update the heap page's LSN.
82398246
*/
82408247
XLogRecPtr
82418248
log_heap_visible(RelFileLocatorrlocator,Bufferheap_buffer,Buffervm_buffer,
8242-
TransactionIdcutoff_xid,uint8vmflags)
8249+
TransactionIdsnapshotConflictHorizon,uint8vmflags)
82438250
{
82448251
xl_heap_visiblexlrec;
82458252
XLogRecPtrrecptr;
@@ -8248,7 +8255,7 @@ log_heap_visible(RelFileLocator rlocator, Buffer heap_buffer, Buffer vm_buffer,
82488255
Assert(BufferIsValid(heap_buffer));
82498256
Assert(BufferIsValid(vm_buffer));
82508257

8251-
xlrec.cutoff_xid=cutoff_xid;
8258+
xlrec.snapshotConflictHorizon=snapshotConflictHorizon;
82528259
xlrec.flags=vmflags;
82538260
XLogBeginInsert();
82548261
XLogRegisterData((char*)&xlrec,SizeOfHeapVisible);
@@ -8683,7 +8690,8 @@ heap_xlog_prune(XLogReaderState *record)
86838690
* no queries running for which the removed tuples are still visible.
86848691
*/
86858692
if (InHotStandby)
8686-
ResolveRecoveryConflictWithSnapshot(xlrec->latestRemovedXid,rlocator);
8693+
ResolveRecoveryConflictWithSnapshot(xlrec->snapshotConflictHorizon,
8694+
rlocator);
86878695

86888696
/*
86898697
* If we have a full-page image, restore it (using a cleanup lock) and
@@ -8851,7 +8859,8 @@ heap_xlog_visible(XLogReaderState *record)
88518859
* rather than killing the transaction outright.
88528860
*/
88538861
if (InHotStandby)
8854-
ResolveRecoveryConflictWithSnapshot(xlrec->cutoff_xid,rlocator);
8862+
ResolveRecoveryConflictWithSnapshot(xlrec->snapshotConflictHorizon,
8863+
rlocator);
88558864

88568865
/*
88578866
* Read the heap page, if it still exists. If the heap file has dropped or
@@ -8939,7 +8948,7 @@ heap_xlog_visible(XLogReaderState *record)
89398948
visibilitymap_pin(reln,blkno,&vmbuffer);
89408949

89418950
visibilitymap_set(reln,blkno,InvalidBuffer,lsn,vmbuffer,
8942-
xlrec->cutoff_xid,xlrec->flags);
8951+
xlrec->snapshotConflictHorizon,xlrec->flags);
89438952

89448953
ReleaseBuffer(vmbuffer);
89458954
FreeFakeRelcacheEntry(reln);
@@ -9105,7 +9114,8 @@ heap_xlog_freeze_page(XLogReaderState *record)
91059114
RelFileLocatorrlocator;
91069115

91079116
XLogRecGetBlockTag(record,0,&rlocator,NULL,NULL);
9108-
ResolveRecoveryConflictWithSnapshot(xlrec->latestRemovedXid,rlocator);
9117+
ResolveRecoveryConflictWithSnapshot(xlrec->snapshotConflictHorizon,
9118+
rlocator);
91099119
}
91109120

91119121
if (XLogReadBufferForRedo(record,0,&buffer)==BLK_NEEDS_REDO)

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ typedef struct
4949
boolold_snap_used;
5050

5151
TransactionIdnew_prune_xid;/* new prune hint value for page */
52-
TransactionIdlatestRemovedXid;/* latest xidto beremoved by this prune */
52+
TransactionIdsnapshotConflictHorizon;/* latest xid removed */
5353
intnredirected;/* numbers of entries in arrays below */
5454
intndead;
5555
intnunused;
@@ -295,7 +295,7 @@ heap_page_prune(Relation relation, Buffer buffer,
295295
prstate.old_snap_xmin=old_snap_xmin;
296296
prstate.old_snap_ts=old_snap_ts;
297297
prstate.old_snap_used= false;
298-
prstate.latestRemovedXid=InvalidTransactionId;
298+
prstate.snapshotConflictHorizon=InvalidTransactionId;
299299
prstate.nredirected=prstate.ndead=prstate.nunused=0;
300300
memset(prstate.marked,0,sizeof(prstate.marked));
301301

@@ -418,7 +418,7 @@ heap_page_prune(Relation relation, Buffer buffer,
418418
xl_heap_prunexlrec;
419419
XLogRecPtrrecptr;
420420

421-
xlrec.latestRemovedXid=prstate.latestRemovedXid;
421+
xlrec.snapshotConflictHorizon=prstate.snapshotConflictHorizon;
422422
xlrec.nredirected=prstate.nredirected;
423423
xlrec.ndead=prstate.ndead;
424424

@@ -636,8 +636,8 @@ heap_prune_chain(Buffer buffer, OffsetNumber rootoffnum, PruneState *prstate)
636636
!HeapTupleHeaderIsHotUpdated(htup))
637637
{
638638
heap_prune_record_unused(prstate,rootoffnum);
639-
HeapTupleHeaderAdvanceLatestRemovedXid(htup,
640-
&prstate->latestRemovedXid);
639+
HeapTupleHeaderAdvanceConflictHorizon(htup,
640+
&prstate->snapshotConflictHorizon);
641641
ndeleted++;
642642
}
643643

@@ -773,8 +773,8 @@ heap_prune_chain(Buffer buffer, OffsetNumber rootoffnum, PruneState *prstate)
773773
if (tupdead)
774774
{
775775
latestdead=offnum;
776-
HeapTupleHeaderAdvanceLatestRemovedXid(htup,
777-
&prstate->latestRemovedXid);
776+
HeapTupleHeaderAdvanceConflictHorizon(htup,
777+
&prstate->snapshotConflictHorizon);
778778
}
779779
elseif (!recent_dead)
780780
break;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp