4 * server checks and output routines
6 * Copyright (c) 2010-2012, PostgreSQL Global Development Group
7 * contrib/pg_upgrade/check.c
12 #include "pg_upgrade.h"
15 static void set_locale_and_encoding(ClusterInfo *cluster);
16 static void check_new_cluster_is_empty(void);
17 static void check_locale_and_encoding(ControlData *oldctrl,
18 ControlData *newctrl);
19 static void check_is_super_user(ClusterInfo *cluster);
20 static void check_for_prepared_transactions(ClusterInfo *cluster);
21 static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
22 static void check_for_reg_data_type_usage(ClusterInfo *cluster);
23 static void check_for_support_lib(ClusterInfo *cluster);
24 static void get_bin_version(ClusterInfo *cluster);
28 output_check_banner(bool *live_check)
30 if (user_opts.check && is_server_running(old_cluster.pgdata))
33 if (old_cluster.port == DEF_PGUPORT)
34 pg_log(PG_FATAL, "When checking a live old server, "
35 "you must specify the old server's port number.\n");
36 if (old_cluster.port == new_cluster.port)
37 pg_log(PG_FATAL, "When checking a live server, "
38 "the old and new port numbers must be different.\n");
39 pg_log(PG_REPORT, "Performing Consistency Checks on Old Live Server\n");
40 pg_log(PG_REPORT, "------------------------------------------------\n");
44 pg_log(PG_REPORT, "Performing Consistency Checks\n");
45 pg_log(PG_REPORT, "-----------------------------\n");
51 check_old_cluster(bool live_check, char **sequence_script_file_name)
56 start_postmaster(&old_cluster);
58 set_locale_and_encoding(&old_cluster);
60 get_pg_database_relfilenode(&old_cluster);
62 /* Extract a list of databases and tables from the old cluster */
63 get_db_and_rel_infos(&old_cluster);
67 get_loadable_libraries();
71 * Check for various failure cases
73 check_is_super_user(&old_cluster);
74 check_for_prepared_transactions(&old_cluster);
75 check_for_reg_data_type_usage(&old_cluster);
76 check_for_isn_and_int8_passing_mismatch(&old_cluster);
78 /* old = PG 8.3 checks? */
79 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
81 old_8_3_check_for_name_data_type_usage(&old_cluster);
82 old_8_3_check_for_tsquery_usage(&old_cluster);
83 old_8_3_check_ltree_usage(&old_cluster);
86 old_8_3_rebuild_tsvector_tables(&old_cluster, true);
87 old_8_3_invalidate_hash_gin_indexes(&old_cluster, true);
88 old_8_3_invalidate_bpchar_pattern_ops_indexes(&old_cluster, true);
93 * While we have the old server running, create the script to
94 * properly restore its sequence values but we report this at the
97 *sequence_script_file_name =
98 old_8_3_create_sequence_script(&old_cluster);
101 /* Pre-PG 9.0 had no large object permissions */
102 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
103 new_9_0_populate_pg_largeobject_metadata(&old_cluster, true);
106 * While not a check option, we do this now because this is the only time
107 * the old server is running.
109 if (!user_opts.check)
116 stop_postmaster(false);
121 check_new_cluster(void)
123 set_locale_and_encoding(&new_cluster);
125 get_db_and_rel_infos(&new_cluster);
127 check_new_cluster_is_empty();
128 check_for_prepared_transactions(&new_cluster);
130 check_loadable_libraries();
132 check_locale_and_encoding(&old_cluster.controldata, &new_cluster.controldata);
134 if (user_opts.transfer_mode == TRANSFER_MODE_LINK)
140 report_clusters_compatible(void)
144 pg_log(PG_REPORT, "\n*Clusters are compatible*\n");
145 /* stops new cluster */
146 stop_postmaster(false);
150 pg_log(PG_REPORT, "\n"
151 "If pg_upgrade fails after this point, you must re-initdb the\n"
152 "new cluster before continuing.\n");
157 issue_warnings(char *sequence_script_file_name)
159 /* old = PG 8.3 warnings? */
160 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
162 start_postmaster(&new_cluster);
164 /* restore proper sequence values using file created from old server */
165 if (sequence_script_file_name)
167 prep_status("Adjusting sequences");
169 SYSTEMQUOTE "\"%s/psql\" --set ON_ERROR_STOP=on "
170 "--no-psqlrc --port %d --username \"%s\" "
171 "-f \"%s\" --dbname template1 >> \"%s\"" SYSTEMQUOTE,
172 new_cluster.bindir, new_cluster.port, os_info.user,
173 sequence_script_file_name, log_opts.filename2);
174 unlink(sequence_script_file_name);
178 old_8_3_rebuild_tsvector_tables(&new_cluster, false);
179 old_8_3_invalidate_hash_gin_indexes(&new_cluster, false);
180 old_8_3_invalidate_bpchar_pattern_ops_indexes(&new_cluster, false);
181 stop_postmaster(false);
184 /* Create dummy large object permissions for old < PG 9.0? */
185 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
187 start_postmaster(&new_cluster);
188 new_9_0_populate_pg_largeobject_metadata(&new_cluster, false);
189 stop_postmaster(false);
195 output_completion_banner(char *deletion_script_file_name)
197 /* Did we copy the free space files? */
198 if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804)
200 "Optimizer statistics are not transferred by pg_upgrade so\n"
201 "consider running:\n"
202 " vacuumdb --all --analyze-only\n"
203 "on the newly-upgraded cluster.\n\n");
206 "Optimizer statistics and free space information are not transferred\n"
207 "by pg_upgrade so consider running:\n"
208 " vacuumdb --all --analyze\n"
209 "on the newly-upgraded cluster.\n\n");
212 "Running this script will delete the old cluster's data files:\n"
214 deletion_script_file_name);
219 check_cluster_versions(void)
221 prep_status("Checking cluster versions");
223 /* get old and new cluster versions */
224 old_cluster.major_version = get_major_server_version(&old_cluster);
225 new_cluster.major_version = get_major_server_version(&new_cluster);
228 * We allow upgrades from/to the same major version for alpha/beta
232 if (GET_MAJOR_VERSION(old_cluster.major_version) < 803)
233 pg_log(PG_FATAL, "This utility can only upgrade from PostgreSQL version 8.3 and later.\n");
235 /* Only current PG version is supported as a target */
236 if (GET_MAJOR_VERSION(new_cluster.major_version) != GET_MAJOR_VERSION(PG_VERSION_NUM))
237 pg_log(PG_FATAL, "This utility can only upgrade to PostgreSQL version %s.\n",
241 * We can't allow downgrading because we use the target pg_dumpall, and
242 * pg_dumpall cannot operate on new database versions, only older versions.
244 if (old_cluster.major_version > new_cluster.major_version)
245 pg_log(PG_FATAL, "This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
247 /* get old and new binary versions */
248 get_bin_version(&old_cluster);
249 get_bin_version(&new_cluster);
251 /* Ensure binaries match the designated data directories */
252 if (GET_MAJOR_VERSION(old_cluster.major_version) !=
253 GET_MAJOR_VERSION(old_cluster.bin_version))
255 "Old cluster data and binary directories are from different major versions.\n");
256 if (GET_MAJOR_VERSION(new_cluster.major_version) !=
257 GET_MAJOR_VERSION(new_cluster.bin_version))
259 "New cluster data and binary directories are from different major versions.\n");
266 check_cluster_compatibility(bool live_check)
268 check_for_support_lib(&new_cluster);
270 /* get/check pg_control data of servers */
271 get_control_data(&old_cluster, live_check);
272 get_control_data(&new_cluster, false);
273 check_control_data(&old_cluster.controldata, &new_cluster.controldata);
275 /* Is it 9.0 but without tablespace directories? */
276 if (GET_MAJOR_VERSION(new_cluster.major_version) == 900 &&
277 new_cluster.controldata.cat_ver < TABLE_SPACE_SUBDIRS_CAT_VER)
278 pg_log(PG_FATAL, "This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n"
279 "because of backend API changes made during development.\n");
284 * set_locale_and_encoding()
286 * query the database to get the template0 locale
289 set_locale_and_encoding(ClusterInfo *cluster)
291 ControlData *ctrl = &cluster->controldata;
295 int cluster_version = cluster->major_version;
297 conn = connectToServer(cluster, "template1");
299 /* for pg < 80400, we got the values from pg_controldata */
300 if (cluster_version >= 80400)
305 res = executeQueryOrDie(conn,
306 "SELECT datcollate, datctype "
307 "FROM pg_catalog.pg_database "
308 "WHERE datname = 'template0' ");
309 assert(PQntuples(res) == 1);
311 i_datcollate = PQfnumber(res, "datcollate");
312 i_datctype = PQfnumber(res, "datctype");
314 ctrl->lc_collate = pg_strdup(PQgetvalue(res, 0, i_datcollate));
315 ctrl->lc_ctype = pg_strdup(PQgetvalue(res, 0, i_datctype));
320 res = executeQueryOrDie(conn,
321 "SELECT pg_catalog.pg_encoding_to_char(encoding) "
322 "FROM pg_catalog.pg_database "
323 "WHERE datname = 'template0' ");
324 assert(PQntuples(res) == 1);
326 i_encoding = PQfnumber(res, "pg_encoding_to_char");
327 ctrl->encoding = pg_strdup(PQgetvalue(res, 0, i_encoding));
336 * check_locale_and_encoding()
338 * locale is not in pg_controldata in 8.4 and later so
339 * we probably had to get via a database query.
342 check_locale_and_encoding(ControlData *oldctrl,
343 ControlData *newctrl)
345 /* These are often defined with inconsistent case, so use pg_strcasecmp(). */
346 if (pg_strcasecmp(oldctrl->lc_collate, newctrl->lc_collate) != 0)
348 "old and new cluster lc_collate values do not match\n");
349 if (pg_strcasecmp(oldctrl->lc_ctype, newctrl->lc_ctype) != 0)
351 "old and new cluster lc_ctype values do not match\n");
352 if (pg_strcasecmp(oldctrl->encoding, newctrl->encoding) != 0)
354 "old and new cluster encoding values do not match\n");
359 check_new_cluster_is_empty(void)
363 for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
366 RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
368 for (relnum = 0; relnum < rel_arr->nrels;
371 /* pg_largeobject and its index should be skipped */
372 if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
373 pg_log(PG_FATAL, "New cluster database \"%s\" is not empty\n",
374 new_cluster.dbarr.dbs[dbnum].db_name);
382 * create_script_for_old_cluster_deletion()
384 * This is particularly useful for tablespace deletion.
387 create_script_for_old_cluster_deletion(char **deletion_script_file_name)
392 *deletion_script_file_name = pg_malloc(MAXPGPATH);
394 prep_status("Creating script to delete old cluster");
396 snprintf(*deletion_script_file_name, MAXPGPATH, "%s/delete_old_cluster.%s",
397 os_info.cwd, SCRIPT_EXT);
399 if ((script = fopen(*deletion_script_file_name, "w")) == NULL)
400 pg_log(PG_FATAL, "Could not open file \"%s\": %s\n",
401 *deletion_script_file_name, getErrorText(errno));
404 /* add shebang header */
405 fprintf(script, "#!/bin/sh\n\n");
408 /* delete old cluster's default tablespace */
409 fprintf(script, RMDIR_CMD " %s\n", old_cluster.pgdata);
411 /* delete old cluster's alternate tablespaces */
412 for (tblnum = 0; tblnum < os_info.num_tablespaces; tblnum++)
415 * Do the old cluster's per-database directories share a directory
416 * with a new version-specific tablespace?
418 if (strlen(old_cluster.tablespace_suffix) == 0)
420 /* delete per-database directories */
423 fprintf(script, "\n");
424 /* remove PG_VERSION? */
425 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
426 fprintf(script, RM_CMD " %s%s/PG_VERSION\n",
427 os_info.tablespaces[tblnum], old_cluster.tablespace_suffix);
429 for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
431 fprintf(script, RMDIR_CMD " %s%s/%d\n",
432 os_info.tablespaces[tblnum], old_cluster.tablespace_suffix,
433 old_cluster.dbarr.dbs[dbnum].db_oid);
439 * Simply delete the tablespace directory, which might be ".old"
440 * or a version-specific subdirectory.
442 fprintf(script, RMDIR_CMD " %s%s\n",
443 os_info.tablespaces[tblnum], old_cluster.tablespace_suffix);
449 if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
450 pg_log(PG_FATAL, "Could not add execute permission to file \"%s\": %s\n",
451 *deletion_script_file_name, getErrorText(errno));
459 * check_is_super_user()
461 * Make sure we are the super-user.
464 check_is_super_user(ClusterInfo *cluster)
467 PGconn *conn = connectToServer(cluster, "template1");
469 prep_status("Checking database user is a superuser");
471 /* Can't use pg_authid because only superusers can view it. */
472 res = executeQueryOrDie(conn,
474 "FROM pg_catalog.pg_roles "
475 "WHERE rolname = current_user");
477 if (PQntuples(res) != 1 || strcmp(PQgetvalue(res, 0, 0), "t") != 0)
478 pg_log(PG_FATAL, "database user \"%s\" is not a superuser\n",
490 * check_for_prepared_transactions()
492 * Make sure there are no prepared transactions because the storage format
493 * might have changed.
496 check_for_prepared_transactions(ClusterInfo *cluster)
499 PGconn *conn = connectToServer(cluster, "template1");
501 prep_status("Checking for prepared transactions");
503 res = executeQueryOrDie(conn,
505 "FROM pg_catalog.pg_prepared_xacts");
507 if (PQntuples(res) != 0)
508 pg_log(PG_FATAL, "The %s cluster contains prepared transactions\n",
509 CLUSTER_NAME(cluster));
520 * check_for_isn_and_int8_passing_mismatch()
522 * contrib/isn relies on data type int8, and in 8.4 int8 can now be passed
523 * by value. The schema dumps the CREATE TYPE PASSEDBYVALUE setting so
524 * it must match for the old and new servers.
527 check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
532 char output_path[MAXPGPATH];
534 prep_status("Checking for contrib/isn with bigint-passing mismatch");
536 if (old_cluster.controldata.float8_pass_by_value ==
537 new_cluster.controldata.float8_pass_by_value)
544 snprintf(output_path, sizeof(output_path), "%s/contrib_isn_and_int8_pass_by_value.txt",
547 for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
550 bool db_used = false;
555 DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
556 PGconn *conn = connectToServer(cluster, active_db->db_name);
558 /* Find any functions coming from contrib/isn */
559 res = executeQueryOrDie(conn,
560 "SELECT n.nspname, p.proname "
561 "FROM pg_catalog.pg_proc p, "
562 " pg_catalog.pg_namespace n "
563 "WHERE p.pronamespace = n.oid AND "
564 " p.probin = '$libdir/isn'");
566 ntups = PQntuples(res);
567 i_nspname = PQfnumber(res, "nspname");
568 i_proname = PQfnumber(res, "proname");
569 for (rowno = 0; rowno < ntups; rowno++)
572 if (script == NULL && (script = fopen(output_path, "w")) == NULL)
573 pg_log(PG_FATAL, "Could not open file \"%s\": %s\n",
574 output_path, getErrorText(errno));
577 fprintf(script, "Database: %s\n", active_db->db_name);
580 fprintf(script, " %s.%s\n",
581 PQgetvalue(res, rowno, i_nspname),
582 PQgetvalue(res, rowno, i_proname));
595 pg_log(PG_REPORT, "fatal\n");
597 "Your installation contains \"contrib/isn\" functions which rely on the\n"
598 "bigint data type. Your old and new clusters pass bigint values\n"
599 "differently so this cluster cannot currently be upgraded. You can\n"
600 "manually upgrade databases that use \"contrib/isn\" facilities and remove\n"
601 "\"contrib/isn\" from the old cluster and restart the upgrade. A list of\n"
602 "the problem functions is in the file:\n"
603 " %s\n\n", output_path);
611 * check_for_reg_data_type_usage()
612 * pg_upgrade only preserves these system values:
617 * Many of the reg* data types reference system catalog info that is
618 * not preserved, and hence these data types cannot be used in user
619 * tables upgraded by pg_upgrade.
622 check_for_reg_data_type_usage(ClusterInfo *cluster)
627 char output_path[MAXPGPATH];
629 prep_status("Checking for reg* system OID user data types");
631 snprintf(output_path, sizeof(output_path), "%s/tables_using_reg.txt",
634 for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
637 bool db_used = false;
643 DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
644 PGconn *conn = connectToServer(cluster, active_db->db_name);
647 * While several relkinds don't store any data, e.g. views, they
648 * can be used to define data types of other columns, so we
649 * check all relkinds.
651 res = executeQueryOrDie(conn,
652 "SELECT n.nspname, c.relname, a.attname "
653 "FROM pg_catalog.pg_class c, "
654 " pg_catalog.pg_namespace n, "
655 " pg_catalog.pg_attribute a "
656 "WHERE c.oid = a.attrelid AND "
657 " NOT a.attisdropped AND "
659 " 'pg_catalog.regproc'::pg_catalog.regtype, "
660 " 'pg_catalog.regprocedure'::pg_catalog.regtype, "
661 " 'pg_catalog.regoper'::pg_catalog.regtype, "
662 " 'pg_catalog.regoperator'::pg_catalog.regtype, "
663 /* regclass.oid is preserved, so 'regclass' is OK */
664 /* regtype.oid is preserved, so 'regtype' is OK */
665 " 'pg_catalog.regconfig'::pg_catalog.regtype, "
666 " 'pg_catalog.regdictionary'::pg_catalog.regtype) AND "
667 " c.relnamespace = n.oid AND "
668 " n.nspname != 'pg_catalog' AND "
669 " n.nspname != 'information_schema'");
671 ntups = PQntuples(res);
672 i_nspname = PQfnumber(res, "nspname");
673 i_relname = PQfnumber(res, "relname");
674 i_attname = PQfnumber(res, "attname");
675 for (rowno = 0; rowno < ntups; rowno++)
678 if (script == NULL && (script = fopen(output_path, "w")) == NULL)
679 pg_log(PG_FATAL, "Could not open file \"%s\": %s\n",
680 output_path, getErrorText(errno));
683 fprintf(script, "Database: %s\n", active_db->db_name);
686 fprintf(script, " %s.%s.%s\n",
687 PQgetvalue(res, rowno, i_nspname),
688 PQgetvalue(res, rowno, i_relname),
689 PQgetvalue(res, rowno, i_attname));
702 pg_log(PG_REPORT, "fatal\n");
704 "Your installation contains one of the reg* data types in user tables.\n"
705 "These data types reference system OIDs that are not preserved by\n"
706 "pg_upgrade, so this cluster cannot currently be upgraded. You can\n"
707 "remove the problem tables and restart the upgrade. A list of the problem\n"
708 "columns is in the file:\n"
709 " %s\n\n", output_path);
717 * Test pg_upgrade_support.so is in the proper place. We cannot copy it
718 * ourselves because install directories are typically root-owned.
721 check_for_support_lib(ClusterInfo *cluster)
724 char libdir[MAX_STRING];
725 char libfile[MAXPGPATH];
729 snprintf(cmd, sizeof(cmd), "\"%s/pg_config\" --pkglibdir", cluster->bindir);
731 if ((output = popen(cmd, "r")) == NULL ||
732 fgets(libdir, sizeof(libdir), output) == NULL)
733 pg_log(PG_FATAL, "Could not get pkglibdir data using %s: %s\n",
734 cmd, getErrorText(errno));
739 /* Remove trailing newline */
740 if (strchr(libdir, '\n') != NULL)
741 *strchr(libdir, '\n') = '\0';
743 snprintf(libfile, sizeof(libfile), "%s/pg_upgrade_support%s", libdir,
746 if ((lib_test = fopen(libfile, "r")) == NULL)
748 "The pg_upgrade_support module must be created and installed in the %s cluster.\n",
749 CLUSTER_NAME(cluster));
756 get_bin_version(ClusterInfo *cluster)
758 char cmd[MAXPGPATH], cmd_output[MAX_STRING];
760 int pre_dot, post_dot;
762 snprintf(cmd, sizeof(cmd), "\"%s/pg_ctl\" --version", cluster->bindir);
764 if ((output = popen(cmd, "r")) == NULL ||
765 fgets(cmd_output, sizeof(cmd_output), output) == NULL)
766 pg_log(PG_FATAL, "Could not get pg_ctl version data using %s: %s\n",
767 cmd, getErrorText(errno));
771 /* Remove trailing newline */
772 if (strchr(cmd_output, '\n') != NULL)
773 *strchr(cmd_output, '\n') = '\0';
775 if (sscanf(cmd_output, "%*s %*s %d.%d", &pre_dot, &post_dot) != 2)
776 pg_log(PG_FATAL, "could not get version from %s\n", cmd);
778 cluster->bin_version = (pre_dot * 100 + post_dot) * 100;