Add start time to pg_stat_activity
authorBruce Momjian
Thu, 20 Mar 2003 03:34:57 +0000 (03:34 +0000)
committerBruce Momjian
Thu, 20 Mar 2003 03:34:57 +0000 (03:34 +0000)
Neil Conway

20 files changed:
doc/src/sgml/func.sgml
doc/src/sgml/monitoring.sgml
doc/src/sgml/runtime.sgml
src/backend/catalog/heap.c
src/backend/catalog/namespace.c
src/backend/commands/cluster.c
src/backend/commands/sequence.c
src/backend/commands/tablecmds.c
src/backend/executor/execMain.c
src/backend/libpq/hba.c
src/backend/postmaster/pgstat.c
src/backend/utils/adt/nabstime.c
src/backend/utils/adt/pgstatfuncs.c
src/backend/utils/error/elog.c
src/bin/initdb/initdb.sh
src/bin/pg_dump/pg_backup_tar.c
src/include/catalog/catversion.h
src/include/catalog/pg_proc.h
src/include/pgstat.h
src/test/regress/expected/rules.out

index 91cc2c70af4c8be0f07527d2b7a7c22dca810a1c..256b0fa3fae42e52e5d5abeab52c250743732b07 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -5315,7 +5315,7 @@ SELECT LOCALTIMESTAMP;
 
    
     There is also the function timeofday(), which for historical
-    reasons returns a text string rather than a timestamp value:
+    reasons returns a text string rather than a timestamp value:
 
 SELECT timeofday();
 Result: Sat Feb 17 19:07:32.000126 2001 EST
@@ -5326,7 +5326,11 @@ SELECT timeofday();
     It is important to know that
     CURRENT_TIMESTAMP and related functions return
     the start time of the current transaction; their values do not
-    change during the transaction. timeofday()
+    change during the transaction. This is considered a feature:
+    the intent is to allow a single transaction to have a consistent
+    notion of the current time, so that multiple
+    modifications within the same transaction bear the same
+    timestamp. timeofday()
     returns the wall-clock time and does advance during transactions.
    
 
index 78c1bdbec3fe929c4d5ab97c812f48e937a869a3..002134c9acde98f43d7c5fd8f0cf6e8684a54e06 100644 (file)
@@ -1,5 +1,5 @@
 
 
 
@@ -146,12 +146,13 @@ postgres: user database host 
    
     
      Since the variables STATS_COMMAND_STRING,
-     STATS_BLOCK_LEVEL,
-     and STATS_ROW_LEVEL
-     default to false, no statistics are actually collected
-     in the default configuration.  You must turn one or more of them on
-     before you will get useful results from the statistical display
-     functions.
+     STATS_BLOCK_LEVEL, and
+     STATS_ROW_LEVEL default to false,
+     very few statistics are collected in the default
+     configuration. Enabling one or more of these configuration
+     variables will significantly enhance the amount of useful data
+     produced by the statistics collector, at the expense of
+     additional run-time overhead.
     
    
 
@@ -205,11 +206,15 @@ postgres: user database host 
     
      
       pg_stat_activity
-      One row per server process, showing process ID, database,
-      user, and current query.  The current query column is only available
-      to superusers; for others it reads as null.  (Note that because of
-      the collector's reporting delay, current query will only be up-to-date
-      for long-running queries.)
+      One row per server process, showing process
+      ID, database, user, current query, and the time at
+      which the current query began execution. The columns that report
+      data on the current query are only available if the
+      STATS_COMMAND_STRING configuration option has
+      been enabled. Furthermore, these columns can only be accessed by
+      superusers; to other users, they always appear NULL. (Note that
+      because of the collector's reporting delay, current query will
+      only be up-to-date for long-running queries.)
      
 
      
@@ -333,10 +338,20 @@ postgres: user database host 
   
 
   
-   The pg_statio_ views are primarily useful to determine
-   the effectiveness of the buffer cache.  When the number of actual disk
-   reads is much smaller than the number of buffer hits, then the cache
-   is satisfying most read requests without invoking a kernel call.
+   The pg_statio_ views are primarily useful to
+   determine the effectiveness of the buffer cache.  When the number
+   of actual disk reads is much smaller than the number of buffer
+   hits, then the cache is satisfying most read requests without
+   invoking a kernel call. However, these statistics do not give the
+   entire story: due to the way in which PostgreSQL
+   handles disk I/O, data that is not in the
+   PostgreSQL buffer cache may still reside in the
+   kernel's I/O cache, and may therefore still be fetched without
+   requiring a physical read. Users interested in obtaining more
+   detailed information on PostgreSQL I/O behavior are
+   advised to use the PostgreSQL statistics collector
+   in combination with operating system utilities that allow insight
+   into the kernel's handling of I/O.
   
 
   
@@ -401,7 +416,7 @@ postgres: user database host 
       pg_stat_get_db_blocks_hit(oid)
       bigint
       
-       Number of disk block requests found in cache for database
+       Number of disk block fetch requests found in cache for database
       
      
 
@@ -478,7 +493,7 @@ postgres: user database host 
       set of integer
       
        Set of currently active backend IDs (from 1 to N where N is the
-       number of active backends).  See usage example below.
+       number of active backends).  See usage example below
       
      
 
@@ -518,15 +533,27 @@ postgres: user database host 
       pg_stat_get_backend_activity(integer)
       text
       
-       Current query of backend process (NULL if caller is not superuser)
+       Current query of backend process (NULL if caller is not
+       superuser, or STATS_COMMAND_STRING is not enabled)
       
      
 
+     
+      pg_stat_get_backend_activity_start(integer)
+      text
+      
+       The time at which the specified backend's currently executing query was
+       initiated (NULL if caller is not superuser, or
+       STATS_COMMAND_STRING is not enabled)
+      
+     
+
+
      
       pg_stat_reset()
       boolean
       
-       Reset all currently collected statistics.
+       Reset all currently collected statistics
       
      
     
@@ -535,7 +562,8 @@ postgres: user database host 
 
    
     
-     Blocks_fetched minus blocks_hit gives the number of kernel
+     blocks_fetched minus
+     blocks_hit gives the number of kernel
      read() calls issued for the table, index, or
      database; but the actual number of physical reads is usually
      lower due to kernel-level buffering.
index 86d5ddc28525f3fe1bf9d18c371d8aceba827173..408c81e2ee5a444453f1366bb0936c077153ab76 100644 (file)
@@ -1,5 +1,5 @@
 
 
 
@@ -1182,16 +1182,31 @@ env PGOPTIONS='-c geqo=off' psql
 
      
       STATS_COMMAND_STRING (boolean)
+      
+       
+        Enables the collection of statistics on the currently
+        executing command of each backend, along with the time at
+        which that query began execution. This option is off by
+        default. Note that even when enabled, this information is only
+        visible to the superuser, so it should not represent a
+        security risk. This data can be accessed via the
+        pg_stat_activity system view; refer
+        to the &cite-admin; for more information.
+       
+      
+     
+
+     
       STATS_BLOCK_LEVEL (boolean)
       STATS_ROW_LEVEL (boolean)
       
        
-        Determines what information backends send to the statistics
-        collector process: current commands, block-level activity
-        statistics, or row-level activity statistics.  All default to
-        off.  Enabling statistics collection costs a small amount of
-        time per query, but is invaluable for debugging and
-        performance tuning.
+        Enables the collection of block-level and row-level statistics
+        on database activity, respectively. These options are off by
+        default. This data can be accessed via the
+        pg_stat and
+        pg_statio family of system views;
+        refer to the &cite-admin; for more information.
        
       
      
index 8d176c12cde6707326115f0e91d03c15cb3ab47e..105026a50e9a1e802d10f48d16e8ff76fbeeacb0 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.239 2003/01/08 22:06:20 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.240 2003/03/20 03:34:55 momjian Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -961,7 +961,8 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
    attStruct->attstattarget = 0;
 
    /* Change the column name to something that isn't likely to conflict */
-   snprintf(newattname, NAMEDATALEN, "........pg.dropped.%d........", attnum);
+   snprintf(newattname, sizeof(newattname),
+            "........pg.dropped.%d........", attnum);
    namestrcpy(&(attStruct->attname), newattname);
 
    simple_heap_update(attr_rel, &tuple->t_self, tuple);
index 367903f59fa7dce868da14bdf24f95a887adb098..90c26288f52903c9f1866681d94b37fc06850943 100644 (file)
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.48 2003/03/06 22:54:49 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.49 2003/03/20 03:34:55 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1598,7 +1598,7 @@ InitTempTableNamespace(void)
        elog(ERROR, "%s: not authorized to create temp tables",
             DatabaseName);
 
-   snprintf(namespaceName, NAMEDATALEN, "pg_temp_%d", MyBackendId);
+   snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
 
    namespaceId = GetSysCacheOid(NAMESPACENAME,
                                 CStringGetDatum(namespaceName),
index 30d251869bc553d08823f21952af732e5f412bcc..0c1a7d3c70c2d588ffa6c6208c95d40c4126ec3e 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.106 2003/03/03 04:37:37 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.107 2003/03/20 03:34:55 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -405,7 +405,7 @@ rebuild_relation(Relation OldHeap, Oid indexOid)
     * namespace from the old, or we will have problems with the TEMP
     * status of temp tables.
     */
-   snprintf(NewHeapName, NAMEDATALEN, "pg_temp_%u", tableOid);
+   snprintf(NewHeapName, sizeof(NewHeapName), "pg_temp_%u", tableOid);
 
    OIDNewHeap = make_new_heap(tableOid, NewHeapName);
    /*
@@ -625,7 +625,8 @@ rebuild_indexes(Oid OIDOldHeap, List *indexes)
        Relation    pg_index;
 
        /* Create the new index under a temporary name */
-       snprintf(newIndexName, NAMEDATALEN, "pg_temp_%u", attrs->indexOID);
+       snprintf(newIndexName, sizeof(newIndexName),
+                "pg_temp_%u", attrs->indexOID);
 
        /*
         * The new index will have primary and constraint status set to
index c3ea6a14c0064ab8052b43e96718e2c8fd4ffdba..bca6512cef671b1a438bb139622584f7a9625e61 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.91 2003/02/13 05:25:24 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.92 2003/03/20 03:34:55 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -406,7 +406,7 @@ nextval(PG_FUNCTION_ARGS)
                {
                    char        buf[100];
 
-                   snprintf(buf, 100, INT64_FORMAT, maxv);
+                   snprintf(buf, sizeof(buf), INT64_FORMAT, maxv);
                    elog(ERROR, "%s.nextval: reached MAXVALUE (%s)",
                         sequence->relname, buf);
                }
@@ -427,7 +427,7 @@ nextval(PG_FUNCTION_ARGS)
                {
                    char        buf[100];
 
-                   snprintf(buf, 100, INT64_FORMAT, minv);
+                   snprintf(buf, sizeof(buf), INT64_FORMAT, minv);
                    elog(ERROR, "%s.nextval: reached MINVALUE (%s)",
                         sequence->relname, buf);
                }
@@ -569,9 +569,9 @@ do_setval(RangeVar *sequence, int64 next, bool iscalled)
                    bufm[100],
                    bufx[100];
 
-       snprintf(bufv, 100, INT64_FORMAT, next);
-       snprintf(bufm, 100, INT64_FORMAT, seq->min_value);
-       snprintf(bufx, 100, INT64_FORMAT, seq->max_value);
+       snprintf(bufv, sizeof(bufv), INT64_FORMAT, next);
+       snprintf(bufm, sizeof(bufm), INT64_FORMAT, seq->min_value);
+       snprintf(bufx, sizeof(bufx), INT64_FORMAT, seq->max_value);
        elog(ERROR, "%s.setval: value %s is out of bounds (%s,%s)",
             sequence->relname, bufv, bufm, bufx);
    }
@@ -861,8 +861,8 @@ init_params(CreateSeqStmt *seq, Form_pg_sequence new)
        char        bufm[100],
                    bufx[100];
 
-       snprintf(bufm, 100, INT64_FORMAT, new->min_value);
-       snprintf(bufx, 100, INT64_FORMAT, new->max_value);
+       snprintf(bufm, sizeof(bufm), INT64_FORMAT, new->min_value);
+       snprintf(bufx, sizeof(bufx), INT64_FORMAT, new->max_value);
        elog(ERROR, "DefineSequence: MINVALUE (%s) must be less than MAXVALUE (%s)",
             bufm, bufx);
    }
@@ -882,8 +882,8 @@ init_params(CreateSeqStmt *seq, Form_pg_sequence new)
        char        bufs[100],
                    bufm[100];
 
-       snprintf(bufs, 100, INT64_FORMAT, new->last_value);
-       snprintf(bufm, 100, INT64_FORMAT, new->min_value);
+       snprintf(bufs, sizeof(bufs), INT64_FORMAT, new->last_value);
+       snprintf(bufm, sizeof(bufm), INT64_FORMAT, new->min_value);
        elog(ERROR, "DefineSequence: START value (%s) can't be less than MINVALUE (%s)",
             bufs, bufm);
    }
@@ -892,8 +892,8 @@ init_params(CreateSeqStmt *seq, Form_pg_sequence new)
        char        bufs[100],
                    bufm[100];
 
-       snprintf(bufs, 100, INT64_FORMAT, new->last_value);
-       snprintf(bufm, 100, INT64_FORMAT, new->max_value);
+       snprintf(bufs, sizeof(bufs), INT64_FORMAT, new->last_value);
+       snprintf(bufm, sizeof(bufm), INT64_FORMAT, new->max_value);
        elog(ERROR, "DefineSequence: START value (%s) can't be greater than MAXVALUE (%s)",
             bufs, bufm);
    }
@@ -904,7 +904,7 @@ init_params(CreateSeqStmt *seq, Form_pg_sequence new)
    {
        char        buf[100];
 
-       snprintf(buf, 100, INT64_FORMAT, new->cache_value);
+       snprintf(buf, sizeof(buf), INT64_FORMAT, new->cache_value);
        elog(ERROR, "DefineSequence: CACHE (%s) can't be <= 0",
             buf);
    }
index 13401ed107fb93ee16bb7dd123dcb7a467e6bc15..f23c88f6fe6154fc024635872efa3acb32cc2223 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.67 2003/02/13 05:19:59 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.68 2003/03/20 03:34:55 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3875,8 +3875,8 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
    /*
     * Create the toast table and its index
     */
-   snprintf(toast_relname, NAMEDATALEN, "pg_toast_%u", relOid);
-   snprintf(toast_idxname, NAMEDATALEN, "pg_toast_%u_index", relOid);
+   snprintf(toast_relname, sizeof(toast_relname), "pg_toast_%u", relOid);
+   snprintf(toast_idxname, sizeof(toast_idxname), "pg_toast_%u_index", relOid);
 
    /* this is pretty painful...  need a tuple descriptor */
    tupdesc = CreateTemplateTupleDesc(3, false);
index 638cc61bef4c8bfc98be487f6d26c87998196837..e9cbd734b309f384156d81dc2c87969da3e7b497 100644 (file)
@@ -26,7 +26,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.202 2003/03/11 19:40:22 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.203 2003/03/20 03:34:55 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -603,7 +603,7 @@ InitPlan(QueryDesc *queryDesc)
            erm = (execRowMark *) palloc(sizeof(execRowMark));
            erm->relation = relation;
            erm->rti = rti;
-           snprintf(erm->resname, 32, "ctid%u", rti);
+           snprintf(erm->resname, sizeof(erm->resname), "ctid%u", rti);
            estate->es_rowMark = lappend(estate->es_rowMark, erm);
        }
    }
