Re: [HACKERS] Duplicate usage of tablespace location? - Mailing list pgsql-hackers

From Kyotaro HORIGUCHI
Subject Re: [HACKERS] Duplicate usage of tablespace location?
Date
Msg-id 20170511.130920.76697388.horiguchi.kyotaro@lab.ntt.co.jp
Whole thread Raw
In response to Re: [HACKERS] Duplicate usage of tablespace location?  (Neha Khatri <nehakhatri5@gmail.com>)
Responses Re: [HACKERS] Duplicate usage of tablespace location?
List pgsql-hackers
Hello,

At Fri, 5 May 2017 21:42:47 +1000, Neha Khatri <nehakhatri5@gmail.com> wrote in
<CAFO0U+8fHoVDCJDLQP+g9nKFhOyiDYnFvNMSNbjTJQFY+SjS+A@mail.gmail.com>
> As Kyotaro san pointed out, the commit 22817041 started allowing creation
> of multiple "tablespace version directories" in same location. However the
> original purpose of that commit was to allow that just for the upgrade
> purpose. So couple of points:
> - The commit violated the requirement of emptiness of the tablespace
> location directory.
>     (Though it is still prevented to create multiple tablespaces belonging
> to one server, in same location.)
> - The comment did not document this change in specification.
> 
> Probably it was not anticipated at that time that a user could create the
> tablespaces for different server version at the same location.
> 
> Now that this behaviour is present in field for a while, there is
> likelihood of having systems with tablespaces for two different versions,
> in same location. To avoid the problem reported in [1] for such systems,
> here are couple of alternative approaches:
> 
> 1. Allow creation of multiple tablespaces in single location for different
> server versions, but not the same version(exception).
> a) Also allow this capability in utilities like pg_basebackup( and others
> that update tablespaces) .
> b) Update the documentation about this specification change.
> 
> I don't see this breaking any backwards compatibility.

Yeah, it is just clarification of the behavior in the
documentation. The current behavior is somewhat inconsistent but
practical.

> 2. Retain the current base rule of creating Tablespaces i.e. "The location
> must be an existing, empty directory". This means:
> a) For the future release, have a strict directory emptiness check while
> creating new tablespace.
> b) Only during upgrade, allow creation of multiple tablepaces in same
> location .
> c) Document the fact that only during upgrade the system would create
> multiple tablespaces in same location.

Honestly saying, I think it adds nothing good other than seeming
consistency. (Even though I sent such a patch:p)

> d) Provide a flexibility to change the location of an existing tablespace,
> something like:
> ALTER TABLESPACE tblspcname SET LOCATION '/path/to/newlocation'
> [where newlocation is an existing empty direcotry]
> 
> With the altered location of a tablespace it should be possible to perform
> the pg_basebackup successfully.

If we can accept multiple server versions share a tablespace
directory, pg_basebackup also can allow that situation. The
attached patch does that. Similary to the server code, it
correctly fails if the same version subdirectory exists.

$ pg_basebackup -D $PGDATA -h /tmp -p 5432 -X stream -T /home/horiguti/data/tsp1=/home/horiguti/data/tsp2
pg_basebackup: could not create directory "/home/horiguti/data/tsp2/PG_10_201705091": File exists
pg_basebackup: removing contents of data directory "/home/horiguti/data/data_work_s"

> I noticed some solutions for moving PostgreSQL tablesspaces, on internet.
> But some are slow, others cause incompatibility for tools like pgAdmin. I
> am not able to find any discussion about moving tablespace location in
> mailing lists too. So I am not sure if there is already any conclusion
> about supporting or not supporting ALTER TABLESPACE LOCATION.
> To me, the first approach above looks like providing more independence to
> the user about choice of tablespace location. Also, it is not clear that
> why the directory emptiness rule was introduced in first place. Any insight
> on that will be useful.

Originally (before 9.0) files in a tablespace is directly placed
in the "location" and it is reasonable at that time.

> Regards,
> Neha
> 
> [1]https://www.postgresql.org/message-id/2008148.rxBNyNRHPZ@peanuts2
> 
> Cheers,
> Neha
> 
> On Fri, Apr 7, 2017 at 11:02 AM, Kyotaro HORIGUCHI <
> horiguchi.kyotaro@lab.ntt.co.jp> wrote:
> 
> > I don't mean that this is the only or best way to go.
> >
> > I apologize for the possible lack of explanation.
> >
> > At Thu, 06 Apr 2017 12:03:51 -0400, Tom Lane <tgl@sss.pgh.pa.us> wrote in
> > <21084.1491494631@sss.pgh.pa.us>
> > > Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp> writes:
> > > > I noticed by the following report, PostgreSQL can share the same
> > > > directory as tablespaces of two servers with different
> > > > pg-versions.
> > >
> > > > https://www.postgresql.org/message-id/2008148.rxBNyNRHPZ@peanuts2
> > >
> > > > 8.4 checked that the tablespace location is empty, but from 9.0,
> > > > the check is replaced with creating a PG_PGVER_CATVER
> > > > subdirectory. This works for multiple servers with the same
> > > > version, but don't for servers with different versions.
> > >
> > > Please explain why you think it doesn't work.  This patch seems to
> > > be reverting an intentional behavioral change, and you haven't
> >
> > I understand that the change is for in-place upgrade, not for
> > sharing a tablespace diretory between two version of PostgreSQL
> > servers. It actually rejects the second server with the same
> > version to come. If this is correct, it doesn't seem right to
> > accept the second server of the different version.
> >
> > If we allow sharing of the directory, theoretically we can allow
> > the same between the same version of servers by adding system
> > identifier in the subdirectory name.
> >
> >
> > > really explained why we'd want to.  It certainly doesn't look like
> > > it addresses the referenced complaint about pg_basebackup behavior.
> >
> > My point is that "the direcotry for newly created tablespace is
> > really reuiqred to be literary empty or not?"
> >
> > Practically it doesn't need to be empty and succesful creation of
> > PG_VER_CATVER directory is enough as the current implement
> > does. If we take this way the documentation and pg_basebackup
> > should be changed and the problem will be resolved as the result.
> >
> > https://www.postgresql.org/docs/9.6/static/manage-ag-tablespaces.html
> >
> > - The location must be an existing, empty directory that is owned
> > - by the PostgreSQL operating system user. All objects subsequently
> > - created within the tablespace will be stored in files underneath
> > - this directory.
> > + CREATE TABLESPACE creates a subdirectory named after server
> > + version in the location. The location must not contain a file
> > + or directory of that name for the subdirectory. All objects
> > + subsequently created within the tablespace will be stored in
> > + files underneath the subdirectory.
> >
> > Then, modify pg_basebackup to follow the description above.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index e2a2ebb..969b600 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -130,7 +130,7 @@ static PQExpBuffer recoveryconfcontents = NULL;/* Function headers */static void usage(void);static
voiddisconnect_and_exit(int code);
 
-static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found);
+static void verify_and_create_dir(char *dirname, bool *created, bool *found, bool allow_nonempty);static void
progress_report(inttablespacenum, const char *filename, bool force);static void ReceiveTarFile(PGconn *conn, PGresult
*res,int rownum);
 
@@ -145,6 +145,8 @@ static bool reached_end_position(XLogRecPtr segendpos, uint32 timeline,static const char
*get_tablespace_mapping(constchar *dir);static void tablespace_list_append(const char *arg);
 
+#define verify_dir_is_empty_or_create(dirname, created, found) \
+    verify_and_create_dir(dirname, created, found, false)static voidcleanup_directories_atexit(void)
@@ -646,7 +648,8 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier) * be give and the process
ended.*/static void
 
-verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
+verify_and_create_dir(char *dirname, bool *created, bool *found,
+                     bool allow_nonempty){    switch (pg_check_dir(dirname))    {
@@ -680,6 +683,9 @@ verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)            /*
*Exists, not empty             */
 
+            if (allow_nonempty)
+                return;
+            fprintf(stderr,                    _("%s: directory \"%s\" exists but is not empty\n"),
progname,dirname);
 
@@ -1854,7 +1860,7 @@ BaseBackup(void)        {            char       *path = (char *)
get_tablespace_mapping(PQgetvalue(res,i, 1));
 
-            verify_dir_is_empty_or_create(path, &made_tablespace_dirs, &found_tablespace_dirs);
+            verify_and_create_dir(path, &made_tablespace_dirs, &found_tablespace_dirs, true);        }    }

pgsql-hackers by date:

Previous
From: Michael Paquier
Date:
Subject: Re: [HACKERS] SCRAM in the PG 10 release notes
Next
From: Michael Paquier
Date:
Subject: Re: [HACKERS] [Proposal] Allow users to specify multiple tables inVACUUM commands