4 * server checks and output routines
6 * Copyright (c) 2010, PostgreSQL Global Development Group
7 * contrib/pg_upgrade/check.c
10 #include "pg_upgrade.h"
13 static void set_locale_and_encoding(Cluster whichCluster);
14 static void check_new_db_is_empty(void);
15 static void check_locale_and_encoding(ControlData *oldctrl,
16 ControlData *newctrl);
17 static void check_for_isn_and_int8_passing_mismatch(
18 Cluster whichCluster);
19 static void check_for_reg_data_type_usage(Cluster whichCluster);
23 output_check_banner(bool *live_check)
25 if (user_opts.check && is_server_running(old_cluster.pgdata))
28 if (old_cluster.port == new_cluster.port)
29 pg_log(PG_FATAL, "When checking a live server, "
30 "the old and new port numbers must be different.\n");
31 pg_log(PG_REPORT, "PerForming Consistency Checks on Old Live Server\n");
32 pg_log(PG_REPORT, "------------------------------------------------\n");
36 pg_log(PG_REPORT, "Performing Consistency Checks\n");
37 pg_log(PG_REPORT, "-----------------------------\n");
43 check_old_cluster(bool live_check,
44 char **sequence_script_file_name)
49 start_postmaster(CLUSTER_OLD, false);
51 set_locale_and_encoding(CLUSTER_OLD);
53 get_pg_database_relfilenode(CLUSTER_OLD);
55 /* Extract a list of databases and tables from the old cluster */
56 get_db_and_rel_infos(&old_cluster.dbarr, CLUSTER_OLD);
60 get_loadable_libraries();
64 * Check for various failure cases
67 check_for_reg_data_type_usage(CLUSTER_OLD);
68 check_for_isn_and_int8_passing_mismatch(CLUSTER_OLD);
70 /* old = PG 8.3 checks? */
71 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
73 old_8_3_check_for_name_data_type_usage(CLUSTER_OLD);
74 old_8_3_check_for_tsquery_usage(CLUSTER_OLD);
77 old_8_3_rebuild_tsvector_tables(true, CLUSTER_OLD);
78 old_8_3_invalidate_hash_gin_indexes(true, CLUSTER_OLD);
79 old_8_3_invalidate_bpchar_pattern_ops_indexes(true, CLUSTER_OLD);
84 * While we have the old server running, create the script to
85 * properly restore its sequence values but we report this at the
88 *sequence_script_file_name =
89 old_8_3_create_sequence_script(CLUSTER_OLD);
92 /* Pre-PG 9.0 had no large object permissions */
93 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
94 new_9_0_populate_pg_largeobject_metadata(true, CLUSTER_OLD);
97 * While not a check option, we do this now because this is the only time
98 * the old server is running.
100 if (!user_opts.check)
107 stop_postmaster(false, false);
112 check_new_cluster(void)
114 set_locale_and_encoding(CLUSTER_NEW);
116 check_new_db_is_empty();
118 check_loadable_libraries();
120 check_locale_and_encoding(&old_cluster.controldata, &new_cluster.controldata);
122 if (user_opts.transfer_mode == TRANSFER_MODE_LINK)
128 report_clusters_compatible(void)
132 pg_log(PG_REPORT, "\n*Clusters are compatible*\n");
133 /* stops new cluster */
134 stop_postmaster(false, false);
138 pg_log(PG_REPORT, "\n"
139 "| If pg_upgrade fails after this point, you must\n"
140 "| re-initdb the new cluster before continuing.\n"
141 "| You will also need to remove the \".old\" suffix\n"
142 "| from %s/global/pg_control.old.\n", old_cluster.pgdata);
147 issue_warnings(char *sequence_script_file_name)
149 /* old = PG 8.3 warnings? */
150 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
152 start_postmaster(CLUSTER_NEW, true);
154 /* restore proper sequence values using file created from old server */
155 if (sequence_script_file_name)
157 prep_status("Adjusting sequences");
159 SYSTEMQUOTE "\"%s/psql\" --set ON_ERROR_STOP=on "
160 "--no-psqlrc --port %d --username \"%s\" "
161 "-f \"%s\" --dbname template1 >> \"%s\"" SYSTEMQUOTE,
162 new_cluster.bindir, new_cluster.port, os_info.user,
163 sequence_script_file_name, log_opts.filename);
164 unlink(sequence_script_file_name);
168 old_8_3_rebuild_tsvector_tables(false, CLUSTER_NEW);
169 old_8_3_invalidate_hash_gin_indexes(false, CLUSTER_NEW);
170 old_8_3_invalidate_bpchar_pattern_ops_indexes(false, CLUSTER_NEW);
171 stop_postmaster(false, true);
174 /* Create dummy large object permissions for old < PG 9.0? */
175 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
177 start_postmaster(CLUSTER_NEW, true);
178 new_9_0_populate_pg_largeobject_metadata(false, CLUSTER_NEW);
179 stop_postmaster(false, true);
185 output_completion_banner(char *deletion_script_file_name)
187 /* Did we migrate the free space files? */
188 if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804)
190 "| Optimizer statistics is not transferred by pg_upgrade\n"
191 "| so consider running:\n"
192 "| \tvacuumdb --all --analyze-only\n"
193 "| on the newly-upgraded cluster.\n\n");
196 "| Optimizer statistics and free space information\n"
197 "| are not transferred by pg_upgrade so consider\n"
199 "| \tvacuumdb --all --analyze\n"
200 "| on the newly-upgraded cluster.\n\n");
203 "| Running this script will delete the old cluster's data files:\n"
205 deletion_script_file_name);
210 check_cluster_versions(void)
212 /* get old and new cluster versions */
213 old_cluster.major_version = get_major_server_version(&old_cluster.major_version_str, CLUSTER_OLD);
214 new_cluster.major_version = get_major_server_version(&new_cluster.major_version_str, CLUSTER_NEW);
216 /* We allow migration from/to the same major version for beta upgrades */
218 if (GET_MAJOR_VERSION(old_cluster.major_version) < 803)
219 pg_log(PG_FATAL, "This utility can only upgrade from PostgreSQL version 8.3 and later.\n");
221 /* Only current PG version is supported as a target */
222 if (GET_MAJOR_VERSION(new_cluster.major_version) != GET_MAJOR_VERSION(PG_VERSION_NUM))
223 pg_log(PG_FATAL, "This utility can only upgrade to PostgreSQL version %s.\n",
227 * We can't allow downgrading because we use the target pg_dumpall, and
228 * pg_dumpall cannot operate on new datbase versions, only older versions.
230 if (old_cluster.major_version > new_cluster.major_version)
231 pg_log(PG_FATAL, "This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
236 check_cluster_compatibility(bool live_check)
238 char libfile[MAXPGPATH];
242 * Test pg_upgrade_support.so is in the proper place. We cannot copy it
243 * ourselves because install directories are typically root-owned.
245 snprintf(libfile, sizeof(libfile), "%s/pg_upgrade_support%s", new_cluster.libpath,
248 if ((lib_test = fopen(libfile, "r")) == NULL)
250 "\npg_upgrade_support%s must be created and installed in %s\n", DLSUFFIX, libfile);
254 /* get/check pg_control data of servers */
255 get_control_data(&old_cluster, live_check);
256 get_control_data(&new_cluster, false);
257 check_control_data(&old_cluster.controldata, &new_cluster.controldata);
259 /* Is it 9.0 but without tablespace directories? */
260 if (GET_MAJOR_VERSION(new_cluster.major_version) == 900 &&
261 new_cluster.controldata.cat_ver < TABLE_SPACE_SUBDIRS)
262 pg_log(PG_FATAL, "This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n"
263 "because of backend API changes made during development.\n");
268 * set_locale_and_encoding()
270 * query the database to get the template0 locale
273 set_locale_and_encoding(Cluster whichCluster)
275 ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
276 ControlData *ctrl = &active_cluster->controldata;
280 int cluster_version = active_cluster->major_version;
282 conn = connectToServer("template1", whichCluster);
284 /* for pg < 80400, we got the values from pg_controldata */
285 if (cluster_version >= 80400)
290 res = executeQueryOrDie(conn,
291 "SELECT datcollate, datctype "
292 "FROM pg_catalog.pg_database "
293 "WHERE datname = 'template0' ");
294 assert(PQntuples(res) == 1);
296 i_datcollate = PQfnumber(res, "datcollate");
297 i_datctype = PQfnumber(res, "datctype");
299 ctrl->lc_collate = pg_strdup(PQgetvalue(res, 0, i_datcollate));
300 ctrl->lc_ctype = pg_strdup(PQgetvalue(res, 0, i_datctype));
305 res = executeQueryOrDie(conn,
306 "SELECT pg_catalog.pg_encoding_to_char(encoding) "
307 "FROM pg_catalog.pg_database "
308 "WHERE datname = 'template0' ");
309 assert(PQntuples(res) == 1);
311 i_encoding = PQfnumber(res, "pg_encoding_to_char");
312 ctrl->encoding = pg_strdup(PQgetvalue(res, 0, i_encoding));
321 * check_locale_and_encoding()
323 * locale is not in pg_controldata in 8.4 and later so
324 * we probably had to get via a database query.
327 check_locale_and_encoding(ControlData *oldctrl,
328 ControlData *newctrl)
330 if (strcmp(oldctrl->lc_collate, newctrl->lc_collate) != 0)
332 "old and new cluster lc_collate values do not match\n");
333 if (strcmp(oldctrl->lc_ctype, newctrl->lc_ctype) != 0)
335 "old and new cluster lc_ctype values do not match\n");
336 if (strcmp(oldctrl->encoding, newctrl->encoding) != 0)
338 "old and new cluster encoding values do not match\n");
343 check_new_db_is_empty(void)
348 get_db_and_rel_infos(&new_cluster.dbarr, CLUSTER_NEW);
350 for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
353 RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
355 for (relnum = 0; relnum < rel_arr->nrels;
358 /* pg_largeobject and its index should be skipped */
359 if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
367 dbarr_free(&new_cluster.dbarr);
370 pg_log(PG_FATAL, "New cluster is not empty; exiting\n");
375 * create_script_for_old_cluster_deletion()
377 * This is particularly useful for tablespace deletion.
380 create_script_for_old_cluster_deletion(
381 char **deletion_script_file_name)
386 *deletion_script_file_name = pg_malloc(MAXPGPATH);
388 prep_status("Creating script to delete old cluster");
390 snprintf(*deletion_script_file_name, MAXPGPATH, "%s/delete_old_cluster.%s",
391 os_info.cwd, SCRIPT_EXT);
393 if ((script = fopen(*deletion_script_file_name, "w")) == NULL)
394 pg_log(PG_FATAL, "Could not create necessary file: %s\n",
395 *deletion_script_file_name);
398 /* add shebang header */
399 fprintf(script, "#!/bin/sh\n\n");
402 /* delete old cluster's default tablespace */
403 fprintf(script, RMDIR_CMD " %s\n", old_cluster.pgdata);
405 /* delete old cluster's alternate tablespaces */
406 for (tblnum = 0; tblnum < os_info.num_tablespaces; tblnum++)
409 * Do the old cluster's per-database directories share a directory
410 * with a new version-specific tablespace?
412 if (strlen(old_cluster.tablespace_suffix) == 0)
414 /* delete per-database directories */
417 fprintf(script, "\n");
418 /* remove PG_VERSION? */
419 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
420 fprintf(script, RM_CMD " %s%s/PG_VERSION\n",
421 os_info.tablespaces[tblnum], old_cluster.tablespace_suffix);
423 for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
425 fprintf(script, RMDIR_CMD " %s%s/%d\n",
426 os_info.tablespaces[tblnum], old_cluster.tablespace_suffix,
427 old_cluster.dbarr.dbs[dbnum].db_oid);
433 * Simply delete the tablespace directory, which might be ".old"
434 * or a version-specific subdirectory.
436 fprintf(script, RMDIR_CMD " %s%s\n",
437 os_info.tablespaces[tblnum], old_cluster.tablespace_suffix);
443 if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
444 pg_log(PG_FATAL, "Could not add execute permission to file: %s\n",
445 *deletion_script_file_name);
453 * check_for_isn_and_int8_passing_mismatch()
455 * /contrib/isn relies on data type int8, and in 8.4 int8 can now be passed
456 * by value. The schema dumps the CREATE TYPE PASSEDBYVALUE setting so
457 * it must match for the old and new servers.
460 check_for_isn_and_int8_passing_mismatch(Cluster whichCluster)
462 ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
466 char output_path[MAXPGPATH];
468 prep_status("Checking for /contrib/isn with bigint-passing mismatch");
470 if (old_cluster.controldata.float8_pass_by_value ==
471 new_cluster.controldata.float8_pass_by_value)
478 snprintf(output_path, sizeof(output_path), "%s/contrib_isn_and_int8_pass_by_value.txt",
481 for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
484 bool db_used = false;
489 DbInfo *active_db = &active_cluster->dbarr.dbs[dbnum];
490 PGconn *conn = connectToServer(active_db->db_name, whichCluster);
492 /* Find any functions coming from contrib/isn */
493 res = executeQueryOrDie(conn,
494 "SELECT n.nspname, p.proname "
495 "FROM pg_catalog.pg_proc p, "
496 " pg_catalog.pg_namespace n "
497 "WHERE p.pronamespace = n.oid AND "
498 " p.probin = '$libdir/isn'");
500 ntups = PQntuples(res);
501 i_nspname = PQfnumber(res, "nspname");
502 i_proname = PQfnumber(res, "proname");
503 for (rowno = 0; rowno < ntups; rowno++)
506 if (script == NULL && (script = fopen(output_path, "w")) == NULL)
507 pg_log(PG_FATAL, "Could not create necessary file: %s\n", output_path);
510 fprintf(script, "Database: %s\n", active_db->db_name);
513 fprintf(script, " %s.%s\n",
514 PQgetvalue(res, rowno, i_nspname),
515 PQgetvalue(res, rowno, i_proname));
526 pg_log(PG_REPORT, "fatal\n");
528 "| Your installation contains \"/contrib/isn\" functions\n"
529 "| which rely on the bigint data type. Your old and\n"
530 "| new clusters pass bigint values differently so this\n"
531 "| cluster cannot currently be upgraded. You can\n"
532 "| manually migrate data that use \"/contrib/isn\"\n"
533 "| facilities and remove \"/contrib/isn\" from the\n"
534 "| old cluster and restart the migration. A list\n"
535 "| of the problem functions is in the file:\n"
536 "| \t%s\n\n", output_path);
544 * check_for_reg_data_type_usage()
545 * pg_upgrade only preserves these system values:
546 * pg_class.relfilenode
550 * Most of the reg* data types reference system catalog info that is
551 * not preserved, and hence these data types cannot be used in user
552 * tables upgraded by pg_upgrade.
555 check_for_reg_data_type_usage(Cluster whichCluster)
557 ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster);
561 char output_path[MAXPGPATH];
563 prep_status("Checking for reg* system oid user data types");
565 snprintf(output_path, sizeof(output_path), "%s/tables_using_reg.txt",
568 for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++)
571 bool db_used = false;
577 DbInfo *active_db = &active_cluster->dbarr.dbs[dbnum];
578 PGconn *conn = connectToServer(active_db->db_name, whichCluster);
580 res = executeQueryOrDie(conn,
581 "SELECT n.nspname, c.relname, a.attname "
582 "FROM pg_catalog.pg_class c, "
583 " pg_catalog.pg_namespace n, "
584 " pg_catalog.pg_attribute a "
585 "WHERE c.oid = a.attrelid AND "
586 " NOT a.attisdropped AND "
588 " 'pg_catalog.regproc'::pg_catalog.regtype, "
589 " 'pg_catalog.regprocedure'::pg_catalog.regtype, "
590 " 'pg_catalog.regoper'::pg_catalog.regtype, "
591 " 'pg_catalog.regoperator'::pg_catalog.regtype, "
592 " 'pg_catalog.regclass'::pg_catalog.regtype, "
593 /* regtype.oid is preserved, so 'regtype' is OK */
594 " 'pg_catalog.regconfig'::pg_catalog.regtype, "
595 " 'pg_catalog.regdictionary'::pg_catalog.regtype) AND "
596 " c.relnamespace = n.oid AND "
597 " n.nspname != 'pg_catalog' AND "
598 " n.nspname != 'information_schema'");
600 ntups = PQntuples(res);
601 i_nspname = PQfnumber(res, "nspname");
602 i_relname = PQfnumber(res, "relname");
603 i_attname = PQfnumber(res, "attname");
604 for (rowno = 0; rowno < ntups; rowno++)
607 if (script == NULL && (script = fopen(output_path, "w")) == NULL)
608 pg_log(PG_FATAL, "Could not create necessary file: %s\n", output_path);
611 fprintf(script, "Database: %s\n", active_db->db_name);
614 fprintf(script, " %s.%s.%s\n",
615 PQgetvalue(res, rowno, i_nspname),
616 PQgetvalue(res, rowno, i_relname),
617 PQgetvalue(res, rowno, i_attname));
628 pg_log(PG_REPORT, "fatal\n");
630 "| Your installation contains one of the reg* data types in\n"
631 "| user tables. These data types reference system oids that\n"
632 "| are not preserved by pg_upgrade, so this cluster cannot\n"
633 "| currently be upgraded. You can remove the problem tables\n"
634 "| and restart the migration. A list of the problem columns\n"
635 "| is in the file:\n"
636 "| \t%s\n\n", output_path);