index 1cc0c98a57c142d149d8bab18b8f4707a4b09fc6..721ccf621e9bffda4dbadd6d1a64e028902cd907 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.94 2003/03/15 16:18:25 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.95 2003/03/20 03:34:55 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1162,7 +1162,7 @@ ident_inet(const struct in_addr remote_ip_addr,
            char        ident_query[80];
 
            /* The query we send to the Ident server */
-           snprintf(ident_query, 80, "%d,%d\n",
+           snprintf(ident_query, sizeof(ident_query), "%d,%d\n",
                     ntohs(remote_port), ntohs(local_port));
            /* loop in case send is interrupted */
            do
index 17c11682cf9e0cd60244a57474a8615c6418f7c4..86d47db9efd14f7d83c45d95f906d63ec6930006 100644 (file)
@@ -16,7 +16,7 @@
  *
  * Copyright (c) 2001, PostgreSQL Global Development Group
  *
- * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.31 2002/10/24 23:19:13 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.32 2003/03/20 03:34:56 momjian Exp $
  * ----------
  */
 #include "postgres.h"
@@ -1757,6 +1757,8 @@ pgstat_add_backend(PgStat_MsgHdr *msg)
    beentry->databaseid = msg->m_databaseid;
    beentry->procpid = msg->m_procpid;
    beentry->userid = msg->m_userid;
+   beentry->activity_start_sec = 0;
+   beentry->activity_start_usec = 0;
    MemSet(beentry->activity, 0, PGSTAT_ACTIVITY_SIZE);
 
    /*
@@ -2460,6 +2462,8 @@ pgstat_recv_beterm(PgStat_MsgBeterm *msg, int len)
 static void
 pgstat_recv_activity(PgStat_MsgActivity *msg, int len)
 {
+   PgStat_StatBeEntry *entry;
+
    /*
     * Here we check explicitly for 0 return, since we don't want to
     * mangle the activity of an active backend by a delayed packed from a
@@ -2468,8 +2472,12 @@ pgstat_recv_activity(PgStat_MsgActivity *msg, int len)
    if (pgstat_add_backend(&msg->m_hdr) != 0)
        return;
 
-   strncpy(pgStatBeTable[msg->m_hdr.m_backendid - 1].activity,
-           msg->m_what, PGSTAT_ACTIVITY_SIZE);
+   entry = &(pgStatBeTable[msg->m_hdr.m_backendid - 1]);
+
+   strncpy(entry->activity, msg->m_what, PGSTAT_ACTIVITY_SIZE);
+
+   entry->activity_start_sec =
+       GetCurrentAbsoluteTimeUsec(&entry->activity_start_usec);
 }
 
 
index 408b1ee14dd09a800482390826377218937b6bc1..8a75bdffbeeb425c4186b6ce7215a801f28af2a1 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.104 2003/02/22 05:57:45 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.105 2003/03/20 03:34:56 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -82,10 +82,13 @@ static int istinterval(char *i_string,
            AbsoluteTime *i_end);
 
 
-/* GetCurrentAbsoluteTime()
- * Get the current system time.
+/* 
+ * GetCurrentAbsoluteTime()
+ *
+ * Get the current system time. Set timezone parameters if not specified
+ * elsewhere.  Define HasCTZSet to allow clients to specify the default
+ * timezone.
  *
- * Returns the number of seconds since epoch (January 1 1970 GMT).
  */
 AbsoluteTime
 GetCurrentAbsoluteTime(void)
@@ -127,9 +130,14 @@ GetCurrentDateTime(struct tm * tm)
    abstime2tm(GetCurrentTransactionStartTime(), &tz, tm, NULL);
 }
 
-/* GetCurrentTimeUsec()
- * Get the transaction start time ("now()") broken down as a struct tm,
- * plus fractional-second and timezone info.
+/* 
+ * GetCurrentAbsoluteTimeUsec()
+ *
+ * Get the current system time. Set timezone parameters if not specified
+ * elsewhere.  Define HasCTZSet to allow clients to specify the default
+ * timezone.
+ *
+ * Returns the number of seconds since epoch (January 1 1970 GMT)
  */
 void
 GetCurrentTimeUsec(struct tm * tm, fsec_t *fsec, int *tzp)
index 42b63b8739f1c0f7067c09811d2f100e00d2511b..455da1c2aa9429d257efc85ac79a6c10c317d049 100644 (file)
@@ -25,6 +25,7 @@ extern Datum pg_stat_get_backend_pid(PG_FUNCTION_ARGS);
 extern Datum pg_stat_get_backend_dbid(PG_FUNCTION_ARGS);
 extern Datum pg_stat_get_backend_userid(PG_FUNCTION_ARGS);
 extern Datum pg_stat_get_backend_activity(PG_FUNCTION_ARGS);
+extern Datum pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS);
 
 extern Datum pg_stat_get_db_numbackends(PG_FUNCTION_ARGS);
 extern Datum pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS);
@@ -221,7 +222,6 @@ pg_backend_pid(PG_FUNCTION_ARGS)
 
 /*
  * Built-in function for resetting the counters
- *
  */
 Datum
 pg_stat_reset(PG_FUNCTION_ARGS)
@@ -301,6 +301,50 @@ pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
 }
 
 
+Datum
+pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
+{
+   PgStat_StatBeEntry  *beentry;
+   int32                beid;
+   AbsoluteTime         sec;
+   int                  usec;
+   Timestamp            result;
+
+   beid = PG_GETARG_INT32(0);
+
+   if (!superuser())
+       PG_RETURN_NULL();
+
+   if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+       PG_RETURN_NULL();
+
+   sec = beentry->activity_start_sec;
+   usec = beentry->activity_start_usec;
+
+   /*
+    * No time recorded for start of current query -- this is the case
+    * if the user hasn't enabled query-level stats collection.
+    */
+   if (sec == 0 && usec == 0)
+       PG_RETURN_NULL();
+
+   /*
+    * This method of converting "Unix time" (sec/usec since epoch) to a
+    * PostgreSQL timestamp is an ugly hack -- if you fix it, be sure to
+    * fix the similar hackery in timestamp.c
+    */
+#ifdef HAVE_INT64_TIMESTAMP
+   result = (((sec - ((date2j(2000, 1, 1) - date2j(1970, 1, 1)) * 86400))
+              * INT64CONST(1000000)) + usec);
+#else
+   result = (sec + (usec * 1.0e-6) - ((date2j(2000, 1, 1) -
+                                       date2j(1970, 1, 1)) * 86400));
+#endif
+
+   PG_RETURN_TIMESTAMP(result);
+}
+
+
 Datum
 pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
 {
index 868db0907e720c4c9aacb4810a7d8d0f2af1d859..763024b5773905f5d43124e0acbaff24f529ebee 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.106 2003/01/07 22:23:17 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.107 2003/03/20 03:34:56 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -215,7 +215,8 @@ elog(int lev, const char *fmt,...)
         * Prints the failure line of the COPY.  Wow, what a hack!  bjm
         * Translator:  Error message will be truncated at 31 characters.
         */
-       snprintf(copylineno_buf, 32, gettext("copy: line %d, "), copy_lineno);
+       snprintf(copylineno_buf, sizeof(copylineno_buf),
+                gettext("copy: line %d, "), copy_lineno);
        space_needed += strlen(copylineno_buf);
    }
 
