Skip to content

Commit 7170f21

Browse files
committed
Allow "in place" tablespaces.
Provide a developer-only GUC allow_in_place_tablespaces, disabled by default. When enabled, tablespaces can be created with an empty LOCATION string, meaning that they should be created as a directory directly beneath pg_tblspc. This can be used for new testing scenarios, in a follow-up patch. Not intended for end-user usage, since it might confuse backup tools that expect symlinks. Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/CA%2BhUKGKpRWQ9SxdxxDmTBCJoR0YnFpMBe7kyzY8SUQk%2BHeskxg%40mail.gmail.com
1 parent c4cc285 commit 7170f21

File tree

4 files changed

+65
-7
lines changed

4 files changed

+65
-7
lines changed

doc/src/sgml/config.sgml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10433,6 +10433,25 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
1043310433
</para>
1043410434

1043510435
<variablelist>
10436+
<varlistentry id="guc-allow-in-place-tablespaces" xreflabel="allow_in_place_tablespaces">
10437+
<term><varname>allow_in_place_tablespaces</varname> (<type>boolean</type>)
10438+
<indexterm>
10439+
<primary><varname>allow_in_place_tablespaces</varname> configuration parameter</primary>
10440+
</indexterm>
10441+
</term>
10442+
<listitem>
10443+
<para>
10444+
Allows tablespaces to be created as directories inside
10445+
<filename>pg_tblspc</filename>, when an empty location string
10446+
is provided to the <command>CREATE TABLESPACE</command> command. This
10447+
is intended to allow testing replication scenarios where primary and
10448+
standby servers are running on the same machine. Such directories
10449+
are likely to confuse backup tools that expect to find only symbolic
10450+
links in that location. Only superusers can change this setting.
10451+
</para>
10452+
</listitem>
10453+
</varlistentry>
10454+
1043610455
<varlistentry id="guc-allow-system-table-mods" xreflabel="allow_system_table_mods">
1043710456
<term><varname>allow_system_table_mods</varname> (<type>boolean</type>)
1043810457
<indexterm>

src/backend/commands/tablespace.c

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
/* GUC variables */
8888
char *default_tablespace = NULL;
8989
char *temp_tablespaces = NULL;
90+
bool allow_in_place_tablespaces = false;
9091

9192

9293
static void create_tablespace_directories(const char *location,
@@ -241,6 +242,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
241242
char *location;
242243
Oid ownerId;
243244
Datum newOptions;
245+
bool in_place;
244246

245247
/* Must be superuser */
246248
if (!superuser())
@@ -266,12 +268,15 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
266268
(errcode(ERRCODE_INVALID_NAME),
267269
errmsg("tablespace location cannot contain single quotes")));
268270

271+
in_place = allow_in_place_tablespaces && strlen(location) == 0;
272+
269273
/*
270274
* Allowing relative paths seems risky
271275
*
272-
* this also helps us ensure that location is not empty or whitespace
276+
* This also helps us ensure that location is not empty or whitespace,
277+
* unless specifying a developer-only in-place tablespace.
273278
*/
274-
if (!is_absolute_path(location))
279+
if (!in_place && !is_absolute_path(location))
275280
ereport(ERROR,
276281
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
277282
errmsg("tablespace location must be an absolute path")));
@@ -590,16 +595,36 @@ create_tablespace_directories(const char *location, const Oid tablespaceoid)
590595
char *linkloc;
591596
char *location_with_version_dir;
592597
struct stat st;
598+
bool in_place;
593599

594600
linkloc = psprintf("pg_tblspc/%u", tablespaceoid);
595-
location_with_version_dir = psprintf("%s/%s", location,
601+
602+
/*
603+
* If we're asked to make an 'in place' tablespace, create the directory
604+
* directly where the symlink would normally go. This is a developer-only
605+
* option for now, to facilitate regression testing.
606+
*/
607+
in_place = strlen(location) == 0;
608+
609+
if (in_place)
610+
{
611+
if (MakePGDirectory(linkloc) < 0 && errno != EEXIST)
612+
ereport(ERROR,
613+
(errcode_for_file_access(),
614+
errmsg("could not create directory \"%s\": %m",
615+
linkloc)));
616+
}
617+
618+
location_with_version_dir = psprintf("%s/%s", in_place ? linkloc : location,
596619
TABLESPACE_VERSION_DIRECTORY);
597620

598621
/*
599622
* Attempt to coerce target directory to safe permissions. If this fails,
600-
* it doesn't exist or has the wrong owner.
623+
* it doesn't exist or has the wrong owner. Not needed for in-place mode,
624+
* because in that case we created the directory with the desired
625+
* permissions.
601626
*/
602-
if (chmod(location, pg_dir_create_mode) != 0)
627+
if (!in_place && chmod(location, pg_dir_create_mode) != 0)
603628
{
604629
if (errno == ENOENT)
605630
ereport(ERROR,
@@ -648,13 +673,13 @@ create_tablespace_directories(const char *location, const Oid tablespaceoid)
648673
/*
649674
* In recovery, remove old symlink, in case it points to the wrong place.
650675
*/
651-
if (InRecovery)
676+
if (!in_place && InRecovery)
652677
remove_tablespace_symlink(linkloc);
653678

654679
/*
655680
* Create the symlink under PGDATA
656681
*/
657-
if (symlink(location, linkloc) < 0)
682+
if (!in_place && symlink(location, linkloc) < 0)
658683
ereport(ERROR,
659684
(errcode_for_file_access(),
660685
errmsg("could not create symbolic link \"%s\": %m",

src/backend/utils/misc/guc.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "catalog/storage.h"
4747
#include "commands/async.h"
4848
#include "commands/prepare.h"
49+
#include "commands/tablespace.h"
4950
#include "commands/trigger.h"
5051
#include "commands/user.h"
5152
#include "commands/vacuum.h"
@@ -1961,6 +1962,17 @@ static struct config_bool ConfigureNamesBool[] =
19611962
NULL, NULL, NULL
19621963
},
19631964

1965+
{
1966+
{"allow_in_place_tablespaces", PGC_SUSET, DEVELOPER_OPTIONS,
1967+
gettext_noop("Allows tablespaces directly inside pg_tblspc, for testing."),
1968+
NULL,
1969+
GUC_NOT_IN_SAMPLE
1970+
},
1971+
&allow_in_place_tablespaces,
1972+
false,
1973+
NULL, NULL, NULL
1974+
},
1975+
19641976
{
19651977
{"lo_compat_privileges", PGC_SUSET, COMPAT_OPTIONS_PREVIOUS,
19661978
gettext_noop("Enables backward compatibility mode for privilege checks on large objects."),

src/include/commands/tablespace.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "lib/stringinfo.h"
2020
#include "nodes/parsenodes.h"
2121

22+
extern bool allow_in_place_tablespaces;
23+
2224
/* XLOG stuff */
2325
#define XLOG_TBLSPC_CREATE 0x00
2426
#define XLOG_TBLSPC_DROP 0x10

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy