OSDN Git Service

Add last-vacuum/analyze-time columns to the stats collector, both manual and
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 19 May 2006 19:08:27 +0000 (19:08 +0000)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 19 May 2006 19:08:27 +0000 (19:08 +0000)
issued by autovacuum.  Add accessor functions to them, and use those in the
pg_stat_*_tables system views.

Catalog version bumped due to changes in the pgstat views and the pgstat file.

Patch from Larry Rosenman, minor improvements by me.

doc/src/sgml/monitoring.sgml
src/backend/catalog/system_views.sql
src/backend/postmaster/pgstat.c
src/backend/utils/adt/pgstatfuncs.c
src/include/catalog/catversion.h
src/include/catalog/pg_proc.h
src/include/pgstat.h
src/test/regress/expected/rules.out

index 41ee901..c9a2c4f 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/monitoring.sgml,v 1.31 2006/03/10 19:10:48 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/monitoring.sgml,v 1.32 2006/05/19 19:08:26 alvherre Exp $ -->
 
 <chapter id="monitoring">
  <title>Monitoring Database Activity</title>
@@ -250,7 +250,9 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
      <row>
       <entry><structname>pg_stat_all_tables</></entry>
       <entry>For each table in the current database (including TOAST tables),
-      the table OID, schema and table name, number of sequential
+      the table OID, schema and table name, the last time the table was
+      vacuumed by the user and the autovacuum daemon, the last time the table
+      was analyzed by the user and the autovacuum daemon, number of sequential
       scans initiated, number of live rows fetched by sequential
       scans, number of index scans initiated (over all indexes
       belonging to the table), number of live rows fetched by index
@@ -544,6 +546,38 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
      </row>
 
      <row>
+      <entry><literal><function>pg_stat_get_last_vacuum_time</function>(<type>oid</type>)</literal></entry>
+      <entry><type>timestamptz</type></entry>
+      <entry>
+       Time of the last vacuum initiated by the user
+      </entry>
+     </row>
+
+     <row>
+      <entry><literal><function>pg_stat_get_last_autovacuum_time</function>(<type>oid</type>)</literal></entry>
+      <entry><type>timestamptz</type></entry>
+      <entry>
+       Time of the last vacuum initiated by the autovacuum daemon
+      </entry>
+     </row>
+
+     <row>
+      <entry><literal><function>pg_stat_get_last_analyze_time</function>(<type>oid</type>)</literal></entry>
+      <entry><type>timestamptz</type></entry>
+      <entry>
+       Time of the last analyze initiated by the user
+      </entry>
+     </row>
+
+     <row>
+      <entry><literal><function>pg_stat_get_last_autoanalyze_time</function>(<type>oid</type>)</literal></entry>
+      <entry><type>timestamptz</type></entry>
+      <entry>
+       Time of the last analyze initiated by the autovacuum daemon
+      </entry>
+     </row>
+
+     <row>
       <entry><literal><function>pg_stat_get_backend_idset</function>()</literal></entry>
       <entry><type>setof integer</type></entry>
       <entry>
index 907a254..eba3108 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1996-2006, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.26 2006/03/05 15:58:23 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.27 2006/05/19 19:08:26 alvherre Exp $
  */
 
 CREATE VIEW pg_roles AS 
@@ -193,6 +193,10 @@ CREATE VIEW pg_stat_all_tables AS
             C.oid AS relid, 
             N.nspname AS schemaname, 
             C.relname AS relname, 
+            pg_stat_get_last_vacuum_time(C.oid) as last_vacuum,
+            pg_stat_get_last_autovacuum_time(C.oid) as last_autovacuum,
+            pg_stat_get_last_analyze_time(C.oid) as last_analyze,
+            pg_stat_get_last_autoanalyze_time(C.oid) as last_autoanalyze,
             pg_stat_get_numscans(C.oid) AS seq_scan, 
             pg_stat_get_tuples_returned(C.oid) AS seq_tup_read, 
             sum(pg_stat_get_numscans(I.indexrelid))::bigint AS idx_scan, 
index c10850a..a15f6cb 100644 (file)
@@ -13,7 +13,7 @@
  *
  *     Copyright (c) 2001-2006, PostgreSQL Global Development Group
  *
- *     $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.125 2006/05/19 15:15:37 alvherre Exp $
+ *     $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.126 2006/05/19 19:08:26 alvherre Exp $
  * ----------
  */
 #include "postgres.h"
@@ -739,6 +739,8 @@ pgstat_report_vacuum(Oid tableoid, bool shared,
        msg.m_databaseid = shared ? InvalidOid : MyDatabaseId;
        msg.m_tableoid = tableoid;
        msg.m_analyze = analyze;
+       msg.m_autovacuum = IsAutoVacuumProcess(); /* is this autovacuum? */
+       msg.m_vacuumtime = GetCurrentTimestamp();
        msg.m_tuples = tuples;
        pgstat_send(&msg, sizeof(msg));
 }
@@ -762,6 +764,8 @@ pgstat_report_analyze(Oid tableoid, bool shared, PgStat_Counter livetuples,
        pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_ANALYZE);
        msg.m_databaseid = shared ? InvalidOid : MyDatabaseId;
        msg.m_tableoid = tableoid;
+       msg.m_autovacuum = IsAutoVacuumProcess(); /* is this autovacuum? */
+       msg.m_analyzetime = GetCurrentTimestamp();
        msg.m_live_tuples = livetuples;
        msg.m_dead_tuples = deadtuples;
        pgstat_send(&msg, sizeof(msg));
@@ -2887,10 +2891,20 @@ pgstat_recv_vacuum(PgStat_MsgVacuum *msg, int len)
        if (tabentry == NULL)
                return;
 
+       if (msg->m_autovacuum) 
+               tabentry->autovac_vacuum_timestamp = msg->m_vacuumtime;
+       else 
+               tabentry->vacuum_timestamp = msg->m_vacuumtime; 
        tabentry->n_live_tuples = msg->m_tuples;
        tabentry->n_dead_tuples = 0;
        if (msg->m_analyze)
+       {
                tabentry->last_anl_tuples = msg->m_tuples;
+               if (msg->m_autovacuum)
+                       tabentry->autovac_analyze_timestamp = msg->m_vacuumtime;
+               else
+                       tabentry->analyze_timestamp = msg->m_vacuumtime;
+       }
 }
 
 /* ----------
@@ -2919,6 +2933,10 @@ pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len)
        if (tabentry == NULL)
                return;
 
+       if (msg->m_autovacuum) 
+               tabentry->autovac_analyze_timestamp = msg->m_analyzetime;
+       else 
+               tabentry->analyze_timestamp = msg->m_analyzetime;
        tabentry->n_live_tuples = msg->m_live_tuples;
        tabentry->n_dead_tuples = msg->m_dead_tuples;
        tabentry->last_anl_tuples = msg->m_live_tuples + msg->m_dead_tuples;
@@ -3005,6 +3023,10 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len)
                        tabentry->n_dead_tuples = tabmsg[i].t_tuples_updated +
                                tabmsg[i].t_tuples_deleted;
                        tabentry->last_anl_tuples = 0;
+                       tabentry->vacuum_timestamp = 0;
+                       tabentry->autovac_vacuum_timestamp = 0;
+                       tabentry->analyze_timestamp = 0;
+                       tabentry->autovac_analyze_timestamp = 0;
 
                        tabentry->blocks_fetched = tabmsg[i].t_blocks_fetched;
                        tabentry->blocks_hit = tabmsg[i].t_blocks_hit;
index 362aa1d..eaf3793 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.28 2006/05/19 15:15:37 alvherre Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.29 2006/05/19 19:08:26 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,6 +34,10 @@ extern Datum pg_stat_get_tuples_updated(PG_FUNCTION_ARGS);
 extern Datum pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS);
 extern Datum pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS);
 extern Datum pg_stat_get_blocks_hit(PG_FUNCTION_ARGS);
+extern Datum pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS);
+extern Datum pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS);
+extern Datum pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS);
+extern Datum pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS);
 
 extern Datum pg_stat_get_backend_idset(PG_FUNCTION_ARGS);
 extern Datum pg_backend_pid(PG_FUNCTION_ARGS);
@@ -197,6 +201,85 @@ pg_stat_get_blocks_hit(PG_FUNCTION_ARGS)
        PG_RETURN_INT64(result);
 }
 
+Datum
+pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS)
+{
+       PgStat_StatTabEntry *tabentry;
+       Oid                     relid;
+       TimestampTz     result;
+
+       relid = PG_GETARG_OID(0);
+
+       if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
+               result = 0;
+       else
+               result = tabentry->vacuum_timestamp;
+
+       if (result == 0)
+               PG_RETURN_NULL();
+       else
+               PG_RETURN_TIMESTAMPTZ(result);
+}
+
+Datum
+pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS)
+{
+       PgStat_StatTabEntry *tabentry;
+       Oid                     relid;
+       TimestampTz     result;
+
+       relid = PG_GETARG_OID(0);
+
+       if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
+               result = 0;
+       else
+               result = tabentry->autovac_vacuum_timestamp;
+
+       if (result == 0)
+               PG_RETURN_NULL();
+       else
+               PG_RETURN_TIMESTAMPTZ(result);
+}
+
+Datum
+pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS)
+{
+       PgStat_StatTabEntry *tabentry;
+       Oid                     relid;
+       TimestampTz     result;
+
+       relid = PG_GETARG_OID(0);
+
+       if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
+               result = 0;
+       else
+               result = tabentry->analyze_timestamp;
+
+       if (result == 0)
+               PG_RETURN_NULL();
+       else
+               PG_RETURN_TIMESTAMPTZ(result);
+}
+
+Datum
+pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS)
+{
+       PgStat_StatTabEntry *tabentry;
+       Oid                     relid;
+       TimestampTz     result;
+
+       relid = PG_GETARG_OID(0);
+
+       if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
+               result = 0;
+       else
+               result = tabentry->autovac_analyze_timestamp;
+
+       if (result == 0)
+               PG_RETURN_NULL();
+       else
+               PG_RETURN_TIMESTAMPTZ(result);
+}
 
 Datum
 pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
index 9e0d999..17ce73d 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.332 2006/05/17 16:37:06 teodor Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.333 2006/05/19 19:08:26 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200605171
+#define CATALOG_VERSION_NO     200605191
 
 #endif
index 09d57d9..c101a3c 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.411 2006/05/10 23:18:39 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.412 2006/05/19 19:08:26 alvherre Exp $
  *
  * NOTES
  *       The script catalog/genbki.sh reads this file and generates .bki
@@ -2839,6 +2839,14 @@ DATA(insert OID = 1934 (  pg_stat_get_blocks_fetched     PGNSP PGUID 12 f f t f s 1
 DESCR("Statistics: Number of blocks fetched");
 DATA(insert OID = 1935 (  pg_stat_get_blocks_hit               PGNSP PGUID 12 f f t f s 1 20 "26" _null_ _null_ _null_ pg_stat_get_blocks_hit - _null_ ));
 DESCR("Statistics: Number of blocks found in cache");
+DATA(insert OID = 2781 (  pg_stat_get_last_vacuum_time PGNSP PGUID 12 f f t f s 1 1184 "26" _null_ _null_ _null_       pg_stat_get_last_vacuum_time - _null_));
+DESCR("Statistics: Last manual vacuum time for a table");
+DATA(insert OID = 2782 (  pg_stat_get_last_autovacuum_time PGNSP PGUID 12 f f t f s 1 1184 "26" _null_ _null_ _null_   pg_stat_get_last_autovacuum_time - _null_));
+DESCR("Statistics: Last auto vacuum time for a table");
+DATA(insert OID = 2783 (  pg_stat_get_last_analyze_time PGNSP PGUID 12 f f t f s 1 1184 "26" _null_ _null_ _null_      pg_stat_get_last_analyze_time - _null_));
+DESCR("Statistics: Last manual analyze time for a table");
+DATA(insert OID = 2784 (  pg_stat_get_last_autoanalyze_time PGNSP PGUID 12 f f t f s 1 1184 "26" _null_ _null_ _null_  pg_stat_get_last_autoanalyze_time - _null_));
+DESCR("Statistics: Last auto analyze time for a table");
 DATA(insert OID = 1936 (  pg_stat_get_backend_idset            PGNSP PGUID 12 f f t t s 0 23 "" _null_ _null_ _null_ pg_stat_get_backend_idset - _null_ ));
 DESCR("Statistics: Currently active backend IDs");
 DATA(insert OID = 2026 (  pg_backend_pid                               PGNSP PGUID 12 f f t f s 0 23 "" _null_ _null_ _null_ pg_backend_pid - _null_ ));
index 4497e4d..d9d1e11 100644 (file)
@@ -5,7 +5,7 @@
  *
  *     Copyright (c) 2001-2006, PostgreSQL Global Development Group
  *
- *     $PostgreSQL: pgsql/src/include/pgstat.h,v 1.44 2006/04/27 00:06:59 momjian Exp $
+ *     $PostgreSQL: pgsql/src/include/pgstat.h,v 1.45 2006/05/19 19:08:26 alvherre Exp $
  * ----------
  */
 #ifndef PGSTAT_H
@@ -161,6 +161,8 @@ typedef struct PgStat_MsgVacuum
        Oid                     m_databaseid;
        Oid                     m_tableoid;
        bool            m_analyze;
+       bool            m_autovacuum;
+       TimestampTz m_vacuumtime;
        PgStat_Counter m_tuples;
 } PgStat_MsgVacuum;
 
@@ -174,6 +176,8 @@ typedef struct PgStat_MsgAnalyze
        PgStat_MsgHdr m_hdr;
        Oid                     m_databaseid;
        Oid                     m_tableoid;
+       bool            m_autovacuum; 
+       TimestampTz m_analyzetime; 
        PgStat_Counter m_live_tuples;
        PgStat_Counter m_dead_tuples;
 } PgStat_MsgAnalyze;
@@ -344,6 +348,10 @@ typedef struct PgStat_StatBeEntry
 typedef struct PgStat_StatTabEntry
 {
        Oid                     tableid;
+       TimestampTz vacuum_timestamp; /* user initiated vacuum */
+       TimestampTz autovac_vacuum_timestamp; /* autovacuum initiated */
+       TimestampTz analyze_timestamp; /* user initiated */
+       TimestampTz autovac_analyze_timestamp; /* autovacuum initiated */
 
        PgStat_Counter numscans;
 
index 7d38d3e..76a1a54 100644 (file)
@@ -1289,12 +1289,12 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
  pg_shadow                | SELECT pg_authid.rolname AS usename, pg_authid.oid AS usesysid, pg_authid.rolcreatedb AS usecreatedb, pg_authid.rolsuper AS usesuper, pg_authid.rolcatupdate AS usecatupd, pg_authid.rolpassword AS passwd, (pg_authid.rolvaliduntil)::abstime AS valuntil, pg_authid.rolconfig AS useconfig FROM pg_authid WHERE pg_authid.rolcanlogin;
  pg_stat_activity         | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.rolname AS usename, pg_stat_get_backend_activity(s.backendid) AS current_query, pg_stat_get_backend_activity_start(s.backendid) AS query_start, pg_stat_get_backend_start(s.backendid) AS backend_start, pg_stat_get_backend_client_addr(s.backendid) AS client_addr, pg_stat_get_backend_client_port(s.backendid) AS client_port FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_authid u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.oid));
  pg_stat_all_indexes      | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"]));
- pg_stat_all_tables       | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, (sum(pg_stat_get_numscans(i.indexrelid)))::bigint AS idx_scan, ((sum(pg_stat_get_tuples_fetched(i.indexrelid)))::bigint + pg_stat_get_tuples_fetched(c.oid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])) GROUP BY c.oid, n.nspname, c.relname;
+ pg_stat_all_tables       | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_last_vacuum_time(c.oid) AS last_vacuum, pg_stat_get_last_autovacuum_time(c.oid) AS last_autovacuum, pg_stat_get_last_analyze_time(c.oid) AS last_analyze, pg_stat_get_last_autoanalyze_time(c.oid) AS last_autoanalyze, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, (sum(pg_stat_get_numscans(i.indexrelid)))::bigint AS idx_scan, ((sum(pg_stat_get_tuples_fetched(i.indexrelid)))::bigint + pg_stat_get_tuples_fetched(c.oid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])) GROUP BY c.oid, n.nspname, c.relname;
  pg_stat_database         | SELECT d.oid AS datid, d.datname, pg_stat_get_db_numbackends(d.oid) AS numbackends, pg_stat_get_db_xact_commit(d.oid) AS xact_commit, pg_stat_get_db_xact_rollback(d.oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(d.oid) - pg_stat_get_db_blocks_hit(d.oid)) AS blks_read, pg_stat_get_db_blocks_hit(d.oid) AS blks_hit FROM pg_database d;
  pg_stat_sys_indexes      | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (pg_stat_all_indexes.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
- pg_stat_sys_tables       | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del FROM pg_stat_all_tables WHERE (pg_stat_all_tables.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
+ pg_stat_sys_tables       | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.last_vacuum, pg_stat_all_tables.last_autovacuum, pg_stat_all_tables.last_analyze, pg_stat_all_tables.last_autoanalyze, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del FROM pg_stat_all_tables WHERE (pg_stat_all_tables.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
  pg_stat_user_indexes     | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (pg_stat_all_indexes.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
- pg_stat_user_tables      | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del FROM pg_stat_all_tables WHERE (pg_stat_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
+ pg_stat_user_tables      | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.last_vacuum, pg_stat_all_tables.last_autovacuum, pg_stat_all_tables.last_analyze, pg_stat_all_tables.last_autoanalyze, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del FROM pg_stat_all_tables WHERE (pg_stat_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
  pg_statio_all_indexes    | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, (pg_stat_get_blocks_fetched(i.oid) - pg_stat_get_blocks_hit(i.oid)) AS idx_blks_read, pg_stat_get_blocks_hit(i.oid) AS idx_blks_hit FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"]));
  pg_statio_all_sequences  | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS blks_read, pg_stat_get_blocks_hit(c.oid) AS blks_hit FROM (pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'S'::"char");
  pg_statio_all_tables     | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS heap_blks_read, pg_stat_get_blocks_hit(c.oid) AS heap_blks_hit, (sum((pg_stat_get_blocks_fetched(i.indexrelid) - pg_stat_get_blocks_hit(i.indexrelid))))::bigint AS idx_blks_read, (sum(pg_stat_get_blocks_hit(i.indexrelid)))::bigint AS idx_blks_hit, (pg_stat_get_blocks_fetched(t.oid) - pg_stat_get_blocks_hit(t.oid)) AS toast_blks_read, pg_stat_get_blocks_hit(t.oid) AS toast_blks_hit, (pg_stat_get_blocks_fetched(x.oid) - pg_stat_get_blocks_hit(x.oid)) AS tidx_blks_read, pg_stat_get_blocks_hit(x.oid) AS tidx_blks_hit FROM ((((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_class t ON ((c.reltoastrelid = t.oid))) LEFT JOIN pg_class x ON ((t.reltoastidxid = x.oid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])) GROUP BY c.oid, n.nspname, c.relname, t.oid, x.oid;