*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.240 2007/04/26 23:24:44 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.241 2007/04/30 03:23:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/*
* xactStartTimestamp is the value of transaction_timestamp().
* stmtStartTimestamp is the value of statement_timestamp().
+ * xactStopTimestamp is the time at which we log a commit or abort WAL record.
* These do not change as we enter and exit subtransactions, so we don't
* keep them inside the TransactionState stack.
*/
static TimestampTz xactStartTimestamp;
static TimestampTz stmtStartTimestamp;
+static TimestampTz xactStopTimestamp;
/*
* GID to be used for preparing the current transaction. This is also
return stmtStartTimestamp;
}
+/*
+ * GetCurrentTransactionStopTimestamp
+ *
+ * We return current time if the transaction stop time hasn't been set
+ * (which can happen if we decide we don't need to log an XLOG record).
+ */
+TimestampTz
+GetCurrentTransactionStopTimestamp(void)
+{
+ if (xactStopTimestamp != 0)
+ return xactStopTimestamp;
+ return GetCurrentTimestamp();
+}
+
/*
* SetCurrentStatementStartTimestamp
*/
stmtStartTimestamp = GetCurrentTimestamp();
}
+/*
+ * SetCurrentTransactionStopTimestamp
+ */
+static inline void
+SetCurrentTransactionStopTimestamp(void)
+{
+ xactStopTimestamp = GetCurrentTimestamp();
+}
+
/*
* GetCurrentTransactionNestLevel
*
*/
MyProc->inCommit = true;
- xlrec.xtime = time(NULL);
+ SetCurrentTransactionStopTimestamp();
+ xlrec.xtime = timestamptz_to_time_t(xactStopTimestamp);
xlrec.nrels = nrels;
xlrec.nsubxacts = nchildren;
rdata[0].data = (char *) (&xlrec);
xl_xact_abort xlrec;
XLogRecPtr recptr;
- xlrec.xtime = time(NULL);
+ SetCurrentTransactionStopTimestamp();
+ xlrec.xtime = timestamptz_to_time_t(xactStopTimestamp);
xlrec.nrels = nrels;
xlrec.nsubxacts = nchildren;
rdata[0].data = (char *) (&xlrec);
/*
* set transaction_timestamp() (a/k/a now()). We want this to be the same
* as the first command's statement_timestamp(), so don't do a fresh
- * GetCurrentTimestamp() call (which'd be expensive anyway).
+ * GetCurrentTimestamp() call (which'd be expensive anyway). Also,
+ * mark xactStopTimestamp as unset.
*/
xactStartTimestamp = stmtStartTimestamp;
+ xactStopTimestamp = 0;
pgstat_report_txn_timestamp(xactStartTimestamp);
/*
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.106 2007/04/19 16:26:44 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.107 2007/04/30 03:23:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/* Log the action if appropriate */
if (IsAutoVacuumWorkerProcess() && Log_autovacuum >= 0)
{
- long diff = 0L;
-
- if (Log_autovacuum > 0)
- {
- TimestampTz endtime;
- int usecs;
- long secs;
-
- endtime = GetCurrentTimestamp();
- TimestampDifference(starttime, endtime, &secs, &usecs);
-
- diff = secs * 1000 + usecs / 1000;
- }
-
- if (Log_autovacuum == 0 || diff >= Log_autovacuum)
- {
+ if (Log_autovacuum == 0 ||
+ TimestampDifferenceExceeds(starttime, GetCurrentTimestamp(),
+ Log_autovacuum))
ereport(LOG,
(errmsg("automatic analyze of table \"%s.%s.%s\" system usage: %s",
get_database_name(MyDatabaseId),
get_namespace_name(RelationGetNamespace(onerel)),
RelationGetRelationName(onerel),
pg_rusage_show(&ru0))));
- }
}
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.87 2007/04/19 16:26:44 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.88 2007/04/30 03:23:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/* and log the action if appropriate */
if (IsAutoVacuumWorkerProcess() && Log_autovacuum >= 0)
{
- long diff = 0L;
-
- if (Log_autovacuum > 0)
- {
- TimestampTz endtime;
- int usecs;
- long secs;
-
- endtime = GetCurrentTimestamp();
- TimestampDifference(starttime, endtime, &secs, &usecs);
-
- diff = secs * 1000 + usecs / 1000;
- }
-
- if (Log_autovacuum == 0 || diff >= Log_autovacuum)
- {
+ if (Log_autovacuum == 0 ||
+ TimestampDifferenceExceeds(starttime, GetCurrentTimestamp(),
+ Log_autovacuum))
ereport(LOG,
(errmsg("automatic vacuum of table \"%s.%s.%s\": index scans: %d\n"
"pages: %d removed, %d remain\n"
vacrelstats->pages_removed, vacrelstats->rel_pages,
vacrelstats->tuples_deleted, vacrelstats->rel_tuples,
pg_rusage_show(&ru0))));
- }
}
}
*
* Copyright (c) 2001-2007, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.153 2007/04/21 04:10:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.154 2007/04/30 03:23:49 tgl Exp $
* ----------
*/
#include "postgres.h"
/* ----------
* pgstat_report_tabstat() -
*
- * Called from tcop/postgres.c to send the so far collected
- * per table access statistics to the collector.
+ * Called from tcop/postgres.c to send the so far collected per-table
+ * access statistics to the collector. Note that this is called only
+ * when not within a transaction, so it is fair to use transaction stop
+ * time as an approximation of current time.
* ----------
*/
void
pgstat_report_tabstat(void)
{
+ static TimestampTz last_report = 0;
+ TimestampTz now;
+
+ /* Don't expend a clock check if nothing to do */
+ if (RegularTabStat.tsa_used == 0 &&
+ SharedTabStat.tsa_used == 0)
+ return;
+
+ /*
+ * Don't send a message unless it's been at least PGSTAT_STAT_INTERVAL
+ * msec since we last sent one.
+ */
+ now = GetCurrentTransactionStopTimestamp();
+ if (!TimestampDifferenceExceeds(last_report, now, PGSTAT_STAT_INTERVAL))
+ return;
+ last_report = now;
+
/*
- * For each message buffer used during the last query set the header
+ * For each message buffer used during the last queries, set the header
* fields and send it out; then mark the entries unused.
*/
pgstat_report_one_tabstat(&RegularTabStat, MyDatabaseId);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.174 2007/02/27 23:48:09 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.175 2007/04/30 03:23:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
}
}
+/*
+ * TimestampDifferenceExceeds -- report whether the difference between two
+ * timestamps is >= a threshold (expressed in milliseconds)
+ *
+ * Both inputs must be ordinary finite timestamps (in current usage,
+ * they'll be results from GetCurrentTimestamp()).
+ */
+bool
+TimestampDifferenceExceeds(TimestampTz start_time,
+ TimestampTz stop_time,
+ int msec)
+{
+ TimestampTz diff = stop_time - start_time;
+
+#ifdef HAVE_INT64_TIMESTAMP
+ return (diff >= msec * INT64CONST(1000));
+#else
+ return (diff * 1000.0 >= msec);
+#endif
+}
+
/*
* Convert a time_t to TimestampTz.
*
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/xact.h,v 1.85 2007/03/13 00:33:42 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/xact.h,v 1.86 2007/04/30 03:23:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern CommandId GetCurrentCommandId(void);
extern TimestampTz GetCurrentTransactionStartTimestamp(void);
extern TimestampTz GetCurrentStatementStartTimestamp(void);
+extern TimestampTz GetCurrentTransactionStopTimestamp(void);
extern void SetCurrentStatementStartTimestamp(void);
extern int GetCurrentTransactionNestLevel(void);
extern bool TransactionIdIsCurrentTransactionId(TransactionId xid);
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.67 2007/02/16 03:39:45 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.68 2007/04/30 03:23:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern void TimestampDifference(TimestampTz start_time, TimestampTz stop_time,
long *secs, int *microsecs);
+extern bool TimestampDifferenceExceeds(TimestampTz start_time,
+ TimestampTz stop_time,
+ int msec);
extern TimestampTz time_t_to_timestamptz(time_t tm);
extern time_t timestamptz_to_time_t(TimestampTz t);
1
(1 row)
+-- force the rate-limiting logic in pgstat_report_tabstat() to time out
+-- and send a message
+SELECT pg_sleep(1.0);
+ pg_sleep
+----------
+
+(1 row)
+
-- wait for stats collector to update
SELECT wait_for_stats();
wait_for_stats
-- do an indexscan
SELECT count(*) FROM tenk2 WHERE unique1 = 1;
+-- force the rate-limiting logic in pgstat_report_tabstat() to time out
+-- and send a message
+SELECT pg_sleep(1.0);
+
-- wait for stats collector to update
SELECT wait_for_stats();