Add an EXPLAIN (BUFFERS) option to show buffer-usage statistics.
This patch also removes buffer-usage statistics from the track_counts output, since this (or the global server statistics) is deemed to be a better interface to this information. Itagaki Takahiro, reviewed by Euler Taveira de Oliveira.
This commit is contained in:
parent
6f1bf75d50
commit
cddca5ec13
@ -6,7 +6,7 @@
|
|||||||
* Copyright (c) 2008-2009, PostgreSQL Global Development Group
|
* Copyright (c) 2008-2009, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/contrib/auto_explain/auto_explain.c,v 1.9 2009/12/12 00:35:33 rhaas Exp $
|
* $PostgreSQL: pgsql/contrib/auto_explain/auto_explain.c,v 1.10 2009/12/15 04:57:46 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -22,6 +22,7 @@ PG_MODULE_MAGIC;
|
|||||||
static int auto_explain_log_min_duration = -1; /* msec or -1 */
|
static int auto_explain_log_min_duration = -1; /* msec or -1 */
|
||||||
static bool auto_explain_log_analyze = false;
|
static bool auto_explain_log_analyze = false;
|
||||||
static bool auto_explain_log_verbose = false;
|
static bool auto_explain_log_verbose = false;
|
||||||
|
static bool auto_explain_log_buffers = false;
|
||||||
static int auto_explain_log_format = EXPLAIN_FORMAT_TEXT;
|
static int auto_explain_log_format = EXPLAIN_FORMAT_TEXT;
|
||||||
static bool auto_explain_log_nested_statements = false;
|
static bool auto_explain_log_nested_statements = false;
|
||||||
|
|
||||||
@ -93,6 +94,16 @@ _PG_init(void)
|
|||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
DefineCustomBoolVariable("auto_explain.log_buffers",
|
||||||
|
"Log buffers usage.",
|
||||||
|
NULL,
|
||||||
|
&auto_explain_log_buffers,
|
||||||
|
false,
|
||||||
|
PGC_SUSET,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
DefineCustomEnumVariable("auto_explain.log_format",
|
DefineCustomEnumVariable("auto_explain.log_format",
|
||||||
"EXPLAIN format to be used for plan logging.",
|
"EXPLAIN format to be used for plan logging.",
|
||||||
NULL,
|
NULL,
|
||||||
@ -147,7 +158,11 @@ explain_ExecutorStart(QueryDesc *queryDesc, int eflags)
|
|||||||
{
|
{
|
||||||
/* Enable per-node instrumentation iff log_analyze is required. */
|
/* Enable per-node instrumentation iff log_analyze is required. */
|
||||||
if (auto_explain_log_analyze && (eflags & EXEC_FLAG_EXPLAIN_ONLY) == 0)
|
if (auto_explain_log_analyze && (eflags & EXEC_FLAG_EXPLAIN_ONLY) == 0)
|
||||||
queryDesc->doInstrument = true;
|
{
|
||||||
|
queryDesc->instrument_options |= INSTRUMENT_TIMER;
|
||||||
|
if (auto_explain_log_buffers)
|
||||||
|
queryDesc->instrument_options |= INSTRUMENT_BUFFERS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev_ExecutorStart)
|
if (prev_ExecutorStart)
|
||||||
@ -167,7 +182,7 @@ explain_ExecutorStart(QueryDesc *queryDesc, int eflags)
|
|||||||
MemoryContext oldcxt;
|
MemoryContext oldcxt;
|
||||||
|
|
||||||
oldcxt = MemoryContextSwitchTo(queryDesc->estate->es_query_cxt);
|
oldcxt = MemoryContextSwitchTo(queryDesc->estate->es_query_cxt);
|
||||||
queryDesc->totaltime = InstrAlloc(1);
|
queryDesc->totaltime = InstrAlloc(1, INSTRUMENT_ALL);
|
||||||
MemoryContextSwitchTo(oldcxt);
|
MemoryContextSwitchTo(oldcxt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,8 +234,9 @@ explain_ExecutorEnd(QueryDesc *queryDesc)
|
|||||||
ExplainState es;
|
ExplainState es;
|
||||||
|
|
||||||
ExplainInitState(&es);
|
ExplainInitState(&es);
|
||||||
es.analyze = (queryDesc->doInstrument && auto_explain_log_analyze);
|
es.analyze = (queryDesc->instrument_options && auto_explain_log_analyze);
|
||||||
es.verbose = auto_explain_log_verbose;
|
es.verbose = auto_explain_log_verbose;
|
||||||
|
es.buffers = (es.analyze && auto_explain_log_buffers);
|
||||||
es.format = auto_explain_log_format;
|
es.format = auto_explain_log_format;
|
||||||
|
|
||||||
ExplainBeginOutput(&es);
|
ExplainBeginOutput(&es);
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* Copyright (c) 2008-2009, PostgreSQL Global Development Group
|
* Copyright (c) 2008-2009, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/contrib/pg_stat_statements/pg_stat_statements.c,v 1.7 2009/12/01 02:31:11 momjian Exp $
|
* $PostgreSQL: pgsql/contrib/pg_stat_statements/pg_stat_statements.c,v 1.8 2009/12/15 04:57:46 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -495,7 +495,7 @@ pgss_ExecutorStart(QueryDesc *queryDesc, int eflags)
|
|||||||
MemoryContext oldcxt;
|
MemoryContext oldcxt;
|
||||||
|
|
||||||
oldcxt = MemoryContextSwitchTo(queryDesc->estate->es_query_cxt);
|
oldcxt = MemoryContextSwitchTo(queryDesc->estate->es_query_cxt);
|
||||||
queryDesc->totaltime = InstrAlloc(1);
|
queryDesc->totaltime = InstrAlloc(1, INSTRUMENT_ALL);
|
||||||
MemoryContextSwitchTo(oldcxt);
|
MemoryContextSwitchTo(oldcxt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/auto-explain.sgml,v 1.5 2009/12/11 01:33:35 adunstan Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/auto-explain.sgml,v 1.6 2009/12/15 04:57:47 rhaas Exp $ -->
|
||||||
|
|
||||||
<sect1 id="auto-explain">
|
<sect1 id="auto-explain">
|
||||||
<title>auto_explain</title>
|
<title>auto_explain</title>
|
||||||
@ -102,6 +102,25 @@ LOAD 'auto_explain';
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<varname>auto_explain.log_buffers</varname> (<type>boolean</type>)
|
||||||
|
</term>
|
||||||
|
<indexterm>
|
||||||
|
<primary><varname>auto_explain.log_buffers</> configuration parameter</primary>
|
||||||
|
</indexterm>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<varname>auto_explain.log_buffers</varname> causes <command>EXPLAIN
|
||||||
|
(ANALYZE, BUFFERS)</> output, rather than just <command>EXPLAIN</>
|
||||||
|
output, to be printed when an execution plan is logged. This parameter is
|
||||||
|
off by default. Only superusers can change this setting. This
|
||||||
|
parameter has no effect unless <varname>auto_explain.log_analyze</>
|
||||||
|
parameter is set.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<varname>auto_explain.log_format</varname> (<type>enum</type>)
|
<varname>auto_explain.log_format</varname> (<type>enum</type>)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/explain.sgml,v 1.47 2009/12/11 01:33:35 adunstan Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/explain.sgml,v 1.48 2009/12/15 04:57:47 rhaas Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ PostgreSQL documentation
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<synopsis>
|
<synopsis>
|
||||||
EXPLAIN [ ( { ANALYZE <replaceable class="parameter">boolean</replaceable> | VERBOSE <replaceable class="parameter">boolean</replaceable> | COSTS <replaceable class="parameter">boolean</replaceable> | FORMAT { TEXT | XML | JSON | YAML } } [, ...] ) ] <replaceable class="parameter">statement</replaceable>
|
EXPLAIN [ ( { ANALYZE <replaceable class="parameter">boolean</replaceable> | VERBOSE <replaceable class="parameter">boolean</replaceable> | COSTS <replaceable class="parameter">boolean</replaceable> | BUFFERS <replaceable class="parameter">boolean</replaceable> | FORMAT { TEXT | XML | JSON | YAML } } [, ...] ) ] <replaceable class="parameter">statement</replaceable>
|
||||||
EXPLAIN [ ANALYZE ] [ VERBOSE ] <replaceable class="parameter">statement</replaceable>
|
EXPLAIN [ ANALYZE ] [ VERBOSE ] <replaceable class="parameter">statement</replaceable>
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
@ -139,6 +139,24 @@ ROLLBACK;
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>BUFFERS</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Include information on buffer usage. Specifically, include the number of
|
||||||
|
shared blocks hits, reads, and writes, the number of local blocks hits,
|
||||||
|
reads, and writes, and the number of temp blocks reads and writes.
|
||||||
|
Shared blocks, local blocks, and temp blocks contain tables and indexes,
|
||||||
|
temporary tables and temporary indexes, and disk blocks used in sort and
|
||||||
|
materialized plans, respectively. The number of blocks shown for an
|
||||||
|
upper-level node includes those used by all its child nodes. In text
|
||||||
|
format, only non-zero values are printed. This parameter may only be
|
||||||
|
used with <literal>ANALYZE</literal> parameter. It defaults to
|
||||||
|
<literal>FALSE</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>FORMAT</literal></term>
|
<term><literal>FORMAT</literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.318 2009/11/20 20:38:10 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.319 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1094,7 +1094,7 @@ DoCopy(const CopyStmt *stmt, const char *queryString)
|
|||||||
cstate->queryDesc = CreateQueryDesc(plan, queryString,
|
cstate->queryDesc = CreateQueryDesc(plan, queryString,
|
||||||
GetActiveSnapshot(),
|
GetActiveSnapshot(),
|
||||||
InvalidSnapshot,
|
InvalidSnapshot,
|
||||||
dest, NULL, false);
|
dest, NULL, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call ExecutorStart to prepare the plan for execution.
|
* Call ExecutorStart to prepare the plan for execution.
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994-5, Regents of the University of California
|
* Portions Copyright (c) 1994-5, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.195 2009/12/12 00:35:33 rhaas Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.196 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -125,6 +125,8 @@ ExplainQuery(ExplainStmt *stmt, const char *queryString,
|
|||||||
es.verbose = defGetBoolean(opt);
|
es.verbose = defGetBoolean(opt);
|
||||||
else if (strcmp(opt->defname, "costs") == 0)
|
else if (strcmp(opt->defname, "costs") == 0)
|
||||||
es.costs = defGetBoolean(opt);
|
es.costs = defGetBoolean(opt);
|
||||||
|
else if (strcmp(opt->defname, "buffers") == 0)
|
||||||
|
es.buffers = defGetBoolean(opt);
|
||||||
else if (strcmp(opt->defname, "format") == 0)
|
else if (strcmp(opt->defname, "format") == 0)
|
||||||
{
|
{
|
||||||
char *p = defGetString(opt);
|
char *p = defGetString(opt);
|
||||||
@ -150,6 +152,11 @@ ExplainQuery(ExplainStmt *stmt, const char *queryString,
|
|||||||
opt->defname)));
|
opt->defname)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (es.buffers && !es.analyze)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
|
errmsg("EXPLAIN option BUFFERS requires ANALYZE")));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run parse analysis and rewrite. Note this also acquires sufficient
|
* Run parse analysis and rewrite. Note this also acquires sufficient
|
||||||
* locks on the source table(s).
|
* locks on the source table(s).
|
||||||
@ -339,6 +346,12 @@ ExplainOnePlan(PlannedStmt *plannedstmt, ExplainState *es,
|
|||||||
instr_time starttime;
|
instr_time starttime;
|
||||||
double totaltime = 0;
|
double totaltime = 0;
|
||||||
int eflags;
|
int eflags;
|
||||||
|
int instrument_option = 0;
|
||||||
|
|
||||||
|
if (es->analyze)
|
||||||
|
instrument_option |= INSTRUMENT_TIMER;
|
||||||
|
if (es->buffers)
|
||||||
|
instrument_option |= INSTRUMENT_BUFFERS;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use a snapshot with an updated command ID to ensure this query sees
|
* Use a snapshot with an updated command ID to ensure this query sees
|
||||||
@ -349,7 +362,7 @@ ExplainOnePlan(PlannedStmt *plannedstmt, ExplainState *es,
|
|||||||
/* Create a QueryDesc requesting no output */
|
/* Create a QueryDesc requesting no output */
|
||||||
queryDesc = CreateQueryDesc(plannedstmt, queryString,
|
queryDesc = CreateQueryDesc(plannedstmt, queryString,
|
||||||
GetActiveSnapshot(), InvalidSnapshot,
|
GetActiveSnapshot(), InvalidSnapshot,
|
||||||
None_Receiver, params, es->analyze);
|
None_Receiver, params, instrument_option);
|
||||||
|
|
||||||
INSTR_TIME_SET_CURRENT(starttime);
|
INSTR_TIME_SET_CURRENT(starttime);
|
||||||
|
|
||||||
@ -1042,6 +1055,84 @@ ExplainNode(Plan *plan, PlanState *planstate,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Show buffer usage */
|
||||||
|
if (es->buffers)
|
||||||
|
{
|
||||||
|
const BufferUsage *usage = &planstate->instrument->bufusage;
|
||||||
|
|
||||||
|
if (es->format == EXPLAIN_FORMAT_TEXT)
|
||||||
|
{
|
||||||
|
bool has_shared = (usage->shared_blks_hit > 0 ||
|
||||||
|
usage->shared_blks_read > 0 ||
|
||||||
|
usage->shared_blks_written);
|
||||||
|
bool has_local = (usage->local_blks_hit > 0 ||
|
||||||
|
usage->local_blks_read > 0 ||
|
||||||
|
usage->local_blks_written);
|
||||||
|
bool has_temp = (usage->temp_blks_read > 0 ||
|
||||||
|
usage->temp_blks_written);
|
||||||
|
|
||||||
|
/* Show only positive counter values. */
|
||||||
|
if (has_shared || has_local || has_temp)
|
||||||
|
{
|
||||||
|
appendStringInfoSpaces(es->str, es->indent * 2);
|
||||||
|
appendStringInfoString(es->str, "Buffers:");
|
||||||
|
|
||||||
|
if (has_shared)
|
||||||
|
{
|
||||||
|
appendStringInfoString(es->str, " shared");
|
||||||
|
if (usage->shared_blks_hit > 0)
|
||||||
|
appendStringInfo(es->str, " hit=%ld",
|
||||||
|
usage->shared_blks_hit);
|
||||||
|
if (usage->shared_blks_read > 0)
|
||||||
|
appendStringInfo(es->str, " read=%ld",
|
||||||
|
usage->shared_blks_read);
|
||||||
|
if (usage->shared_blks_written > 0)
|
||||||
|
appendStringInfo(es->str, " written=%ld",
|
||||||
|
usage->shared_blks_written);
|
||||||
|
if (has_local || has_temp)
|
||||||
|
appendStringInfoChar(es->str, ',');
|
||||||
|
}
|
||||||
|
if (has_local)
|
||||||
|
{
|
||||||
|
appendStringInfoString(es->str, " local");
|
||||||
|
if (usage->local_blks_hit > 0)
|
||||||
|
appendStringInfo(es->str, " hit=%ld",
|
||||||
|
usage->local_blks_hit);
|
||||||
|
if (usage->local_blks_read > 0)
|
||||||
|
appendStringInfo(es->str, " read=%ld",
|
||||||
|
usage->local_blks_read);
|
||||||
|
if (usage->local_blks_written > 0)
|
||||||
|
appendStringInfo(es->str, " written=%ld",
|
||||||
|
usage->local_blks_written);
|
||||||
|
if (has_temp)
|
||||||
|
appendStringInfoChar(es->str, ',');
|
||||||
|
}
|
||||||
|
if (has_temp)
|
||||||
|
{
|
||||||
|
appendStringInfoString(es->str, " temp");
|
||||||
|
if (usage->temp_blks_read > 0)
|
||||||
|
appendStringInfo(es->str, " read=%ld",
|
||||||
|
usage->temp_blks_read);
|
||||||
|
if (usage->temp_blks_written > 0)
|
||||||
|
appendStringInfo(es->str, " written=%ld",
|
||||||
|
usage->temp_blks_written);
|
||||||
|
}
|
||||||
|
appendStringInfoChar(es->str, '\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExplainPropertyLong("Shared Hit Blocks", usage->shared_blks_hit, es);
|
||||||
|
ExplainPropertyLong("Shared Read Blocks", usage->shared_blks_read, es);
|
||||||
|
ExplainPropertyLong("Shared Written Blocks", usage->shared_blks_written, es);
|
||||||
|
ExplainPropertyLong("Local Hit Blocks", usage->local_blks_hit, es);
|
||||||
|
ExplainPropertyLong("Local Read Blocks", usage->local_blks_read, es);
|
||||||
|
ExplainPropertyLong("Local Written Blocks", usage->local_blks_written, es);
|
||||||
|
ExplainPropertyLong("Temp Read Blocks", usage->temp_blks_read, es);
|
||||||
|
ExplainPropertyLong("Temp Written Blocks", usage->temp_blks_written, es);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Get ready to display the child plans */
|
/* Get ready to display the child plans */
|
||||||
haschildren = plan->initPlan ||
|
haschildren = plan->initPlan ||
|
||||||
outerPlan(plan) ||
|
outerPlan(plan) ||
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.309 2009/12/11 03:34:55 itagaki Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.310 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -936,7 +936,7 @@ ExecuteTruncate(TruncateStmt *stmt)
|
|||||||
rel,
|
rel,
|
||||||
0, /* dummy rangetable index */
|
0, /* dummy rangetable index */
|
||||||
CMD_DELETE, /* don't need any index info */
|
CMD_DELETE, /* don't need any index info */
|
||||||
false);
|
0);
|
||||||
resultRelInfo++;
|
resultRelInfo++;
|
||||||
}
|
}
|
||||||
estate->es_result_relations = resultRelInfos;
|
estate->es_result_relations = resultRelInfos;
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.337 2009/12/11 18:14:43 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.338 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -180,7 +180,7 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
|
|||||||
*/
|
*/
|
||||||
estate->es_snapshot = RegisterSnapshot(queryDesc->snapshot);
|
estate->es_snapshot = RegisterSnapshot(queryDesc->snapshot);
|
||||||
estate->es_crosscheck_snapshot = RegisterSnapshot(queryDesc->crosscheck_snapshot);
|
estate->es_crosscheck_snapshot = RegisterSnapshot(queryDesc->crosscheck_snapshot);
|
||||||
estate->es_instrument = queryDesc->doInstrument;
|
estate->es_instrument = queryDesc->instrument_options;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the plan state tree
|
* Initialize the plan state tree
|
||||||
@ -859,7 +859,7 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo,
|
|||||||
Relation resultRelationDesc,
|
Relation resultRelationDesc,
|
||||||
Index resultRelationIndex,
|
Index resultRelationIndex,
|
||||||
CmdType operation,
|
CmdType operation,
|
||||||
bool doInstrument)
|
int instrument_options)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Check valid relkind ... parser and/or planner should have noticed this
|
* Check valid relkind ... parser and/or planner should have noticed this
|
||||||
@ -914,10 +914,8 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo,
|
|||||||
palloc0(n * sizeof(FmgrInfo));
|
palloc0(n * sizeof(FmgrInfo));
|
||||||
resultRelInfo->ri_TrigWhenExprs = (List **)
|
resultRelInfo->ri_TrigWhenExprs = (List **)
|
||||||
palloc0(n * sizeof(List *));
|
palloc0(n * sizeof(List *));
|
||||||
if (doInstrument)
|
if (instrument_options)
|
||||||
resultRelInfo->ri_TrigInstrument = InstrAlloc(n);
|
resultRelInfo->ri_TrigInstrument = InstrAlloc(n, instrument_options);
|
||||||
else
|
|
||||||
resultRelInfo->ri_TrigInstrument = NULL;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/execProcnode.c,v 1.68 2009/10/12 18:10:41 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/execProcnode.c,v 1.69 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -321,7 +321,7 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
|
|||||||
|
|
||||||
/* Set up instrumentation for this node if requested */
|
/* Set up instrumentation for this node if requested */
|
||||||
if (estate->es_instrument)
|
if (estate->es_instrument)
|
||||||
result->instrument = InstrAlloc(1);
|
result->instrument = InstrAlloc(1, estate->es_instrument);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.137 2009/12/14 02:15:51 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.138 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -414,7 +414,7 @@ postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
|
|||||||
fcache->src,
|
fcache->src,
|
||||||
snapshot, InvalidSnapshot,
|
snapshot, InvalidSnapshot,
|
||||||
dest,
|
dest,
|
||||||
fcache->paramLI, false);
|
fcache->paramLI, 0);
|
||||||
else
|
else
|
||||||
es->qd = CreateUtilityQueryDesc(es->stmt,
|
es->qd = CreateUtilityQueryDesc(es->stmt,
|
||||||
fcache->src,
|
fcache->src,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Copyright (c) 2001-2009, PostgreSQL Global Development Group
|
* Copyright (c) 2001-2009, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/instrument.c,v 1.22 2009/01/01 17:23:41 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/instrument.c,v 1.23 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -17,14 +17,28 @@
|
|||||||
|
|
||||||
#include "executor/instrument.h"
|
#include "executor/instrument.h"
|
||||||
|
|
||||||
|
BufferUsage pgBufferUsage;
|
||||||
|
|
||||||
|
static void BufferUsageAccumDiff(BufferUsage *dst,
|
||||||
|
const BufferUsage *add, const BufferUsage *sub);
|
||||||
|
|
||||||
/* Allocate new instrumentation structure(s) */
|
/* Allocate new instrumentation structure(s) */
|
||||||
Instrumentation *
|
Instrumentation *
|
||||||
InstrAlloc(int n)
|
InstrAlloc(int n, int instrument_options)
|
||||||
{
|
{
|
||||||
Instrumentation *instr = palloc0(n * sizeof(Instrumentation));
|
Instrumentation *instr;
|
||||||
|
|
||||||
/* we don't need to do any initialization except zero 'em */
|
/* timer is always required for now */
|
||||||
|
Assert(instrument_options & INSTRUMENT_TIMER);
|
||||||
|
|
||||||
|
instr = palloc0(n * sizeof(Instrumentation));
|
||||||
|
if (instrument_options & INSTRUMENT_BUFFERS)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
instr[i].needs_bufusage = true;
|
||||||
|
}
|
||||||
|
|
||||||
return instr;
|
return instr;
|
||||||
}
|
}
|
||||||
@ -37,6 +51,10 @@ InstrStartNode(Instrumentation *instr)
|
|||||||
INSTR_TIME_SET_CURRENT(instr->starttime);
|
INSTR_TIME_SET_CURRENT(instr->starttime);
|
||||||
else
|
else
|
||||||
elog(DEBUG2, "InstrStartNode called twice in a row");
|
elog(DEBUG2, "InstrStartNode called twice in a row");
|
||||||
|
|
||||||
|
/* initialize buffer usage per plan node */
|
||||||
|
if (instr->needs_bufusage)
|
||||||
|
instr->bufusage_start = pgBufferUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exit from a plan node */
|
/* Exit from a plan node */
|
||||||
@ -59,6 +77,11 @@ InstrStopNode(Instrumentation *instr, double nTuples)
|
|||||||
|
|
||||||
INSTR_TIME_SET_ZERO(instr->starttime);
|
INSTR_TIME_SET_ZERO(instr->starttime);
|
||||||
|
|
||||||
|
/* Adds delta of buffer usage to node's count. */
|
||||||
|
if (instr->needs_bufusage)
|
||||||
|
BufferUsageAccumDiff(&instr->bufusage,
|
||||||
|
&pgBufferUsage, &instr->bufusage_start);
|
||||||
|
|
||||||
/* Is this the first tuple of this cycle? */
|
/* Is this the first tuple of this cycle? */
|
||||||
if (!instr->running)
|
if (!instr->running)
|
||||||
{
|
{
|
||||||
@ -95,3 +118,19 @@ InstrEndLoop(Instrumentation *instr)
|
|||||||
instr->firsttuple = 0;
|
instr->firsttuple = 0;
|
||||||
instr->tuplecount = 0;
|
instr->tuplecount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
BufferUsageAccumDiff(BufferUsage *dst,
|
||||||
|
const BufferUsage *add,
|
||||||
|
const BufferUsage *sub)
|
||||||
|
{
|
||||||
|
/* dst += add - sub */
|
||||||
|
dst->shared_blks_hit += add->shared_blks_hit - sub->shared_blks_hit;
|
||||||
|
dst->shared_blks_read += add->shared_blks_read - sub->shared_blks_read;
|
||||||
|
dst->shared_blks_written += add->shared_blks_written - sub->shared_blks_written;
|
||||||
|
dst->local_blks_hit += add->local_blks_hit - sub->local_blks_hit;
|
||||||
|
dst->local_blks_read += add->local_blks_read - sub->local_blks_read;
|
||||||
|
dst->local_blks_written += add->local_blks_written - sub->local_blks_written;
|
||||||
|
dst->temp_blks_read += add->temp_blks_read - sub->temp_blks_read;
|
||||||
|
dst->temp_blks_written += add->temp_blks_written - sub->temp_blks_written;
|
||||||
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.211 2009/11/04 22:26:06 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.212 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1908,7 +1908,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
|
|||||||
plansource->query_string,
|
plansource->query_string,
|
||||||
snap, crosscheck_snapshot,
|
snap, crosscheck_snapshot,
|
||||||
dest,
|
dest,
|
||||||
paramLI, false);
|
paramLI, 0);
|
||||||
res = _SPI_pquery(qdesc, fire_triggers,
|
res = _SPI_pquery(qdesc, fire_triggers,
|
||||||
canSetTag ? tcount : 0);
|
canSetTag ? tcount : 0);
|
||||||
FreeQueryDesc(qdesc);
|
FreeQueryDesc(qdesc);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.82 2009/01/01 17:23:47 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.83 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -22,16 +22,6 @@ BufferDesc *BufferDescriptors;
|
|||||||
char *BufferBlocks;
|
char *BufferBlocks;
|
||||||
int32 *PrivateRefCount;
|
int32 *PrivateRefCount;
|
||||||
|
|
||||||
/* statistics counters */
|
|
||||||
long int ReadBufferCount;
|
|
||||||
long int ReadLocalBufferCount;
|
|
||||||
long int BufferHitCount;
|
|
||||||
long int LocalBufferHitCount;
|
|
||||||
long int BufferFlushCount;
|
|
||||||
long int LocalBufferFlushCount;
|
|
||||||
long int BufFileReadCount;
|
|
||||||
long int BufFileWriteCount;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Data Structures:
|
* Data Structures:
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.252 2009/06/11 14:49:01 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.253 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -34,6 +34,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
|
#include "executor/instrument.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "pg_trace.h"
|
#include "pg_trace.h"
|
||||||
#include "pgstat.h"
|
#include "pgstat.h"
|
||||||
@ -300,22 +301,23 @@ ReadBuffer_common(SMgrRelation smgr, bool isLocalBuf, ForkNumber forkNum,
|
|||||||
|
|
||||||
if (isLocalBuf)
|
if (isLocalBuf)
|
||||||
{
|
{
|
||||||
ReadLocalBufferCount++;
|
|
||||||
bufHdr = LocalBufferAlloc(smgr, forkNum, blockNum, &found);
|
bufHdr = LocalBufferAlloc(smgr, forkNum, blockNum, &found);
|
||||||
if (found)
|
if (found)
|
||||||
LocalBufferHitCount++;
|
pgBufferUsage.local_blks_hit++;
|
||||||
|
else
|
||||||
|
pgBufferUsage.local_blks_read++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ReadBufferCount++;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lookup the buffer. IO_IN_PROGRESS is set if the requested block is
|
* lookup the buffer. IO_IN_PROGRESS is set if the requested block is
|
||||||
* not currently in memory.
|
* not currently in memory.
|
||||||
*/
|
*/
|
||||||
bufHdr = BufferAlloc(smgr, forkNum, blockNum, strategy, &found);
|
bufHdr = BufferAlloc(smgr, forkNum, blockNum, strategy, &found);
|
||||||
if (found)
|
if (found)
|
||||||
BufferHitCount++;
|
pgBufferUsage.shared_blks_hit++;
|
||||||
|
else
|
||||||
|
pgBufferUsage.shared_blks_read++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* At this point we do NOT hold any locks. */
|
/* At this point we do NOT hold any locks. */
|
||||||
@ -1610,54 +1612,6 @@ SyncOneBuffer(int buf_id, bool skip_recently_used)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return a palloc'd string containing buffer usage statistics.
|
|
||||||
*/
|
|
||||||
char *
|
|
||||||
ShowBufferUsage(void)
|
|
||||||
{
|
|
||||||
StringInfoData str;
|
|
||||||
float hitrate;
|
|
||||||
float localhitrate;
|
|
||||||
|
|
||||||
initStringInfo(&str);
|
|
||||||
|
|
||||||
if (ReadBufferCount == 0)
|
|
||||||
hitrate = 0.0;
|
|
||||||
else
|
|
||||||
hitrate = (float) BufferHitCount *100.0 / ReadBufferCount;
|
|
||||||
|
|
||||||
if (ReadLocalBufferCount == 0)
|
|
||||||
localhitrate = 0.0;
|
|
||||||
else
|
|
||||||
localhitrate = (float) LocalBufferHitCount *100.0 / ReadLocalBufferCount;
|
|
||||||
|
|
||||||
appendStringInfo(&str,
|
|
||||||
"!\tShared blocks: %10ld read, %10ld written, buffer hit rate = %.2f%%\n",
|
|
||||||
ReadBufferCount - BufferHitCount, BufferFlushCount, hitrate);
|
|
||||||
appendStringInfo(&str,
|
|
||||||
"!\tLocal blocks: %10ld read, %10ld written, buffer hit rate = %.2f%%\n",
|
|
||||||
ReadLocalBufferCount - LocalBufferHitCount, LocalBufferFlushCount, localhitrate);
|
|
||||||
appendStringInfo(&str,
|
|
||||||
"!\tDirect blocks: %10ld read, %10ld written\n",
|
|
||||||
BufFileReadCount, BufFileWriteCount);
|
|
||||||
|
|
||||||
return str.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ResetBufferUsage(void)
|
|
||||||
{
|
|
||||||
BufferHitCount = 0;
|
|
||||||
ReadBufferCount = 0;
|
|
||||||
BufferFlushCount = 0;
|
|
||||||
LocalBufferHitCount = 0;
|
|
||||||
ReadLocalBufferCount = 0;
|
|
||||||
LocalBufferFlushCount = 0;
|
|
||||||
BufFileReadCount = 0;
|
|
||||||
BufFileWriteCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AtEOXact_Buffers - clean up at end of transaction.
|
* AtEOXact_Buffers - clean up at end of transaction.
|
||||||
*
|
*
|
||||||
@ -1916,7 +1870,7 @@ FlushBuffer(volatile BufferDesc *buf, SMgrRelation reln)
|
|||||||
(char *) BufHdrGetBlock(buf),
|
(char *) BufHdrGetBlock(buf),
|
||||||
false);
|
false);
|
||||||
|
|
||||||
BufferFlushCount++;
|
pgBufferUsage.shared_blks_written++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mark the buffer as clean (unless BM_JUST_DIRTIED has become set) and
|
* Mark the buffer as clean (unless BM_JUST_DIRTIED has become set) and
|
||||||
|
@ -9,13 +9,14 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.87 2009/06/11 14:49:01 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.88 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
|
#include "executor/instrument.h"
|
||||||
#include "storage/buf_internals.h"
|
#include "storage/buf_internals.h"
|
||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
#include "storage/smgr.h"
|
#include "storage/smgr.h"
|
||||||
@ -209,7 +210,7 @@ LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum,
|
|||||||
/* Mark not-dirty now in case we error out below */
|
/* Mark not-dirty now in case we error out below */
|
||||||
bufHdr->flags &= ~BM_DIRTY;
|
bufHdr->flags &= ~BM_DIRTY;
|
||||||
|
|
||||||
LocalBufferFlushCount++;
|
pgBufferUsage.local_blks_written++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/storage/file/buffile.c,v 1.34 2009/06/11 14:49:01 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/storage/file/buffile.c,v 1.35 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
* NOTES:
|
* NOTES:
|
||||||
*
|
*
|
||||||
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "executor/instrument.h"
|
||||||
#include "storage/fd.h"
|
#include "storage/fd.h"
|
||||||
#include "storage/buffile.h"
|
#include "storage/buffile.h"
|
||||||
#include "storage/buf_internals.h"
|
#include "storage/buf_internals.h"
|
||||||
@ -240,7 +241,7 @@ BufFileLoadBuffer(BufFile *file)
|
|||||||
file->offsets[file->curFile] += file->nbytes;
|
file->offsets[file->curFile] += file->nbytes;
|
||||||
/* we choose not to advance curOffset here */
|
/* we choose not to advance curOffset here */
|
||||||
|
|
||||||
BufFileReadCount++;
|
pgBufferUsage.temp_blks_read++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -304,7 +305,7 @@ BufFileDumpBuffer(BufFile *file)
|
|||||||
file->curOffset += bytestowrite;
|
file->curOffset += bytestowrite;
|
||||||
wpos += bytestowrite;
|
wpos += bytestowrite;
|
||||||
|
|
||||||
BufFileWriteCount++;
|
pgBufferUsage.temp_blks_written++;
|
||||||
}
|
}
|
||||||
file->dirty = false;
|
file->dirty = false;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.575 2009/11/04 22:26:06 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.576 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* this is the "main" module of the postgres backend and
|
* this is the "main" module of the postgres backend and
|
||||||
@ -3901,7 +3901,6 @@ ResetUsage(void)
|
|||||||
{
|
{
|
||||||
getrusage(RUSAGE_SELF, &Save_r);
|
getrusage(RUSAGE_SELF, &Save_r);
|
||||||
gettimeofday(&Save_t, NULL);
|
gettimeofday(&Save_t, NULL);
|
||||||
ResetBufferUsage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -3912,7 +3911,6 @@ ShowUsage(const char *title)
|
|||||||
sys;
|
sys;
|
||||||
struct timeval elapse_t;
|
struct timeval elapse_t;
|
||||||
struct rusage r;
|
struct rusage r;
|
||||||
char *bufusage;
|
|
||||||
|
|
||||||
getrusage(RUSAGE_SELF, &r);
|
getrusage(RUSAGE_SELF, &r);
|
||||||
gettimeofday(&elapse_t, NULL);
|
gettimeofday(&elapse_t, NULL);
|
||||||
@ -3986,10 +3984,6 @@ ShowUsage(const char *title)
|
|||||||
r.ru_nvcsw, r.ru_nivcsw);
|
r.ru_nvcsw, r.ru_nivcsw);
|
||||||
#endif /* HAVE_GETRUSAGE */
|
#endif /* HAVE_GETRUSAGE */
|
||||||
|
|
||||||
bufusage = ShowBufferUsage();
|
|
||||||
appendStringInfo(&str, "! buffer usage stats:\n%s", bufusage);
|
|
||||||
pfree(bufusage);
|
|
||||||
|
|
||||||
/* remove trailing newline */
|
/* remove trailing newline */
|
||||||
if (str.data[str.len - 1] == '\n')
|
if (str.data[str.len - 1] == '\n')
|
||||||
str.data[--str.len] = '\0';
|
str.data[--str.len] = '\0';
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.132 2009/10/10 01:43:49 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.133 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -67,7 +67,7 @@ CreateQueryDesc(PlannedStmt *plannedstmt,
|
|||||||
Snapshot crosscheck_snapshot,
|
Snapshot crosscheck_snapshot,
|
||||||
DestReceiver *dest,
|
DestReceiver *dest,
|
||||||
ParamListInfo params,
|
ParamListInfo params,
|
||||||
bool doInstrument)
|
int instrument_options)
|
||||||
{
|
{
|
||||||
QueryDesc *qd = (QueryDesc *) palloc(sizeof(QueryDesc));
|
QueryDesc *qd = (QueryDesc *) palloc(sizeof(QueryDesc));
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ CreateQueryDesc(PlannedStmt *plannedstmt,
|
|||||||
qd->crosscheck_snapshot = RegisterSnapshot(crosscheck_snapshot);
|
qd->crosscheck_snapshot = RegisterSnapshot(crosscheck_snapshot);
|
||||||
qd->dest = dest; /* output dest */
|
qd->dest = dest; /* output dest */
|
||||||
qd->params = params; /* parameter values passed into query */
|
qd->params = params; /* parameter values passed into query */
|
||||||
qd->doInstrument = doInstrument; /* instrumentation wanted? */
|
qd->instrument_options = instrument_options; /* instrumentation wanted? */
|
||||||
|
|
||||||
/* null these fields until set by ExecutorStart */
|
/* null these fields until set by ExecutorStart */
|
||||||
qd->tupDesc = NULL;
|
qd->tupDesc = NULL;
|
||||||
@ -111,7 +111,7 @@ CreateUtilityQueryDesc(Node *utilitystmt,
|
|||||||
qd->crosscheck_snapshot = InvalidSnapshot; /* RI check snapshot */
|
qd->crosscheck_snapshot = InvalidSnapshot; /* RI check snapshot */
|
||||||
qd->dest = dest; /* output dest */
|
qd->dest = dest; /* output dest */
|
||||||
qd->params = params; /* parameter values passed into query */
|
qd->params = params; /* parameter values passed into query */
|
||||||
qd->doInstrument = false; /* uninteresting for utilities */
|
qd->instrument_options = false; /* uninteresting for utilities */
|
||||||
|
|
||||||
/* null these fields until set by ExecutorStart */
|
/* null these fields until set by ExecutorStart */
|
||||||
qd->tupDesc = NULL;
|
qd->tupDesc = NULL;
|
||||||
@ -178,7 +178,7 @@ ProcessQuery(PlannedStmt *plan,
|
|||||||
*/
|
*/
|
||||||
queryDesc = CreateQueryDesc(plan, sourceText,
|
queryDesc = CreateQueryDesc(plan, sourceText,
|
||||||
GetActiveSnapshot(), InvalidSnapshot,
|
GetActiveSnapshot(), InvalidSnapshot,
|
||||||
dest, params, false);
|
dest, params, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up to collect AFTER triggers
|
* Set up to collect AFTER triggers
|
||||||
@ -515,7 +515,7 @@ PortalStart(Portal portal, ParamListInfo params, Snapshot snapshot)
|
|||||||
InvalidSnapshot,
|
InvalidSnapshot,
|
||||||
None_Receiver,
|
None_Receiver,
|
||||||
params,
|
params,
|
||||||
false);
|
0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We do *not* call AfterTriggerBeginQuery() here. We assume
|
* We do *not* call AfterTriggerBeginQuery() here. We assume
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994-5, Regents of the University of California
|
* Portions Copyright (c) 1994-5, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/commands/explain.h,v 1.43 2009/12/12 00:35:34 rhaas Exp $
|
* $PostgreSQL: pgsql/src/include/commands/explain.h,v 1.44 2009/12/15 04:57:47 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -30,6 +30,7 @@ typedef struct ExplainState
|
|||||||
bool verbose; /* be verbose */
|
bool verbose; /* be verbose */
|
||||||
bool analyze; /* print actual times */
|
bool analyze; /* print actual times */
|
||||||
bool costs; /* print costs */
|
bool costs; /* print costs */
|
||||||
|
bool buffers; /* print buffer usage */
|
||||||
ExplainFormat format; /* output format */
|
ExplainFormat format; /* output format */
|
||||||
/* other states */
|
/* other states */
|
||||||
PlannedStmt *pstmt; /* top of plan */
|
PlannedStmt *pstmt; /* top of plan */
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/executor/execdesc.h,v 1.40 2009/01/02 20:42:00 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/executor/execdesc.h,v 1.41 2009/12/15 04:57:48 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -42,7 +42,7 @@ typedef struct QueryDesc
|
|||||||
Snapshot crosscheck_snapshot; /* crosscheck for RI update/delete */
|
Snapshot crosscheck_snapshot; /* crosscheck for RI update/delete */
|
||||||
DestReceiver *dest; /* the destination for tuple output */
|
DestReceiver *dest; /* the destination for tuple output */
|
||||||
ParamListInfo params; /* param values being passed in */
|
ParamListInfo params; /* param values being passed in */
|
||||||
bool doInstrument; /* TRUE requests runtime instrumentation */
|
int instrument_options; /* OR of InstrumentOption flags */
|
||||||
|
|
||||||
/* These fields are set by ExecutorStart */
|
/* These fields are set by ExecutorStart */
|
||||||
TupleDesc tupDesc; /* descriptor for result tuples */
|
TupleDesc tupDesc; /* descriptor for result tuples */
|
||||||
@ -60,7 +60,7 @@ extern QueryDesc *CreateQueryDesc(PlannedStmt *plannedstmt,
|
|||||||
Snapshot crosscheck_snapshot,
|
Snapshot crosscheck_snapshot,
|
||||||
DestReceiver *dest,
|
DestReceiver *dest,
|
||||||
ParamListInfo params,
|
ParamListInfo params,
|
||||||
bool doInstrument);
|
int instrument_options);
|
||||||
|
|
||||||
extern QueryDesc *CreateUtilityQueryDesc(Node *utilitystmt,
|
extern QueryDesc *CreateUtilityQueryDesc(Node *utilitystmt,
|
||||||
const char *sourceText,
|
const char *sourceText,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.164 2009/12/07 05:22:23 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.165 2009/12/15 04:57:48 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -161,7 +161,7 @@ extern void InitResultRelInfo(ResultRelInfo *resultRelInfo,
|
|||||||
Relation resultRelationDesc,
|
Relation resultRelationDesc,
|
||||||
Index resultRelationIndex,
|
Index resultRelationIndex,
|
||||||
CmdType operation,
|
CmdType operation,
|
||||||
bool doInstrument);
|
int instrument_options);
|
||||||
extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid);
|
extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid);
|
||||||
extern bool ExecContextForcesOids(PlanState *planstate, bool *hasoids);
|
extern bool ExecContextForcesOids(PlanState *planstate, bool *hasoids);
|
||||||
extern void ExecConstraints(ResultRelInfo *resultRelInfo,
|
extern void ExecConstraints(ResultRelInfo *resultRelInfo,
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2001-2009, PostgreSQL Global Development Group
|
* Copyright (c) 2001-2009, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/executor/instrument.h,v 1.20 2009/01/01 17:23:59 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/executor/instrument.h,v 1.21 2009/12/15 04:57:48 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -16,22 +16,46 @@
|
|||||||
#include "portability/instr_time.h"
|
#include "portability/instr_time.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct BufferUsage
|
||||||
|
{
|
||||||
|
long shared_blks_hit; /* # of shared buffer hits */
|
||||||
|
long shared_blks_read; /* # of shared disk blocks read */
|
||||||
|
long shared_blks_written; /* # of shared disk blocks written */
|
||||||
|
long local_blks_hit; /* # of local buffer hits */
|
||||||
|
long local_blks_read; /* # of local disk blocks read */
|
||||||
|
long local_blks_written; /* # of local disk blocks written */
|
||||||
|
long temp_blks_read; /* # of temp blocks read */
|
||||||
|
long temp_blks_written; /* # of temp blocks written */
|
||||||
|
} BufferUsage;
|
||||||
|
|
||||||
|
typedef enum InstrumentOption
|
||||||
|
{
|
||||||
|
INSTRUMENT_TIMER = 1 << 0, /* needs timer */
|
||||||
|
INSTRUMENT_BUFFERS = 1 << 1, /* needs buffer usage */
|
||||||
|
INSTRUMENT_ALL = 0x7FFFFFFF
|
||||||
|
} InstrumentOption;
|
||||||
|
|
||||||
typedef struct Instrumentation
|
typedef struct Instrumentation
|
||||||
{
|
{
|
||||||
/* Info about current plan cycle: */
|
/* Info about current plan cycle: */
|
||||||
bool running; /* TRUE if we've completed first tuple */
|
bool running; /* TRUE if we've completed first tuple */
|
||||||
|
bool needs_bufusage; /* TRUE if we need buffer usage */
|
||||||
instr_time starttime; /* Start time of current iteration of node */
|
instr_time starttime; /* Start time of current iteration of node */
|
||||||
instr_time counter; /* Accumulated runtime for this node */
|
instr_time counter; /* Accumulated runtime for this node */
|
||||||
double firsttuple; /* Time for first tuple of this cycle */
|
double firsttuple; /* Time for first tuple of this cycle */
|
||||||
double tuplecount; /* Tuples emitted so far this cycle */
|
double tuplecount; /* Tuples emitted so far this cycle */
|
||||||
|
BufferUsage bufusage_start; /* Buffer usage at start */
|
||||||
/* Accumulated statistics across all completed cycles: */
|
/* Accumulated statistics across all completed cycles: */
|
||||||
double startup; /* Total startup time (in seconds) */
|
double startup; /* Total startup time (in seconds) */
|
||||||
double total; /* Total total time (in seconds) */
|
double total; /* Total total time (in seconds) */
|
||||||
double ntuples; /* Total tuples produced */
|
double ntuples; /* Total tuples produced */
|
||||||
double nloops; /* # of run cycles for this node */
|
double nloops; /* # of run cycles for this node */
|
||||||
|
BufferUsage bufusage; /* Total buffer usage */
|
||||||
} Instrumentation;
|
} Instrumentation;
|
||||||
|
|
||||||
extern Instrumentation *InstrAlloc(int n);
|
extern BufferUsage pgBufferUsage;
|
||||||
|
|
||||||
|
extern Instrumentation *InstrAlloc(int n, int instrument_options);
|
||||||
extern void InstrStartNode(Instrumentation *instr);
|
extern void InstrStartNode(Instrumentation *instr);
|
||||||
extern void InstrStopNode(Instrumentation *instr, double nTuples);
|
extern void InstrStopNode(Instrumentation *instr, double nTuples);
|
||||||
extern void InstrEndLoop(Instrumentation *instr);
|
extern void InstrEndLoop(Instrumentation *instr);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.213 2009/12/07 05:22:23 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.214 2009/12/15 04:57:48 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -370,7 +370,7 @@ typedef struct EState
|
|||||||
uint32 es_processed; /* # of tuples processed */
|
uint32 es_processed; /* # of tuples processed */
|
||||||
Oid es_lastoid; /* last oid processed (by INSERT) */
|
Oid es_lastoid; /* last oid processed (by INSERT) */
|
||||||
|
|
||||||
bool es_instrument; /* true requests runtime instrumentation */
|
int es_instrument; /* OR of InstrumentOption flags */
|
||||||
bool es_select_into; /* true if doing SELECT INTO */
|
bool es_select_into; /* true if doing SELECT INTO */
|
||||||
bool es_into_oids; /* true to generate OIDs in SELECT INTO */
|
bool es_into_oids; /* true to generate OIDs in SELECT INTO */
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.102 2009/06/11 14:49:12 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.103 2009/12/15 04:57:48 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -173,16 +173,6 @@ extern PGDLLIMPORT BufferDesc *BufferDescriptors;
|
|||||||
/* in localbuf.c */
|
/* in localbuf.c */
|
||||||
extern BufferDesc *LocalBufferDescriptors;
|
extern BufferDesc *LocalBufferDescriptors;
|
||||||
|
|
||||||
/* event counters in buf_init.c */
|
|
||||||
extern long int ReadBufferCount;
|
|
||||||
extern long int ReadLocalBufferCount;
|
|
||||||
extern long int BufferHitCount;
|
|
||||||
extern long int LocalBufferHitCount;
|
|
||||||
extern long int BufferFlushCount;
|
|
||||||
extern long int LocalBufferFlushCount;
|
|
||||||
extern long int BufFileReadCount;
|
|
||||||
extern long int BufFileWriteCount;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internal routines: only called by bufmgr
|
* Internal routines: only called by bufmgr
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.121 2009/06/11 14:49:12 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.122 2009/12/15 04:57:48 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -173,8 +173,6 @@ extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
|
|||||||
extern void InitBufferPool(void);
|
extern void InitBufferPool(void);
|
||||||
extern void InitBufferPoolAccess(void);
|
extern void InitBufferPoolAccess(void);
|
||||||
extern void InitBufferPoolBackend(void);
|
extern void InitBufferPoolBackend(void);
|
||||||
extern char *ShowBufferUsage(void);
|
|
||||||
extern void ResetBufferUsage(void);
|
|
||||||
extern void AtEOXact_Buffers(bool isCommit);
|
extern void AtEOXact_Buffers(bool isCommit);
|
||||||
extern void PrintBufferLeakWarning(Buffer buffer);
|
extern void PrintBufferLeakWarning(Buffer buffer);
|
||||||
extern void CheckPointBuffers(int flags);
|
extern void CheckPointBuffers(int flags);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user