Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+19
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

+32-7
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

+12
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

+2
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)