]> granicus.if.org Git - postgresql/commitdiff
Add a trace_sort option to help with measuring resource usage of external
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 3 Oct 2005 22:55:56 +0000 (22:55 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 3 Oct 2005 22:55:56 +0000 (22:55 +0000)
sort operations.  Per recent discussion.  Simon Riggs and Tom Lane.

doc/src/sgml/config.sgml
src/backend/utils/misc/guc.c
src/backend/utils/sort/tuplesort.c
src/include/pg_config_manual.h

index d239654b47b570394348afb448ebf93ce157f183..710605ca7002263a5f6ae52a0b1fe2d3326e5e46 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.23 2005/09/24 23:25:31 neilc Exp $
+$PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.24 2005/10/03 22:55:50 tgl Exp $
 -->
 <chapter Id="runtime-config">
   <title>Run-time Configuration</title>
@@ -4071,6 +4071,21 @@ plruby.use_strict = true        # generates error: unknown class name
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-trace-sort" xreflabel="trace_sort">
+      <term><varname>trace_sort</varname> (<type>boolean</type>)</term>
+      <indexterm>
+       <primary><varname>trace_sort</> configuration parameter</primary>
+      </indexterm>
+      <listitem>
+       <para>
+        If on, emit information about resource usage during sort operations.
+        This option is only available if the <symbol>TRACE_SORT</symbol> macro
+        was defined when <productname>PostgreSQL</productname> was compiled.
+        (However, <symbol>TRACE_SORT</symbol> is currently defined by default.)
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><varname>trace_locks</varname> (<type>boolean</type>)</term>
       <term><varname>trace_lwlocks</varname> (<type>boolean</type>)</term>
index 1315afff0c2b006336ef25865c753e1b5a919f03..d9932e05177c9585e94a4e795ae30904dfcaacb2 100644 (file)
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.289 2005/09/24 22:54:39 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.290 2005/10/03 22:55:51 tgl Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -92,6 +92,9 @@ extern int    CommitDelay;
 extern int     CommitSiblings;
 extern char *default_tablespace;
 extern bool    fullPageWrites;
+#ifdef TRACE_SORT
+extern bool    trace_sort;
+#endif
 
 static const char *assign_log_destination(const char *value,
                                           bool doit, GucSource source);
@@ -891,6 +894,18 @@ static struct config_bool ConfigureNamesBool[] =
                false, NULL, NULL
        },
 
+#ifdef TRACE_SORT
+       {
+               {"trace_sort", PGC_USERSET, DEVELOPER_OPTIONS,
+                       gettext_noop("Emit information about resource usage in sorting."),
+                       NULL,
+                       GUC_NOT_IN_SAMPLE
+               },
+               &trace_sort,
+               false, NULL, NULL
+       },
+#endif
+
 #ifdef WAL_DEBUG
        {
                {"wal_debug", PGC_SUSET, DEVELOPER_OPTIONS,
index 3ec1cf127f3cf3cc3a53da90a4c994b7dd3c6f19..53f2b546f462480cb59a5c4f80dde584976a53f9 100644 (file)
@@ -78,7 +78,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.50 2005/09/23 15:36:57 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.51 2005/10/03 22:55:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "utils/logtape.h"
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
+#include "utils/pg_rusage.h"
 #include "utils/syscache.h"
 #include "utils/tuplesort.h"
 
 
+/* GUC variable */
+#ifdef TRACE_SORT
+bool                   trace_sort = false;
+#endif
+
+
 /*
  * Possible states of a Tuplesort object.  These denote the states that
  * persist between calls of Tuplesort routines.
@@ -283,6 +290,13 @@ struct Tuplesortstate
        /* we need typelen and byval in order to know how to copy the Datums. */
        int                     datumTypeLen;
        bool            datumTypeByVal;
+
+       /*
+        * Resource snapshot for time of sort start.
+        */
+#ifdef TRACE_SORT
+       PGRUsage        ru_start;
+#endif
 };
 
 #define COMPARETUP(state,a,b)  ((*(state)->comparetup) (state, a, b))
@@ -422,6 +436,11 @@ tuplesort_begin_common(int workMem, bool randomAccess)
 
        state = (Tuplesortstate *) palloc0(sizeof(Tuplesortstate));
 
+#ifdef TRACE_SORT
+       if (trace_sort)
+               pg_rusage_init(&state->ru_start);
+#endif
+
        state->status = TSS_INITIAL;
        state->randomAccess = randomAccess;
        state->availMem = workMem * 1024L;
@@ -456,6 +475,13 @@ tuplesort_begin_heap(TupleDesc tupDesc,
 
        AssertArg(nkeys > 0);
 
+#ifdef TRACE_SORT
+       if (trace_sort)
+               elog(NOTICE,
+                        "begin tuple sort: nkeys = %d, workMem = %d, randomAccess = %c",
+                        nkeys, workMem, randomAccess ? 't' : 'f');
+#endif
+
        state->comparetup = comparetup_heap;
        state->copytup = copytup_heap;
        state->writetup = writetup_heap;
@@ -499,6 +525,14 @@ tuplesort_begin_index(Relation indexRel,
 {
        Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
 
+#ifdef TRACE_SORT
+       if (trace_sort)
+               elog(NOTICE,
+                        "begin index sort: unique = %c, workMem = %d, randomAccess = %c",
+                        enforceUnique ? 't' : 'f',
+                        workMem, randomAccess ? 't' : 'f');
+#endif
+
        state->comparetup = comparetup_index;
        state->copytup = copytup_index;
        state->writetup = writetup_index;
@@ -522,6 +556,13 @@ tuplesort_begin_datum(Oid datumType,
        int16           typlen;
        bool            typbyval;
 
+#ifdef TRACE_SORT
+       if (trace_sort)
+               elog(NOTICE,
+                        "begin datum sort: workMem = %d, randomAccess = %c",
+                        workMem, randomAccess ? 't' : 'f');
+#endif
+
        state->comparetup = comparetup_datum;
        state->copytup = copytup_datum;
        state->writetup = writetup_datum;
@@ -573,6 +614,12 @@ tuplesort_end(Tuplesortstate *state)
        if (state->sortFnKinds)
                pfree(state->sortFnKinds);
 
+#ifdef TRACE_SORT
+       if (trace_sort)
+               elog(NOTICE, "sort ended: %s",
+                        pg_rusage_show(&state->ru_start));
+#endif
+
        pfree(state);
 }
 
@@ -712,6 +759,12 @@ puttuple_common(Tuplesortstate *state, void *tuple)
 void
 tuplesort_performsort(Tuplesortstate *state)
 {
+#ifdef TRACE_SORT
+       if (trace_sort)
+               elog(NOTICE, "performsort starting: %s",
+                        pg_rusage_show(&state->ru_start));
+#endif
+
        switch (state->status)
        {
                case TSS_INITIAL:
@@ -751,6 +804,13 @@ tuplesort_performsort(Tuplesortstate *state)
                        elog(ERROR, "invalid tuplesort state");
                        break;
        }
+
+#ifdef TRACE_SORT
+       if (trace_sort)
+               elog(NOTICE, "performsort done%s: %s",
+                        (state->status == TSS_FINALMERGE) ? " (except final merge)" : "",
+                        pg_rusage_show(&state->ru_start));
+#endif
 }
 
 /*
@@ -986,6 +1046,12 @@ inittapes(Tuplesortstate *state)
        int                     ntuples,
                                j;
 
+#ifdef TRACE_SORT
+       if (trace_sort)
+               elog(NOTICE, "switching to external sort: %s",
+                        pg_rusage_show(&state->ru_start));
+#endif
+
        state->tapeset = LogicalTapeSetCreate(MAXTAPES);
 
        /*
@@ -1243,6 +1309,12 @@ mergeonerun(Tuplesortstate *state)
         */
        markrunend(state, destTape);
        state->tp_runs[TAPERANGE]++;
+
+#ifdef TRACE_SORT
+       if (trace_sort)
+               elog(NOTICE, "finished merge step: %s",
+                        pg_rusage_show(&state->ru_start));
+#endif
 }
 
 /*
@@ -1456,6 +1528,14 @@ dumptuples(Tuplesortstate *state, bool alltuples)
                        state->tp_runs[state->destTape]++;
                        state->tp_dummy[state->destTape]--; /* per Alg D step D2 */
 
+#ifdef TRACE_SORT
+                       if (trace_sort)
+                               elog(NOTICE, "finished writing%s run %d: %s",
+                                        (state->memtupcount == 0) ? " final" : "",
+                                        state->currentRun,
+                                        pg_rusage_show(&state->ru_start));
+#endif
+
                        /*
                         * Done if heap is empty, else prepare for new run.
                         */
index b36714b87bd2e03b5e3011e6b492aff36f977b35..bf82771d45c90380ba308dc4d7a634aaf124fd4a 100644 (file)
@@ -6,7 +6,7 @@
  * for developers.     If you edit any of these, be sure to do a *full*
  * rebuild (and an initdb if noted).
  *
- * $PostgreSQL: pgsql/src/include/pg_config_manual.h,v 1.16 2005/03/29 03:01:32 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/pg_config_manual.h,v 1.17 2005/10/03 22:55:56 tgl Exp $
  *------------------------------------------------------------------------
  */
 
  */
 /* #define WAL_DEBUG */
 
+/*
+ * Enable tracing of resource consumption during sort operations;
+ * see also the trace_sort GUC var.  For 8.1 this is enabled by default.
+ */
+#define TRACE_SORT 1
+
 /*
  * Other debug #defines (documentation, anyone?)
  */
-/* #define IPORTAL_DEBUG  */
-/* #define HEAPDEBUGALL  */
+/* #define HEAPDEBUGALL */
 /* #define ACLDEBUG */
 /* #define RTDEBUG */
-/* #define GISTDEBUG */