Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit692bcad

Browse files
committed
Allow CLUSTER and VACUUM FULL to change tablespace
1 parent7acd35b commit692bcad

File tree

13 files changed

+231
-16
lines changed

13 files changed

+231
-16
lines changed

‎doc/src/sgml/ref/cluster.sgml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ PostgreSQL documentation
2121

2222
<refsynopsisdiv>
2323
<synopsis>
24-
CLUSTER [VERBOSE] <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">index_name</replaceable> ]
24+
CLUSTER [VERBOSE] <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">index_name</replaceable> ] [ TABLESPACE <replaceable class="parameter">new_tablespace</replaceable> ]
2525
CLUSTER [VERBOSE]
2626
</synopsis>
2727
</refsynopsisdiv>
@@ -99,6 +99,15 @@ CLUSTER [VERBOSE]
9999
</listitem>
100100
</varlistentry>
101101

102+
<varlistentry>
103+
<term><replaceable class="parameter">new_tablespace</replaceable></term>
104+
<listitem>
105+
<para>
106+
The name of a specific tablespace to store clustered relations.
107+
</para>
108+
</listitem>
109+
</varlistentry>
110+
102111
<varlistentry>
103112
<term><literal>VERBOSE</literal></term>
104113
<listitem>

‎doc/src/sgml/ref/vacuum.sgml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ PostgreSQL documentation
2323
<synopsis>
2424
VACUUM [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] [ <replaceable class="parameter">table_and_columns</replaceable> [, ...] ]
2525
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ <replaceable class="parameter">table_and_columns</replaceable> [, ...] ]
26+
VACUUM ( FULL [, ...] ) [ TABLESPACE <replaceable class="parameter">new_tablespace</replaceable> ] [ <replaceable class="parameter">table_and_columns</replaceable> [, ...] ]
2627

2728
<phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
2829

@@ -299,6 +300,16 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ <replaceable class="paramet
299300
</para>
300301
</listitem>
301302
</varlistentry>
303+
304+
<varlistentry>
305+
<term><replaceable class="parameter">new_tablespace</replaceable></term>
306+
<listitem>
307+
<para>
308+
The name of a specific tablespace to write a new copy of the table.
309+
</para>
310+
</listitem>
311+
</varlistentry>
312+
302313
</variablelist>
303314
</refsect1>
304315

‎src/backend/commands/cluster.c

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@
3333
#include"catalog/namespace.h"
3434
#include"catalog/objectaccess.h"
3535
#include"catalog/pg_am.h"
36+
#include"catalog/pg_tablespace.h"
3637
#include"catalog/toasting.h"
3738
#include"commands/cluster.h"
3839
#include"commands/progress.h"
3940
#include"commands/tablecmds.h"
41+
#include"commands/tablespace.h"
4042
#include"commands/vacuum.h"
4143
#include"miscadmin.h"
4244
#include"optimizer/optimizer.h"
@@ -67,7 +69,7 @@ typedef struct
6769
}RelToCluster;
6870

6971

