Re: crash-recovery replay of CREATE TABLESPACE is broken in HEAD - Mailing list pgsql-hackers

From Bruce Momjian
Subject Re: crash-recovery replay of CREATE TABLESPACE is broken in HEAD
Date
Msg-id 201007181554.o6IFspb29506@momjian.us
Whole thread Raw
In response to Re: crash-recovery replay of CREATE TABLESPACE is broken in HEAD  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: crash-recovery replay of CREATE TABLESPACE is broken in HEAD
List pgsql-hackers
Tom Lane wrote:
> Heikki Linnakangas <heikki.linnakangas@enterprisedb.com> writes:
> > Maybe you should check that it points to the right location? Or drop and
> > recreate the symlink, and ignore failure at mkdir.
>
> More specifically, ignore EEXIST failure when replaying mkdir.  Anything
> else is still a problem.

Thanks for the help.  I tried to find somewhere else in our recovery
code that was similar but didn't find anything.

The attached patch does as suggested.  I added the recovery code to the
create tablespace function so I didn't have to duplicate all the code
that computes the path names.

Attached.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + None of us is going to be here forever. +
Index: src/backend/commands/tablespace.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/tablespace.c,v
retrieving revision 1.77
diff -c -c -r1.77 tablespace.c
*** src/backend/commands/tablespace.c    18 Jul 2010 04:47:46 -0000    1.77
--- src/backend/commands/tablespace.c    18 Jul 2010 15:53:34 -0000
***************
*** 568,578 ****
       */
      if (mkdir(location_with_version_dir, S_IRWXU) < 0)
      {
          if (errno == EEXIST)
!             ereport(ERROR,
!                     (errcode(ERRCODE_OBJECT_IN_USE),
!                      errmsg("directory \"%s\" already in use as a tablespace",
!                             location_with_version_dir)));
          else
              ereport(ERROR,
                      (errcode_for_file_access(),
--- 568,582 ----
       */
      if (mkdir(location_with_version_dir, S_IRWXU) < 0)
      {
+         /* In recovery, directory might already exists, which is OK */
          if (errno == EEXIST)
!         {
!             if (!InRecovery)
!                 ereport(ERROR,
!                         (errcode(ERRCODE_OBJECT_IN_USE),
!                          errmsg("directory \"%s\" already in use as a tablespace",
!                                 location_with_version_dir)));
!         }
          else
              ereport(ERROR,
                      (errcode_for_file_access(),
***************
*** 580,585 ****
--- 584,599 ----
                              location_with_version_dir)));
      }

+     /* Remove old symlink in recovery, in case it points to the wrong place */
+     if (InRecovery)
+     {
+         if (unlink(linkloc) < 0 && errno != ENOENT)
+             ereport(ERROR,
+                     (errcode_for_file_access(),
+                      errmsg("could not remove symbolic link \"%s\": %m",
+                             linkloc)));
+     }
+
      /*
       * Create the symlink under PGDATA
       */

pgsql-hackers by date:

Previous
From: Bruce Momjian
Date:
Subject: Fix for libpq compile
Next
From: Simon Riggs
Date:
Subject: Re: ALTER TABLE SET STATISTICS requires AccessExclusiveLock