On 04/06/2015 22:10, Guillaume Lelarge wrote:
> 2015-01-05 17:44 GMT+01:00 Guillaume Lelarge <guilla...@lelarge.info
> <mailto:guilla...@lelarge.info>>:
> 
>     2015-01-05 17:40 GMT+01:00 Robert Haas <robertmh...@gmail.com
>     <mailto:robertmh...@gmail.com>>:
> 
>         On Wed, Dec 31, 2014 at 12:46 PM, Tom Lane <t...@sss.pgh.pa.us
>         <mailto:t...@sss.pgh.pa.us>> wrote:
>         > I'd be all right with putting the data structure declarations in a 
> file
>         > named something like autovacuum_private.h, especially if it carried 
> an
>         > annotation that "if you depend on this, don't be surprised if we 
> break
>         > your code in future".
> 
>         Works for me.  I am not in general surprised when we do things that
>         break my code, or anyway, the code that I'm responsible for
>         maintaining.  But I think it makes sense to segregate this into a
>         separate header file so that we are clear that it is only
>         exposed for
>         the benefit of extension authors, not so that other things in
>         the core
>         system can touch it.
> 
> 
>     I'm fine with that too. I'll try to find some time to work on that.
> 
> 
> So I took a look at this this week. I discovered, with the help of a
> coworker, that I can already use the AutoVacuumShmem pointer and read
> the struct. Unfortunately, it doesn't give me as much details as I would
> have liked. The list of databases and tables aren't in shared memory.
> They are local to the process that uses them. Putting them in shared
> memory (if at all possible) would imply a much bigger patch than I was
> willing to write right now.
> 
> Thanks anyway for the help.
> 
> 

Sorry to revive such an old thread.

I think some hooks in the autovacuum could be enough to have good
insight without exposing private structure.

Please find attached a patch that adds some hooks to the autovacuum, and
as an example a quick proof of concept extension that use them and allow
to see what are the autovacuum worker todo list, skipped tables and so on.

I'm not really sure about which information should be provided, so I'm
open to any suggestion to improve this.
-- 
Julien Rouhaud
http://dalibo.com - http://dalibo.org
diff --git a/src/backend/postmaster/autovacuum.c 
b/src/backend/postmaster/autovacuum.c
index e2859df..e219b78 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -123,6 +123,12 @@ int                        autovacuum_vac_cost_limit;
 
 int                    Log_autovacuum_min_duration = -1;
 
+/* Hook for plugins to get informations */
+autovacuum_list_tables_hook_type autovacuum_list_tables_hook = NULL;
+autovacuum_begin_table_hook_type autovacuum_begin_table_hook = NULL;
+autovacuum_end_table_hook_type autovacuum_end_table_hook = NULL;
+autovacuum_database_finished_hook_type autovacuum_database_finished_hook = 
NULL;
+
 /* how long to keep pgstat data in the launcher, in milliseconds */
 #define STATS_READ_DELAY 1000
 
@@ -2178,6 +2184,13 @@ do_autovacuum(void)
                                                                                
  ALLOCSET_DEFAULT_MINSIZE,
                                                                                
  ALLOCSET_DEFAULT_MAXSIZE);
 
+       /* inform potential extension about the table we plan to clean */
+       if (autovacuum_list_tables_hook)
+       {
+               (*autovacuum_list_tables_hook) (MyWorkerInfo->wi_proc->pid,
+                               MyDatabaseId, table_oids);
+       }
+
        /*
         * Perform operations on collected tables.
         */
@@ -2243,6 +2256,12 @@ do_autovacuum(void)
                if (skipit)
                {
                        LWLockRelease(AutovacuumScheduleLock);
+
+                       /* warn potential extension we won't work on this table 
*/
+                       if (autovacuum_end_table_hook)
+                               (*autovacuum_end_table_hook) 
(MyWorkerInfo->wi_proc->pid,
+                                               MyDatabaseId, relid, false);
+
                        continue;
                }
 
@@ -2263,6 +2282,12 @@ do_autovacuum(void)
                {
                        /* someone else vacuumed the table, or it went away */
                        LWLockRelease(AutovacuumScheduleLock);
+
+                       /* warn potential extension we won't work on this table 
*/
+                       if (autovacuum_end_table_hook)
+                               (*autovacuum_end_table_hook) 
(MyWorkerInfo->wi_proc->pid,
+                                               MyDatabaseId, relid, false);
+
                        continue;
                }
 
@@ -2316,6 +2341,12 @@ do_autovacuum(void)
                if (!tab->at_relname || !tab->at_nspname || !tab->at_datname)
                        goto deleted;
 
+               /* warn potential extension we're starting to work on this 
table */
+               if (autovacuum_begin_table_hook)
+                       (*autovacuum_begin_table_hook) 
(MyWorkerInfo->wi_proc->pid,
+                                       MyDatabaseId, tab->at_relid, 
tab->at_vacoptions,
+                                       tab->at_params);
+
                /*
                 * We will abort vacuuming the current table if something 
errors out,
                 * and continue with the next one in schedule; in particular, 
this
@@ -2337,6 +2368,11 @@ do_autovacuum(void)
                }
                PG_CATCH();
                {
+                       /* warn potential extension we cancelled work on this 
table */
+                       if (autovacuum_end_table_hook)
+                               (*autovacuum_end_table_hook) 
(MyWorkerInfo->wi_proc->pid,
+                                               MyDatabaseId, relid, true);
+
                        /*
                         * Abort the transaction, start a new one, and proceed 
with the
                         * next table in our list.
@@ -2384,6 +2420,11 @@ deleted:
                MyWorkerInfo->wi_tableoid = InvalidOid;
                LWLockRelease(AutovacuumLock);
 
+               /* warn potential extension we've finished working on this 
table */
+               if (autovacuum_end_table_hook)
+                       (*autovacuum_end_table_hook) 
(MyWorkerInfo->wi_proc->pid,
+                                       MyDatabaseId, relid, false);
+
                /* restore vacuum cost GUCs for the next iteration */
                VacuumCostDelay = stdVacuumCostDelay;
                VacuumCostLimit = stdVacuumCostLimit;
@@ -2402,6 +2443,10 @@ deleted:
 
        /* Finally close out the last transaction. */
        CommitTransactionCommand();
+
+       /* inform potential extension we finished working on this database */
+       if (autovacuum_database_finished_hook)
+               (*autovacuum_database_finished_hook) 
(MyWorkerInfo->wi_proc->pid);
 }
 
 /*
diff --git a/src/include/postmaster/autovacuum.h 
b/src/include/postmaster/autovacuum.h
index b5000b0..8b2dd23 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -14,6 +14,7 @@
 #ifndef AUTOVACUUM_H
 #define AUTOVACUUM_H
 
+#include "commands/vacuum.h"
 
 /* GUC variables */
 extern bool autovacuum_start_daemon;
@@ -29,6 +30,21 @@ extern int   autovacuum_multixact_freeze_max_age;
 extern int     autovacuum_vac_cost_delay;
 extern int     autovacuum_vac_cost_limit;
 
+/* Hooks for plugins to get informations */
+typedef void (*autovacuum_list_tables_hook_type) (int pid, Oid dbid,
+               List *table_oids);
+extern PGDLLIMPORT autovacuum_list_tables_hook_type 
autovacuum_list_tables_hook;
+
+typedef void (*autovacuum_begin_table_hook_type) (int pid, Oid dbid, Oid relid,
+               int vacoptions, VacuumParams params);
+extern PGDLLIMPORT autovacuum_begin_table_hook_type 
autovacuum_begin_table_hook;
+
+typedef void (*autovacuum_end_table_hook_type) (int pid, Oid dbid, Oid relid, 
bool cancelled);
+extern PGDLLIMPORT autovacuum_end_table_hook_type autovacuum_end_table_hook;
+
+typedef void (*autovacuum_database_finished_hook_type) (int pid);
+extern PGDLLIMPORT autovacuum_database_finished_hook_type 
autovacuum_database_finished_hook;
+
 /* autovacuum launcher PID, only valid when worker is shutting down */
 extern int     AutovacuumLauncherPid;
 

Attachment: pg_stat_autovacuum.tgz
Description: application/compressed-tar

-- 
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