70-
staticvoidrebuild_relation(RelationOldHeap,OidindexOid,boolverbose);
72+
staticvoidrebuild_relation(RelationOldHeap,OidindexOid,OidNewTableSpaceOid,boolverbose);
7173
staticvoidcopy_table_data(OidOIDNewHeap,OidOIDOldHeap,OidOIDOldIndex,
7274
boolverbose,bool*pSwapToastByContent,
7375
TransactionId*pFreezeXid,MultiXactId*pCutoffMulti);
@@ -101,6 +103,22 @@ static List *get_tables_to_cluster(MemoryContext cluster_context);
101103
void
102104
cluster(ClusterStmt*stmt,boolisTopLevel)
103105
{
106+
/* Oid of tablespace to use for clustered relation. */
107+
OidtablespaceOid=InvalidOid;
108+
109+
/* Select tablespace Oid to use. */
110+
if (stmt->tablespacename)
111+
{
112+
tablespaceOid=get_tablespace_oid(stmt->tablespacename, false);
113+
114+
/* Can't move a non-shared relation into pg_global */
115+
if (tablespaceOid==GLOBALTABLESPACE_OID)
116+
ereport(ERROR,
117+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
118+
errmsg("cannot move non-shared relation to tablespace \"%s\"",
119+
stmt->tablespacename)));
120+
}
121+
104122
if (stmt->relation!=NULL)
105123
{
106124
/* This is the single-relation case. */
@@ -182,7 +200,7 @@ cluster(ClusterStmt *stmt, bool isTopLevel)
182200
table_close(rel,NoLock);
183201

184202
/* Do the job. */
185-
cluster_rel(tableOid,indexOid,stmt->options);
203+
cluster_rel(tableOid,indexOid,tablespaceOid,stmt->options);
186204
}
187205
else
188206
{
@@ -230,7 +248,7 @@ cluster(ClusterStmt *stmt, bool isTopLevel)
230248
/* functions in indexes may want a snapshot set */
231249
PushActiveSnapshot(GetTransactionSnapshot());
232250
/* Do the job. */
233-
cluster_rel(rvtc->tableOid,rvtc->indexOid,
251+
cluster_rel(rvtc->tableOid,rvtc->indexOid,tablespaceOid,
234252
stmt->options |CLUOPT_RECHECK);
235253
PopActiveSnapshot();
236254
CommitTransactionCommand();
@@ -262,7 +280,7 @@ cluster(ClusterStmt *stmt, bool isTopLevel)
262280
* and error messages should refer to the operation as VACUUM not CLUSTER.
263281
*/
264282
void
265-
cluster_rel(OidtableOid,OidindexOid,intoptions)
283+
cluster_rel(OidtableOid,OidindexOid,OidtablespaceOid,intoptions)
266284
{
267285
RelationOldHeap;
268286
boolverbose= ((options&CLUOPT_VERBOSE)!=0);
@@ -375,6 +393,23 @@ cluster_rel(Oid tableOid, Oid indexOid, int options)
375393
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
376394
errmsg("cannot cluster a shared catalog")));
377395

396+
if (OidIsValid(tablespaceOid)&&
397+
!allowSystemTableMods&&IsSystemRelation(OldHeap))
398+
ereport(ERROR,
399+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
400+
errmsg("permission denied: \"%s\" is a system catalog",
401+
RelationGetRelationName(OldHeap))));
402+
403+
/*
404+
* We cannot support moving mapped relations into different tablespaces.
405+
* (In particular this eliminates all shared catalogs.)
406+
*/
407+
if (OidIsValid(tablespaceOid)&&RelationIsMapped(OldHeap))
408+
ereport(ERROR,
409+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
410+
errmsg("cannot change tablespace of mapped relation \"%s\"",
411+
RelationGetRelationName(OldHeap))));
412+
378413
/*
379414
* Don't process temp tables of other backends ... their local buffer
380415
* manager is not going to cope.
@@ -425,7 +460,7 @@ cluster_rel(Oid tableOid, Oid indexOid, int options)
425460
TransferPredicateLocksToHeapRelation(OldHeap);
426461

427462
/* rebuild_relation does all the dirty work */
428-
rebuild_relation(OldHeap,indexOid,verbose);
463+
rebuild_relation(OldHeap,indexOid,tablespaceOid,verbose);
429464

430465
/* NB: rebuild_relation does table_close() on OldHeap */
431466

@@ -584,7 +619,7 @@ mark_index_clustered(Relation rel, Oid indexOid, bool is_internal)
584619
* NB: this routine closes OldHeap at the right time; caller should not.
585620
*/
586621
staticvoid
587-
rebuild_relation(RelationOldHeap,OidindexOid,boolverbose)
622+
rebuild_relation(RelationOldHeap,OidindexOid,OidNewTablespaceOid,boolverbose)
588623
{
589624
OidtableOid=RelationGetRelid(OldHeap);
590625
OidtableSpace=OldHeap->rd_rel->reltablespace;
@@ -595,6 +630,10 @@ rebuild_relation(Relation OldHeap, Oid indexOid, bool verbose)
595630
TransactionIdfrozenXid;
596631
MultiXactIdcutoffMulti;
597632

633+
/* Use new tablespace if passed. */
634+
if (OidIsValid(NewTablespaceOid))
635+
tableSpace=NewTablespaceOid;
636+
598637
/* Mark the correct index as clustered */
599638
if (OidIsValid(indexOid))
600639
mark_index_clustered(OldHeap,indexOid, true);
@@ -1039,6 +1078,13 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
10391078
*/
10401079
Assert(!target_is_pg_class);
10411080

1081+
if (!allowSystemTableMods&&IsSystemClass(r1,relform1)&&
1082+
relform1->reltablespace!=relform2->reltablespace)
1083+
ereport(ERROR,
1084+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1085+
errmsg("permission denied: \"%s\" is a system catalog",
1086+
get_rel_name(r1))));
1087+
10421088
swaptemp=relform1->relfilenode;
10431089
relform1->relfilenode=relform2->relfilenode;
10441090
relform2->relfilenode=swaptemp;

‎src/backend/commands/vacuum.c

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,16 @@
3131
#include"access/tableam.h"
3232
#include"access/transam.h"
3333
#include"access/xact.h"
34+
#include"catalog/catalog.h"
3435
#include"catalog/namespace.h"
3536
#include"catalog/pg_database.h"
3637
#include"catalog/pg_inherits.h"
3738
#include"catalog/pg_namespace.h"
39+
#include"catalog/pg_tablespace.h"
3840
#include"commands/cluster.h"
3941
#include"commands/defrem.h"
4042
#include"commands/vacuum.h"
43+
#include"commands/tablespace.h"
4144
#include"miscadmin.h"
4245
#include"nodes/makefuncs.h"
4346
#include"pgstat.h"
@@ -106,6 +109,8 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
106109
booldisable_page_skipping= false;
107110
boolparallel_option= false;
108111
ListCell*lc;
112+
OidtablespaceOid=InvalidOid;/* Oid of tablespace to use for relations
113+
* after VACUUM FULL. */
109114

110115
/* Set default value */
111116
params.index_cleanup=VACOPT_TERNARY_DEFAULT;
@@ -241,6 +246,28 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
241246
params.multixact_freeze_table_age=-1;
242247
}
243248

249+
/* Get tablespace Oid to use. */
250+
if (vacstmt->tablespacename)
251+
{
252+
if (params.options&VACOPT_FULL)
253+
{
254+
tablespaceOid=get_tablespace_oid(vacstmt->tablespacename, false);
255+
256+
/* Can't move a non-shared relation into pg_global */
257+
if (tablespaceOid==GLOBALTABLESPACE_OID)
258+
ereport(ERROR,
259+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
260+
errmsg("cannot move non-shared relation to tablespace \"%s\"",
261+
vacstmt->tablespacename)));
262+
}
263+
else
264+
ereport(ERROR,
265+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
266+
errmsg("incompatible TABLESPACE option"),
267+
errdetail("You can only use TABLESPACE with VACUUM FULL.")));
268+
}
269+
params.tablespace_oid=tablespaceOid;
270+
244271
/* user-invoked vacuum is never "for wraparound" */
245272
params.is_wraparound= false;
246273

@@ -1672,8 +1699,9 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
16721699
LOCKMODElmode;
16731700
Relationonerel;
16741701
LockRelIdonerelid;
1675-
Oidtoast_relid;
1676-
Oidsave_userid;
1702+
Oidtoast_relid,
1703+
save_userid,
1704+
tablespaceOid=InvalidOid;
16771705
intsave_sec_context;
16781706
intsave_nestlevel;
16791707

@@ -1807,6 +1835,23 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
18071835
return true;
18081836
}
18091837

1838+
/*
1839+
* We cannot support moving system relations into different tablespaces,
1840+
* unless allow_system_table_mods=1.
1841+
*/
1842+
if (params->options&VACOPT_FULL&&
1843+
OidIsValid(params->tablespace_oid)&&
1844+
IsSystemRelation(onerel)&& !allowSystemTableMods)
1845+
{
1846+
ereport(WARNING,
1847+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1848+
errmsg("skipping tablespace change of \"%s\"",
1849+
RelationGetRelationName(onerel)),
1850+
errdetail("Cannot move system relation, only VACUUM is performed.")));
1851+
}
1852+
else
1853+
tablespaceOid=params->tablespace_oid;
1854+
18101855
/*
18111856
* Get a session-level lock too. This will protect our access to the
18121857
* relation across multiple transactions, so that we can vacuum the
@@ -1876,7 +1921,7 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
18761921
cluster_options |=CLUOPT_VERBOSE;
18771922

18781923
/* VACUUM FULL is now a variant of CLUSTER; see cluster.c */
1879-
cluster_rel(relid,InvalidOid,cluster_options);
1924+
cluster_rel(relid,InvalidOid,tablespaceOid,cluster_options);
18801925
}
18811926
else
18821927
table_relation_vacuum(onerel,params,vac_strategy);

‎src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3316,6 +3316,7 @@ _copyClusterStmt(const ClusterStmt *from)
33163316
COPY_NODE_FIELD(relation);
33173317
COPY_STRING_FIELD(indexname);
33183318
COPY_SCALAR_FIELD(options);
3319+
COPY_STRING_FIELD(tablespacename);
33193320

33203321
returnnewnode;
33213322
}
@@ -3901,6 +3902,7 @@ _copyVacuumStmt(const VacuumStmt *from)
39013902
COPY_NODE_FIELD(options);
39023903
COPY_NODE_FIELD(rels);
39033904
COPY_SCALAR_FIELD(is_vacuumcmd);
3905+
COPY_STRING_FIELD(tablespacename);
39043906

39053907
returnnewnode;
39063908
}

‎src/backend/nodes/equalfuncs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,6 +1215,7 @@ _equalClusterStmt(const ClusterStmt *a, const ClusterStmt *b)
12151215
COMPARE_NODE_FIELD(relation);
12161216
COMPARE_STRING_FIELD(indexname);
12171217
COMPARE_SCALAR_FIELD(options);
1218+
COMPARE_SCALAR_FIELD(tablespacename);
12181219

12191220
return true;
12201221
}
@@ -1702,6 +1703,7 @@ _equalVacuumStmt(const VacuumStmt *a, const VacuumStmt *b)
17021703
COMPARE_NODE_FIELD(options);
17031704
COMPARE_NODE_FIELD(rels);
17041705
COMPARE_SCALAR_FIELD(is_vacuumcmd);
1706+
COMPARE_SCALAR_FIELD(tablespacename);
17051707

17061708
return true;
17071709
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp