4 * server checks and output routines
6 * Copyright (c) 2010-2011, PostgreSQL Global Development Group
7 * contrib/pg_upgrade/check.c
10 #include "pg_upgrade.h"
13 static void set_locale_and_encoding(ClusterInfo *cluster);
14 static void check_new_cluster_is_empty(void);
15 static void check_old_cluster_has_new_cluster_dbs(void);
16 static void check_locale_and_encoding(ControlData *oldctrl,
17 ControlData *newctrl);
18 static void check_is_super_user(ClusterInfo *cluster);
19 static void check_for_prepared_transactions(ClusterInfo *cluster);
20 static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
21 static void check_for_reg_data_type_usage(ClusterInfo *cluster);
22 static void check_for_support_lib(ClusterInfo *cluster);
23 static void get_bin_version(ClusterInfo *cluster);
27 output_check_banner(bool *live_check)
29 if (user_opts.check && is_server_running(old_cluster.pgdata))
32 if (old_cluster.port == DEF_PGUPORT)
33 pg_log(PG_FATAL, "When checking a live old server, "
34 "you must specify the old server's port number.\n");
35 if (old_cluster.port == new_cluster.port)
36 pg_log(PG_FATAL, "When checking a live server, "
37 "the old and new port numbers must be different.\n");
38 pg_log(PG_REPORT, "Performing Consistency Checks on Old Live Server\n");
39 pg_log(PG_REPORT, "------------------------------------------------\n");
43 pg_log(PG_REPORT, "Performing Consistency Checks\n");
44 pg_log(PG_REPORT, "-----------------------------\n");
50 check_old_cluster(bool live_check, char **sequence_script_file_name)
55 start_postmaster(&old_cluster);
57 set_locale_and_encoding(&old_cluster);
59 get_pg_database_relfilenode(&old_cluster);
61 /* Extract a list of databases and tables from the old cluster */
62 get_db_and_rel_infos(&old_cluster);
66 get_loadable_libraries();
70 * Check for various failure cases
72 check_is_super_user(&old_cluster);
73 check_for_prepared_transactions(&old_cluster);
74 check_for_reg_data_type_usage(&old_cluster);
75 check_for_isn_and_int8_passing_mismatch(&old_cluster);
77 /* old = PG 8.3 checks? */
78 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
80 old_8_3_check_for_name_data_type_usage(&old_cluster);
81 old_8_3_check_for_tsquery_usage(&old_cluster);
84 old_8_3_rebuild_tsvector_tables(&old_cluster, true);
85 old_8_3_invalidate_hash_gin_indexes(&old_cluster, true);
86 old_8_3_invalidate_bpchar_pattern_ops_indexes(&old_cluster, true);
91 * While we have the old server running, create the script to
92 * properly restore its sequence values but we report this at the
95 *sequence_script_file_name =
96 old_8_3_create_sequence_script(&old_cluster);
99 /* Pre-PG 9.0 had no large object permissions */
100 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
101 new_9_0_populate_pg_largeobject_metadata(&old_cluster, true);
104 * While not a check option, we do this now because this is the only time
105 * the old server is running.
107 if (!user_opts.check)
114 stop_postmaster(false);
119 check_new_cluster(void)
121 set_locale_and_encoding(&new_cluster);
123 get_db_and_rel_infos(&new_cluster);
125 check_new_cluster_is_empty();
126 check_for_prepared_transactions(&new_cluster);
127 check_old_cluster_has_new_cluster_dbs();
129 check_loadable_libraries();
131 check_locale_and_encoding(&old_cluster.controldata, &new_cluster.controldata);
133 if (user_opts.transfer_mode == TRANSFER_MODE_LINK)
139 report_clusters_compatible(void)
143 pg_log(PG_REPORT, "\n*Clusters are compatible*\n");
144 /* stops new cluster */
145 stop_postmaster(false);
149 pg_log(PG_REPORT, "\n"
150 "| If pg_upgrade fails after this point, you must\n"
151 "| re-initdb the new cluster before continuing.\n"
152 "| You will also need to remove the \".old\" suffix\n"
153 "| from %s/global/pg_control.old.\n", old_cluster.pgdata);
158 issue_warnings(char *sequence_script_file_name)
160 /* old = PG 8.3 warnings? */
161 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
163 start_postmaster(&new_cluster);
165 /* restore proper sequence values using file created from old server */
166 if (sequence_script_file_name)
168 prep_status("Adjusting sequences");
170 SYSTEMQUOTE "\"%s/psql\" --set ON_ERROR_STOP=on "
171 "--no-psqlrc --port %d --username \"%s\" "
172 "-f \"%s\" --dbname template1 >> \"%s\"" SYSTEMQUOTE,
173 new_cluster.bindir, new_cluster.port, os_info.user,
174 sequence_script_file_name, log_opts.filename);
175 unlink(sequence_script_file_name);
179 old_8_3_rebuild_tsvector_tables(&new_cluster, false);
180 old_8_3_invalidate_hash_gin_indexes(&new_cluster, false);
181 old_8_3_invalidate_bpchar_pattern_ops_indexes(&new_cluster, false);
182 stop_postmaster(false);
185 /* Create dummy large object permissions for old < PG 9.0? */
186 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
188 start_postmaster(&new_cluster);
189 new_9_0_populate_pg_largeobject_metadata(&new_cluster, false);
190 stop_postmaster(false);
196 output_completion_banner(char *deletion_script_file_name)
198 /* Did we copy the free space files? */
199 if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804)
201 "| Optimizer statistics are not transferred by pg_upgrade\n"
202 "| so consider running:\n"
203 "| \tvacuumdb --all --analyze-only\n"
204 "| on the newly-upgraded cluster.\n\n");
207 "| Optimizer statistics and free space information\n"
208 "| are not transferred by pg_upgrade so consider\n"
210 "| \tvacuumdb --all --analyze\n"
211 "| on the newly-upgraded cluster.\n\n");
214 "| Running this script will delete the old cluster's data files:\n"
216 deletion_script_file_name);
221 check_cluster_versions(void)
223 prep_status("Checking cluster versions");
225 /* get old and new cluster versions */
226 old_cluster.major_version = get_major_server_version(&old_cluster);
227 new_cluster.major_version = get_major_server_version(&new_cluster);
230 * We allow upgrades from/to the same major version for alpha/beta
234 if (GET_MAJOR_VERSION(old_cluster.major_version) < 803)
235 pg_log(PG_FATAL, "This utility can only upgrade from PostgreSQL version 8.3 and later.\n");
237 /* Only current PG version is supported as a target */
238 if (GET_MAJOR_VERSION(new_cluster.major_version) != GET_MAJOR_VERSION(PG_VERSION_NUM))
239 pg_log(PG_FATAL, "This utility can only upgrade to PostgreSQL version %s.\n",
243 * We can't allow downgrading because we use the target pg_dumpall, and
244 * pg_dumpall cannot operate on new database versions, only older versions.
246 if (old_cluster.major_version > new_cluster.major_version)
247 pg_log(PG_FATAL, "This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
249 /* get old and new binary versions */
250 get_bin_version(&old_cluster);
251 get_bin_version(&new_cluster);
253 /* Ensure binaries match the designated data directories */
254 if (GET_MAJOR_VERSION(old_cluster.major_version) !=
255 GET_MAJOR_VERSION(old_cluster.bin_version))
257 "Old cluster data and binary directories are from different major versions.\n");
258 if (GET_MAJOR_VERSION(new_cluster.major_version) !=
259 GET_MAJOR_VERSION(new_cluster.bin_version))
261 "New cluster data and binary directories are from different major versions.\n");
268 check_cluster_compatibility(bool live_check)
270 check_for_support_lib(&new_cluster);
272 /* get/check pg_control data of servers */
273 get_control_data(&old_cluster, live_check);
274 get_control_data(&new_cluster, false);
275 check_control_data(&old_cluster.controldata, &new_cluster.controldata);
277 /* Is it 9.0 but without tablespace directories? */
278 if (GET_MAJOR_VERSION(new_cluster.major_version) == 900 &&
279 new_cluster.controldata.cat_ver < TABLE_SPACE_SUBDIRS_CAT_VER)
280 pg_log(PG_FATAL, "This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n"
281 "because of backend API changes made during development.\n");
286 * set_locale_and_encoding()
288 * query the database to get the template0 locale
291 set_locale_and_encoding(ClusterInfo *cluster)
293 ControlData *ctrl = &cluster->controldata;
297 int cluster_version = cluster->major_version;
299 conn = connectToServer(cluster, "template1");
301 /* for pg < 80400, we got the values from pg_controldata */
302 if (cluster_version >= 80400)
307 res = executeQueryOrDie(conn,
308 "SELECT datcollate, datctype "
309 "FROM pg_catalog.pg_database "
310 "WHERE datname = 'template0' ");
311 assert(PQntuples(res) == 1);
313 i_datcollate = PQfnumber(res, "datcollate");
314 i_datctype = PQfnumber(res, "datctype");
316 ctrl->lc_collate = pg_strdup(PQgetvalue(res, 0, i_datcollate));
317 ctrl->lc_ctype = pg_strdup(PQgetvalue(res, 0, i_datctype));
322 res = executeQueryOrDie(conn,
323 "SELECT pg_catalog.pg_encoding_to_char(encoding) "
324 "FROM pg_catalog.pg_database "
325 "WHERE datname = 'template0' ");
326 assert(PQntuples(res) == 1);
328 i_encoding = PQfnumber(res, "pg_encoding_to_char");
329 ctrl->encoding = pg_strdup(PQgetvalue(res, 0, i_encoding));
338 * check_locale_and_encoding()
340 * locale is not in pg_controldata in 8.4 and later so
341 * we probably had to get via a database query.
344 check_locale_and_encoding(ControlData *oldctrl,
345 ControlData *newctrl)
347 /* These are often defined with inconsistent case, so use pg_strcasecmp(). */
348 if (pg_strcasecmp(oldctrl->lc_collate, newctrl->lc_collate) != 0)
350 "old and new cluster lc_collate values do not match\n");
351 if (pg_strcasecmp(oldctrl->lc_ctype, newctrl->lc_ctype) != 0)
353 "old and new cluster lc_ctype values do not match\n");
354 if (pg_strcasecmp(oldctrl->encoding, newctrl->encoding) != 0)
356 "old and new cluster encoding values do not match\n");
361 check_new_cluster_is_empty(void)
365 for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
368 RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
370 for (relnum = 0; relnum < rel_arr->nrels;
373 /* pg_largeobject and its index should be skipped */
374 if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
375 pg_log(PG_FATAL, "New cluster database \"%s\" is not empty\n",
376 new_cluster.dbarr.dbs[dbnum].db_name);
384 * If someone removes the 'postgres' database from the old cluster and
385 * the new cluster has a 'postgres' database, the number of databases
386 * will not match. We actually could upgrade such a setup, but it would
387 * violate the 1-to-1 mapping of database counts, so we throw an error
388 * instead. We would detect this as a database count mismatch during
389 * upgrade, but we want to detect it during the check phase and report
393 check_old_cluster_has_new_cluster_dbs(void)
398 for (new_dbnum = 0; new_dbnum < new_cluster.dbarr.ndbs; new_dbnum++)
400 for (old_dbnum = 0; old_dbnum < old_cluster.dbarr.ndbs; old_dbnum++)
401 if (strcmp(old_cluster.dbarr.dbs[old_dbnum].db_name,
402 new_cluster.dbarr.dbs[new_dbnum].db_name) == 0)
404 if (old_dbnum == old_cluster.dbarr.ndbs)
405 pg_log(PG_FATAL, "New cluster database \"%s\" does not exist in the old cluster\n",
406 new_cluster.dbarr.dbs[new_dbnum].db_name);
412 * create_script_for_old_cluster_deletion()
414 * This is particularly useful for tablespace deletion.
417 create_script_for_old_cluster_deletion(char **deletion_script_file_name)
422 *deletion_script_file_name = pg_malloc(MAXPGPATH);
424 prep_status("Creating script to delete old cluster");
426 snprintf(*deletion_script_file_name, MAXPGPATH, "%s/delete_old_cluster.%s",
427 os_info.cwd, SCRIPT_EXT);
429 if ((script = fopen(*deletion_script_file_name, "w")) == NULL)
430 pg_log(PG_FATAL, "Could not create necessary file: %s\n",
431 *deletion_script_file_name);
434 /* add shebang header */
435 fprintf(script, "#!/bin/sh\n\n");
438 /* delete old cluster's default tablespace */
439 fprintf(script, RMDIR_CMD " %s\n", old_cluster.pgdata);
441 /* delete old cluster's alternate tablespaces */
442 for (tblnum = 0; tblnum < os_info.num_tablespaces; tblnum++)
445 * Do the old cluster's per-database directories share a directory
446 * with a new version-specific tablespace?
448 if (strlen(old_cluster.tablespace_suffix) == 0)
450 /* delete per-database directories */
453 fprintf(script, "\n");
454 /* remove PG_VERSION? */
455 if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
456 fprintf(script, RM_CMD " %s%s/PG_VERSION\n",
457 os_info.tablespaces[tblnum], old_cluster.tablespace_suffix);
459 for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
461 fprintf(script, RMDIR_CMD " %s%s/%d\n",
462 os_info.tablespaces[tblnum], old_cluster.tablespace_suffix,
463 old_cluster.dbarr.dbs[dbnum].db_oid);
469 * Simply delete the tablespace directory, which might be ".old"
470 * or a version-specific subdirectory.
472 fprintf(script, RMDIR_CMD " %s%s\n",
473 os_info.tablespaces[tblnum], old_cluster.tablespace_suffix);
479 if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
480 pg_log(PG_FATAL, "Could not add execute permission to file: %s\n",
481 *deletion_script_file_name);
489 * check_is_super_user()
491 * Make sure we are the super-user.
494 check_is_super_user(ClusterInfo *cluster)
497 PGconn *conn = connectToServer(cluster, "template1");
499 prep_status("Checking database user is a superuser");
501 /* Can't use pg_authid because only superusers can view it. */
502 res = executeQueryOrDie(conn,
504 "FROM pg_catalog.pg_roles "
505 "WHERE rolname = current_user");
507 if (PQntuples(res) != 1 || strcmp(PQgetvalue(res, 0, 0), "t") != 0)
508 pg_log(PG_FATAL, "database user \"%s\" is not a superuser\n",
520 * check_for_prepared_transactions()
522 * Make sure there are no prepared transactions because the storage format
523 * might have changed.
526 check_for_prepared_transactions(ClusterInfo *cluster)
529 PGconn *conn = connectToServer(cluster, "template1");
531 prep_status("Checking for prepared transactions");
533 res = executeQueryOrDie(conn,
535 "FROM pg_catalog.pg_prepared_xact()");
537 if (PQntuples(res) != 0)
538 pg_log(PG_FATAL, "The %s cluster contains prepared transactions\n",
539 CLUSTER_NAME(cluster));
550 * check_for_isn_and_int8_passing_mismatch()
552 * contrib/isn relies on data type int8, and in 8.4 int8 can now be passed
553 * by value. The schema dumps the CREATE TYPE PASSEDBYVALUE setting so
554 * it must match for the old and new servers.
557 check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
562 char output_path[MAXPGPATH];
564 prep_status("Checking for contrib/isn with bigint-passing mismatch");
566 if (old_cluster.controldata.float8_pass_by_value ==
567 new_cluster.controldata.float8_pass_by_value)
574 snprintf(output_path, sizeof(output_path), "%s/contrib_isn_and_int8_pass_by_value.txt",
577 for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
580 bool db_used = false;
585 DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
586 PGconn *conn = connectToServer(cluster, active_db->db_name);
588 /* Find any functions coming from contrib/isn */
589 res = executeQueryOrDie(conn,
590 "SELECT n.nspname, p.proname "
591 "FROM pg_catalog.pg_proc p, "
592 " pg_catalog.pg_namespace n "
593 "WHERE p.pronamespace = n.oid AND "
594 " p.probin = '$libdir/isn'");
596 ntups = PQntuples(res);
597 i_nspname = PQfnumber(res, "nspname");
598 i_proname = PQfnumber(res, "proname");
599 for (rowno = 0; rowno < ntups; rowno++)
602 if (script == NULL && (script = fopen(output_path, "w")) == NULL)
603 pg_log(PG_FATAL, "Could not create necessary file: %s\n", output_path);
606 fprintf(script, "Database: %s\n", active_db->db_name);
609 fprintf(script, " %s.%s\n",
610 PQgetvalue(res, rowno, i_nspname),
611 PQgetvalue(res, rowno, i_proname));
624 pg_log(PG_REPORT, "fatal\n");
626 "| Your installation contains \"contrib/isn\" functions\n"
627 "| which rely on the bigint data type. Your old and\n"
628 "| new clusters pass bigint values differently so this\n"
629 "| cluster cannot currently be upgraded. You can\n"
630 "| manually upgrade data that use \"contrib/isn\"\n"
631 "| facilities and remove \"contrib/isn\" from the\n"
632 "| old cluster and restart the upgrade. A list\n"
633 "| of the problem functions is in the file:\n"
634 "| \t%s\n\n", output_path);
642 * check_for_reg_data_type_usage()
643 * pg_upgrade only preserves these system values:
644 * pg_class.relfilenode
648 * Most of the reg* data types reference system catalog info that is
649 * not preserved, and hence these data types cannot be used in user
650 * tables upgraded by pg_upgrade.
653 check_for_reg_data_type_usage(ClusterInfo *cluster)
658 char output_path[MAXPGPATH];
660 prep_status("Checking for reg* system oid user data types");
662 snprintf(output_path, sizeof(output_path), "%s/tables_using_reg.txt",
665 for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
668 bool db_used = false;
674 DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
675 PGconn *conn = connectToServer(cluster, active_db->db_name);
677 res = executeQueryOrDie(conn,
678 "SELECT n.nspname, c.relname, a.attname "
679 "FROM pg_catalog.pg_class c, "
680 " pg_catalog.pg_namespace n, "
681 " pg_catalog.pg_attribute a "
682 "WHERE c.oid = a.attrelid AND "
683 " NOT a.attisdropped AND "
685 " 'pg_catalog.regproc'::pg_catalog.regtype, "
686 " 'pg_catalog.regprocedure'::pg_catalog.regtype, "
687 " 'pg_catalog.regoper'::pg_catalog.regtype, "
688 " 'pg_catalog.regoperator'::pg_catalog.regtype, "
689 " 'pg_catalog.regclass'::pg_catalog.regtype, "
690 /* regtype.oid is preserved, so 'regtype' is OK */
691 " 'pg_catalog.regconfig'::pg_catalog.regtype, "
692 " 'pg_catalog.regdictionary'::pg_catalog.regtype) AND "
693 " c.relnamespace = n.oid AND "
694 " n.nspname != 'pg_catalog' AND "
695 " n.nspname != 'information_schema'");
697 ntups = PQntuples(res);
698 i_nspname = PQfnumber(res, "nspname");
699 i_relname = PQfnumber(res, "relname");
700 i_attname = PQfnumber(res, "attname");
701 for (rowno = 0; rowno < ntups; rowno++)
704 if (script == NULL && (script = fopen(output_path, "w")) == NULL)
705 pg_log(PG_FATAL, "Could not create necessary file: %s\n", output_path);
708 fprintf(script, "Database: %s\n", active_db->db_name);
711 fprintf(script, " %s.%s.%s\n",
712 PQgetvalue(res, rowno, i_nspname),
713 PQgetvalue(res, rowno, i_relname),
714 PQgetvalue(res, rowno, i_attname));
727 pg_log(PG_REPORT, "fatal\n");
729 "| Your installation contains one of the reg* data types in\n"
730 "| user tables. These data types reference system oids that\n"
731 "| are not preserved by pg_upgrade, so this cluster cannot\n"
732 "| currently be upgraded. You can remove the problem tables\n"
733 "| and restart the upgrade. A list of the problem columns\n"
734 "| is in the file:\n"
735 "| \t%s\n\n", output_path);
743 * Test pg_upgrade_support.so is in the proper place. We cannot copy it
744 * ourselves because install directories are typically root-owned.
747 check_for_support_lib(ClusterInfo *cluster)
750 char libdir[MAX_STRING];
751 char libfile[MAXPGPATH];
755 snprintf(cmd, sizeof(cmd), "\"%s/pg_config\" --pkglibdir", cluster->bindir);
757 if ((output = popen(cmd, "r")) == NULL)
758 pg_log(PG_FATAL, "Could not get pkglibdir data: %s\n",
759 getErrorText(errno));
761 fgets(libdir, sizeof(libdir), output);
765 /* Remove trailing newline */
766 if (strchr(libdir, '\n') != NULL)
767 *strchr(libdir, '\n') = '\0';
769 snprintf(libfile, sizeof(libfile), "%s/pg_upgrade_support%s", libdir,
772 if ((lib_test = fopen(libfile, "r")) == NULL)
774 "The pg_upgrade_support module must be created and installed in the %s cluster.\n",
775 CLUSTER_NAME(cluster));
782 get_bin_version(ClusterInfo *cluster)
784 char cmd[MAXPGPATH], cmd_output[MAX_STRING];
786 int pre_dot, post_dot;
788 snprintf(cmd, sizeof(cmd), "\"%s/pg_ctl\" --version", cluster->bindir);
790 if ((output = popen(cmd, "r")) == NULL)
791 pg_log(PG_FATAL, "Could not get pg_ctl version data: %s\n",
792 getErrorText(errno));
794 fgets(cmd_output, sizeof(cmd_output), output);
798 /* Remove trailing newline */
799 if (strchr(cmd_output, '\n') != NULL)
800 *strchr(cmd_output, '\n') = '\0';
802 if (sscanf(cmd_output, "%*s %*s %d.%d", &pre_dot, &post_dot) != 2)
803 pg_log(PG_FATAL, "could not get version from %s\n", cmd);
805 cluster->bin_version = (pre_dot * 100 + post_dot) * 100;