Skip to content

Commit 957d08c

Browse files
committed
Implement rate-limiting logic on how often backends will attempt to send
messages to the stats collector. This avoids the problem that enabling stats_row_level for autovacuum has a significant overhead for short read-only transactions, as noted by Arjen van der Meijden. We can avoid an extra gettimeofday call by piggybacking on the one done for WAL-logging xact commit or abort (although that doesn't help read-only transactions, since they don't WAL-log anything). In my proposal for this, I noted that we could change the WAL log entries for commit/abort to record full TimestampTz precision, instead of only time_t as at present. That's not done in this patch, but will be committed separately.
1 parent 57b82bf commit 957d08c

File tree

9 files changed

+104
-47
lines changed

9 files changed

+104
-47
lines changed

src/backend/access/transam/xact.c

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.240 2007/04/26 23:24:44 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.241 2007/04/30 03:23:48 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -160,11 +160,13 @@ static CommandId currentCommandId;
160160
/*
161161
* xactStartTimestamp is the value of transaction_timestamp().
162162
* stmtStartTimestamp is the value of statement_timestamp().
163+
* xactStopTimestamp is the time at which we log a commit or abort WAL record.
163164
* These do not change as we enter and exit subtransactions, so we don't
164165
* keep them inside the TransactionState stack.
165166
*/
166167
static TimestampTz xactStartTimestamp;
167168
static TimestampTz stmtStartTimestamp;
169+
static TimestampTz xactStopTimestamp;
168170

169171
/*
170172
* GID to be used for preparing the current transaction. This is also
@@ -435,6 +437,20 @@ GetCurrentStatementStartTimestamp(void)
435437
return stmtStartTimestamp;
436438
}
437439

440+
/*
441+
* GetCurrentTransactionStopTimestamp
442+
*
443+
* We return current time if the transaction stop time hasn't been set
444+
* (which can happen if we decide we don't need to log an XLOG record).
445+
*/
446+
TimestampTz
447+
GetCurrentTransactionStopTimestamp(void)
448+
{
449+
if (xactStopTimestamp != 0)
450+
return xactStopTimestamp;
451+
return GetCurrentTimestamp();
452+
}
453+
438454
/*
439455
* SetCurrentStatementStartTimestamp
440456
*/
@@ -444,6 +460,15 @@ SetCurrentStatementStartTimestamp(void)
444460
stmtStartTimestamp = GetCurrentTimestamp();
445461
}
446462

463+
/*
464+
* SetCurrentTransactionStopTimestamp
465+
*/
466+
static inline void
467+
SetCurrentTransactionStopTimestamp(void)
468+
{
469+
xactStopTimestamp = GetCurrentTimestamp();
470+
}
471+
447472
/*
448473
* GetCurrentTransactionNestLevel
449474
*
@@ -747,7 +772,8 @@ RecordTransactionCommit(void)
747772
*/
748773
MyProc->inCommit = true;
749774

750-
xlrec.xtime = time(NULL);
775+
SetCurrentTransactionStopTimestamp();
776+
xlrec.xtime = timestamptz_to_time_t(xactStopTimestamp);
751777
xlrec.nrels = nrels;
752778
xlrec.nsubxacts = nchildren;
753779
rdata[0].data = (char *) (&xlrec);
@@ -1042,7 +1068,8 @@ RecordTransactionAbort(void)
10421068
xl_xact_abort xlrec;
10431069
XLogRecPtr recptr;
10441070

1045-
xlrec.xtime = time(NULL);
1071+
SetCurrentTransactionStopTimestamp();
1072+
xlrec.xtime = timestamptz_to_time_t(xactStopTimestamp);
10461073
xlrec.nrels = nrels;
10471074
xlrec.nsubxacts = nchildren;
10481075
rdata[0].data = (char *) (&xlrec);
@@ -1415,9 +1442,11 @@ StartTransaction(void)
14151442
/*
14161443
* set transaction_timestamp() (a/k/a now()). We want this to be the same
14171444
* as the first command's statement_timestamp(), so don't do a fresh
1418-
* GetCurrentTimestamp() call (which'd be expensive anyway).
1445+
* GetCurrentTimestamp() call (which'd be expensive anyway). Also,
1446+
* mark xactStopTimestamp as unset.
14191447
*/
14201448
xactStartTimestamp = stmtStartTimestamp;
1449+
xactStopTimestamp = 0;
14211450
pgstat_report_txn_timestamp(xactStartTimestamp);
14221451

