Age Owner TLA Line data Source code
1 : /*
2 : * check.c
3 : *
4 : * server checks and output routines
5 : *
6 : * Copyright (c) 2010-2023, PostgreSQL Global Development Group
7 : * src/bin/pg_upgrade/check.c
8 : */
9 :
10 : #include "postgres_fe.h"
11 :
12 : #include "catalog/pg_authid_d.h"
13 : #include "catalog/pg_collation.h"
14 : #include "fe_utils/string_utils.h"
15 : #include "mb/pg_wchar.h"
16 : #include "pg_upgrade.h"
17 :
18 : static void check_new_cluster_is_empty(void);
19 : static void check_is_install_user(ClusterInfo *cluster);
20 : static void check_proper_datallowconn(ClusterInfo *cluster);
21 : static void check_for_prepared_transactions(ClusterInfo *cluster);
22 : static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
23 : static void check_for_user_defined_postfix_ops(ClusterInfo *cluster);
24 : static void check_for_incompatible_polymorphics(ClusterInfo *cluster);
25 : static void check_for_tables_with_oids(ClusterInfo *cluster);
26 : static void check_for_composite_data_type_usage(ClusterInfo *cluster);
27 : static void check_for_reg_data_type_usage(ClusterInfo *cluster);
28 : static void check_for_aclitem_data_type_usage(ClusterInfo *cluster);
29 : static void check_for_jsonb_9_4_usage(ClusterInfo *cluster);
30 : static void check_for_pg_role_prefix(ClusterInfo *cluster);
31 : static void check_for_new_tablespace_dir(ClusterInfo *new_cluster);
32 : static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster);
33 :
34 :
35 : /*
36 : * fix_path_separator
37 : * For non-Windows, just return the argument.
38 : * For Windows convert any forward slash to a backslash
39 : * such as is suitable for arguments to builtin commands
3870 andrew 40 ECB : * like RMDIR and DEL.
41 : */
42 : static char *
3870 andrew 43 GIC 1 : fix_path_separator(char *path)
44 : {
45 : #ifdef WIN32
46 :
47 : char *result;
48 : char *c;
49 :
50 : result = pg_strdup(path);
51 :
52 : for (c = result; *c != '\0'; c++)
53 : if (*c == '/')
54 : *c = '\\';
55 :
3870 andrew 56 ECB : return result;
57 : #else
58 :
3870 andrew 59 GIC 1 : return path;
60 : #endif
3870 andrew 61 ECB : }
62 :
4715 bruce 63 : void
3727 bruce 64 GIC 2 : output_check_banner(bool live_check)
4715 bruce 65 EUB : {
3727 bruce 66 GIC 2 : if (user_opts.check && live_check)
67 : {
2056 peter_e 68 UIC 0 : pg_log(PG_REPORT,
69 : "Performing Consistency Checks on Old Live Server\n"
70 : "------------------------------------------------");
4715 bruce 71 ECB : }
72 : else
73 : {
2056 peter_e 74 GIC 2 : pg_log(PG_REPORT,
2056 peter_e 75 ECB : "Performing Consistency Checks\n"
76 : "-----------------------------");
77 : }
4715 bruce 78 GIC 2 : }
4715 bruce 79 ECB :
80 :
81 : void
3149 bruce 82 GIC 2 : check_and_dump_old_cluster(bool live_check)
4715 bruce 83 ECB : {
84 : /* -- OLD -- */
85 :
4715 bruce 86 GIC 2 : if (!live_check)
3727 bruce 87 CBC 2 : start_postmaster(&old_cluster, true);
88 :
4715 bruce 89 ECB : /* Extract a list of databases and tables from the old cluster */
4481 bruce 90 GIC 2 : get_db_and_rel_infos(&old_cluster);
4715 bruce 91 ECB :
4555 bruce 92 GIC 2 : init_tablespaces();
93 :
94 2 : get_loadable_libraries();
95 :
96 :
4715 bruce 97 ECB : /*
98 : * Check for various failure cases
99 : */
3170 bruce 100 CBC 2 : check_is_install_user(&old_cluster);
2885 101 2 : check_proper_datallowconn(&old_cluster);
4317 102 2 : check_for_prepared_transactions(&old_cluster);
710 tgl 103 GIC 2 : check_for_composite_data_type_usage(&old_cluster);
4481 bruce 104 2 : check_for_reg_data_type_usage(&old_cluster);
105 2 : check_for_isn_and_int8_passing_mismatch(&old_cluster);
106 :
107 : /*
108 : * PG 16 increased the size of the 'aclitem' type, which breaks the on-disk
109 : * format for existing data.
110 : */
137 andrew 111 GNC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1500)
137 andrew 112 UNC 0 : check_for_aclitem_data_type_usage(&old_cluster);
113 :
114 : /*
738 heikki.linnakangas 115 ECB : * PG 14 changed the function signature of encoding conversion functions.
738 heikki.linnakangas 116 EUB : * Conversions from older versions cannot be upgraded automatically
117 : * because the user-defined functions used by the encoding conversions
118 : * need to be changed to match the new signature.
119 : */
738 heikki.linnakangas 120 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1300)
738 heikki.linnakangas 121 UIC 0 : check_for_user_defined_encoding_conversions(&old_cluster);
122 :
123 : /*
934 tgl 124 ECB : * Pre-PG 14 allowed user defined postfix operators, which are not
934 tgl 125 EUB : * supported anymore. Verify there are none, iff applicable.
126 : */
934 tgl 127 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1300)
934 tgl 128 UIC 0 : check_for_user_defined_postfix_ops(&old_cluster);
129 :
130 : /*
278 tgl 131 ECB : * PG 14 changed polymorphic functions from anyarray to
278 tgl 132 EUB : * anycompatiblearray.
133 : */
278 tgl 134 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1300)
278 tgl 135 UIC 0 : check_for_incompatible_polymorphics(&old_cluster);
136 :
137 : /*
1601 andres 138 ECB : * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
1601 andres 139 EUB : * supported anymore. Verify there are none, iff applicable.
140 : */
1601 andres 141 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1100)
1601 andres 142 UIC 0 : check_for_tables_with_oids(&old_cluster);
143 :
144 : /*
1273 tomas.vondra 145 ECB : * PG 12 changed the 'sql_identifier' type storage to be based on name,
1273 tomas.vondra 146 EUB : * not varchar, which breaks on-disk format for existing data. So we need
147 : * to prevent upgrade when used in user objects (tables, indexes, ...).
148 : */
1273 tomas.vondra 149 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1100)
1273 tomas.vondra 150 UIC 0 : old_11_check_for_sql_identifier_data_type_usage(&old_cluster);
151 :
152 : /*
2151 rhaas 153 ECB : * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
2151 rhaas 154 EUB : * hash indexes
155 : */
2265 tgl 156 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 906)
157 : {
2265 tgl 158 UIC 0 : old_9_6_check_for_unknown_data_type_usage(&old_cluster);
2151 rhaas 159 0 : if (user_opts.check)
2151 rhaas 160 LBC 0 : old_9_6_invalidate_hash_indexes(&old_cluster, true);
161 : }
2265 tgl 162 EUB :
2557 sfrost 163 : /* 9.5 and below should not have roles starting with pg_ */
2557 sfrost 164 GBC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 905)
2557 sfrost 165 UIC 0 : check_for_pg_role_prefix(&old_cluster);
166 :
3114 bruce 167 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) == 904 &&
3114 bruce 168 LBC 0 : old_cluster.controldata.cat_ver < JSONB_FORMAT_CHANGE_CAT_VER)
3114 bruce 169 UBC 0 : check_for_jsonb_9_4_usage(&old_cluster);
170 :
3252 bruce 171 ECB : /* Pre-PG 9.4 had a different 'line' data type internal format */
3252 bruce 172 GBC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 903)
3252 bruce 173 UBC 0 : old_9_3_check_for_line_data_type_usage(&old_cluster);
174 :
175 : /*
4715 bruce 176 ECB : * While not a check option, we do this now because this is the only time
4715 bruce 177 EUB : * the old server is running.
178 : */
4555 bruce 179 GIC 2 : if (!user_opts.check)
180 1 : generate_old_dump();
181 :
4715 182 2 : if (!live_check)
4367 bruce 183 CBC 2 : stop_postmaster(false);
4715 184 2 : }
185 :
4715 bruce 186 ECB :
187 : void
4555 bruce 188 CBC 2 : check_new_cluster(void)
189 : {
4373 bruce 190 GIC 2 : get_db_and_rel_infos(&new_cluster);
191 :
4373 bruce 192 CBC 2 : check_new_cluster_is_empty();
4715 bruce 193 ECB :
4555 bruce 194 GIC 2 : check_loadable_libraries();
4715 bruce 195 ECB :
1614 peter_e 196 GIC 2 : switch (user_opts.transfer_mode)
1614 peter_e 197 ECB : {
1614 peter_e 198 UIC 0 : case TRANSFER_MODE_CLONE:
1614 peter_e 199 LBC 0 : check_file_clone();
1614 peter_e 200 UIC 0 : break;
1614 peter_e 201 GBC 2 : case TRANSFER_MODE_COPY:
202 2 : break;
1614 peter_e 203 UBC 0 : case TRANSFER_MODE_LINK:
1614 peter_e 204 LBC 0 : check_hard_link();
205 0 : break;
1614 peter_e 206 EUB : }
3952 bruce 207 :
3170 bruce 208 GBC 2 : check_is_install_user(&new_cluster);
209 :
3952 bruce 210 GIC 2 : check_for_prepared_transactions(&new_cluster);
906 bruce 211 ECB :
906 bruce 212 GIC 2 : check_for_new_tablespace_dir(&new_cluster);
4715 bruce 213 CBC 2 : }
214 :
4715 bruce 215 ECB :
216 : void
4555 bruce 217 GIC 2 : report_clusters_compatible(void)
218 : {
219 2 : if (user_opts.check)
4715 bruce 220 ECB : {
271 tgl 221 GNC 1 : pg_log(PG_REPORT, "\n*Clusters are compatible*");
4715 bruce 222 ECB : /* stops new cluster */
4367 bruce 223 GIC 1 : stop_postmaster(false);
305 michael 224 ECB :
305 michael 225 GIC 1 : cleanup_output_dirs();
4386 peter_e 226 CBC 1 : exit(0);
227 : }
4715 bruce 228 ECB :
4555 bruce 229 CBC 1 : pg_log(PG_REPORT, "\n"
230 : "If pg_upgrade fails after this point, you must re-initdb the\n"
231 : "new cluster before continuing.");
4715 232 1 : }
233 :
234 :
4715 bruce 235 ECB : void
2119 bruce 236 GIC 1 : issue_warnings_and_set_wal_level(void)
237 : {
238 : /*
2118 tgl 239 ECB : * We unconditionally start/stop the new server because pg_resetwal -o set
240 : * wal_level to 'minimum'. If the user is upgrading standby servers using
241 : * the rsync instructions, they will need pg_upgrade to write its final
242 : * WAL record showing wal_level as 'replica'.
243 : */
2119 bruce 244 GIC 1 : start_postmaster(&new_cluster, true);
245 :
246 : /* Reindex hash indexes for old < 10.0 */
2151 rhaas 247 CBC 1 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 906)
2151 rhaas 248 UIC 0 : old_9_6_invalidate_hash_indexes(&new_cluster, false);
249 :
614 bruce 250 CBC 1 : report_extension_updates(&new_cluster);
614 bruce 251 EUB :
2119 bruce 252 GIC 1 : stop_postmaster(false);
4715 bruce 253 CBC 1 : }
254 :
4715 bruce 255 ECB :
256 : void
881 magnus 257 GIC 1 : output_completion_banner(char *deletion_script_file_name)
258 : {
259 : PQExpBufferData user_specification;
881 magnus 260 ECB :
881 magnus 261 GIC 1 : initPQExpBuffer(&user_specification);
262 1 : if (os_info.user_specified)
263 : {
881 magnus 264 LBC 0 : appendPQExpBufferStr(&user_specification, "-U ");
265 0 : appendShellString(&user_specification, os_info.user);
881 magnus 266 UIC 0 : appendPQExpBufferChar(&user_specification, ' ');
881 magnus 267 EUB : }
268 :
915 bruce 269 GBC 1 : pg_log(PG_REPORT,
270 : "Optimizer statistics are not transferred by pg_upgrade.\n"
271 : "Once you start the new server, consider running:\n"
272 : " %s/vacuumdb %s--all --analyze-in-stages", new_cluster.bindir, user_specification.data);
273 :
3706 bruce 274 GIC 1 : if (deletion_script_file_name)
275 1 : pg_log(PG_REPORT,
276 : "Running this script will delete the old cluster's data files:\n"
277 : " %s",
3706 bruce 278 ECB : deletion_script_file_name);
279 : else
3706 bruce 280 UIC 0 : pg_log(PG_REPORT,
281 : "Could not create a script to delete the old cluster's data files\n"
282 : "because user-defined tablespaces or the new cluster's data directory\n"
2495 rhaas 283 EUB : "exist in the old cluster directory. The old cluster's contents must\n"
284 : "be deleted manually.");
285 :
881 magnus 286 GIC 1 : termPQExpBuffer(&user_specification);
4715 bruce 287 1 : }
288 :
4715 bruce 289 ECB :
290 : void
4555 bruce 291 GIC 2 : check_cluster_versions(void)
292 : {
4309 293 2 : prep_status("Checking cluster versions");
4309 bruce 294 ECB :
295 : /* cluster versions should already have been obtained */
1970 tgl 296 CBC 2 : Assert(old_cluster.major_version != 0);
1970 tgl 297 GIC 2 : Assert(new_cluster.major_version != 0);
298 :
4382 bruce 299 ECB : /*
300 : * We allow upgrades from/to the same major version for alpha/beta
301 : * upgrades
302 : */
303 :
481 tgl 304 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) < 902)
271 tgl 305 UNC 0 : pg_fatal("This utility can only upgrade from PostgreSQL version %s and later.",
306 : "9.2");
4715 bruce 307 ECB :
4715 bruce 308 EUB : /* Only current PG version is supported as a target */
4555 bruce 309 GIC 2 : if (GET_MAJOR_VERSION(new_cluster.major_version) != GET_MAJOR_VERSION(PG_VERSION_NUM))
271 tgl 310 UNC 0 : pg_fatal("This utility can only upgrade to PostgreSQL version %s.",
311 : PG_MAJORVERSION);
4715 bruce 312 ECB :
4715 bruce 313 EUB : /*
314 : * We can't allow downgrading because we use the target pg_dump, and
315 : * pg_dump cannot operate on newer database versions, only current and
316 : * older versions.
317 : */
4555 bruce 318 GIC 2 : if (old_cluster.major_version > new_cluster.major_version)
271 tgl 319 UNC 0 : pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.");
320 :
4309 bruce 321 ECB : /* Ensure binaries match the designated data directories */
4309 bruce 322 GBC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) !=
4309 bruce 323 GIC 2 : GET_MAJOR_VERSION(old_cluster.bin_version))
271 tgl 324 UNC 0 : pg_fatal("Old cluster data and binary directories are from different major versions.");
4309 bruce 325 CBC 2 : if (GET_MAJOR_VERSION(new_cluster.major_version) !=
326 2 : GET_MAJOR_VERSION(new_cluster.bin_version))
271 tgl 327 UNC 0 : pg_fatal("New cluster data and binary directories are from different major versions.");
4309 bruce 328 ECB :
4309 bruce 329 CBC 2 : check_ok();
4715 bruce 330 GBC 2 : }
331 :
4715 bruce 332 ECB :
333 : void
4555 bruce 334 GIC 2 : check_cluster_compatibility(bool live_check)
335 : {
336 : /* get/check pg_control data of servers */
4555 bruce 337 CBC 2 : get_control_data(&old_cluster, live_check);
4555 bruce 338 GIC 2 : get_control_data(&new_cluster, false);
339 2 : check_control_data(&old_cluster.controldata, &new_cluster.controldata);
4715 bruce 340 ECB :
3870 bruce 341 CBC 2 : if (live_check && old_cluster.port == new_cluster.port)
3477 peter_e 342 LBC 0 : pg_fatal("When checking a live server, "
343 : "the old and new port numbers must be different.");
4715 bruce 344 GIC 2 : }
345 :
346 :
4715 bruce 347 EUB : static void
4373 bruce 348 GBC 2 : check_new_cluster_is_empty(void)
4715 bruce 349 EUB : {
350 : int dbnum;
351 :
4555 bruce 352 GIC 6 : for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
353 : {
354 : int relnum;
355 4 : RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
356 :
4715 357 12 : for (relnum = 0; relnum < rel_arr->nrels;
4715 bruce 358 CBC 8 : relnum++)
359 : {
360 : /* pg_largeobject and its index should be skipped */
4715 bruce 361 GIC 8 : if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
271 tgl 362 UNC 0 : pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"",
1787 peter_e 363 UBC 0 : new_cluster.dbarr.dbs[dbnum].db_name,
364 0 : rel_arr->rels[relnum].nspname,
1787 peter_e 365 UIC 0 : rel_arr->rels[relnum].relname);
366 : }
4715 bruce 367 EUB : }
3103 heikki.linnakangas 368 GIC 2 : }
369 :
370 : /*
906 bruce 371 EUB : * A previous run of pg_upgrade might have failed and the new cluster
372 : * directory recreated, but they might have forgotten to remove
373 : * the new cluster's tablespace directories. Therefore, check that
374 : * new cluster tablespace directories do not already exist. If
375 : * they do, it would cause an error while restoring global objects.
376 : * This allows the failure to be detected at check time, rather than
377 : * during schema restore.
378 : */
379 : static void
906 bruce 380 GBC 2 : check_for_new_tablespace_dir(ClusterInfo *new_cluster)
906 bruce 381 EUB : {
382 : int tblnum;
383 : char new_tablespace_dir[MAXPGPATH];
384 :
906 bruce 385 GIC 2 : prep_status("Checking for new cluster tablespace directories");
906 bruce 386 EUB :
906 bruce 387 GIC 2 : for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
388 : {
389 : struct stat statbuf;
390 :
906 bruce 391 UIC 0 : snprintf(new_tablespace_dir, MAXPGPATH, "%s%s",
697 tgl 392 UBC 0 : os_info.old_tablespaces[tblnum],
697 tgl 393 EUB : new_cluster->tablespace_suffix);
394 :
906 bruce 395 UBC 0 : if (stat(new_tablespace_dir, &statbuf) == 0 || errno != ENOENT)
271 tgl 396 UNC 0 : pg_fatal("new cluster tablespace directory already exists: \"%s\"",
397 : new_tablespace_dir);
398 : }
906 bruce 399 ECB :
906 bruce 400 GIC 2 : check_ok();
401 2 : }
906 bruce 402 ECB :
4715 bruce 403 EUB : /*
404 : * create_script_for_old_cluster_deletion()
405 : *
406 : * This is particularly useful for tablespace deletion.
4715 bruce 407 ECB : */
408 : void
4309 bruce 409 GIC 1 : create_script_for_old_cluster_deletion(char **deletion_script_file_name)
410 : {
4715 411 1 : FILE *script = NULL;
412 : int tblnum;
413 : char old_cluster_pgdata[MAXPGPATH],
414 : new_cluster_pgdata[MAXPGPATH];
415 :
3102 416 1 : *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
417 : SCRIPT_PREFIX, SCRIPT_EXT);
4715 bruce 418 ECB :
2607 bruce 419 GIC 1 : strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
420 1 : canonicalize_path(old_cluster_pgdata);
2607 bruce 421 ECB :
2607 bruce 422 GIC 1 : strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
2607 bruce 423 CBC 1 : canonicalize_path(new_cluster_pgdata);
424 :
425 : /* Some people put the new data directory inside the old one. */
426 1 : if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
427 : {
2607 bruce 428 UIC 0 : pg_log(PG_WARNING,
429 : "\nWARNING: new data directory should not be inside the old data directory, i.e. %s", old_cluster_pgdata);
430 :
431 : /* Unlink file in case it is left over from a previous run. */
432 0 : unlink(*deletion_script_file_name);
433 0 : pg_free(*deletion_script_file_name);
434 0 : *deletion_script_file_name = NULL;
435 0 : return;
436 : }
2607 bruce 437 ECB :
3706 438 : /*
3602 bruce 439 EUB : * Some users (oddly) create tablespaces inside the cluster data
440 : * directory. We can't create a proper old cluster delete script in that
441 : * case.
3706 bruce 442 ECB : */
3706 bruce 443 GIC 1 : for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
3706 bruce 444 ECB : {
445 : char old_tablespace_dir[MAXPGPATH];
446 :
3706 bruce 447 UIC 0 : strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
448 0 : canonicalize_path(old_tablespace_dir);
3706 bruce 449 LBC 0 : if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
3706 bruce 450 EUB : {
451 : /* reproduce warning from CREATE TABLESPACE that is in the log */
2903 bruce 452 UIC 0 : pg_log(PG_WARNING,
453 : "\nWARNING: user-defined tablespace locations should not be inside the data directory, i.e. %s", old_tablespace_dir);
454 :
455 : /* Unlink file in case it is left over from a previous run. */
3706 456 0 : unlink(*deletion_script_file_name);
3706 bruce 457 LBC 0 : pg_free(*deletion_script_file_name);
3706 bruce 458 UBC 0 : *deletion_script_file_name = NULL;
3706 bruce 459 UIC 0 : return;
3706 bruce 460 ECB : }
461 : }
462 :
3706 bruce 463 GIC 1 : prep_status("Creating script to delete old cluster");
3706 bruce 464 ECB :
4045 bruce 465 CBC 1 : if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
271 tgl 466 UNC 0 : pg_fatal("could not open file \"%s\": %s",
2382 tgl 467 UIC 0 : *deletion_script_file_name, strerror(errno));
468 :
469 : #ifndef WIN32
470 : /* add shebang header */
4715 bruce 471 GIC 1 : fprintf(script, "#!/bin/sh\n\n");
472 : #endif
473 :
474 : /* delete old cluster's default tablespace */
2890 475 1 : fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
2890 bruce 476 ECB : fix_path_separator(old_cluster.pgdata), PATH_QUOTE);
477 :
478 : /* delete old cluster's alternate tablespaces */
3742 bruce 479 GIC 1 : for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
480 : {
481 : /*
482 : * Do the old cluster's per-database directories share a directory
483 : * with a new version-specific tablespace?
4715 bruce 484 ECB : */
4555 bruce 485 UIC 0 : if (strlen(old_cluster.tablespace_suffix) == 0)
486 : {
4715 bruce 487 ECB : /* delete per-database directories */
488 : int dbnum;
489 :
4715 bruce 490 UIC 0 : fprintf(script, "\n");
491 :
4177 492 0 : for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
727 peter 493 LBC 0 : fprintf(script, RMDIR_CMD " %c%s%c%u%c\n", PATH_QUOTE,
3742 bruce 494 UIC 0 : fix_path_separator(os_info.old_tablespaces[tblnum]),
2890 495 0 : PATH_SEPARATOR, old_cluster.dbarr.dbs[dbnum].db_oid,
2890 bruce 496 ECB : PATH_QUOTE);
497 : }
498 : else
499 : {
3260 bruce 500 LBC 0 : char *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
4660 bruce 501 ECB :
502 : /*
4715 503 : * Simply delete the tablespace directory, which might be ".old"
504 : * or a version-specific subdirectory.
505 : */
2890 bruce 506 LBC 0 : fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
3602 507 0 : fix_path_separator(os_info.old_tablespaces[tblnum]),
508 : fix_path_separator(suffix_path), PATH_QUOTE);
3343 509 0 : pfree(suffix_path);
510 : }
511 : }
4715 bruce 512 ECB :
4715 bruce 513 GBC 1 : fclose(script);
514 :
515 : #ifndef WIN32
4715 bruce 516 GIC 1 : if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
271 tgl 517 UNC 0 : pg_fatal("could not add execute permission to file \"%s\": %s",
2382 tgl 518 UIC 0 : *deletion_script_file_name, strerror(errno));
519 : #endif
520 :
4555 bruce 521 GIC 1 : check_ok();
4715 bruce 522 ECB : }
523 :
4641 bruce 524 EUB :
4355 525 : /*
3170 526 : * check_is_install_user()
527 : *
528 : * Check we are the install user, and that the new cluster
529 : * has no other users.
530 : */
531 : static void
3170 bruce 532 GIC 4 : check_is_install_user(ClusterInfo *cluster)
4355 bruce 533 ECB : {
534 : PGresult *res;
4355 bruce 535 CBC 4 : PGconn *conn = connectToServer(cluster, "template1");
536 :
3170 537 4 : prep_status("Checking database user is the install user");
538 :
4355 bruce 539 EUB : /* Can't use pg_authid because only superusers can view it. */
4355 bruce 540 GBC 4 : res = executeQueryOrDie(conn,
3952 bruce 541 EUB : "SELECT rolsuper, oid "
542 : "FROM pg_catalog.pg_roles "
543 : "WHERE rolname = current_user "
544 : "AND rolname !~ '^pg_'");
545 :
546 : /*
547 : * We only allow the install user in the new cluster (see comment below)
548 : * and we preserve pg_authid.oid, so this must be the install user in the
549 : * old cluster too.
3170 bruce 550 ECB : */
3170 bruce 551 CBC 4 : if (PQntuples(res) != 1 ||
3170 bruce 552 GIC 4 : atooid(PQgetvalue(res, 0, 1)) != BOOTSTRAP_SUPERUSERID)
271 tgl 553 UNC 0 : pg_fatal("database user \"%s\" is not the install user",
554 : os_info.user);
555 :
3952 bruce 556 GIC 4 : PQclear(res);
557 :
558 4 : res = executeQueryOrDie(conn,
559 : "SELECT COUNT(*) "
560 : "FROM pg_catalog.pg_roles "
2557 sfrost 561 ECB : "WHERE rolname !~ '^pg_'");
562 :
3952 bruce 563 GIC 4 : if (PQntuples(res) != 1)
271 tgl 564 UNC 0 : pg_fatal("could not determine the number of users");
565 :
3170 bruce 566 ECB : /*
567 : * We only allow the install user in the new cluster because other defined
568 : * users might match users defined in the old cluster and generate an
569 : * error during pg_dump restore.
570 : */
19 dgustafsson 571 GNC 4 : if (cluster == &new_cluster && strcmp(PQgetvalue(res, 0, 0), "1") != 0)
271 tgl 572 UNC 0 : pg_fatal("Only the install user can be defined in the new cluster.");
573 :
4355 bruce 574 GBC 4 : PQclear(res);
4355 bruce 575 EUB :
4355 bruce 576 GIC 4 : PQfinish(conn);
4353 bruce 577 EUB :
4353 bruce 578 GIC 4 : check_ok();
4355 579 4 : }
4355 bruce 580 ECB :
581 :
381 dgustafsson 582 : /*
583 : * check_proper_datallowconn
584 : *
585 : * Ensure that all non-template0 databases allow connections since they
586 : * otherwise won't be restored; and that template0 explicitly doesn't allow
587 : * connections since it would make pg_dumpall --globals restore fail.
588 : */
589 : static void
2885 bruce 590 GIC 2 : check_proper_datallowconn(ClusterInfo *cluster)
591 : {
592 : int dbnum;
593 : PGconn *conn_template1;
594 : PGresult *dbres;
595 : int ntups;
2885 bruce 596 ECB : int i_datname;
597 : int i_datallowconn;
381 dgustafsson 598 GIC 2 : FILE *script = NULL;
381 dgustafsson 599 ECB : char output_path[MAXPGPATH];
600 :
2885 bruce 601 CBC 2 : prep_status("Checking database connection settings");
602 :
381 dgustafsson 603 2 : snprintf(output_path, sizeof(output_path), "%s/%s",
381 dgustafsson 604 ECB : log_opts.basedir,
605 : "databases_with_datallowconn_false.txt");
606 :
2885 bruce 607 CBC 2 : conn_template1 = connectToServer(cluster, "template1");
2885 bruce 608 ECB :
609 : /* get database names */
2885 bruce 610 GIC 2 : dbres = executeQueryOrDie(conn_template1,
2885 bruce 611 EUB : "SELECT datname, datallowconn "
612 : "FROM pg_catalog.pg_database");
613 :
2885 bruce 614 GIC 2 : i_datname = PQfnumber(dbres, "datname");
2885 bruce 615 GBC 2 : i_datallowconn = PQfnumber(dbres, "datallowconn");
616 :
2885 bruce 617 GIC 2 : ntups = PQntuples(dbres);
2885 bruce 618 GBC 16 : for (dbnum = 0; dbnum < ntups; dbnum++)
619 : {
2885 bruce 620 GIC 14 : char *datname = PQgetvalue(dbres, dbnum, i_datname);
621 14 : char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
622 :
2885 bruce 623 GBC 14 : if (strcmp(datname, "template0") == 0)
2885 bruce 624 EUB : {
625 : /* avoid restore failure when pg_dumpall tries to create template0 */
2885 bruce 626 GIC 2 : if (strcmp(datallowconn, "t") == 0)
2885 bruce 627 UBC 0 : pg_fatal("template0 must not allow connections, "
628 : "i.e. its pg_database.datallowconn must be false");
629 : }
630 : else
631 : {
632 : /*
633 : * avoid datallowconn == false databases from being skipped on
2878 bruce 634 EUB : * restore
635 : */
2885 bruce 636 GBC 12 : if (strcmp(datallowconn, "f") == 0)
381 dgustafsson 637 EUB : {
381 dgustafsson 638 UBC 0 : if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
271 tgl 639 UNC 0 : pg_fatal("could not open file \"%s\": %s",
381 dgustafsson 640 UBC 0 : output_path, strerror(errno));
381 dgustafsson 641 EUB :
381 dgustafsson 642 UIC 0 : fprintf(script, "%s\n", datname);
381 dgustafsson 643 EUB : }
2885 bruce 644 : }
645 : }
646 :
2885 bruce 647 GIC 2 : PQclear(dbres);
648 :
649 2 : PQfinish(conn_template1);
650 :
381 dgustafsson 651 GBC 2 : if (script)
652 : {
221 dgustafsson 653 UNC 0 : fclose(script);
271 tgl 654 0 : pg_log(PG_REPORT, "fatal");
381 dgustafsson 655 UIC 0 : pg_fatal("All non-template0 databases must allow connections, i.e. their\n"
381 dgustafsson 656 EUB : "pg_database.datallowconn must be true. Your installation contains\n"
657 : "non-template0 databases with their pg_database.datallowconn set to\n"
658 : "false. Consider allowing connection for all non-template0 databases\n"
659 : "or drop the databases which do not allow connections. A list of\n"
660 : "databases with the problem is in the file:\n"
661 : " %s", output_path);
662 : }
663 : else
381 dgustafsson 664 GIC 2 : check_ok();
2885 bruce 665 2 : }
666 :
2885 bruce 667 EUB :
668 : /*
669 : * check_for_prepared_transactions()
670 : *
671 : * Make sure there are no prepared transactions because the storage format
672 : * might have changed.
673 : */
4317 674 : static void
4317 bruce 675 GIC 4 : check_for_prepared_transactions(ClusterInfo *cluster)
676 : {
4317 bruce 677 EUB : PGresult *res;
4317 bruce 678 GIC 4 : PGconn *conn = connectToServer(cluster, "template1");
679 :
4317 bruce 680 GBC 4 : prep_status("Checking for prepared transactions");
681 :
682 4 : res = executeQueryOrDie(conn,
683 : "SELECT * "
684 : "FROM pg_catalog.pg_prepared_xacts");
685 :
4317 bruce 686 GIC 4 : if (PQntuples(res) != 0)
2095 alvherre 687 EUB : {
2095 alvherre 688 UIC 0 : if (cluster == &old_cluster)
271 tgl 689 UNC 0 : pg_fatal("The source cluster contains prepared transactions");
2095 alvherre 690 EUB : else
271 tgl 691 UNC 0 : pg_fatal("The target cluster contains prepared transactions");
692 : }
693 :
4317 bruce 694 GIC 4 : PQclear(res);
695 :
696 4 : PQfinish(conn);
697 :
4317 bruce 698 GBC 4 : check_ok();
699 4 : }
700 :
701 :
702 : /*
703 : * check_for_isn_and_int8_passing_mismatch()
704 : *
705 : * contrib/isn relies on data type int8, and in 8.4 int8 can now be passed
706 : * by value. The schema dumps the CREATE TYPE PASSEDBYVALUE setting so
4641 bruce 707 EUB : * it must match for the old and new servers.
708 : */
709 : static void
4481 bruce 710 GIC 2 : check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
711 : {
712 : int dbnum;
4641 713 2 : FILE *script = NULL;
714 : char output_path[MAXPGPATH];
715 :
4343 peter_e 716 2 : prep_status("Checking for contrib/isn with bigint-passing mismatch");
717 :
4555 bruce 718 2 : if (old_cluster.controldata.float8_pass_by_value ==
719 2 : new_cluster.controldata.float8_pass_by_value)
720 : {
4641 bruce 721 EUB : /* no mismatch */
4555 bruce 722 GBC 2 : check_ok();
4641 723 2 : return;
4641 bruce 724 EUB : }
725 :
427 michael 726 UBC 0 : snprintf(output_path, sizeof(output_path), "%s/%s",
427 michael 727 EUB : log_opts.basedir,
728 : "contrib_isn_and_int8_pass_by_value.txt");
4641 bruce 729 :
4481 bruce 730 UBC 0 : for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
4641 bruce 731 EUB : {
732 : PGresult *res;
4641 bruce 733 UBC 0 : bool db_used = false;
734 : int ntups;
4641 bruce 735 EUB : int rowno;
736 : int i_nspname,
737 : i_proname;
4481 bruce 738 UBC 0 : DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
4481 bruce 739 UIC 0 : PGconn *conn = connectToServer(cluster, active_db->db_name);
740 :
741 : /* Find any functions coming from contrib/isn */
4555 742 0 : res = executeQueryOrDie(conn,
743 : "SELECT n.nspname, p.proname "
744 : "FROM pg_catalog.pg_proc p, "
745 : " pg_catalog.pg_namespace n "
4641 bruce 746 EUB : "WHERE p.pronamespace = n.oid AND "
747 : " p.probin = '$libdir/isn'");
748 :
4641 bruce 749 UIC 0 : ntups = PQntuples(res);
750 0 : i_nspname = PQfnumber(res, "nspname");
4641 bruce 751 UBC 0 : i_proname = PQfnumber(res, "proname");
4641 bruce 752 UIC 0 : for (rowno = 0; rowno < ntups; rowno++)
4641 bruce 753 EUB : {
4045 bruce 754 UBC 0 : if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
271 tgl 755 UNC 0 : pg_fatal("could not open file \"%s\": %s",
2382 tgl 756 UIC 0 : output_path, strerror(errno));
4641 bruce 757 0 : if (!db_used)
758 : {
1279 759 0 : fprintf(script, "In database: %s\n", active_db->db_name);
4641 760 0 : db_used = true;
4641 bruce 761 EUB : }
4641 bruce 762 UBC 0 : fprintf(script, " %s.%s\n",
763 : PQgetvalue(res, rowno, i_nspname),
764 : PQgetvalue(res, rowno, i_proname));
765 : }
766 :
4641 bruce 767 UIC 0 : PQclear(res);
768 :
769 0 : PQfinish(conn);
770 : }
4641 bruce 771 EUB :
4415 bruce 772 UIC 0 : if (script)
773 : {
221 dgustafsson 774 UNC 0 : fclose(script);
271 tgl 775 0 : pg_log(PG_REPORT, "fatal");
3477 peter_e 776 UBC 0 : pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
777 : "bigint data type. Your old and new clusters pass bigint values\n"
2118 tgl 778 EUB : "differently so this cluster cannot currently be upgraded. You can\n"
779 : "manually dump databases in the old cluster that use \"contrib/isn\"\n"
780 : "facilities, drop them, perform the upgrade, and then restore them. A\n"
781 : "list of the problem functions is in the file:\n"
782 : " %s", output_path);
4641 bruce 783 : }
784 : else
4555 bruce 785 UBC 0 : check_ok();
786 : }
787 :
788 : /*
789 : * Verify that no user defined postfix operators exist.
934 tgl 790 EUB : */
791 : static void
934 tgl 792 UIC 0 : check_for_user_defined_postfix_ops(ClusterInfo *cluster)
793 : {
794 : int dbnum;
934 tgl 795 UBC 0 : FILE *script = NULL;
796 : char output_path[MAXPGPATH];
797 :
934 tgl 798 UIC 0 : prep_status("Checking for user-defined postfix operators");
799 :
427 michael 800 0 : snprintf(output_path, sizeof(output_path), "%s/%s",
427 michael 801 EUB : log_opts.basedir,
802 : "postfix_ops.txt");
934 tgl 803 :
804 : /* Find any user defined postfix operators */
934 tgl 805 UBC 0 : for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
806 : {
807 : PGresult *res;
934 tgl 808 UIC 0 : bool db_used = false;
809 : int ntups;
810 : int rowno;
811 : int i_oproid,
812 : i_oprnsp,
813 : i_oprname,
814 : i_typnsp,
815 : i_typname;
934 tgl 816 UBC 0 : DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
934 tgl 817 UIC 0 : PGconn *conn = connectToServer(cluster, active_db->db_name);
818 :
819 : /*
820 : * The query below hardcodes FirstNormalObjectId as 16384 rather than
821 : * interpolating that C #define into the query because, if that
822 : * #define is ever changed, the cutoff we want to use is the value
823 : * used by pre-version 14 servers, not that of some future version.
824 : */
825 0 : res = executeQueryOrDie(conn,
826 : "SELECT o.oid AS oproid, "
827 : " n.nspname AS oprnsp, "
828 : " o.oprname, "
829 : " tn.nspname AS typnsp, "
830 : " t.typname "
831 : "FROM pg_catalog.pg_operator o, "
832 : " pg_catalog.pg_namespace n, "
833 : " pg_catalog.pg_type t, "
834 : " pg_catalog.pg_namespace tn "
835 : "WHERE o.oprnamespace = n.oid AND "
836 : " o.oprleft = t.oid AND "
837 : " t.typnamespace = tn.oid AND "
838 : " o.oprright = 0 AND "
839 : " o.oid >= 16384");
840 0 : ntups = PQntuples(res);
841 0 : i_oproid = PQfnumber(res, "oproid");
842 0 : i_oprnsp = PQfnumber(res, "oprnsp");
843 0 : i_oprname = PQfnumber(res, "oprname");
844 0 : i_typnsp = PQfnumber(res, "typnsp");
845 0 : i_typname = PQfnumber(res, "typname");
846 0 : for (rowno = 0; rowno < ntups; rowno++)
934 tgl 847 EUB : {
934 tgl 848 UBC 0 : if (script == NULL &&
849 0 : (script = fopen_priv(output_path, "w")) == NULL)
271 tgl 850 UNC 0 : pg_fatal("could not open file \"%s\": %s",
934 tgl 851 UBC 0 : output_path, strerror(errno));
934 tgl 852 UIC 0 : if (!db_used)
934 tgl 853 EUB : {
934 tgl 854 UBC 0 : fprintf(script, "In database: %s\n", active_db->db_name);
855 0 : db_used = true;
934 tgl 856 EUB : }
934 tgl 857 UBC 0 : fprintf(script, " (oid=%s) %s.%s (%s.%s, NONE)\n",
858 : PQgetvalue(res, rowno, i_oproid),
934 tgl 859 EUB : PQgetvalue(res, rowno, i_oprnsp),
860 : PQgetvalue(res, rowno, i_oprname),
861 : PQgetvalue(res, rowno, i_typnsp),
862 : PQgetvalue(res, rowno, i_typname));
863 : }
864 :
934 tgl 865 UIC 0 : PQclear(res);
866 :
867 0 : PQfinish(conn);
934 tgl 868 EUB : }
869 :
934 tgl 870 UIC 0 : if (script)
934 tgl 871 EUB : {
221 dgustafsson 872 UNC 0 : fclose(script);
271 tgl 873 0 : pg_log(PG_REPORT, "fatal");
934 tgl 874 UBC 0 : pg_fatal("Your installation contains user-defined postfix operators, which are not\n"
875 : "supported anymore. Consider dropping the postfix operators and replacing\n"
876 : "them with prefix operators or function calls.\n"
877 : "A list of user-defined postfix operators is in the file:\n"
878 : " %s", output_path);
879 : }
880 : else
934 tgl 881 UIC 0 : check_ok();
882 0 : }
4641 bruce 883 EUB :
884 : /*
278 tgl 885 : * check_for_incompatible_polymorphics()
886 : *
887 : * Make sure nothing is using old polymorphic functions with
888 : * anyarray/anyelement rather than the new anycompatible variants.
889 : */
890 : static void
278 tgl 891 UIC 0 : check_for_incompatible_polymorphics(ClusterInfo *cluster)
278 tgl 892 EUB : {
893 : PGresult *res;
278 tgl 894 UIC 0 : FILE *script = NULL;
278 tgl 895 EUB : char output_path[MAXPGPATH];
896 : PQExpBufferData old_polymorphics;
897 :
278 tgl 898 UBC 0 : prep_status("Checking for incompatible polymorphic functions");
899 :
900 0 : snprintf(output_path, sizeof(output_path), "%s/%s",
901 : log_opts.basedir,
902 : "incompatible_polymorphics.txt");
903 :
904 : /* The set of problematic functions varies a bit in different versions */
905 0 : initPQExpBuffer(&old_polymorphics);
906 :
278 tgl 907 UIC 0 : appendPQExpBufferStr(&old_polymorphics,
278 tgl 908 EUB : "'array_append(anyarray,anyelement)'"
909 : ", 'array_cat(anyarray,anyarray)'"
910 : ", 'array_prepend(anyelement,anyarray)'");
911 :
278 tgl 912 UIC 0 : if (GET_MAJOR_VERSION(cluster->major_version) >= 903)
278 tgl 913 UBC 0 : appendPQExpBufferStr(&old_polymorphics,
278 tgl 914 EUB : ", 'array_remove(anyarray,anyelement)'"
915 : ", 'array_replace(anyarray,anyelement,anyelement)'");
916 :
278 tgl 917 UIC 0 : if (GET_MAJOR_VERSION(cluster->major_version) >= 905)
918 0 : appendPQExpBufferStr(&old_polymorphics,
919 : ", 'array_position(anyarray,anyelement)'"
920 : ", 'array_position(anyarray,anyelement,integer)'"
921 : ", 'array_positions(anyarray,anyelement)'"
922 : ", 'width_bucket(anyelement,anyarray)'");
923 :
278 tgl 924 UBC 0 : for (int dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
278 tgl 925 EUB : {
278 tgl 926 UBC 0 : bool db_used = false;
927 0 : DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
278 tgl 928 UIC 0 : PGconn *conn = connectToServer(cluster, active_db->db_name);
278 tgl 929 EUB : int ntups;
930 : int i_objkind,
931 : i_objname;
932 :
933 : /*
934 : * The query below hardcodes FirstNormalObjectId as 16384 rather than
935 : * interpolating that C #define into the query because, if that
936 : * #define is ever changed, the cutoff we want to use is the value
937 : * used by pre-version 14 servers, not that of some future version.
938 : */
278 tgl 939 UIC 0 : res = executeQueryOrDie(conn,
940 : /* Aggregate transition functions */
941 : "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
278 tgl 942 EUB : "FROM pg_proc AS p "
943 : "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
944 : "JOIN pg_proc AS transfn ON transfn.oid=a.aggtransfn "
945 : "WHERE p.oid >= 16384 "
946 : "AND a.aggtransfn = ANY(ARRAY[%s]::regprocedure[]) "
947 : "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
948 :
949 : /* Aggregate final functions */
950 : "UNION ALL "
951 : "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
952 : "FROM pg_proc AS p "
953 : "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
954 : "JOIN pg_proc AS finalfn ON finalfn.oid=a.aggfinalfn "
955 : "WHERE p.oid >= 16384 "
956 : "AND a.aggfinalfn = ANY(ARRAY[%s]::regprocedure[]) "
957 : "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
958 :
959 : /* Operators */
960 : "UNION ALL "
961 : "SELECT 'operator' AS objkind, op.oid::regoperator::text AS objname "
962 : "FROM pg_operator AS op "
963 : "WHERE op.oid >= 16384 "
964 : "AND oprcode = ANY(ARRAY[%s]::regprocedure[]) "
965 : "AND oprleft = ANY(ARRAY['anyarray', 'anyelement']::regtype[]);",
966 : old_polymorphics.data,
967 : old_polymorphics.data,
968 : old_polymorphics.data);
969 :
278 tgl 970 UIC 0 : ntups = PQntuples(res);
971 :
278 tgl 972 LBC 0 : i_objkind = PQfnumber(res, "objkind");
278 tgl 973 UIC 0 : i_objname = PQfnumber(res, "objname");
974 :
975 0 : for (int rowno = 0; rowno < ntups; rowno++)
976 : {
977 0 : if (script == NULL &&
978 0 : (script = fopen_priv(output_path, "w")) == NULL)
271 tgl 979 UNC 0 : pg_fatal("could not open file \"%s\": %s",
278 tgl 980 UIC 0 : output_path, strerror(errno));
278 tgl 981 LBC 0 : if (!db_used)
982 : {
278 tgl 983 UIC 0 : fprintf(script, "In database: %s\n", active_db->db_name);
984 0 : db_used = true;
985 : }
986 :
987 0 : fprintf(script, " %s: %s\n",
988 : PQgetvalue(res, rowno, i_objkind),
989 : PQgetvalue(res, rowno, i_objname));
990 : }
991 :
992 0 : PQclear(res);
993 0 : PQfinish(conn);
994 : }
995 :
278 tgl 996 LBC 0 : if (script)
997 : {
998 0 : fclose(script);
271 tgl 999 UNC 0 : pg_log(PG_REPORT, "fatal");
278 tgl 1000 UIC 0 : pg_fatal("Your installation contains user-defined objects that refer to internal\n"
1001 : "polymorphic functions with arguments of type \"anyarray\" or \"anyelement\".\n"
1002 : "These user-defined objects must be dropped before upgrading and restored\n"
278 tgl 1003 ECB : "afterwards, changing them to refer to the new corresponding functions with\n"
1004 : "arguments of type \"anycompatiblearray\" and \"anycompatible\".\n"
1005 : "A list of the problematic objects is in the file:\n"
1006 : " %s", output_path);
1007 : }
1008 : else
278 tgl 1009 UBC 0 : check_ok();
278 tgl 1010 EUB :
278 tgl 1011 UIC 0 : termPQExpBuffer(&old_polymorphics);
1012 0 : }
1013 :
1014 : /*
1015 : * Verify that no tables are declared WITH OIDS.
1016 : */
1017 : static void
1601 andres 1018 LBC 0 : check_for_tables_with_oids(ClusterInfo *cluster)
1601 andres 1019 ECB : {
1020 : int dbnum;
1601 andres 1021 UIC 0 : FILE *script = NULL;
1022 : char output_path[MAXPGPATH];
1023 :
1441 alvherre 1024 0 : prep_status("Checking for tables WITH OIDS");
1025 :
427 michael 1026 0 : snprintf(output_path, sizeof(output_path), "%s/%s",
1027 : log_opts.basedir,
1028 : "tables_with_oids.txt");
1029 :
1030 : /* Find any tables declared WITH OIDS */
1601 andres 1031 0 : for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1601 andres 1032 ECB : {
1033 : PGresult *res;
1601 andres 1034 UIC 0 : bool db_used = false;
1035 : int ntups;
1036 : int rowno;
1601 andres 1037 ECB : int i_nspname,
1038 : i_relname;
1601 andres 1039 LBC 0 : DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1601 andres 1040 UIC 0 : PGconn *conn = connectToServer(cluster, active_db->db_name);
1041 :
1042 0 : res = executeQueryOrDie(conn,
1043 : "SELECT n.nspname, c.relname "
1044 : "FROM pg_catalog.pg_class c, "
1045 : " pg_catalog.pg_namespace n "
1046 : "WHERE c.relnamespace = n.oid AND "
1601 andres 1047 ECB : " c.relhasoids AND"
1048 : " n.nspname NOT IN ('pg_catalog')");
1049 :
1601 andres 1050 UIC 0 : ntups = PQntuples(res);
1051 0 : i_nspname = PQfnumber(res, "nspname");
1052 0 : i_relname = PQfnumber(res, "relname");
1053 0 : for (rowno = 0; rowno < ntups; rowno++)
1054 : {
1055 0 : if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
271 tgl 1056 UNC 0 : pg_fatal("could not open file \"%s\": %s",
1601 andres 1057 UIC 0 : output_path, strerror(errno));
1058 0 : if (!db_used)
1059 : {
1279 bruce 1060 0 : fprintf(script, "In database: %s\n", active_db->db_name);
1601 andres 1061 0 : db_used = true;
1062 : }
1063 0 : fprintf(script, " %s.%s\n",
1064 : PQgetvalue(res, rowno, i_nspname),
1065 : PQgetvalue(res, rowno, i_relname));
1601 andres 1066 ECB : }
1067 :
1601 andres 1068 UBC 0 : PQclear(res);
1601 andres 1069 EUB :
1601 andres 1070 UIC 0 : PQfinish(conn);
1071 : }
1072 :
1073 0 : if (script)
1601 andres 1074 ECB : {
221 dgustafsson 1075 UNC 0 : fclose(script);
271 tgl 1076 0 : pg_log(PG_REPORT, "fatal");
1229 bruce 1077 UIC 0 : pg_fatal("Your installation contains tables declared WITH OIDS, which is not\n"
1078 : "supported anymore. Consider removing the oid column using\n"
1079 : " ALTER TABLE ... SET WITHOUT OIDS;\n"
1080 : "A list of tables with the problem is in the file:\n"
1081 : " %s", output_path);
1082 : }
1083 : else
1601 andres 1084 UBC 0 : check_ok();
1601 andres 1085 UIC 0 : }
1086 :
1087 :
710 tgl 1088 EUB : /*
1089 : * check_for_composite_data_type_usage()
1090 : * Check for system-defined composite types used in user tables.
1091 : *
1092 : * The OIDs of rowtypes of system catalogs and information_schema views
1093 : * can change across major versions; unlike user-defined types, we have
1094 : * no mechanism for forcing them to be the same in the new cluster.
1095 : * Hence, if any user table uses one, that's problematic for pg_upgrade.
1096 : */
1097 : static void
710 tgl 1098 GIC 2 : check_for_composite_data_type_usage(ClusterInfo *cluster)
1099 : {
1100 : bool found;
1101 : Oid firstUserOid;
1102 : char output_path[MAXPGPATH];
710 tgl 1103 EUB : char *base_query;
1104 :
710 tgl 1105 GIC 2 : prep_status("Checking for system-defined composite types in user tables");
1106 :
208 michael 1107 2 : snprintf(output_path, sizeof(output_path), "%s/%s",
1108 : log_opts.basedir,
1109 : "tables_using_composite.txt");
1110 :
1111 : /*
710 tgl 1112 EUB : * Look for composite types that were made during initdb *or* belong to
1113 : * information_schema; that's important in case information_schema was
1114 : * dropped and reloaded.
1115 : *
1116 : * The cutoff OID here should match the source cluster's value of
1117 : * FirstNormalObjectId. We hardcode it rather than using that C #define
1118 : * because, if that #define is ever changed, our own version's value is
1119 : * NOT what to use. Eventually we may need a test on the source cluster's
1120 : * version to select the correct value.
1121 : */
710 tgl 1122 GBC 2 : firstUserOid = 16384;
1123 :
1124 2 : base_query = psprintf("SELECT t.oid FROM pg_catalog.pg_type t "
710 tgl 1125 EUB : "LEFT JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid "
1126 : " WHERE typtype = 'c' AND (t.oid < %u OR nspname = 'information_schema')",
1127 : firstUserOid);
1128 :
710 tgl 1129 GIC 2 : found = check_for_data_types_usage(cluster, base_query, output_path);
1130 :
1131 2 : free(base_query);
1132 :
710 tgl 1133 GBC 2 : if (found)
710 tgl 1134 EUB : {
271 tgl 1135 UNC 0 : pg_log(PG_REPORT, "fatal");
710 tgl 1136 UIC 0 : pg_fatal("Your installation contains system-defined composite type(s) in user tables.\n"
1137 : "These type OIDs are not stable across PostgreSQL versions,\n"
1138 : "so this cluster cannot currently be upgraded. You can\n"
1139 : "drop the problem columns and restart the upgrade.\n"
1140 : "A list of the problem columns is in the file:\n"
1141 : " %s", output_path);
710 tgl 1142 EUB : }
1143 : else
710 tgl 1144 GIC 2 : check_ok();
710 tgl 1145 GBC 2 : }
1146 :
1147 : /*
1148 : * check_for_reg_data_type_usage()
4641 bruce 1149 EUB : * pg_upgrade only preserves these system values:
1150 : * pg_class.oid
1151 : * pg_type.oid
1152 : * pg_enum.oid
1153 : *
4143 1154 : * Many of the reg* data types reference system catalog info that is
1155 : * not preserved, and hence these data types cannot be used in user
1156 : * tables upgraded by pg_upgrade.
1157 : */
4417 tgl 1158 : static void
4481 bruce 1159 GIC 2 : check_for_reg_data_type_usage(ClusterInfo *cluster)
1160 : {
1161 : bool found;
1162 : char output_path[MAXPGPATH];
4641 bruce 1163 EUB :
2067 peter_e 1164 GBC 2 : prep_status("Checking for reg* data types in user tables");
4641 bruce 1165 EUB :
208 michael 1166 GBC 2 : snprintf(output_path, sizeof(output_path), "%s/%s",
1167 : log_opts.basedir,
208 michael 1168 EUB : "tables_using_reg.txt");
4641 bruce 1169 :
710 tgl 1170 : /*
1171 : * Note: older servers will not have all of these reg* types, so we have
1172 : * to write the query like this rather than depending on casts to regtype.
1173 : */
710 tgl 1174 GIC 2 : found = check_for_data_types_usage(cluster,
1175 : "SELECT oid FROM pg_catalog.pg_type t "
710 tgl 1176 EUB : "WHERE t.typnamespace = "
1177 : " (SELECT oid FROM pg_catalog.pg_namespace "
1178 : " WHERE nspname = 'pg_catalog') "
1179 : " AND t.typname IN ( "
1180 : /* pg_class.oid is preserved, so 'regclass' is OK */
1181 : " 'regcollation', "
1182 : " 'regconfig', "
1183 : " 'regdictionary', "
1184 : " 'regnamespace', "
1185 : " 'regoper', "
1186 : " 'regoperator', "
1187 : " 'regproc', "
1188 : " 'regprocedure' "
1189 : /* pg_authid.oid is preserved, so 'regrole' is OK */
1190 : /* pg_type.oid is (mostly) preserved, so 'regtype' is OK */
1191 : " )",
1192 : output_path);
1193 :
4641 bruce 1194 GIC 2 : if (found)
1195 : {
271 tgl 1196 UNC 0 : pg_log(PG_REPORT, "fatal");
3477 peter_e 1197 UIC 0 : pg_fatal("Your installation contains one of the reg* data types in user tables.\n"
2118 tgl 1198 EUB : "These data types reference system OIDs that are not preserved by\n"
1199 : "pg_upgrade, so this cluster cannot currently be upgraded. You can\n"
1200 : "drop the problem columns and restart the upgrade.\n"
710 1201 : "A list of the problem columns is in the file:\n"
1202 : " %s", output_path);
1203 : }
4641 bruce 1204 : else
4555 bruce 1205 GIC 2 : check_ok();
4641 bruce 1206 GBC 2 : }
1207 :
1208 : /*
1209 : * check_for_aclitem_data_type_usage
1210 : *
1211 : * aclitem changed its storage format in 16, so check for it.
1212 : */
1213 : static void
137 andrew 1214 UNC 0 : check_for_aclitem_data_type_usage(ClusterInfo *cluster)
1215 : {
1216 : char output_path[MAXPGPATH];
1217 :
1218 0 : prep_status("Checking for incompatible aclitem data type in user tables");
1219 :
1220 0 : snprintf(output_path, sizeof(output_path), "tables_using_aclitem.txt");
1221 :
1222 0 : if (check_for_data_type_usage(cluster, "pg_catalog.aclitem", output_path))
1223 : {
1224 0 : pg_log(PG_REPORT, "fatal");
1225 0 : pg_fatal("Your installation contains the \"aclitem\" data type in user tables.\n"
1226 : "The internal format of \"aclitem\" changed in PostgreSQL version 16\n"
1227 : "so this cluster cannot currently be upgraded. You can drop the\n"
1228 : "problem columns and restart the upgrade. A list of the problem\n"
1229 : "columns is in the file:\n"
1230 : " %s", output_path);
1231 : }
1232 : else
1233 0 : check_ok();
1234 0 : }
1235 :
1236 : /*
1237 : * check_for_jsonb_9_4_usage()
3114 bruce 1238 EUB : *
1239 : * JSONB changed its storage format during 9.4 beta, so check for it.
1240 : */
1241 : static void
3114 bruce 1242 UIC 0 : check_for_jsonb_9_4_usage(ClusterInfo *cluster)
1243 : {
1244 : char output_path[MAXPGPATH];
1245 :
2038 peter_e 1246 0 : prep_status("Checking for incompatible \"jsonb\" data type");
3114 bruce 1247 EUB :
208 michael 1248 UBC 0 : snprintf(output_path, sizeof(output_path), "%s/%s",
1249 : log_opts.basedir,
1250 : "tables_using_jsonb.txt");
1251 :
710 tgl 1252 UIC 0 : if (check_for_data_type_usage(cluster, "pg_catalog.jsonb", output_path))
1253 : {
271 tgl 1254 UNC 0 : pg_log(PG_REPORT, "fatal");
2056 peter_e 1255 UIC 0 : pg_fatal("Your installation contains the \"jsonb\" data type in user tables.\n"
1229 bruce 1256 EUB : "The internal format of \"jsonb\" changed during 9.4 beta so this\n"
1257 : "cluster cannot currently be upgraded. You can\n"
1258 : "drop the problem columns and restart the upgrade.\n"
1259 : "A list of the problem columns is in the file:\n"
1260 : " %s", output_path);
1261 : }
3114 1262 : else
3114 bruce 1263 UBC 0 : check_ok();
1264 0 : }
3114 bruce 1265 EUB :
2557 sfrost 1266 : /*
1267 : * check_for_pg_role_prefix()
1268 : *
1269 : * Versions older than 9.6 should not have any pg_* roles
1270 : */
1271 : static void
2557 sfrost 1272 UBC 0 : check_for_pg_role_prefix(ClusterInfo *cluster)
1273 : {
2557 sfrost 1274 EUB : PGresult *res;
2557 sfrost 1275 UBC 0 : PGconn *conn = connectToServer(cluster, "template1");
1276 : int ntups;
1277 : int i_roloid;
1278 : int i_rolname;
128 dgustafsson 1279 UNC 0 : FILE *script = NULL;
1280 : char output_path[MAXPGPATH];
1281 :
2056 peter_e 1282 UBC 0 : prep_status("Checking for roles starting with \"pg_\"");
1283 :
128 dgustafsson 1284 UNC 0 : snprintf(output_path, sizeof(output_path), "%s/%s",
1285 : log_opts.basedir,
1286 : "pg_role_prefix.txt");
1287 :
2557 sfrost 1288 UIC 0 : res = executeQueryOrDie(conn,
1289 : "SELECT oid AS roloid, rolname "
1290 : "FROM pg_catalog.pg_roles "
1291 : "WHERE rolname ~ '^pg_'");
2557 sfrost 1292 EUB :
128 dgustafsson 1293 UNC 0 : ntups = PQntuples(res);
1294 0 : i_roloid = PQfnumber(res, "roloid");
1295 0 : i_rolname = PQfnumber(res, "rolname");
1296 0 : for (int rowno = 0; rowno < ntups; rowno++)
2095 alvherre 1297 EUB : {
128 dgustafsson 1298 UNC 0 : if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1299 0 : pg_fatal("could not open file \"%s\": %s",
1300 0 : output_path, strerror(errno));
1301 0 : fprintf(script, "%s (oid=%s)\n",
1302 : PQgetvalue(res, rowno, i_rolname),
1303 : PQgetvalue(res, rowno, i_roloid));
2095 alvherre 1304 EUB : }
2557 sfrost 1305 :
2557 sfrost 1306 UBC 0 : PQclear(res);
1307 :
2557 sfrost 1308 UIC 0 : PQfinish(conn);
1309 :
128 dgustafsson 1310 UNC 0 : if (script)
1311 : {
1312 0 : fclose(script);
1313 0 : pg_log(PG_REPORT, "fatal");
1314 0 : pg_fatal("Your installation contains roles starting with \"pg_\".\n"
1315 : "\"pg_\" is a reserved prefix for system roles, the cluster\n"
1316 : "cannot be upgraded until these roles are renamed.\n"
1317 : "A list of roles starting with \"pg_\" is in the file:\n"
1318 : " %s", output_path);
1319 : }
1320 : else
1321 0 : check_ok();
2557 sfrost 1322 UIC 0 : }
1323 :
1324 : /*
738 heikki.linnakangas 1325 EUB : * Verify that no user-defined encoding conversions exist.
1326 : */
1327 : static void
738 heikki.linnakangas 1328 UIC 0 : check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
1329 : {
1330 : int dbnum;
1331 0 : FILE *script = NULL;
1332 : char output_path[MAXPGPATH];
1333 :
1334 0 : prep_status("Checking for user-defined encoding conversions");
1335 :
427 michael 1336 0 : snprintf(output_path, sizeof(output_path), "%s/%s",
1337 : log_opts.basedir,
1338 : "encoding_conversions.txt");
1339 :
1340 : /* Find any user defined encoding conversions */
738 heikki.linnakangas 1341 0 : for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1342 : {
1343 : PGresult *res;
1344 0 : bool db_used = false;
1345 : int ntups;
1346 : int rowno;
1347 : int i_conoid,
1348 : i_conname,
1349 : i_nspname;
1350 0 : DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1351 0 : PGconn *conn = connectToServer(cluster, active_db->db_name);
1352 :
1353 : /*
1354 : * The query below hardcodes FirstNormalObjectId as 16384 rather than
1355 : * interpolating that C #define into the query because, if that
1356 : * #define is ever changed, the cutoff we want to use is the value
1357 : * used by pre-version 14 servers, not that of some future version.
1358 : */
1359 0 : res = executeQueryOrDie(conn,
1360 : "SELECT c.oid as conoid, c.conname, n.nspname "
1361 : "FROM pg_catalog.pg_conversion c, "
1362 : " pg_catalog.pg_namespace n "
1363 : "WHERE c.connamespace = n.oid AND "
1364 : " c.oid >= 16384");
1365 0 : ntups = PQntuples(res);
1366 0 : i_conoid = PQfnumber(res, "conoid");
1367 0 : i_conname = PQfnumber(res, "conname");
1368 0 : i_nspname = PQfnumber(res, "nspname");
1369 0 : for (rowno = 0; rowno < ntups; rowno++)
1370 : {
1371 0 : if (script == NULL &&
1372 0 : (script = fopen_priv(output_path, "w")) == NULL)
271 tgl 1373 UNC 0 : pg_fatal("could not open file \"%s\": %s",
738 heikki.linnakangas 1374 UIC 0 : output_path, strerror(errno));
1375 0 : if (!db_used)
1376 : {
1377 0 : fprintf(script, "In database: %s\n", active_db->db_name);
1378 0 : db_used = true;
1379 : }
1380 0 : fprintf(script, " (oid=%s) %s.%s\n",
1381 : PQgetvalue(res, rowno, i_conoid),
1382 : PQgetvalue(res, rowno, i_nspname),
1383 : PQgetvalue(res, rowno, i_conname));
1384 : }
1385 :
1386 0 : PQclear(res);
1387 :
1388 0 : PQfinish(conn);
1389 : }
1390 :
1391 0 : if (script)
1392 : {
221 dgustafsson 1393 UNC 0 : fclose(script);
271 tgl 1394 0 : pg_log(PG_REPORT, "fatal");
738 heikki.linnakangas 1395 UIC 0 : pg_fatal("Your installation contains user-defined encoding conversions.\n"
1396 : "The conversion function parameters changed in PostgreSQL version 14\n"
1397 : "so this cluster cannot currently be upgraded. You can remove the\n"
1398 : "encoding conversions in the old cluster and restart the upgrade.\n"
1399 : "A list of user-defined encoding conversions is in the file:\n"
1400 : " %s", output_path);
1401 : }
1402 : else
1403 0 : check_ok();
1404 0 : }
|