temporary statistics option at initdb time - Mailing list pgsql-hackers

From Euler Taveira de Oliveira
Subject temporary statistics option at initdb time
Date
Msg-id 489E44F0.8040908@timbira.com
Whole thread Raw
Responses Re: temporary statistics option at initdb time  (Robert Treat <xzilla@users.sourceforge.net>)
List pgsql-hackers
Hi,

After the Magnus patch [1], that make it possible store statistics files
at another (RAM-based) disk, I was thinking that would be useful to add
an option at initdb time to do the symlink as we already do with xlog.
Maybe it could be documented in monitoring.sgml too. Comments?

[1] http://archives.postgresql.org/pgsql-hackers/2008-08/msg00176.php


--
   Euler Taveira de Oliveira
   http://www.timbira.com/
Index: doc/src/sgml/ref/initdb.sgml
===================================================================
RCS file: /a/pgsql/dev/anoncvs/pgsql/doc/src/sgml/ref/initdb.sgml,v
retrieving revision 1.43
diff -c -r1.43 initdb.sgml
*** doc/src/sgml/ref/initdb.sgml    26 Mar 2007 17:23:36 -0000    1.43
--- doc/src/sgml/ref/initdb.sgml    10 Aug 2008 01:04:06 -0000
***************
*** 175,180 ****
--- 175,191 ----
         </para>
        </listitem>
       </varlistentry>
+
+        <varlistentry>
+         <term><option>-S <replaceable class="parameter">directory</replaceable></option></term>
+         <term><option>--statdir=<replaceable class="parameter">directory</replaceable></option></term>
+         <listitem>
+          <para>
+           This option specifies the directory where the temporary statistics
+           should be stored.
+          </para>
+         </listitem>
+        </varlistentry>

       <varlistentry>
        <term><option>-X <replaceable class="parameter">directory</replaceable></option></term>
Index: src/bin/initdb/initdb.c
===================================================================
RCS file: /a/pgsql/dev/anoncvs/pgsql/src/bin/initdb/initdb.c,v
retrieving revision 1.159
diff -c -r1.159 initdb.c
*** src/bin/initdb/initdb.c    5 Aug 2008 12:09:30 -0000    1.159
--- src/bin/initdb/initdb.c    8 Aug 2008 18:34:57 -0000
***************
*** 91,96 ****
--- 91,97 ----
  static bool noclean = false;
  static bool show_setting = false;
  static char *xlog_dir = "";
+ static char *tmp_stat_dir = "";


  /* internal vars */
***************
*** 111,116 ****
--- 112,119 ----
  static bool found_existing_pgdata = false;
  static bool made_new_xlogdir = false;
  static bool found_existing_xlogdir = false;
+ static bool made_new_tmpstatdir = false;
+ static bool found_existing_tmpstatdir = false;
  static char infoversion[100];
  static bool caught_signal = false;
  static bool output_failed = false;
***************
*** 628,633 ****
--- 631,654 ----
                  fprintf(stderr, _("%s: failed to remove contents of transaction log directory\n"),
                          progname);
          }
+
+         if (made_new_tmpstatdir)
+         {
+             fprintf(stderr, _("%s: removing temporary statistics directory \"%s\"\n"),
+                     progname, tmp_stat_dir);
+             if (!rmtree(tmp_stat_dir, true))
+                 fprintf(stderr, _("%s: failed to remove temporary statistics directory\n"),
+                         progname);
+         }
+         else if (found_existing_tmpstatdir)
+         {
+             fprintf(stderr,
+             _("%s: removing contents of temporary statistics directory \"%s\"\n"),
+                     progname, tmp_stat_dir);
+             if (!rmtree(tmp_stat_dir, false))
+                 fprintf(stderr, _("%s: failed to remove contents of temporary statistics directory\n"),
+                         progname);
+         }
          /* otherwise died during startup, do nothing! */
      }
      else
***************
*** 641,646 ****
--- 662,672 ----
              fprintf(stderr,
                      _("%s: transaction log directory \"%s\" not removed at user's request\n"),
                      progname, xlog_dir);
+
+         if (made_new_tmpstatdir || found_existing_tmpstatdir)
+             fprintf(stderr,
+                     _("%s: temporary statistics directory \"%s\" not removed at user's request\n"),
+                     progname, tmp_stat_dir);
      }

      exit(1);
***************
*** 2387,2392 ****
--- 2413,2419 ----
      printf(_("  --no-locale               equivalent to --locale=C\n"));
      printf(_("  -T, --text-search-config=CFG\n"
           "                            default text search configuration\n"));
