]> granicus.if.org Git - postgresql/commitdiff
Allow autoanalyze to add pages deleted from pending list to FSM
authorTeodor Sigaev <teodor@sigaev.ru>
Wed, 23 Sep 2015 12:33:51 +0000 (15:33 +0300)
committerTeodor Sigaev <teodor@sigaev.ru>
Wed, 23 Sep 2015 12:33:51 +0000 (15:33 +0300)
Commit e95680832854cf300e64c10de9cc2f586df558e8 introduces adding pages
to FSM for ordinary insert, but autoanalyze was able just cleanup
pending list without adding to FSM.

Also fix double call of IndexFreeSpaceMapVacuum() during ginvacuumcleanup()

Report from Fujii Masao
Patch by me
Review by Jeff Janes

src/backend/access/gin/ginfast.c
src/backend/access/gin/ginvacuum.c
src/include/access/gin_private.h

index 76bebad8e1f42d156247cc694823d3317c822ce2..4bb22fe0c6fcf06bf9f919f2095bde67d41a51ef 100644 (file)
@@ -434,7 +434,7 @@ ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector)
        END_CRIT_SECTION();
 
        if (needCleanup)
-               ginInsertCleanup(ginstate, false, NULL);
+               ginInsertCleanup(ginstate, false, true, NULL);
 }
 
 /*
@@ -505,7 +505,7 @@ ginHeapTupleFastCollect(GinState *ginstate,
  */
 static bool
 shiftList(Relation index, Buffer metabuffer, BlockNumber newHead,
-                 IndexBulkDeleteResult *stats)
+                 bool fill_fsm, IndexBulkDeleteResult *stats)
 {
        Page            metapage;
        GinMetaPageData *metadata;
@@ -613,7 +613,7 @@ shiftList(Relation index, Buffer metabuffer, BlockNumber newHead,
 
                END_CRIT_SECTION();
 
-               for (i = 0; i < data.ndeleted; i++)
+               for (i = 0; fill_fsm && i < data.ndeleted; i++)
                        RecordFreeIndexPage(index, freespace[i]);
 
        } while (blknoToDelete != newHead);
@@ -732,13 +732,19 @@ processPendingPage(BuildAccumulator *accum, KeyArray *ka,
  * action of removing a page from the pending list really needs exclusive
  * lock.
  *
- * vac_delay indicates that ginInsertCleanup is called from vacuum process,
- * so call vacuum_delay_point() periodically.
+ * vac_delay indicates that ginInsertCleanup should call
+ * vacuum_delay_point() periodically.
+ *
+ * fill_fsm indicates that ginInsertCleanup should add deleted pages
+ * to FSM otherwise caller is responsible to put deleted pages into
+ * FSM.
+ *
  * If stats isn't null, we count deleted pending pages into the counts.
  */
 void
 ginInsertCleanup(GinState *ginstate,
-                                bool vac_delay, IndexBulkDeleteResult *stats)
+                                bool vac_delay, bool fill_fsm,
+                                IndexBulkDeleteResult *stats)
 {
        Relation        index = ginstate->index;
        Buffer          metabuffer,
@@ -899,7 +905,7 @@ ginInsertCleanup(GinState *ginstate,
                         * remove read pages from pending list, at this point all
                         * content of read pages is in regular structure
                         */
-                       if (shiftList(index, metabuffer, blkno, stats))
+                       if (shiftList(index, metabuffer, blkno, fill_fsm, stats))
                        {
                                /* another cleanup process is running concurrently */
                                LockBuffer(metabuffer, GIN_UNLOCK);
@@ -948,7 +954,7 @@ ginInsertCleanup(GinState *ginstate,
         * desirable to recycle them immediately to the FreeSpace Map when
         * ordinary backends clean the list.
         */
-       if (fsm_vac && !vac_delay)
+       if (fsm_vac && fill_fsm)
                IndexFreeSpaceMapVacuum(index);
 
 
index 1315762ecf970c257ef35f0787c5a0f1d7bdf039..323cfb032ca0cb4ecf2261381d127f17f27a41f4 100644 (file)
@@ -544,7 +544,7 @@ ginbulkdelete(PG_FUNCTION_ARGS)
                /* Yes, so initialize stats to zeroes */
                stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
                /* and cleanup any pending inserts */
-               ginInsertCleanup(&gvs.ginstate, true, stats);
+               ginInsertCleanup(&gvs.ginstate, true, false, stats);
        }
 
        /* we'll re-count the tuples each time */
@@ -659,7 +659,7 @@ ginvacuumcleanup(PG_FUNCTION_ARGS)
                if (IsAutoVacuumWorkerProcess())
                {
                        initGinState(&ginstate, index);
-                       ginInsertCleanup(&ginstate, true, stats);
+                       ginInsertCleanup(&ginstate, true, true, stats);
                }
                PG_RETURN_POINTER(stats);
        }
@@ -672,7 +672,7 @@ ginvacuumcleanup(PG_FUNCTION_ARGS)
        {
                stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
                initGinState(&ginstate, index);
-               ginInsertCleanup(&ginstate, true, stats);
+               ginInsertCleanup(&ginstate, true, false, stats);
        }
 
        memset(&idxStat, 0, sizeof(idxStat));
index acbe36a74147e64a5c888de409b8197a24baae79..50218879aa73858f32b20911d939cf39fab020ae 100644 (file)
@@ -936,7 +936,7 @@ extern void ginHeapTupleFastCollect(GinState *ginstate,
                                                OffsetNumber attnum, Datum value, bool isNull,
                                                ItemPointer ht_ctid);
 extern void ginInsertCleanup(GinState *ginstate,
-                                bool vac_delay, IndexBulkDeleteResult *stats);
+                                bool vac_delay, bool fill_fsm, IndexBulkDeleteResult *stats);
 
 /* ginpostinglist.c */