提交 ceda2890 编写于 作者: D Daniel Gustafsson

Add check to refuse upgrades of external partitions

Partitioned tables with external tables in the partition hierarchy
cannot be upgraded since external partition management is prohibited
in utility mode (the partitioning system catalogs are not replicated
to the segments). Add a check for external partitions and abort the
upgrade if found.
上级 8bb9076c
......@@ -52,3 +52,7 @@ synchronization.
- AO table segment files will be rewritten when a segment containing numeric
attributes are written to from database operations.
* External partitions are not supported since management of external partitions
is not allowed in utility mode. All external partitions must be either moved
out of the partition hierarchy with ALTER TABLE EXCHANGE, or dropped, prior
to the upgrade.
......@@ -18,6 +18,7 @@ static void check_proper_datallowconn(migratorContext *ctx, Cluster whichCluster
static void check_for_isn_and_int8_passing_mismatch(migratorContext *ctx,
Cluster whichCluster);
static void check_for_reg_data_type_usage(migratorContext *ctx, Cluster whichCluster);
static void check_external_partition(migratorContext *ctx);
/*
......@@ -98,6 +99,7 @@ check_old_cluster(migratorContext *ctx, bool live_check,
check_proper_datallowconn(ctx, CLUSTER_OLD);
check_for_reg_data_type_usage(ctx, CLUSTER_OLD);
check_for_isn_and_int8_passing_mismatch(ctx, CLUSTER_OLD);
check_external_partition(ctx);
/* old = PG 8.3 checks? */
/*
......@@ -769,3 +771,91 @@ check_for_reg_data_type_usage(migratorContext *ctx, Cluster whichCluster)
else
check_ok(ctx);
}
/*
* check_external_partition
*
* External tables cannot be included in the partitioning hierarchy during the
* initial definition with CREATE TABLE, they must be defined separately and
* injected via ALTER TABLE EXCHANGE. The partitioning system catalogs are
* however not replicated onto the segments which means ALTER TABLE EXCHANGE
* is prohibited in utility mode. This means that pg_upgrade cannot upgrade a
* cluster containing external partitions, they must be handled manually
* before/after the upgrade.
*
* Check for the existence of external partitions and refuse the upgrade if
* found.
*/
static void
check_external_partition(migratorContext *ctx)
{
ClusterInfo *old_cluster = &ctx->old;
char query[QUERY_ALLOC];
char output_path[MAXPGPATH];
FILE *script = NULL;
bool found = false;
int dbnum;
prep_status(ctx, "Checking for external tables used in partitioning");
snprintf(output_path, sizeof(output_path), "%s/external_partitions.txt",
ctx->cwd);
/*
* We need to query the inheritance catalog rather than the partitioning
* catalogs since they are not available on the segments.
*/
snprintf(query, sizeof(query),
"SELECT cc.relname, c.relname AS partname, c.relnamespace "
"FROM pg_inherits i "
" JOIN pg_class c ON (i.inhrelid = c.oid AND c.relstorage = '%c') "
" JOIN pg_class cc ON (i.inhparent = cc.oid);",
RELSTORAGE_EXTERNAL);
for (dbnum = 0; dbnum < old_cluster->dbarr.ndbs; dbnum++)
{
PGresult *res;
int ntups;
int rowno;
DbInfo *active_db = &old_cluster->dbarr.dbs[dbnum];
PGconn *conn;
conn = connectToServer(ctx, active_db->db_name, CLUSTER_OLD);
res = executeQueryOrDie(ctx, conn, query);
ntups = PQntuples(res);
if (ntups > 0)
{
found = true;
if (script == NULL && (script = fopen(output_path, "w")) == NULL)
pg_log(ctx, PG_FATAL, "Could not create necessary file: %s\n",
output_path);
for (rowno = 0; rowno < ntups; rowno++)
{
fprintf(script, "External partition \"%s\" in relation \"%s\"\n",
PQgetvalue(res, rowno, PQfnumber(res, "partname")),
PQgetvalue(res, rowno, PQfnumber(res, "relname")));
}
}
PQclear(res);
PQfinish(conn);
}
if (found)
{
fclose(script);
pg_log(ctx, PG_REPORT, "fatal\n");
pg_log(ctx, PG_FATAL,
"| Your installation contains partitioned tables with external\n"
"| tables as partitions. These partitions need to be removed\n"
"| from the partition hierarchy before the upgrade. A list of\n"
"| external partitions to remove is in the file:\n"
"| \t%s\n\n", output_path);
}
else
{
check_ok(ctx);
}
}
......@@ -38,6 +38,9 @@
#define DB_DUMP_FILE "pg_upgrade_dump_db.sql"
#define ARRAY_DUMP_FILE "pg_upgrade_dump_arraytypes.sql"
/* needs to be kept in sync with pg_class.h */
#define RELSTORAGE_EXTERNAL 'x'
#ifndef WIN32
#define pg_copy_file copy_file
#define pg_mv_file rename
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册