+     printf(_("  -S, --statdir=STATDIR     location for the temporary statistics directory\n"));
      printf(_("  -X, --xlogdir=XLOGDIR     location for the transaction log directory\n"));
      printf(_("  -A, --auth=METHOD         default authentication method for local connections\n"));
      printf(_("  -U, --username=NAME       database superuser name\n"));
***************
*** 2433,2438 ****
--- 2460,2466 ----
          {"show", no_argument, NULL, 's'},
          {"noclean", no_argument, NULL, 'n'},
          {"xlogdir", required_argument, NULL, 'X'},
+         {"statdir", required_argument, NULL, 'S'},
          {NULL, 0, NULL, 0}
      };

***************
*** 2484,2490 ****

      /* process command-line options */

!     while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:sT:X:", long_options, &option_index)) != -1)
      {
          switch (c)
          {
--- 2512,2518 ----

      /* process command-line options */

!     while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:sS:T:X:", long_options, &option_index)) != -1)
      {
          switch (c)
          {
***************
*** 2544,2549 ****
--- 2572,2580 ----
              case 's':
                  show_setting = true;
                  break;
+             case 'S':
+                 tmp_stat_dir = xstrdup(optarg);
+                 break;
              case 'T':
                  default_text_search_config = xstrdup(optarg);
                  break;
***************
*** 3095,3100 ****
--- 3126,3217 ----
  #endif
      }

+     /* Create temporary statistics symlink, if required */
+     if (strcmp(tmp_stat_dir, "") != 0)
+     {
+         char       *linkloc;
+
+         /* clean up temporary statistics directory name, check it's absolute */
+         canonicalize_path(tmp_stat_dir);
+         if (!is_absolute_path(tmp_stat_dir))
+         {
+             fprintf(stderr, _("%s: temporary statistics directory location must be an absolute path\n"), progname);
+             exit_nicely();
+         }
+
+         /* check if the specified tmp_stat directory is empty */
+         switch (check_data_dir(tmp_stat_dir))
+         {
+             case 0:
+                 /* tmp_stat directory not there, must create it */
+                 printf(_("creating directory %s ... "),
+                        tmp_stat_dir);
+                 fflush(stdout);
+
+                 if (mkdir_p(tmp_stat_dir, 0700) != 0)
+                 {
+                     fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"),
+                             progname, tmp_stat_dir, strerror(errno));
+                     exit_nicely();
+                 }
+                 else
+                     check_ok();
+
+                 made_new_tmpstatdir = true;
+                 break;
+             case 1:
+                 /* Present but empty, fix permissions and use it */
+                 printf(_("fixing permissions on existing directory %s ... "),
+                        tmp_stat_dir);
+                 fflush(stdout);
+
+                 if (chmod(tmp_stat_dir, 0700) != 0)
+                 {
+                     fprintf(stderr, _("%s: could not change permissions of directory \"%s\": %s\n"),
+                             progname, tmp_stat_dir, strerror(errno));
+                     exit_nicely();
+                 }
+                 else
+                     check_ok();
+
+                 found_existing_tmpstatdir = true;
+                 break;
+             case 2:
+                 /* Present and not empty */
+                 fprintf(stderr,
+                         _("%s: directory \"%s\" exists but is not empty\n"),
+                         progname, tmp_stat_dir);
+                 fprintf(stderr,
+                         _("If you want to store the temporary statistics there, either\n"
+                           "remove or empty the directory \"%s\".\n"),
+                         tmp_stat_dir);
+                 exit_nicely();
+
+             default:
+                 /* Trouble accessing directory */
+                 fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
+                         progname, tmp_stat_dir, strerror(errno));
+                 exit_nicely();
+         }
+
+         /* form name of the place where the symlink must go */
+         linkloc = (char *) pg_malloc(strlen(pg_data) + 12 + 1);
+         sprintf(linkloc, "%s/pg_stat_tmp", pg_data);
+
+ #ifdef HAVE_SYMLINK
+         if (symlink(tmp_stat_dir, linkloc) != 0)
+         {
+             fprintf(stderr, _("%s: could not create symbolic link \"%s\": %s\n"),
+                     progname, linkloc, strerror(errno));
+             exit_nicely();
+         }
+ #else
+         fprintf(stderr, _("%s: symlinks are not supported on this platform"));
+         exit_nicely();
+ #endif
+     }
+
+
      /* Create required subdirectories */
      printf(_("creating subdirectories ... "));
      fflush(stdout);

pgsql-hackers by date:

Previous
From: Abhijit Menon-Sen
Date:
Subject: Re: which statements need bind/describe messages?
Next
From: Andrew Gierth
Date:
Subject: Re: Replay attack of query cancel