Reply to both emails in one
Fujii:
> So autoanalyze still doesn't call IndexFreeSpaceMapVacuum().

Fixed, see patch

> ginvacuumcleanup calls RecordFreeIndexPage() twice for the same block.

fixed too

Tom:
It seems quite bizarre for auto-analyze to do that.  auto-vacuum, sure,
but I do not think this should get plugged into ANALYZE.

I agree, but we want to have pending list shorter as possible.



--
Teodor Sigaev                                   E-mail: teo...@sigaev.ru
                                                   WWW: http://www.sigaev.ru/
diff --git a/src/backend/access/gin/ginfast.c b/src/backend/access/gin/ginfast.c
index 76bebad..7be9362 100644
--- a/src/backend/access/gin/ginfast.c
+++ b/src/backend/access/gin/ginfast.c
@@ -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;
@@ -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 so 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);
 
 
diff --git a/src/backend/access/gin/ginvacuum.c 
b/src/backend/access/gin/ginvacuum.c
index 1315762..323cfb0 100644
--- a/src/backend/access/gin/ginvacuum.c
+++ b/src/backend/access/gin/ginvacuum.c
@@ -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));
diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
index acbe36a..5021887 100644
--- a/src/include/access/gin_private.h
+++ b/src/include/access/gin_private.h
@@ -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 */
 
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to