Commit 16d8e594 authored by Magnus Hagander's avatar Magnus Hagander

Remove spclocation field from pg_tablespace

Instead, add a function pg_tablespace_location(oid) used to return
the same information, and do this by reading the symbolic link.

Doing it this way makes it possible to relocate a tablespace when the
database is down by simply changing the symbolic link.
parent c6e3ac11
...@@ -193,15 +193,21 @@ get_db_infos(ClusterInfo *cluster) ...@@ -193,15 +193,21 @@ get_db_infos(ClusterInfo *cluster)
int i_datname, int i_datname,
i_oid, i_oid,
i_spclocation; i_spclocation;
char query[QUERY_ALLOC];
res = executeQueryOrDie(conn, snprintf(query, sizeof(query),
"SELECT d.oid, d.datname, t.spclocation " "SELECT d.oid, d.datname, %s "
"FROM pg_catalog.pg_database d " "FROM pg_catalog.pg_database d "
" LEFT OUTER JOIN pg_catalog.pg_tablespace t " " LEFT OUTER JOIN pg_catalog.pg_tablespace t "
" ON d.dattablespace = t.oid " " ON d.dattablespace = t.oid "
"WHERE d.datallowconn = true " "WHERE d.datallowconn = true "
/* we don't preserve pg_database.oid so we sort by name */ /* we don't preserve pg_database.oid so we sort by name */
"ORDER BY 2"); "ORDER BY 2",
/* 9.2 removed the spclocation column */
(GET_MAJOR_VERSION(old_cluster.major_version) <= 901) ?
"t.spclocation" : "pg_catalog.pg_tablespace_location(t.oid) AS spclocation");
res = executeQueryOrDie(conn, "%s", query);
i_oid = PQfnumber(res, "oid"); i_oid = PQfnumber(res, "oid");
i_datname = PQfnumber(res, "datname"); i_datname = PQfnumber(res, "datname");
...@@ -265,7 +271,7 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo) ...@@ -265,7 +271,7 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
snprintf(query, sizeof(query), snprintf(query, sizeof(query),
"SELECT c.oid, n.nspname, c.relname, " "SELECT c.oid, n.nspname, c.relname, "
" c.relfilenode, t.spclocation " " c.relfilenode, %s "
"FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n " "FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n "
" ON c.relnamespace = n.oid " " ON c.relnamespace = n.oid "
" LEFT OUTER JOIN pg_catalog.pg_tablespace t " " LEFT OUTER JOIN pg_catalog.pg_tablespace t "
...@@ -280,6 +286,9 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo) ...@@ -280,6 +286,9 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
" relname IN ('pg_largeobject', 'pg_largeobject_loid_pn_index'%s) )) " " relname IN ('pg_largeobject', 'pg_largeobject_loid_pn_index'%s) )) "
/* we preserve pg_class.oid so we sort by it to match old/new */ /* we preserve pg_class.oid so we sort by it to match old/new */
"ORDER BY 1;", "ORDER BY 1;",
/* 9.2 removed the spclocation column */
(GET_MAJOR_VERSION(old_cluster.major_version) <= 901) ?
"t.spclocation" : "pg_catalog.pg_tablespace_location(t.oid) AS spclocation",
/* see the comment at the top of old_8_3_create_sequence_script() */ /* see the comment at the top of old_8_3_create_sequence_script() */
(GET_MAJOR_VERSION(old_cluster.major_version) <= 803) ? (GET_MAJOR_VERSION(old_cluster.major_version) <= 803) ?
"" : ", 'S'", "" : ", 'S'",
......
...@@ -44,12 +44,18 @@ get_tablespace_paths(void) ...@@ -44,12 +44,18 @@ get_tablespace_paths(void)
PGresult *res; PGresult *res;
int tblnum; int tblnum;
int i_spclocation; int i_spclocation;
char query[QUERY_ALLOC];
res = executeQueryOrDie(conn, snprintf(query, sizeof(query),
"SELECT spclocation " "SELECT %s "
"FROM pg_catalog.pg_tablespace " "FROM pg_catalog.pg_tablespace "
"WHERE spcname != 'pg_default' AND " "WHERE spcname != 'pg_default' AND "
" spcname != 'pg_global'"); " spcname != 'pg_global'",
/* 9.2 removed the spclocation column */
(GET_MAJOR_VERSION(old_cluster.major_version) <= 901) ?
"t.spclocation" : "pg_catalog.pg_tablespace_location(oid) AS spclocation");
res = executeQueryOrDie(conn, "%s", query);
if ((os_info.num_tablespaces = PQntuples(res)) != 0) if ((os_info.num_tablespaces = PQntuples(res)) != 0)
os_info.tablespaces = (char **) pg_malloc( os_info.tablespaces = (char **) pg_malloc(
......
...@@ -5391,13 +5391,6 @@ ...@@ -5391,13 +5391,6 @@
<entry>Owner of the tablespace, usually the user who created it</entry> <entry>Owner of the tablespace, usually the user who created it</entry>
</row> </row>
<row>
<entry><structfield>spclocation</structfield></entry>
<entry><type>text</type></entry>
<entry></entry>
<entry>Location (directory path) of the tablespace</entry>
</row>
<row> <row>
<entry><structfield>spcacl</structfield></entry> <entry><structfield>spcacl</structfield></entry>
<entry><type>aclitem[]</type></entry> <entry><type>aclitem[]</type></entry>
......
...@@ -13611,6 +13611,10 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); ...@@ -13611,6 +13611,10 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
<primary>pg_tablespace_databases</primary> <primary>pg_tablespace_databases</primary>
</indexterm> </indexterm>
<indexterm>
<primary>pg_tablespace_location</primary>
</indexterm>
<indexterm> <indexterm>
<primary>pg_typeof</primary> <primary>pg_typeof</primary>
</indexterm> </indexterm>
...@@ -13758,6 +13762,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); ...@@ -13758,6 +13762,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
<entry><type>setof oid</type></entry> <entry><type>setof oid</type></entry>
<entry>get the set of database OIDs that have objects in the tablespace</entry> <entry>get the set of database OIDs that have objects in the tablespace</entry>
</row> </row>
<row>
<entry><literal><function>pg_tablespace_location(<parameter>tablespace_oid</parameter>)</function></literal></entry>
<entry><type>text</type></entry>
<entry>get the path in the filesystem that this tablespace is located in</entry>
</row>
<row> <row>
<entry><literal><function>pg_typeof(<parameter>any</parameter>)</function></literal></entry> <entry><literal><function>pg_typeof(<parameter>any</parameter>)</function></literal></entry>
<entry><type>regtype</type></entry> <entry><type>regtype</type></entry>
......
...@@ -154,7 +154,7 @@ SELECT attrelid::regclass, array_accum(attname) ...@@ -154,7 +154,7 @@ SELECT attrelid::regclass, array_accum(attname)
attrelid | array_accum attrelid | array_accum
---------------+--------------------------------------- ---------------+---------------------------------------
pg_tablespace | {spcname,spcowner,spclocation,spcacl} pg_tablespace | {spcname,spcowner,spcacl,spcoptions}
(1 row) (1 row)
SELECT attrelid::regclass, array_accum(atttypid::regtype) SELECT attrelid::regclass, array_accum(atttypid::regtype)
...@@ -164,7 +164,7 @@ SELECT attrelid::regclass, array_accum(atttypid::regtype) ...@@ -164,7 +164,7 @@ SELECT attrelid::regclass, array_accum(atttypid::regtype)
attrelid | array_accum attrelid | array_accum
---------------+--------------------------- ---------------+---------------------------
pg_tablespace | {name,oid,text,aclitem[]} pg_tablespace | {name,oid,aclitem[],text[]}
(1 row) (1 row)
</programlisting> </programlisting>
</para> </para>
......
...@@ -314,8 +314,6 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) ...@@ -314,8 +314,6 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
DirectFunctionCall1(namein, CStringGetDatum(stmt->tablespacename)); DirectFunctionCall1(namein, CStringGetDatum(stmt->tablespacename));
values[Anum_pg_tablespace_spcowner - 1] = values[Anum_pg_tablespace_spcowner - 1] =
ObjectIdGetDatum(ownerId); ObjectIdGetDatum(ownerId);
values[Anum_pg_tablespace_spclocation - 1] =
CStringGetTextDatum(location);
nulls[Anum_pg_tablespace_spcacl - 1] = true; nulls[Anum_pg_tablespace_spcacl - 1] = true;
nulls[Anum_pg_tablespace_spcoptions - 1] = true; nulls[Anum_pg_tablespace_spcoptions - 1] = true;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <signal.h> #include <signal.h>
#include <dirent.h> #include <dirent.h>
#include <math.h> #include <math.h>
#include <unistd.h>
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/pg_tablespace.h" #include "catalog/pg_tablespace.h"
...@@ -261,6 +262,44 @@ pg_tablespace_databases(PG_FUNCTION_ARGS) ...@@ -261,6 +262,44 @@ pg_tablespace_databases(PG_FUNCTION_ARGS)
} }
/*
* pg_tablespace_location - get location for a tablespace
*/
Datum
pg_tablespace_location(PG_FUNCTION_ARGS)
{
Oid tablespaceOid = PG_GETARG_OID(0);
char sourcepath[MAXPGPATH];
char targetpath[MAXPGPATH];
int rllen;
/*
* Return empty string for our two default tablespace
*/
if (tablespaceOid == DEFAULTTABLESPACE_OID ||
tablespaceOid == GLOBALTABLESPACE_OID)
PG_RETURN_TEXT_P(cstring_to_text(""));
#if defined(HAVE_READLINK) || defined(WIN32)
/*
* Find the location of the tablespace by reading the symbolic link that is
* in pg_tblspc/<oid>.
*/
snprintf(sourcepath, sizeof(sourcepath), "pg_tblspc/%u", tablespaceOid);
rllen =readlink(sourcepath, targetpath, sizeof(targetpath));
if (rllen < 0 || rllen >= sizeof(targetpath))
ereport(ERROR,
(errmsg("could not read symbolic link \"%s\": %m", sourcepath)));
targetpath[rllen] = '\0';
PG_RETURN_TEXT_P(cstring_to_text(targetpath));
#else
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("tablespaces are not supported on this platform")));
#endif
}
/* /*
* pg_sleep - delay for N seconds * pg_sleep - delay for N seconds
*/ */
......
...@@ -997,7 +997,16 @@ dumpTablespaces(PGconn *conn) ...@@ -997,7 +997,16 @@ dumpTablespaces(PGconn *conn)
* Get all tablespaces except built-in ones (which we assume are named * Get all tablespaces except built-in ones (which we assume are named
* pg_xxx) * pg_xxx)
*/ */
if (server_version >= 90000) if (server_version >= 90200)
res = executeQuery(conn, "SELECT oid, spcname, "
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
"pg_catalog.pg_tablespace_location(oid), spcacl, "
"array_to_string(spcoptions, ', '),"
"pg_catalog.shobj_description(oid, 'pg_tablespace') "
"FROM pg_catalog.pg_tablespace "
"WHERE spcname !~ '^pg_' "
"ORDER BY 1");
else if (server_version >= 90000)
res = executeQuery(conn, "SELECT oid, spcname, " res = executeQuery(conn, "SELECT oid, spcname, "
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
"spclocation, spcacl, " "spclocation, spcacl, "
......
...@@ -139,6 +139,15 @@ describeTablespaces(const char *pattern, bool verbose) ...@@ -139,6 +139,15 @@ describeTablespaces(const char *pattern, bool verbose)
initPQExpBuffer(&buf); initPQExpBuffer(&buf);
if (pset.sversion >= 90200)
printfPQExpBuffer(&buf,
"SELECT spcname AS \"%s\",\n"
" pg_catalog.pg_get_userbyid(spcowner) AS \"%s\",\n"
" pg_catalog.pg_tablespace_location(oid) AS \"%s\"",
gettext_noop("Name"),
gettext_noop("Owner"),
gettext_noop("Location"));
else
printfPQExpBuffer(&buf, printfPQExpBuffer(&buf,
"SELECT spcname AS \"%s\",\n" "SELECT spcname AS \"%s\",\n"
" pg_catalog.pg_get_userbyid(spcowner) AS \"%s\",\n" " pg_catalog.pg_get_userbyid(spcowner) AS \"%s\",\n"
......
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 201112061 #define CATALOG_VERSION_NO 201112071
#endif #endif
...@@ -2686,6 +2686,9 @@ DESCR("statistics: reset collected statistics for a single table or index in the ...@@ -2686,6 +2686,9 @@ DESCR("statistics: reset collected statistics for a single table or index in the
DATA(insert OID = 3777 ( pg_stat_reset_single_function_counters PGNSP PGUID 12 1 0 0 0 f f f f f v 1 0 2278 "26" _null_ _null_ _null_ _null_ pg_stat_reset_single_function_counters _null_ _null_ _null_ )); DATA(insert OID = 3777 ( pg_stat_reset_single_function_counters PGNSP PGUID 12 1 0 0 0 f f f f f v 1 0 2278 "26" _null_ _null_ _null_ _null_ pg_stat_reset_single_function_counters _null_ _null_ _null_ ));
DESCR("statistics: reset collected statistics for a single function in the current database"); DESCR("statistics: reset collected statistics for a single function in the current database");
DATA(insert OID = 3778 ( pg_tablespace_location PGNSP PGUID 12 1 0 0 0 f f f t f s 1 0 25 "26" _null_ _null_ _null_ _null_ pg_tablespace_location _null_ _null_ _null_ ));
DESCR("tablespace location");
DATA(insert OID = 1946 ( encode PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 25 "17 25" _null_ _null_ _null_ _null_ binary_encode _null_ _null_ _null_ )); DATA(insert OID = 1946 ( encode PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 25 "17 25" _null_ _null_ _null_ _null_ binary_encode _null_ _null_ _null_ ));
DESCR("convert bytea value into some ascii-only text string"); DESCR("convert bytea value into some ascii-only text string");
DATA(insert OID = 1947 ( decode PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 17 "25 25" _null_ _null_ _null_ _null_ binary_decode _null_ _null_ _null_ )); DATA(insert OID = 1947 ( decode PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 17 "25 25" _null_ _null_ _null_ _null_ binary_decode _null_ _null_ _null_ ));
......
...@@ -32,7 +32,6 @@ CATALOG(pg_tablespace,1213) BKI_SHARED_RELATION ...@@ -32,7 +32,6 @@ CATALOG(pg_tablespace,1213) BKI_SHARED_RELATION
{ {
NameData spcname; /* tablespace name */ NameData spcname; /* tablespace name */
Oid spcowner; /* owner of tablespace */ Oid spcowner; /* owner of tablespace */
text spclocation; /* physical location (VAR LENGTH) */
aclitem spcacl[1]; /* access permissions (VAR LENGTH) */ aclitem spcacl[1]; /* access permissions (VAR LENGTH) */
text spcoptions[1]; /* per-tablespace options */ text spcoptions[1]; /* per-tablespace options */
} FormData_pg_tablespace; } FormData_pg_tablespace;
...@@ -49,15 +48,14 @@ typedef FormData_pg_tablespace *Form_pg_tablespace; ...@@ -49,15 +48,14 @@ typedef FormData_pg_tablespace *Form_pg_tablespace;
* ---------------- * ----------------
*/ */
#define Natts_pg_tablespace 5 #define Natts_pg_tablespace 4
#define Anum_pg_tablespace_spcname 1 #define Anum_pg_tablespace_spcname 1
#define Anum_pg_tablespace_spcowner 2 #define Anum_pg_tablespace_spcowner 2
#define Anum_pg_tablespace_spclocation 3 #define Anum_pg_tablespace_spcacl 3
#define Anum_pg_tablespace_spcacl 4 #define Anum_pg_tablespace_spcoptions 4
#define Anum_pg_tablespace_spcoptions 5
DATA(insert OID = 1663 ( pg_default PGUID "" _null_ _null_ )); DATA(insert OID = 1663 ( pg_default PGUID _null_ _null_ ));
DATA(insert OID = 1664 ( pg_global PGUID "" _null_ _null_ )); DATA(insert OID = 1664 ( pg_global PGUID _null_ _null_ ));
#define DEFAULTTABLESPACE_OID 1663 #define DEFAULTTABLESPACE_OID 1663
#define GLOBALTABLESPACE_OID 1664 #define GLOBALTABLESPACE_OID 1664
......
...@@ -469,6 +469,7 @@ extern Datum pg_cancel_backend(PG_FUNCTION_ARGS); ...@@ -469,6 +469,7 @@ extern Datum pg_cancel_backend(PG_FUNCTION_ARGS);
extern Datum pg_terminate_backend(PG_FUNCTION_ARGS); extern Datum pg_terminate_backend(PG_FUNCTION_ARGS);
extern Datum pg_reload_conf(PG_FUNCTION_ARGS); extern Datum pg_reload_conf(PG_FUNCTION_ARGS);
extern Datum pg_tablespace_databases(PG_FUNCTION_ARGS); extern Datum pg_tablespace_databases(PG_FUNCTION_ARGS);
extern Datum pg_tablespace_location(PG_FUNCTION_ARGS);
extern Datum pg_rotate_logfile(PG_FUNCTION_ARGS); extern Datum pg_rotate_logfile(PG_FUNCTION_ARGS);
extern Datum pg_sleep(PG_FUNCTION_ARGS); extern Datum pg_sleep(PG_FUNCTION_ARGS);
extern Datum pg_get_keywords(PG_FUNCTION_ARGS); extern Datum pg_get_keywords(PG_FUNCTION_ARGS);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment