Hi Greg,

(2011/08/28 18:54), Greg Smith wrote:
> Updated patch cleans up two diff mistakes made when backing out the 
> progress report feature. The tip-off I screwed up should have been the 
> absurdly high write rate shown. The usleep was accidentally deleted, so 
> it was running without cost limits even applying. Here's a good one 
> instead:
> 
> LOG: automatic vacuum of table "pgbench.public.pgbench_accounts": index 
> scans: 1
> pages: 0 removed, 163935 remain
> tuples: 2000000 removed, 2928356 remain
> buffer usage: 117393 hits, 123351 misses, 102684 dirtied, 2.168 MiB/s 
> write rate
> system usage: CPU 2.54s/6.27u sec elapsed 369.99 sec

I took a look at your patch, and it seems fine about fundamental
functionality, though the patch needed to be rebased against current
HEAD.  Please see attached patch which I used for review.

IIUC, this patch provides:
* Three counters, which are used to keep # of buffers which were (1)
Hits: found in shared buffers, (2) Missed: not found in shared buffers,
and (3) Dirtied: marked as dirty, in an autovacuum of a relation.
These counters are used only when cost-based autovacuum is enabled by
setting vacuum_cost_delay to non-zero.
* Capability to report # of buffers above, and buffer write rate
(MiB/sec) in the existing autovacuum logging message, only when actual
duration > autovacuum_min_duration, and cost-based autovacuum is enabled.

I think one concern is the way showing statistics.  If showing summary
of statistics (at the end of an autovacuum) in server log is enough,
current implementation is fine.  Also showing progress report in server
log would be easy to achieve.  In contrast, reporting progress via
another backend would require shared memory or statistics collector,
rather than per-process global variables.  Anyway, this patch can be the
base of such enhancement.

There are some trivial comments:
* Local variables added by the patch (secs, usecs, write_rate and
endtime) can be moved into narrower scope.
* Initializing starttime to zero seems unnecessary.

In addition, documents about how to use the statistics would be
necessary, maybe in "23.1.5. The Autovacuum Daemon".

I'll set the status of this patch to waiting-on-author. Would you rebase
the patch and post it again?

Regards,
-- 
Shigeru Hanada
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 7fe787e..768c658 100644
*** a/src/backend/commands/vacuum.c
--- b/src/backend/commands/vacuum.c
*************** vacuum(VacuumStmt *vacstmt, Oid relid, b
*** 214,219 ****
--- 214,222 ----
  
                VacuumCostActive = (VacuumCostDelay > 0);
                VacuumCostBalance = 0;
+               VacuumPageHit = 0;
+               VacuumPageMiss = 0;
+               VacuumPageDirty = 0;
  
                /*
                 * Loop to process each selected relation.
diff --git a/src/backend/commands/vacuumlazy.c 
b/src/backend/commands/vacuumlazy.c
index cf8337b..d9bb272 100644
*** a/src/backend/commands/vacuumlazy.c
--- b/src/backend/commands/vacuumlazy.c
*************** lazy_vacuum_rel(Relation onerel, VacuumS
*** 153,170 ****
        int                     nindexes;
        BlockNumber possibly_freeable;
        PGRUsage        ru0;
!       TimestampTz starttime = 0;
        bool            scan_all;
        TransactionId freezeTableLimit;
        BlockNumber new_rel_pages;
        double          new_rel_tuples;
        TransactionId new_frozen_xid;
  
        /* measure elapsed time iff autovacuum logging requires it */
        if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
        {
                pg_rusage_init(&ru0);
!               if (Log_autovacuum_min_duration > 0)
                        starttime = GetCurrentTimestamp();
        }
  
--- 153,173 ----
        int                     nindexes;
        BlockNumber possibly_freeable;
        PGRUsage        ru0;
!       TimestampTz starttime = 0, endtime;
        bool            scan_all;
        TransactionId freezeTableLimit;
        BlockNumber new_rel_pages;
        double          new_rel_tuples;
        TransactionId new_frozen_xid;
+       long            secs;
+       int                     usecs;
+       double          write_rate;
  
        /* measure elapsed time iff autovacuum logging requires it */
        if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
        {
                pg_rusage_init(&ru0);
!               if (Log_autovacuum_min_duration > 0 || VacuumCostActive)
                        starttime = GetCurrentTimestamp();
        }
  
*************** lazy_vacuum_rel(Relation onerel, VacuumS
*** 250,272 ****
        /* and log the action if appropriate */
        if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
        {
                if (Log_autovacuum_min_duration == 0 ||
!                       TimestampDifferenceExceeds(starttime, 
GetCurrentTimestamp(),
                                                                           
Log_autovacuum_min_duration))
!                       ereport(LOG,
!                                       (errmsg("automatic vacuum of table 
\"%s.%s.%s\": index scans: %d\n"
!                                                       "pages: %d removed, %d 
remain\n"
!                                                       "tuples: %.0f removed, 
%.0f remain\n"
!                                                       "system usage: %s",
!                                                       
get_database_name(MyDatabaseId),
!                                                       
get_namespace_name(RelationGetNamespace(onerel)),
!                                                       
RelationGetRelationName(onerel),
!                                                       
vacrelstats->num_index_scans,
!                                                       
vacrelstats->pages_removed,
!                                                       vacrelstats->rel_pages,
!                                                       
vacrelstats->tuples_deleted,
!                                                       new_rel_tuples,
!                                                       pg_rusage_show(&ru0))));
        }
  }
  
--- 253,309 ----
        /* and log the action if appropriate */
        if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
        {
+               endtime = GetCurrentTimestamp();
                if (Log_autovacuum_min_duration == 0 ||
!                       TimestampDifferenceExceeds(starttime, endtime,
                                                                           
Log_autovacuum_min_duration))
!               {
!                       if (VacuumCostActive)
!                       {
!                               TimestampDifference(starttime, endtime, &secs, 
&usecs);
!                               write_rate = 0;
!                               if ((secs > 0) || (usecs > 0))
!                                       write_rate = (double) BLCKSZ * 
VacuumPageDirty / (1024 * 1024) /
!                                               (secs + usecs / 1000000.0);
! 
!                               ereport(LOG,
!                                               (errmsg("automatic vacuum of 
table \"%s.%s.%s\": index scans: %d\n"
!                                                               "pages: %d 
removed, %d remain\n"
!                                                               "tuples: %.0f 
removed, %.0f remain\n"
!                                                               "buffer usage: 
%d hits, %d misses, %d dirtied, %.3f MiB/s write rate\n"
!                                                               "system usage: 
%s",
!                                                               
get_database_name(MyDatabaseId),
!                                                               
get_namespace_name(RelationGetNamespace(onerel)),
!                                                               
RelationGetRelationName(onerel),
!                                                               
vacrelstats->num_index_scans,
!                                                               
vacrelstats->pages_removed,
!                                                               
vacrelstats->rel_pages,
!                                                               
vacrelstats->tuples_deleted,
!                                                               new_rel_tuples,
!                                                               VacuumPageHit,
!                                                               VacuumPageMiss,
!                                                               VacuumPageDirty,
!                                                               write_rate,
!                                                               
pg_rusage_show(&ru0))));
!                       }
!                       else
!                       {
!                               ereport(LOG,
!                                               (errmsg("automatic vacuum of 
table \"%s.%s.%s\": index scans: %d\n"
!                                                               "pages: %d 
removed, %d remain\n"
!                                                               "tuples: %.0f 
removed, %.0f remain\n"
!                                                               "system usage: 
%s",
!                                                               
get_database_name(MyDatabaseId),
!                                                               
get_namespace_name(RelationGetNamespace(onerel)),
!                                                               
RelationGetRelationName(onerel),
!                                                               
vacrelstats->num_index_scans,
!                                                               
vacrelstats->pages_removed,
!                                                               
vacrelstats->rel_pages,
!                                                               
vacrelstats->tuples_deleted,
!                                                               new_rel_tuples,
!                                                               
pg_rusage_show(&ru0))));
!                       }
!               }
        }
  }
  
diff --git a/src/backend/storage/buffer/bufmgr.c 
b/src/backend/storage/buffer/bufmgr.c
index 8647edd..1b0415c 100644
*** a/src/backend/storage/buffer/bufmgr.c
--- b/src/backend/storage/buffer/bufmgr.c
*************** ReadBuffer_common(SMgrRelation smgr, cha
*** 342,348 ****
--- 342,351 ----
                        *hit = true;
  
                        if (VacuumCostActive)
+                       {
+                               VacuumPageHit++;
                                VacuumCostBalance += VacuumCostPageHit;
+                       }
  
                        TRACE_POSTGRESQL_BUFFER_READ_DONE(forkNum, blockNum,
                                                                                
          smgr->smgr_rnode.node.spcNode,
*************** ReadBuffer_common(SMgrRelation smgr, cha
*** 472,478 ****
--- 475,484 ----
        }
  
        if (VacuumCostActive)
+       {
+               VacuumPageMiss++;
                VacuumCostBalance += VacuumCostPageMiss;
+       }
  
        TRACE_POSTGRESQL_BUFFER_READ_DONE(forkNum, blockNum,
                                                                          
smgr->smgr_rnode.node.spcNode,
*************** MarkBufferDirty(Buffer buffer)
*** 975,981 ****
--- 981,990 ----
         * If the buffer was not dirty already, do vacuum cost accounting.
         */
        if (!(bufHdr->flags & BM_DIRTY) && VacuumCostActive)
+       {
+               VacuumPageDirty++;
                VacuumCostBalance += VacuumCostPageDirty;
+       }
  
        bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
  
*************** SetBufferCommitInfoNeedsSave(Buffer buff
*** 2300,2306 ****
--- 2309,2318 ----
                LockBufHdr(bufHdr);
                Assert(bufHdr->refcount > 0);
                if (!(bufHdr->flags & BM_DIRTY) && VacuumCostActive)
+               {
+                       VacuumPageDirty++;
                        VacuumCostBalance += VacuumCostPageDirty;
+               }
                bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
                UnlockBufHdr(bufHdr);
        }
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index c4c4154..9ce64e6 100644
*** a/src/backend/utils/init/globals.c
--- b/src/backend/utils/init/globals.c
*************** int                     VacuumCostPageDirty = 20;
*** 115,120 ****
--- 115,124 ----
  int                   VacuumCostLimit = 200;
  int                   VacuumCostDelay = 0;
  
+ int                   VacuumPageHit = 0;
+ int                   VacuumPageMiss = 0;
+ int                   VacuumPageDirty = 0;
+ 
  int                   VacuumCostBalance = 0;          /* working state for 
vacuum */
  bool          VacuumCostActive = false;
  
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 9d19417..4ee08fe 100644
*** a/src/include/miscadmin.h
--- b/src/include/miscadmin.h
*************** extern int      VacuumCostPageDirty;
*** 230,235 ****
--- 230,239 ----
  extern int    VacuumCostLimit;
  extern int    VacuumCostDelay;
  
+ extern int    VacuumPageHit;
+ extern int    VacuumPageMiss;
+ extern int    VacuumPageDirty;
+ 
  extern int    VacuumCostBalance;
  extern bool VacuumCostActive;
  
-- 
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