@@ -787,8 +788,8 @@ useful_strerror(int errnum)
         * translator: This string will be truncated at 47 characters
         * expanded.
         */
-       snprintf(errorstr_buf, 48, gettext("operating system error %d"),
-                errnum);
+       snprintf(errorstr_buf, sizeof(errorstr_buf),
+                gettext("operating system error %d"), errnum);
        str = errorstr_buf;
    }
 
index 6bd01db36bc7b9647b1aee6933a75499b257bdc5..646b941cfa5367235e314f761c7c5e36f86f4b17 100644 (file)
@@ -27,7 +27,7 @@
 # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
 # Portions Copyright (c) 1994, Regents of the University of California
 #
-# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.185 2003/03/19 16:08:59 petere Exp $
+# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.186 2003/03/20 03:34:56 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -953,7 +953,8 @@ CREATE VIEW pg_stat_activity AS \
             pg_stat_get_backend_pid(S.backendid) AS procpid, \
             pg_stat_get_backend_userid(S.backendid) AS usesysid, \
             U.usename AS usename, \
-            pg_stat_get_backend_activity(S.backendid) AS current_query \
+            pg_stat_get_backend_activity(S.backendid) AS current_query, \
+           pg_stat_get_backend_activity_start(S.backendid) AS query_start \
     FROM pg_database D, \
             (SELECT pg_stat_get_backend_idset() AS backendid) AS S, \
             pg_shadow U \
index 7003b4c64288a0fab950108202ca2a86a591ac24..06734d7a46a2c56dfec6d6d3f5823083697c7a77 100644 (file)
@@ -16,7 +16,7 @@
  *
  *
  * IDENTIFICATION
- *     $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_tar.c,v 1.34 2003/02/01 19:29:16 tgl Exp $
+ *     $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_tar.c,v 1.35 2003/03/20 03:34:56 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1044,8 +1044,8 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th)
        char        buf1[100],
                    buf2[100];
 
