@@ -165,152 +165,6 @@ gistRedoPageUpdateRecord(XLogReaderState *record)
165
165
UnlockReleaseBuffer (buffer );
166
166
}
167
167
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
- }
314
168
315
169
/*
316
170
* redo delete on gist index page to remove tuples marked as DEAD during index
@@ -337,12 +191,11 @@ gistRedoDeleteRecord(XLogReaderState *record)
337
191
*/
338
192
if (InHotStandby )
339
193
{
340
- TransactionId latestRemovedXid = gistRedoDeleteRecordGetLatestRemovedXid (record );
341
194
RelFileNode rnode ;
342
195
343
196
XLogRecGetBlockTag (record , 0 , & rnode , NULL , NULL );
344
197
345
- ResolveRecoveryConflictWithSnapshot (latestRemovedXid , rnode );
198
+ ResolveRecoveryConflictWithSnapshot (xldata -> latestRemovedXid , rnode );
346
199
}
347
200
348
201
if (XLogReadBufferForRedo (record , 0 , & buffer ) == BLK_NEEDS_REDO )
@@ -800,12 +653,12 @@ gistXLogUpdate(Buffer buffer,
800
653
*/
801
654
XLogRecPtr
802
655
gistXLogDelete (Buffer buffer , OffsetNumber * todelete , int ntodelete ,
803
- RelFileNode hnode )
656
+ TransactionId latestRemovedXid )
804
657
{
805
658
gistxlogDelete xlrec ;
806
659
XLogRecPtr recptr ;
807
660
808
- xlrec .hnode = hnode ;
661
+ xlrec .latestRemovedXid = latestRemovedXid ;
809
662
xlrec .ntodelete = ntodelete ;
810
663
811
664
XLogBeginInsert ();
0 commit comments