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

Commitb5f58cf

Browse files
committed
Convert gist to compute page level xid horizon on primary.
Due to parallel development, gist added the missing conflictinformation inc952eae, while558a916 moved that computationto the primary for the index types that already had it. Thus adaptgist to also compute on the primary, usingindex_compute_xid_horizon_for_tuples() instead of its own copy of thelogic.This also adds pg_waldump support for XLOG_GIST_DELETE records, whichpreviously was not properly present.Bumps WAL version.Author: Andres FreundDiscussion:https://postgr.es/m/20190406050243.bszosdg4buvabfrt@alap3.anarazel.de
1 parentb804c18 commitb5f58cf

File tree

6 files changed

+18
-157
lines changed

6 files changed

+18
-157
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,7 @@ gistprunepage(Relation rel, Page page, Buffer buffer, Relation heapRel)
16161616
intndeletable=0;
16171617
OffsetNumberoffnum,
16181618
maxoff;
1619+
TransactionIdlatestRemovedXid=InvalidTransactionId;
16191620

16201621
Assert(GistPageIsLeaf(page));
16211622

@@ -1634,6 +1635,11 @@ gistprunepage(Relation rel, Page page, Buffer buffer, Relation heapRel)
16341635
deletable[ndeletable++]=offnum;
16351636
}
16361637

1638+
if (XLogStandbyInfoActive()&&RelationNeedsWAL(rel))
1639+
latestRemovedXid=
1640+
index_compute_xid_horizon_for_tuples(rel,heapRel,buffer,
1641+
deletable,ndeletable);
1642+
16371643
if (ndeletable>0)
16381644
{
16391645
START_CRIT_SECTION();
@@ -1658,7 +1664,7 @@ gistprunepage(Relation rel, Page page, Buffer buffer, Relation heapRel)
16581664

16591665
recptr=gistXLogDelete(buffer,
16601666
deletable,ndeletable,
1661-
heapRel->rd_node);
1667+
latestRemovedXid);
16621668

16631669
PageSetLSN(page,recptr);
16641670
}

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

Lines changed: 3 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -165,152 +165,6 @@ gistRedoPageUpdateRecord(XLogReaderState *record)
165165
UnlockReleaseBuffer(buffer);
166166
}
167167

