@@ -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- static TransactionId
174- gistRedoDeleteRecordGetLatestRemovedXid (XLogReaderState * record )
175- {
176- gistxlogDelete * xlrec = (gistxlogDelete * ) XLogRecGetData (record );
177- OffsetNumber * todelete ;
178- Buffer ibuffer ,
179- hbuffer ;
180- Page ipage ,
181- hpage ;
182- RelFileNode rnode ;
183- BlockNumber blkno ;
184- ItemId iitemid ,
185- hitemid ;
186- IndexTuple itup ;
187- HeapTupleHeader htuphdr ;
188- BlockNumber hblkno ;
189- OffsetNumber hoffnum ;
190- TransactionId latestRemovedXid = InvalidTransactionId ;
191- int i ;
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- return latestRemovedXid ;
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- return InvalidTransactionId ;
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- return InvalidTransactionId ;
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- else if (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- return latestRemovedXid ;
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- TransactionId latestRemovedXid = gistRedoDeleteRecordGetLatestRemovedXid (record );
341194 RelFileNode rnode ;
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 */
801654XLogRecPtr
802655gistXLogDelete (Buffer buffer , OffsetNumber * todelete , int ntodelete ,
803- RelFileNode hnode )
656+ TransactionId latestRemovedXid )
804657{
805658 gistxlogDelete xlrec ;
806659 XLogRecPtr recptr ;
807660
808- xlrec .hnode = hnode ;
661+ xlrec .latestRemovedXid = latestRemovedXid ;
809662 xlrec .ntodelete = ntodelete ;
810663
811664 XLogBeginInsert ();
0 commit comments