-       snprintf(buf1, 100, INT64_FORMAT, (int64) len);
-       snprintf(buf2, 100, INT64_FORMAT, (int64) th->pos);
+       snprintf(buf1, sizeof(buf1), INT64_FORMAT, (int64) len);
+       snprintf(buf2, sizeof(buf2), INT64_FORMAT, (int64) th->pos);
        die_horribly(AH, modulename, "actual file length (%s) does not match expected (%s)\n",
                     buf1, buf2);
    }
@@ -1081,8 +1081,8 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename)
        char        buf1[100],
                    buf2[100];
 
-       snprintf(buf1, 100, INT64_FORMAT, (int64) ctx->tarFHpos);
-       snprintf(buf2, 100, INT64_FORMAT, (int64) ctx->tarNextMember);
+       snprintf(buf1, sizeof(buf1), INT64_FORMAT, (int64) ctx->tarFHpos);
+       snprintf(buf2, sizeof(buf2), INT64_FORMAT, (int64) ctx->tarNextMember);
        ahlog(AH, 4, "moving from position %s to next member at file position %s\n",
              buf1, buf2);
 
@@ -1093,7 +1093,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename)
    {
        char        buf[100];
 
-       snprintf(buf, 100, INT64_FORMAT, (int64) ctx->tarFHpos);
+       snprintf(buf, sizeof(buf), INT64_FORMAT, (int64) ctx->tarFHpos);
        ahlog(AH, 4, "now at file position %s\n", buf);
    }
 
@@ -1163,8 +1163,8 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
            char        buf1[100],
                        buf2[100];
 
-           snprintf(buf1, 100, INT64_FORMAT, (int64) ftello(ctx->tarFH));
-           snprintf(buf2, 100, INT64_FORMAT, (int64) ftello(ctx->tarFHpos));
+           snprintf(buf1, sizeof(buf1), INT64_FORMAT, (int64) ftello(ctx->tarFH));
+           snprintf(buf2, sizeof(buf2), INT64_FORMAT, (int64) ftello(ctx->tarFHpos));
            die_horribly(AH, modulename,
                         "mismatch in actual vs. predicted file position (%s vs. %s)\n",
                         buf1, buf2);
@@ -1215,7 +1215,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
    {
        char        buf[100];
 
-       snprintf(buf, 100, INT64_FORMAT, (int64) hPos);
+       snprintf(buf, sizeof(buf), INT64_FORMAT, (int64) hPos);
        ahlog(AH, 3, "TOC Entry %s at %s (length %lu, checksum %d)\n",
              tag, buf, (unsigned long) len, sum);
    }
@@ -1224,7 +1224,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
    {
        char        buf[100];
 
-       snprintf(buf, 100, INT64_FORMAT, (int64) ftello(ctx->tarFH));
+       snprintf(buf, sizeof(buf), INT64_FORMAT, (int64) ftello(ctx->tarFH));
        die_horribly(AH, modulename,
                     "corrupt tar header found in %s "
                     "(expected %d, computed %d) file position %s\n",
index 6344f0bae535cfb338c93edc7ae7e77bb26ac72d..8cd3f1472bec06d62b88e4a55299aae86be1a125 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: catversion.h,v 1.180 2003/03/10 03:53:51 tgl Exp $
+ * $Id: catversion.h,v 1.181 2003/03/20 03:34:56 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 200303091
+#define CATALOG_VERSION_NO 200303191
 
 #endif
index 1a16bd8b54b26651ba2f58e581bc3b01584201e4..0938ba0b4768e9ac9faf84ff8d816e1747d0f839 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_proc.h,v 1.287 2003/03/14 04:43:52 tgl Exp $
+ * $Id: pg_proc.h,v 1.288 2003/03/20 03:34:56 momjian Exp $
  *
  * NOTES
  *   The script catalog/genbki.sh reads this file and generates .bki
@@ -2741,6 +2741,8 @@ DATA(insert OID = 1939 (  pg_stat_get_backend_userid  PGNSP PGUID 12 f f t f s 1
 DESCR("Statistics: User ID of backend");
 DATA(insert OID = 1940 (  pg_stat_get_backend_activity PGNSP PGUID 12 f f t f s 1 25 "23"  pg_stat_get_backend_activity - _null_ ));
 DESCR("Statistics: Current query of backend");
+DATA(insert OID = 2094 (  pg_stat_get_backend_activity_start PGNSP PGUID 12 f f t f s 1 1114 "23"  pg_stat_get_backend_activity_start - _null_));
+DESCR("Statistics: Start time for current query of backend");
 DATA(insert OID = 1941 (  pg_stat_get_db_numbackends   PGNSP PGUID 12 f f t f s 1 23 "26"  pg_stat_get_db_numbackends - _null_ ));
 DESCR("Statistics: Number of backends in database");
 DATA(insert OID = 1942 (  pg_stat_get_db_xact_commit   PGNSP PGUID 12 f f t f s 1 20 "26"  pg_stat_get_db_xact_commit - _null_ ));
@@ -2750,7 +2752,7 @@ DESCR("Statistics: Transactions rolled back");
 DATA(insert OID = 1944 (  pg_stat_get_db_blocks_fetched PGNSP PGUID 12 f f t f s 1 20 "26" pg_stat_get_db_blocks_fetched - _null_ ));
 DESCR("Statistics: Blocks fetched for database");
 DATA(insert OID = 1945 (  pg_stat_get_db_blocks_hit        PGNSP PGUID 12 f f t f s 1 20 "26"  pg_stat_get_db_blocks_hit - _null_ ));
-DESCR("Statistics: Block found in cache for database");
+DESCR("Statistics: Blocks found in cache for database");
 
 DATA(insert OID = 1946 (  encode                       PGNSP PGUID 12 f f t f i 2 25 "17 25"  binary_encode - _null_ ));
 DESCR("Convert bytea value into some ascii-only text string");
index 6dcdcb1ecb53272d1210a0a9f963692745760abc..533c2e44f56d1c761bef7f7642264d926d75c1ab 100644 (file)
@@ -5,12 +5,14 @@
  *
  * Copyright (c) 2001, PostgreSQL Global Development Group
  *
- * $Id: pgstat.h,v 1.12 2003/01/09 18:00:24 tgl Exp $
+ * $Id: pgstat.h,v 1.13 2003/03/20 03:34:56 momjian Exp $
  * ----------
  */
 #ifndef PGSTAT_H
 #define PGSTAT_H
 
+#include "utils/nabstime.h"
+
 /* ----------
  * Paths for the statistics files. The %s is replaced with the
  * installations $PGDATA.
@@ -111,6 +113,8 @@ typedef struct PgStat_StatBeEntry
    Oid         userid;
    int         procpid;
    char        activity[PGSTAT_ACTIVITY_SIZE];
+   AbsoluteTime activity_start_sec;
+   int         activity_start_usec;
 } PgStat_StatBeEntry;
 
 
index f302ad93138dd534887fa255f0683584b45faba1..c0127828f22708eaa43922bbcdcbe9c809aa8644 100644 (file)
@@ -1274,7 +1274,7 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
  pg_locks                 | SELECT l.relation, l."database", l."transaction", l.pid, l."mode", l.granted FROM pg_lock_status() l(relation oid, "database" oid, "transaction" xid, pid integer, "mode" text, granted boolean);
  pg_rules                 | SELECT n.nspname AS schemaname, c.relname AS tablename, r.rulename, pg_get_ruledef(r.oid) AS definition FROM ((pg_rewrite r JOIN pg_class c ON ((c.oid = r.ev_class))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (r.rulename <> '_RETURN'::name);
  pg_settings              | SELECT a.name, a.setting FROM pg_show_all_settings() a(name text, setting text);
- 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.usename, pg_stat_get_backend_activity(s.backendid) AS current_query FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_shadow u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.usesysid));
+ 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.usename, pg_stat_get_backend_activity(s.backendid) AS current_query, pg_stat_get_backend_activity_start(s.backendid) AS query_start FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_shadow u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.usesysid));
  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 = 'r'::"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)) AS idx_scan, sum(pg_stat_get_tuples_fetched(i.indexrelid)) 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 = 'r'::"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;