168-
/*
169-
* Get the latestRemovedXid from the heap pages pointed at by the index
170-
* tuples being deleted. See also btree_xlog_delete_get_latestRemovedXid,
171-
* on which this function is based.
172-
*/
173-
staticTransactionId
174-
gistRedoDeleteRecordGetLatestRemovedXid(XLogReaderState*record)
175-
{
176-
gistxlogDelete*xlrec= (gistxlogDelete*)XLogRecGetData(record);
177-
OffsetNumber*todelete;
178-
Bufferibuffer,
179-
hbuffer;
180-
Pageipage,
181-
hpage;
182-
RelFileNodernode;
183-
BlockNumberblkno;
184-
ItemIdiitemid,
185-
hitemid;
186-
IndexTupleitup;
187-
HeapTupleHeaderhtuphdr;
188-
BlockNumberhblkno;
189-
OffsetNumberhoffnum;
190-
TransactionIdlatestRemovedXid=InvalidTransactionId;
191-
inti;
192-
193-
/*
194-
* If there's nothing running on the standby we don't need to derive a
195-
* full latestRemovedXid value, so use a fast path out of here. This
196-
* returns InvalidTransactionId, and so will conflict with all HS
197-
* transactions; but since we just worked out that that's zero people,
198-
* it's OK.
199-
*
200-
* XXX There is a race condition here, which is that a new backend might
201-
* start just after we look. If so, it cannot need to conflict, but this
202-
* coding will result in throwing a conflict anyway.
203-
*/
204-
if (CountDBBackends(InvalidOid)==0)
205-
returnlatestRemovedXid;
206-
207-
/*
208-
* In what follows, we have to examine the previous state of the index
209-
* page, as well as the heap page(s) it points to. This is only valid if
210-
* WAL replay has reached a consistent database state; which means that
211-
* the preceding check is not just an optimization, but is *necessary*. We
212-
* won't have let in any user sessions before we reach consistency.
213-
*/
214-
if (!reachedConsistency)
215-
elog(PANIC,"gistRedoDeleteRecordGetLatestRemovedXid: cannot operate with inconsistent data");
216-
217-
/*
218-
* Get index page. If the DB is consistent, this should not fail, nor
219-
* should any of the heap page fetches below. If one does, we return
220-
* InvalidTransactionId to cancel all HS transactions. That's probably
221-
* overkill, but it's safe, and certainly better than panicking here.
222-
*/
223-
XLogRecGetBlockTag(record,0,&rnode,NULL,&blkno);
224-
ibuffer=XLogReadBufferExtended(rnode,MAIN_FORKNUM,blkno,RBM_NORMAL);
225-
if (!BufferIsValid(ibuffer))
226-
returnInvalidTransactionId;
227-
LockBuffer(ibuffer,BUFFER_LOCK_EXCLUSIVE);
228-
ipage= (Page)BufferGetPage(ibuffer);
229-
230-
/*
231-
* Loop through the deleted index items to obtain the TransactionId from
232-
* the heap items they point to.
233-
*/
234-
todelete= (OffsetNumber*) ((char*)xlrec+SizeOfGistxlogDelete);
235-
236-
for (i=0;i<xlrec->ntodelete;i++)
237-
{
238-
/*
239-
* Identify the index tuple about to be deleted
240-
*/
241-
iitemid=PageGetItemId(ipage,todelete[i]);
242-
itup= (IndexTuple)PageGetItem(ipage,iitemid);
243-
244-
/*
245-
* Locate the heap page that the index tuple points at
246-
*/
247-
hblkno=ItemPointerGetBlockNumber(&(itup->t_tid));
248-
hbuffer=XLogReadBufferExtended(xlrec->hnode,MAIN_FORKNUM,hblkno,RBM_NORMAL);
249-
if (!BufferIsValid(hbuffer))
250-
{
251-
UnlockReleaseBuffer(ibuffer);
252-
returnInvalidTransactionId;
253-
}
254-
LockBuffer(hbuffer,BUFFER_LOCK_SHARE);
255-
hpage= (Page)BufferGetPage(hbuffer);
256-
257-
/*
258-
* Look up the heap tuple header that the index tuple points at by
259-
* using the heap node supplied with the xlrec. We can't use
260-
* heap_fetch, since it uses ReadBuffer rather than XLogReadBuffer.
261-
* Note that we are not looking at tuple data here, just headers.
262-
*/
263-
hoffnum=ItemPointerGetOffsetNumber(&(itup->t_tid));
264-
hitemid=PageGetItemId(hpage,hoffnum);
265-
266-
/*
267-
* Follow any redirections until we find something useful.
268-
*/
269-
while (ItemIdIsRedirected(hitemid))
270-
{
271-
hoffnum=ItemIdGetRedirect(hitemid);
272-
hitemid=PageGetItemId(hpage,hoffnum);
273-
CHECK_FOR_INTERRUPTS();
274-
}
275-
276-
/*
277-
* If the heap item has storage, then read the header and use that to
278-
* set latestRemovedXid.
279-
*
280-
* Some LP_DEAD items may not be accessible, so we ignore them.
281-
*/
282-
if (ItemIdHasStorage(hitemid))
283-
{
284-
htuphdr= (HeapTupleHeader)PageGetItem(hpage,hitemid);
285-
286-
HeapTupleHeaderAdvanceLatestRemovedXid(htuphdr,&latestRemovedXid);
287-
}
288-
elseif (ItemIdIsDead(hitemid))
289-
{
290-
/*
291-
* Conjecture: if hitemid is dead then it had xids before the xids
292-
* marked on LP_NORMAL items. So we just ignore this item and move
293-
* onto the next, for the purposes of calculating
294-
* latestRemovedxids.
295-
*/
296-
}
297-
else
298-
Assert(!ItemIdIsUsed(hitemid));
299-
300-
UnlockReleaseBuffer(hbuffer);
301-
}
302-
303-
UnlockReleaseBuffer(ibuffer);
304-
305-
/*
306-
* If all heap tuples were LP_DEAD then we will be returning
307-
* InvalidTransactionId here, which avoids conflicts. This matches
308-
* existing logic which assumes that LP_DEAD tuples must already be older
309-
* than the latestRemovedXid on the cleanup record that set them as
310-
* LP_DEAD, hence must already have generated a conflict.
311-
*/
312-
returnlatestRemovedXid;
313-
}
314168

315169
/*
316170
* redo delete on gist index page to remove tuples marked as DEAD during index
@@ -337,12 +191,11 @@ gistRedoDeleteRecord(XLogReaderState *record)
337191
*/
338192
if (InHotStandby)
339193
{
340-
TransactionIdlatestRemovedXid=gistRedoDeleteRecordGetLatestRemovedXid(record);
341194
RelFileNodernode;
342195

343196
XLogRecGetBlockTag(record,0,&rnode,NULL,NULL);
344197

345-
ResolveRecoveryConflictWithSnapshot(latestRemovedXid,rnode);
198+
ResolveRecoveryConflictWithSnapshot(xldata->latestRemovedXid,rnode);
346199
}
347200

348201
if (XLogReadBufferForRedo(record,0,&buffer)==BLK_NEEDS_REDO)
@@ -800,12 +653,12 @@ gistXLogUpdate(Buffer buffer,
800653
*/
801654
XLogRecPtr
802655
gistXLogDelete(Bufferbuffer,OffsetNumber*todelete,intntodelete,
803-
RelFileNodehnode)
656+
TransactionIdlatestRemovedXid)
804657
{
805658
gistxlogDeletexlrec;
806659
XLogRecPtrrecptr;
807660

808-
xlrec.hnode=hnode;
661+
xlrec.latestRemovedXid=latestRemovedXid;
809662
xlrec.ntodelete=ntodelete;
810663

811664
XLogBeginInsert();

‎src/backend/access/rmgrdesc/gistdesc.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@ out_gistxlogPageReuse(StringInfo buf, gistxlogPageReuse *xlrec)
3333
}
3434

3535
staticvoid
36-
out_gistxlogDelete(StringInfobuf,gistxlogPageUpdate*xlrec)
36+
out_gistxlogDelete(StringInfobuf,gistxlogDelete*xlrec)
3737
{
38+
appendStringInfo(buf,"delete: latestRemovedXid %u, nitems: %u",
39+
xlrec->latestRemovedXid,xlrec->ntodelete);
40+
3841
}
3942

4043
staticvoid
@@ -66,7 +69,7 @@ gist_desc(StringInfo buf, XLogReaderState *record)
6669
out_gistxlogPageReuse(buf, (gistxlogPageReuse*)rec);
6770
break;
6871
caseXLOG_GIST_DELETE:
69-
out_gistxlogDelete(buf, (gistxlogPageUpdate*)rec);
72+
out_gistxlogDelete(buf, (gistxlogDelete*)rec);
7073
break;
7174
caseXLOG_GIST_PAGE_SPLIT:
7275
out_gistxlogPageSplit(buf, (gistxlogPageSplit*)rec);

‎src/include/access/gist_private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ extern XLogRecPtr gistXLogUpdate(Buffer buffer,
431431
Bufferleftchild);
432432

433433
externXLogRecPtrgistXLogDelete(Bufferbuffer,OffsetNumber*todelete,
434-
intntodelete,RelFileNodehnode);
434+
intntodelete,TransactionIdlatestRemovedXid);
435435

436436
externXLogRecPtrgistXLogSplit(boolpage_is_leaf,
437437
SplitedPageLayout*dist,

‎src/include/access/gistxlog.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ typedef struct gistxlogPageUpdate
4747
*/
4848
typedefstructgistxlogDelete
4949
{
50-
RelFileNodehnode;/* RelFileNode of the heap the index currently
51-
* points at */
50+
TransactionIdlatestRemovedXid;
5251
uint16ntodelete;/* number of deleted offsets */
5352

5453
/*

‎src/include/access/xlog_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
/*
3232
* Each page of XLOG file has a header like this:
3333
*/
34-
#defineXLOG_PAGE_MAGIC0xD100/* can be used as WAL version indicator */
34+
#defineXLOG_PAGE_MAGIC0xD101/* can be used as WAL version indicator */
3535

3636
typedefstructXLogPageHeaderData
3737
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp