PostgreSQL Source Code: src/backend/access/gist/gistvacuum.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
16
27
28
29typedef struct
30{
36
37
38
39
40
45
54
55
56
57
61{
62
63 if (stats == NULL)
65
67
68 return stats;
69}
70
71
72
73
76{
77
79 return stats;
80
81
82
83
84
85
86 if (stats == NULL)
87 {
90 }
91
92
93
94
95
96
97
99 {
102 }
103
104 return stats;
105}
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124static void
127{
131 bool needLock;
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
156
157
158
159
160
161
162
163
164
165
166
168 "GiST VACUUM page set context",
169 16 * 1024,
170 16 * 1024,
171 16 * 1024);
176
177
178 vstate.info = info;
179 vstate.stats = stats;
184 else
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
211
213
214
215
216
217
222 rel,
225 &p,
226 0);
227 for (;;)
228 {
229
230 if (needLock)
233 if (needLock)
235
236
238 break;
239
241
242
243 while (true)
244 {
246
247
249
251
253 break;
254
256 }
257
258
259
260
261
262
264 }
265
267
268
269
270
271
272
273
274
275
276
277
278
279
282
283
285
286
287
288
289
291
292
297}
298
299
300
301
302
303
304
305
306
307static void
309{
317
318
319
320
321
322
324
325restart:
327
328
329
330
331
334
336 {
337
341 }
343 {
344
346 }
348 {
350 int ntodelete = 0;
351 int nremain;
354
355
356
357
358
359
360
361
362
363
364
368 (opaque->rightlink < orig_blkno))
369 {
371 }
372
373
374
375
376
378 {
380
382 off <= maxoff;
384 {
387
388 if (callback(&(idxtuple->t_tid), callback_state))
389 todelete[ntodelete++] = off;
390 }
391 }
392
393
394
395
396
397 if (ntodelete > 0)
398 {
400
402
405
407 {
409
411 todelete, ntodelete,
414 }
415 else
417
419
421
423 }
424
426 if (nremain == 0)
427 {
428
429
430
431
432
433
434
435
436 if (blkno == orig_blkno)
438 }
439 else
441 }
442 else
443 {
444
445
446
447
448
449
450
453
455 off <= maxoff;
457 {
460
463 (errmsg("index \"%s\" contains an inner tuple marked as invalid",
465 errdetail("This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1."),
466 errhint("Please REINDEX it.")));
467 }
468
469
470
471
472
473
474 if (blkno == orig_blkno)
476 }
477
479
480
481
482
483
484
485
486
488 {
489 blkno = recurse_to;
490
491
493
496 goto restart;
497 }
498}
499
500
501
502
503static void
505{
509
510
511
512
515 while (empty_pages_remaining > 0 &&
517 {
521 maxoff;
524 int ntodelete;
525 int deleted;
526
529
532
534 {
535
536
537
538
541 continue;
542 }
543
544
545
546
547
549 ntodelete = 0;
551 off <= maxoff && ntodelete < maxoff - 1;
553 {
557
560 {
561 leafs_to_delete[ntodelete] = leafblk;
562 todelete[ntodelete++] = off;
563 }
564 }
565
566
567
568
569
570
571
572
573
574
575
576
577
578
580
581 deleted = 0;
582 for (int i = 0; i < ntodelete; i++)
583 {
585
586
587
588
589
591 break;
592
597
600 buffer, todelete[i] - deleted,
601 leafbuf))
602 deleted++;
604
606 }
607
609
610
611
612
613
614 empty_pages_remaining -= ntodelete;
615 }
616}
617
618
619
620
621
622
623
624
625
626
627
628
629
630static bool
634{
641
642
643
644
646 {
647
649 return false;
650 }
651
653 return false;
654
656 return false;
657
658
659
660
661
662
663
664
667 {
668
670 return false;
671 }
672
675 return false;
676
681 return false;
682
683
684
685
686
687
688
689
690
691
692
694
696
697
702
703
706
708 recptr = gistXLogPageDelete(leafBuffer, txid, parentBuffer, downlink);
709 else
713
715
716 return true;
717}
#define InvalidBlockNumber
BlockNumber BufferGetBlockNumber(Buffer buffer)
void ReleaseBuffer(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
static bool BufferIsValid(Buffer bufnum)
void PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
void PageIndexTupleDelete(Page page, OffsetNumber offnum)
static Item PageGetItem(const PageData *page, const ItemIdData *itemId)
static bool PageIsNew(const PageData *page)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static void PageSetLSN(Page page, XLogRecPtr lsn)
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
bool(* IndexBulkDeleteCallback)(ItemPointer itemptr, void *state)
MemoryContext GenerationContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
#define GistPageIsLeaf(page)
static void GistPageSetDeleted(Page page, FullTransactionId deletexid)
#define GistMarkTuplesDeleted(page)
#define GistFollowRight(page)
#define GistPageIsDeleted(page)
#define GistPageGetOpaque(page)
#define GistPageGetNSN(page)
#define GistTupleIsInvalid(itup)
bool gistPageRecyclable(Page page)
XLogRecPtr gistGetFakeLSN(Relation rel)
void gistcheckpage(Relation rel, Buffer buf)
static void gistvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
static void gistvacuumpage(GistVacState *vstate, Buffer buffer)
IndexBulkDeleteResult * gistvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
static bool gistdeletepage(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, Buffer parentBuffer, OffsetNumber downlink, Buffer leafBuffer)
static void gistvacuum_delete_empty_pages(IndexVacuumInfo *info, GistVacState *vstate)
IndexBulkDeleteResult * gistbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
XLogRecPtr gistXLogPageDelete(Buffer buffer, FullTransactionId xid, Buffer parentBuffer, OffsetNumber downlinkOffset)
XLogRecPtr gistXLogUpdate(Buffer buffer, OffsetNumber *todelete, int ntodelete, IndexTuple *itup, int ituplen, Buffer leftchildbuf)
Assert(PointerIsAligned(start, uint64))
void IndexFreeSpaceMapVacuum(Relation rel)
void RecordFreeIndexPage(Relation rel, BlockNumber freeBlock)
uint64 intset_num_entries(IntegerSet *intset)
bool intset_is_member(IntegerSet *intset, uint64 x)
void intset_begin_iterate(IntegerSet *intset)
bool intset_iterate_next(IntegerSet *intset, uint64 *next)
IntegerSet * intset_create(void)
void intset_add_member(IntegerSet *intset, uint64 x)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
IndexTupleData * IndexTuple
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define START_CRIT_SECTION()
#define END_CRIT_SECTION()
#define InvalidOffsetNumber
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
void read_stream_reset(ReadStream *stream)
Buffer read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
ReadStream * read_stream_begin_relation(int flags, BufferAccessStrategy strategy, Relation rel, ForkNumber forknum, ReadStreamBlockNumberCB callback, void *callback_private_data, size_t per_buffer_data_size)
void read_stream_end(ReadStream *stream)
BlockNumber block_range_read_stream_cb(ReadStream *stream, void *callback_private_data, void *per_buffer_data)
#define READ_STREAM_MAINTENANCE
#define READ_STREAM_USE_BATCHING
#define RELATION_IS_LOCAL(relation)
#define RelationGetRelationName(relation)
#define RelationNeedsWAL(relation)
BlockNumber last_exclusive
BlockNumber current_blocknum
MemoryContext page_set_context
IndexBulkDeleteCallback callback
IndexBulkDeleteResult * stats
IntegerSet * empty_leaf_set
IntegerSet * internal_page_set
BlockNumber pages_deleted
BlockNumber pages_newly_deleted
BufferAccessStrategy strategy
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
void vacuum_delay_point(bool is_analyze)
FullTransactionId ReadNextFullTransactionId(void)
XLogRecPtr GetInsertRecPtr(void)