14231452
/*

src/backend/commands/analyze.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.106 2007/04/19 16:26:44 alvherre Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.107 2007/04/30 03:23:48 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -468,29 +468,15 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
468468
/* Log the action if appropriate */
469469
if (IsAutoVacuumWorkerProcess() && Log_autovacuum >= 0)
470470
{
471-
long diff = 0L;
472-
473-
if (Log_autovacuum > 0)
474-
{
475-
TimestampTz endtime;
476-
int usecs;
477-
long secs;
478-
479-
endtime = GetCurrentTimestamp();
480-
TimestampDifference(starttime, endtime, &secs, &usecs);
481-
482-
diff = secs * 1000 + usecs / 1000;
483-
}
484-
485-
if (Log_autovacuum == 0 || diff >= Log_autovacuum)
486-
{
471+
if (Log_autovacuum == 0 ||
472+
TimestampDifferenceExceeds(starttime, GetCurrentTimestamp(),
473+
Log_autovacuum))
487474
ereport(LOG,
488475
(errmsg("automatic analyze of table \"%s.%s.%s\" system usage: %s",
489476
get_database_name(MyDatabaseId),
490477
get_namespace_name(RelationGetNamespace(onerel)),
491478
RelationGetRelationName(onerel),
492479
pg_rusage_show(&ru0))));
493-
}
494480
}
495481
}
496482

src/backend/commands/vacuumlazy.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
*
3737
*
3838
* IDENTIFICATION
39-
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.87 2007/04/19 16:26:44 alvherre Exp $
39+
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.88 2007/04/30 03:23:48 tgl Exp $
4040
*
4141
*-------------------------------------------------------------------------
4242
*/
@@ -217,22 +217,9 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
217217
/* and log the action if appropriate */
218218
if (IsAutoVacuumWorkerProcess() && Log_autovacuum >= 0)
219219
{
220-
long diff = 0L;
221-
222-
if (Log_autovacuum > 0)
223-
{
224-
TimestampTz endtime;
225-
int usecs;
226-
long secs;
227-
228-
endtime = GetCurrentTimestamp();
229-
TimestampDifference(starttime, endtime, &secs, &usecs);
230-
231-
diff = secs * 1000 + usecs / 1000;
232-
}
233-
234-
if (Log_autovacuum == 0 || diff >= Log_autovacuum)
235-
{
220+
if (Log_autovacuum == 0 ||
221+
TimestampDifferenceExceeds(starttime, GetCurrentTimestamp(),
222+
Log_autovacuum))
236223
ereport(LOG,
237224
(errmsg("automatic vacuum of table \"%s.%s.%s\": index scans: %d\n"
238225
"pages: %d removed, %d remain\n"
@@ -245,7 +232,6 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
245232
vacrelstats->pages_removed, vacrelstats->rel_pages,
246233
vacrelstats->tuples_deleted, vacrelstats->rel_tuples,
247234
pg_rusage_show(&ru0))));
248-
}
249235
}
250236
}
251237

src/backend/postmaster/pgstat.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
* Copyright (c) 2001-2007, PostgreSQL Global Development Group
1515
*
16-
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.153 2007/04/21 04:10:53 tgl Exp $
16+
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.154 2007/04/30 03:23:49 tgl Exp $
1717
* ----------
1818
*/
1919
#include "postgres.h"
@@ -608,15 +608,34 @@ void allow_immediate_pgstat_restart(void)
608608
/* ----------
609609
* pgstat_report_tabstat() -
610610
*
611-
* Called from tcop/postgres.c to send the so far collected
612-
* per table access statistics to the collector.
611+
* Called from tcop/postgres.c to send the so far collected per-table
612+
* access statistics to the collector. Note that this is called only
613+
* when not within a transaction, so it is fair to use transaction stop
614+
* time as an approximation of current time.
613615
* ----------
614616
*/
615617
void
616618
pgstat_report_tabstat(void)
617619
{
620+
static TimestampTz last_report = 0;
621+
TimestampTz now;
622+
623+
/* Don't expend a clock check if nothing to do */
624+
if (RegularTabStat.tsa_used == 0 &&
625+
SharedTabStat.tsa_used == 0)
626+
return;
627+
628+
/*
629+
* Don't send a message unless it's been at least PGSTAT_STAT_INTERVAL
630+
* msec since we last sent one.
631+
*/
632+
now = GetCurrentTransactionStopTimestamp();
633+
if (!TimestampDifferenceExceeds(last_report, now, PGSTAT_STAT_INTERVAL))
634+
return;
635+
last_report = now;
636+
618637
/*
619-
* For each message buffer used during the last query set the header
638+
* For each message buffer used during the last queries, set the header
620639
* fields and send it out; then mark the entries unused.
621640
*/
622641
pgstat_report_one_tabstat(&RegularTabStat, MyDatabaseId);

src/backend/utils/adt/timestamp.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.174 2007/02/27 23:48:09 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.175 2007/04/30 03:23:49 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1238,6 +1238,27 @@ TimestampDifference(TimestampTz start_time, TimestampTz stop_time,
12381238
}
12391239
}
12401240

1241+
/*
1242+
* TimestampDifferenceExceeds -- report whether the difference between two
1243+
* timestamps is >= a threshold (expressed in milliseconds)
1244+
*
1245+
* Both inputs must be ordinary finite timestamps (in current usage,
1246+
* they'll be results from GetCurrentTimestamp()).
1247+
*/
1248+
bool
1249+
TimestampDifferenceExceeds(TimestampTz start_time,
1250+
TimestampTz stop_time,
1251+
int msec)
1252+
{
1253+
TimestampTz diff = stop_time - start_time;
1254+
1255+
#ifdef HAVE_INT64_TIMESTAMP
1256+
return (diff >= msec * INT64CONST(1000));
1257+
#else
1258+
return (diff * 1000.0 >= msec);
1259+
#endif
1260+
}
1261+
12411262
/*
12421263
* Convert a time_t to TimestampTz.
12431264
*

src/include/access/xact.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/access/xact.h,v 1.85 2007/03/13 00:33:42 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/access/xact.h,v 1.86 2007/04/30 03:23:49 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -142,6 +142,7 @@ extern SubTransactionId GetCurrentSubTransactionId(void);
142142
extern CommandId GetCurrentCommandId(void);
143143
extern TimestampTz GetCurrentTransactionStartTimestamp(void);
144144
extern TimestampTz GetCurrentStatementStartTimestamp(void);
145+
extern TimestampTz GetCurrentTransactionStopTimestamp(void);
145146
extern void SetCurrentStatementStartTimestamp(void);
146147
extern int GetCurrentTransactionNestLevel(void);
147148
extern bool TransactionIdIsCurrentTransactionId(TransactionId xid);

src/include/utils/timestamp.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.67 2007/02/16 03:39:45 momjian Exp $
9+
* $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.68 2007/04/30 03:23:49 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -311,6 +311,9 @@ extern TimestampTz GetCurrentTimestamp(void);
311311

312312
extern void TimestampDifference(TimestampTz start_time, TimestampTz stop_time,
313313
long *secs, int *microsecs);
314+
extern bool TimestampDifferenceExceeds(TimestampTz start_time,
315+
TimestampTz stop_time,
316+
int msec);
314317

315318
extern TimestampTz time_t_to_timestamptz(time_t tm);
316319
extern time_t timestamptz_to_time_t(TimestampTz t);

src/test/regress/expected/stats.out

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ SELECT count(*) FROM tenk2 WHERE unique1 = 1;
7373
1
7474
(1 row)
7575

76+
-- force the rate-limiting logic in pgstat_report_tabstat() to time out
77+
-- and send a message
78+
SELECT pg_sleep(1.0);
79+
pg_sleep
80+
----------
81+
82+
(1 row)
83+
7684
-- wait for stats collector to update
7785
SELECT wait_for_stats();
7886
wait_for_stats

src/test/regress/sql/stats.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ SELECT count(*) FROM tenk2;
6060
-- do an indexscan
6161
SELECT count(*) FROM tenk2 WHERE unique1 = 1;
6262

63+
-- force the rate-limiting logic in pgstat_report_tabstat() to time out
64+
-- and send a message
65+
SELECT pg_sleep(1.0);
66+
6367
-- wait for stats collector to update
6468
SELECT wait_for_stats();
6569

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy