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
40 ECB : * like RMDIR and DEL.
41 : */
42 : static char *
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 :
56 ECB : return result;
57 : #else
58 :
59 GIC 1 : return path;
60 : #endif
61 ECB : }
62 :
63 : void
64 GIC 2 : output_check_banner(bool live_check)
65 EUB : {
66 GIC 2 : if (user_opts.check && live_check)
67 : {
68 UIC 0 : pg_log(PG_REPORT,
69 : "Performing Consistency Checks on Old Live Server\n"
70 : "------------------------------------------------");
71 ECB : }
72 : else
73 : {
74 GIC 2 : pg_log(PG_REPORT,
75 ECB : "Performing Consistency Checks\n"
76 : "-----------------------------");
77 : }
78 GIC 2 : }
79 ECB :
80 :
81 : void
82 GIC 2 : check_and_dump_old_cluster(bool live_check)
83 ECB : {
84 : /* -- OLD -- */
85 :
86 GIC 2 : if (!live_check)
87 CBC 2 : start_postmaster(&old_cluster, true);
88 :
89 ECB : /* Extract a list of databases and tables from the old cluster */
90 GIC 2 : get_db_and_rel_infos(&old_cluster);
91 ECB :
92 GIC 2 : init_tablespaces();
93 :
94 2 : get_loadable_libraries();
95 :
96 :
97 ECB : /*
98 : * Check for various failure cases
99 : */
100 CBC 2 : check_is_install_user(&old_cluster);
101 2 : check_proper_datallowconn(&old_cluster);
102 2 : check_for_prepared_transactions(&old_cluster);
103 GIC 2 : check_for_composite_data_type_usage(&old_cluster);
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 : */
111 GNC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1500)
112 UNC 0 : check_for_aclitem_data_type_usage(&old_cluster);
113 :
114 : /*
115 ECB : * PG 14 changed the function signature of encoding conversion functions.
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 : */
120 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1300)
121 UIC 0 : check_for_user_defined_encoding_conversions(&old_cluster);
122 :
123 : /*
124 ECB : * Pre-PG 14 allowed user defined postfix operators, which are not
125 EUB : * supported anymore. Verify there are none, iff applicable.
126 : */
127 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1300)
128 UIC 0 : check_for_user_defined_postfix_ops(&old_cluster);
129 :
130 : /*
131 ECB : * PG 14 changed polymorphic functions from anyarray to
132 EUB : * anycompatiblearray.
133 : */
134 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1300)
135 UIC 0 : check_for_incompatible_polymorphics(&old_cluster);
136 :
137 : /*
138 ECB : * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
139 EUB : * supported anymore. Verify there are none, iff applicable.
140 : */
141 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1100)
142 UIC 0 : check_for_tables_with_oids(&old_cluster);
143 :
144 : /*
145 ECB : * PG 12 changed the 'sql_identifier' type storage to be based on name,
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 : */
149 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1100)
150 UIC 0 : old_11_check_for_sql_identifier_data_type_usage(&old_cluster);
151 :
152 : /*
153 ECB : * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
154 EUB : * hash indexes
155 : */
156 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 906)
157 : {
158 UIC 0 : old_9_6_check_for_unknown_data_type_usage(&old_cluster);
159 0 : if (user_opts.check)
160 LBC 0 : old_9_6_invalidate_hash_indexes(&old_cluster, true);
161 : }
162 EUB :
163 : /* 9.5 and below should not have roles starting with pg_ */
164 GBC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 905)
165 UIC 0 : check_for_pg_role_prefix(&old_cluster);
166 :
167 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) == 904 &&
168 LBC 0 : old_cluster.controldata.cat_ver < JSONB_FORMAT_CHANGE_CAT_VER)
169 UBC 0 : check_for_jsonb_9_4_usage(&old_cluster);
170 :
171 ECB : /* Pre-PG 9.4 had a different 'line' data type internal format */
172 GBC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 903)
173 UBC 0 : old_9_3_check_for_line_data_type_usage(&old_cluster);
174 :
175 : /*
176 ECB : * While not a check option, we do this now because this is the only time
177 EUB : * the old server is running.
178 : */
179 GIC 2 : if (!user_opts.check)
180 1 : generate_old_dump();
181 :
182 2 : if (!live_check)
183 CBC 2 : stop_postmaster(false);
184 2 : }
185 :
186 ECB :
187 : void
188 CBC 2 : check_new_cluster(void)
189 : {
190 GIC 2 : get_db_and_rel_infos(&new_cluster);
191 :
192 CBC 2 : check_new_cluster_is_empty();
193 ECB :
194 GIC 2 : check_loadable_libraries();
195 ECB :
196 GIC 2 : switch (user_opts.transfer_mode)
197 ECB : {
198 UIC 0 : case TRANSFER_MODE_CLONE:
199 LBC 0 : check_file_clone();
200 UIC 0 : break;
201 GBC 2 : case TRANSFER_MODE_COPY:
202 2 : break;
203 UBC 0 : case TRANSFER_MODE_LINK:
204 LBC 0 : check_hard_link();
205 0 : break;
206 EUB : }
207 :
208 GBC 2 : check_is_install_user(&new_cluster);
209 :
210 GIC 2 : check_for_prepared_transactions(&new_cluster);
211 ECB :
212 GIC 2 : check_for_new_tablespace_dir(&new_cluster);
213 CBC 2 : }
214 :
215 ECB :
216 : void
217 GIC 2 : report_clusters_compatible(void)
218 : {
219 2 : if (user_opts.check)
220 ECB : {
221 GNC 1 : pg_log(PG_REPORT, "\n*Clusters are compatible*");
222 ECB : /* stops new cluster */
223 GIC 1 : stop_postmaster(false);
224 ECB :
225 GIC 1 : cleanup_output_dirs();
226 CBC 1 : exit(0);
227 : }
228 ECB :
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.");
232 1 : }
233 :
234 :
235 ECB : void
236 GIC 1 : issue_warnings_and_set_wal_level(void)
237 : {
238 : /*
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 : */
244 GIC 1 : start_postmaster(&new_cluster, true);
245 :
246 : /* Reindex hash indexes for old < 10.0 */
247 CBC 1 : if (GET_MAJOR_VERSION(old_cluster.major_version) <= 906)
248 UIC 0 : old_9_6_invalidate_hash_indexes(&new_cluster, false);
249 :
250 CBC 1 : report_extension_updates(&new_cluster);
251 EUB :
252 GIC 1 : stop_postmaster(false);
253 CBC 1 : }
254 :
255 ECB :
256 : void
257 GIC 1 : output_completion_banner(char *deletion_script_file_name)
258 : {
259 : PQExpBufferData user_specification;
260 ECB :
261 GIC 1 : initPQExpBuffer(&user_specification);
262 1 : if (os_info.user_specified)
263 : {
264 LBC 0 : appendPQExpBufferStr(&user_specification, "-U ");
265 0 : appendShellString(&user_specification, os_info.user);
266 UIC 0 : appendPQExpBufferChar(&user_specification, ' ');
267 EUB : }
268 :
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 :
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",
278 ECB : deletion_script_file_name);
279 : else
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"
283 EUB : "exist in the old cluster directory. The old cluster's contents must\n"
284 : "be deleted manually.");
285 :
286 GIC 1 : termPQExpBuffer(&user_specification);
287 1 : }
288 :
289 ECB :
290 : void
291 GIC 2 : check_cluster_versions(void)
292 : {
293 2 : prep_status("Checking cluster versions");
294 ECB :
295 : /* cluster versions should already have been obtained */
296 CBC 2 : Assert(old_cluster.major_version != 0);
297 GIC 2 : Assert(new_cluster.major_version != 0);
298 :
299 ECB : /*
300 : * We allow upgrades from/to the same major version for alpha/beta
301 : * upgrades
302 : */
303 :
304 GIC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) < 902)
305 UNC 0 : pg_fatal("This utility can only upgrade from PostgreSQL version %s and later.",
306 : "9.2");
307 ECB :
308 EUB : /* Only current PG version is supported as a target */
309 GIC 2 : if (GET_MAJOR_VERSION(new_cluster.major_version) != GET_MAJOR_VERSION(PG_VERSION_NUM))
310 UNC 0 : pg_fatal("This utility can only upgrade to PostgreSQL version %s.",
311 : PG_MAJORVERSION);
312 ECB :
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 : */
318 GIC 2 : if (old_cluster.major_version > new_cluster.major_version)
319 UNC 0 : pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.");
320 :
321 ECB : /* Ensure binaries match the designated data directories */
322 GBC 2 : if (GET_MAJOR_VERSION(old_cluster.major_version) !=
323 GIC 2 : GET_MAJOR_VERSION(old_cluster.bin_version))
324 UNC 0 : pg_fatal("Old cluster data and binary directories are from different major versions.");
325 CBC 2 : if (GET_MAJOR_VERSION(new_cluster.major_version) !=
326 2 : GET_MAJOR_VERSION(new_cluster.bin_version))
327 UNC 0 : pg_fatal("New cluster data and binary directories are from different major versions.");
328 ECB :
329 CBC 2 : check_ok();
330 GBC 2 : }
331 :
332 ECB :
333 : void
334 GIC 2 : check_cluster_compatibility(bool live_check)
335 : {
336 : /* get/check pg_control data of servers */
337 CBC 2 : get_control_data(&old_cluster, live_check);
338 GIC 2 : get_control_data(&new_cluster, false);
339 2 : check_control_data(&old_cluster.controldata, &new_cluster.controldata);
340 ECB :
341 CBC 2 : if (live_check && old_cluster.port == new_cluster.port)
342 LBC 0 : pg_fatal("When checking a live server, "
343 : "the old and new port numbers must be different.");
344 GIC 2 : }
345 :
346 :
347 EUB : static void
348 GBC 2 : check_new_cluster_is_empty(void)
349 EUB : {
350 : int dbnum;
351 :
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 :
357 12 : for (relnum = 0; relnum < rel_arr->nrels;
358 CBC 8 : relnum++)
359 : {
360 : /* pg_largeobject and its index should be skipped */
361 GIC 8 : if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
362 UNC 0 : pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"",
363 UBC 0 : new_cluster.dbarr.dbs[dbnum].db_name,
364 0 : rel_arr->rels[relnum].nspname,
365 UIC 0 : rel_arr->rels[relnum].relname);
366 : }
367 EUB : }
368 GIC 2 : }
369 :
370 : /*
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
380 GBC 2 : check_for_new_tablespace_dir(ClusterInfo *new_cluster)
381 EUB : {
382 : int tblnum;
383 : char new_tablespace_dir[MAXPGPATH];
384 :
385 GIC 2 : prep_status("Checking for new cluster tablespace directories");
386 EUB :
387 GIC 2 : for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
388 : {
389 : struct stat statbuf;
390 :
391 UIC 0 : snprintf(new_tablespace_dir, MAXPGPATH, "%s%s",
392 UBC 0 : os_info.old_tablespaces[tblnum],
393 EUB : new_cluster->tablespace_suffix);
394 :
395 UBC 0 : if (stat(new_tablespace_dir, &statbuf) == 0 || errno != ENOENT)
396 UNC 0 : pg_fatal("new cluster tablespace directory already exists: \"%s\"",
397 : new_tablespace_dir);
398 : }
399 ECB :
400 GIC 2 : check_ok();
401 2 : }
402 ECB :
403 EUB : /*
404 : * create_script_for_old_cluster_deletion()
405 : *
406 : * This is particularly useful for tablespace deletion.
407 ECB : */
408 : void
409 GIC 1 : create_script_for_old_cluster_deletion(char **deletion_script_file_name)
410 : {
411 1 : FILE *script = NULL;
412 : int tblnum;
413 : char old_cluster_pgdata[MAXPGPATH],
414 : new_cluster_pgdata[MAXPGPATH];
415 :
416 1 : *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
417 : SCRIPT_PREFIX, SCRIPT_EXT);
418 ECB :
419 GIC 1 : strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
420 1 : canonicalize_path(old_cluster_pgdata);
421 ECB :
422 GIC 1 : strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
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 : {
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 : }
437 ECB :
438 : /*
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.
442 ECB : */
443 GIC 1 : for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
444 ECB : {
445 : char old_tablespace_dir[MAXPGPATH];
446 :
447 UIC 0 : strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
448 0 : canonicalize_path(old_tablespace_dir);
449 LBC 0 : if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
450 EUB : {
451 : /* reproduce warning from CREATE TABLESPACE that is in the log */
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. */
456 0 : unlink(*deletion_script_file_name);
457 LBC 0 : pg_free(*deletion_script_file_name);
458 UBC 0 : *deletion_script_file_name = NULL;
459 UIC 0 : return;
460 ECB : }
461 : }
462 :
463 GIC 1 : prep_status("Creating script to delete old cluster");
464 ECB :
465 CBC 1 : if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
466 UNC 0 : pg_fatal("could not open file \"%s\": %s",
467 UIC 0 : *deletion_script_file_name, strerror(errno));
468 :
469 : #ifndef WIN32
470 : /* add shebang header */
471 GIC 1 : fprintf(script, "#!/bin/sh\n\n");
472 : #endif
473 :
474 : /* delete old cluster's default tablespace */
475 1 : fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
476 ECB : fix_path_separator(old_cluster.pgdata), PATH_QUOTE);
477 :
478 : /* delete old cluster's alternate tablespaces */
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?
484 ECB : */
485 UIC 0 : if (strlen(old_cluster.tablespace_suffix) == 0)
486 : {
487 ECB : /* delete per-database directories */
488 : int dbnum;
489 :
490 UIC 0 : fprintf(script, "\n");
491 :
492 0 : for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
493 LBC 0 : fprintf(script, RMDIR_CMD " %c%s%c%u%c\n", PATH_QUOTE,
494 UIC 0 : fix_path_separator(os_info.old_tablespaces[tblnum]),
495 0 : PATH_SEPARATOR, old_cluster.dbarr.dbs[dbnum].db_oid,
496 ECB : PATH_QUOTE);
497 : }
498 : else
499 : {
500 LBC 0 : char *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
501 ECB :
502 : /*
503 : * Simply delete the tablespace directory, which might be ".old"
504 : * or a version-specific subdirectory.
505 : */
506 LBC 0 : fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
507 0 : fix_path_separator(os_info.old_tablespaces[tblnum]),
508 : fix_path_separator(suffix_path), PATH_QUOTE);
509 0 : pfree(suffix_path);
510 : }
511 : }
512 ECB :
513 GBC 1 : fclose(script);
514 :
515 : #ifndef WIN32
516 GIC 1 : if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
517 UNC 0 : pg_fatal("could not add execute permission to file \"%s\": %s",
518 UIC 0 : *deletion_script_file_name, strerror(errno));
519 : #endif
520 :
521 GIC 1 : check_ok();
522 ECB : }
523 :
524 EUB :
525 : /*
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
532 GIC 4 : check_is_install_user(ClusterInfo *cluster)
533 ECB : {
534 : PGresult *res;
535 CBC 4 : PGconn *conn = connectToServer(cluster, "template1");
536 :
537 4 : prep_status("Checking database user is the install user");
538 :
539 EUB : /* Can't use pg_authid because only superusers can view it. */
540 GBC 4 : res = executeQueryOrDie(conn,
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.
550 ECB : */
551 CBC 4 : if (PQntuples(res) != 1 ||
552 GIC 4 : atooid(PQgetvalue(res, 0, 1)) != BOOTSTRAP_SUPERUSERID)
553 UNC 0 : pg_fatal("database user \"%s\" is not the install user",
554 : os_info.user);
555 :
556 GIC 4 : PQclear(res);
557 :
558 4 : res = executeQueryOrDie(conn,
559 : "SELECT COUNT(*) "
560 : "FROM pg_catalog.pg_roles "
561 ECB : "WHERE rolname !~ '^pg_'");
562 :
563 GIC 4 : if (PQntuples(res) != 1)
564 UNC 0 : pg_fatal("could not determine the number of users");
565 :
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 : */
571 GNC 4 : if (cluster == &new_cluster && strcmp(PQgetvalue(res, 0, 0), "1") != 0)
572 UNC 0 : pg_fatal("Only the install user can be defined in the new cluster.");
573 :
574 GBC 4 : PQclear(res);
575 EUB :
576 GIC 4 : PQfinish(conn);
577 EUB :
578 GIC 4 : check_ok();
579 4 : }
580 ECB :
581 :
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
590 GIC 2 : check_proper_datallowconn(ClusterInfo *cluster)
591 : {
592 : int dbnum;
593 : PGconn *conn_template1;
594 : PGresult *dbres;
595 : int ntups;
596 ECB : int i_datname;
597 : int i_datallowconn;
598 GIC 2 : FILE *script = NULL;
599 ECB : char output_path[MAXPGPATH];
600 :
601 CBC 2 : prep_status("Checking database connection settings");
602 :
603 2 : snprintf(output_path, sizeof(output_path), "%s/%s",
604 ECB : log_opts.basedir,
605 : "databases_with_datallowconn_false.txt");
606 :
607 CBC 2 : conn_template1 = connectToServer(cluster, "template1");
608 ECB :
609 : /* get database names */
610 GIC 2 : dbres = executeQueryOrDie(conn_template1,
611 EUB : "SELECT datname, datallowconn "
612 : "FROM pg_catalog.pg_database");
613 :
614 GIC 2 : i_datname = PQfnumber(dbres, "datname");
615 GBC 2 : i_datallowconn = PQfnumber(dbres, "datallowconn");
616 :
617 GIC 2 : ntups = PQntuples(dbres);
618 GBC 16 : for (dbnum = 0; dbnum < ntups; dbnum++)
619 : {
620 GIC 14 : char *datname = PQgetvalue(dbres, dbnum, i_datname);
621 14 : char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
622 :
623 GBC 14 : if (strcmp(datname, "template0") == 0)
624 EUB : {
625 : /* avoid restore failure when pg_dumpall tries to create template0 */
626 GIC 2 : if (strcmp(datallowconn, "t") == 0)
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
634 EUB : * restore
635 : */
636 GBC 12 : if (strcmp(datallowconn, "f") == 0)
637 EUB : {
638 UBC 0 : if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
639 UNC 0 : pg_fatal("could not open file \"%s\": %s",
640 UBC 0 : output_path, strerror(errno));
641 EUB :
642 UIC 0 : fprintf(script, "%s\n", datname);
643 EUB : }
644 : }
645 : }
646 :
647 GIC 2 : PQclear(dbres);
648 :
649 2 : PQfinish(conn_template1);
650 :
651 GBC 2 : if (script)
652 : {
653 UNC 0 : fclose(script);
654 0 : pg_log(PG_REPORT, "fatal");
655 UIC 0 : pg_fatal("All non-template0 databases must allow connections, i.e. their\n"
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
664 GIC 2 : check_ok();
665 2 : }
666 :
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 : */
674 : static void
675 GIC 4 : check_for_prepared_transactions(ClusterInfo *cluster)
676 : {
677 EUB : PGresult *res;
678 GIC 4 : PGconn *conn = connectToServer(cluster, "template1");
679 :
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 :
686 GIC 4 : if (PQntuples(res) != 0)
687 EUB : {
688 UIC 0 : if (cluster == &old_cluster)
689 UNC 0 : pg_fatal("The source cluster contains prepared transactions");
690 EUB : else
691 UNC 0 : pg_fatal("The target cluster contains prepared transactions");
692 : }
693 :
694 GIC 4 : PQclear(res);
695 :
696 4 : PQfinish(conn);
697 :
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
707 EUB : * it must match for the old and new servers.
708 : */
709 : static void
710 GIC 2 : check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
711 : {
712 : int dbnum;
713 2 : FILE *script = NULL;
714 : char output_path[MAXPGPATH];
715 :
716 2 : prep_status("Checking for contrib/isn with bigint-passing mismatch");
717 :
718 2 : if (old_cluster.controldata.float8_pass_by_value ==
719 2 : new_cluster.controldata.float8_pass_by_value)
720 : {
721 EUB : /* no mismatch */
722 GBC 2 : check_ok();
723 2 : return;
724 EUB : }
725 :
726 UBC 0 : snprintf(output_path, sizeof(output_path), "%s/%s",
727 EUB : log_opts.basedir,
728 : "contrib_isn_and_int8_pass_by_value.txt");
729 :
730 UBC 0 : for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
731 EUB : {
732 : PGresult *res;
733 UBC 0 : bool db_used = false;
734 : int ntups;
735 EUB : int rowno;
736 : int i_nspname,
737 : i_proname;
738 UBC 0 : DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
739 UIC 0 : PGconn *conn = connectToServer(cluster, active_db->db_name);
740 :
741 : /* Find any functions coming from contrib/isn */
742 0 : res = executeQueryOrDie(conn,
743 : "SELECT n.nspname, p.proname "
744 : "FROM pg_catalog.pg_proc p, "
745 : " pg_catalog.pg_namespace n "
746 EUB : "WHERE p.pronamespace = n.oid AND "
747 : " p.probin = '$libdir/isn'");
748 :
749 UIC 0 : ntups = PQntuples(res);
750 0 : i_nspname = PQfnumber(res, "nspname");
751 UBC 0 : i_proname = PQfnumber(res, "proname");
752 UIC 0 : for (rowno = 0; rowno < ntups; rowno++)
753 EUB : {
754 UBC 0 : if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
755 UNC 0 : pg_fatal("could not open file \"%s\": %s",
756 UIC 0 : output_path, strerror(errno));
757 0 : if (!db_used)
758 : {
759 0 : fprintf(script, "In database: %s\n", active_db->db_name);
760 0 : db_used = true;
761 EUB : }
762 UBC 0 : fprintf(script, " %s.%s\n",
763 : PQgetvalue(res, rowno, i_nspname),
764 : PQgetvalue(res, rowno, i_proname));
765 : }
766 :
767 UIC 0 : PQclear(res);
768 :
769 0 : PQfinish(conn);
770 : }
771 EUB :
772 UIC 0 : if (script)
773 : {
774 UNC 0 : fclose(script);
775 0 : pg_log(PG_REPORT, "fatal");
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"
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);
783 : }
784 : else
785 UBC 0 : check_ok();
786 : }
787 :
788 : /*
789 : * Verify that no user defined postfix operators exist.
790 EUB : */
791 : static void
792 UIC 0 : check_for_user_defined_postfix_ops(ClusterInfo *cluster)
793 : {
794 : int dbnum;
795 UBC 0 : FILE *script = NULL;
796 : char output_path[MAXPGPATH];
797 :
798 UIC 0 : prep_status("Checking for user-defined postfix operators");
799 :
800 0 : snprintf(output_path, sizeof(output_path), "%s/%s",
801 EUB : log_opts.basedir,
802 : "postfix_ops.txt");
803 :
804 : /* Find any user defined postfix operators */
805 UBC 0 : for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
806 : {
807 : PGresult *res;
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;
816 UBC 0 : DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
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++)
847 EUB : {
848 UBC 0 : if (script == NULL &&
849 0 : (script = fopen_priv(output_path, "w")) == NULL)
850 UNC 0 : pg_fatal("could not open file \"%s\": %s",
851 UBC 0 : output_path, strerror(errno));
852 UIC 0 : if (!db_used)
853 EUB : {
854 UBC 0 : fprintf(script, "In database: %s\n", active_db->db_name);
855 0 : db_used = true;
856 EUB : }
857 UBC 0 : fprintf(script, " (oid=%s) %s.%s (%s.%s, NONE)\n",
858 : PQgetvalue(res, rowno, i_oproid),
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 :
865 UIC 0 : PQclear(res);
866 :
867 0 : PQfinish(conn);
868 EUB : }
869 :
870 UIC 0 : if (script)
871 EUB : {
872 UNC 0 : fclose(script);
873 0 : pg_log(PG_REPORT, "fatal");
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
881 UIC 0 : check_ok();
882 0 : }
883 EUB :
884 : /*
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
891 UIC 0 : check_for_incompatible_polymorphics(ClusterInfo *cluster)
892 EUB : {
893 : PGresult *res;
894 UIC 0 : FILE *script = NULL;
895 EUB : char output_path[MAXPGPATH];
896 : PQExpBufferData old_polymorphics;
897 :
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 :
907 UIC 0 : appendPQExpBufferStr(&old_polymorphics,
908 EUB : "'array_append(anyarray,anyelement)'"
909 : ", 'array_cat(anyarray,anyarray)'"
910 : ", 'array_prepend(anyelement,anyarray)'");
911 :
912 UIC 0 : if (GET_MAJOR_VERSION(cluster->major_version) >= 903)
913 UBC 0 : appendPQExpBufferStr(&old_polymorphics,
914 EUB : ", 'array_remove(anyarray,anyelement)'"
915 : ", 'array_replace(anyarray,anyelement,anyelement)'");
916 :
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 :
924 UBC 0 : for (int dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
925 EUB : {
926 UBC 0 : bool db_used = false;
927 0 : DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
928 UIC 0 : PGconn *conn = connectToServer(cluster, active_db->db_name);
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 : */
939 UIC 0 : res = executeQueryOrDie(conn,
940 : /* Aggregate transition functions */
941 : "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
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 :
970 UIC 0 : ntups = PQntuples(res);
971 :
972 LBC 0 : i_objkind = PQfnumber(res, "objkind");
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)
979 UNC 0 : pg_fatal("could not open file \"%s\": %s",
980 UIC 0 : output_path, strerror(errno));
981 LBC 0 : if (!db_used)
982 : {
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 :
996 LBC 0 : if (script)
997 : {
998 0 : fclose(script);
999 UNC 0 : pg_log(PG_REPORT, "fatal");
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"
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
1009 UBC 0 : check_ok();
1010 EUB :
1011 UIC 0 : termPQExpBuffer(&old_polymorphics);
1012 0 : }
1013 :
1014 : /*
1015 : * Verify that no tables are declared WITH OIDS.
1016 : */
1017 : static void
1018 LBC 0 : check_for_tables_with_oids(ClusterInfo *cluster)
1019 ECB : {
1020 : int dbnum;
1021 UIC 0 : FILE *script = NULL;
1022 : char output_path[MAXPGPATH];
1023 :
1024 0 : prep_status("Checking for tables WITH OIDS");
1025 :
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 */
1031 0 : for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1032 ECB : {
1033 : PGresult *res;
1034 UIC 0 : bool db_used = false;
1035 : int ntups;
1036 : int rowno;
1037 ECB : int i_nspname,
1038 : i_relname;
1039 LBC 0 : DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
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 "
1047 ECB : " c.relhasoids AND"
1048 : " n.nspname NOT IN ('pg_catalog')");
1049 :
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)
1056 UNC 0 : pg_fatal("could not open file \"%s\": %s",
1057 UIC 0 : output_path, strerror(errno));
1058 0 : if (!db_used)
1059 : {
1060 0 : fprintf(script, "In database: %s\n", active_db->db_name);
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));
1066 ECB : }
1067 :
1068 UBC 0 : PQclear(res);
1069 EUB :
1070 UIC 0 : PQfinish(conn);
1071 : }
1072 :
1073 0 : if (script)
1074 ECB : {
1075 UNC 0 : fclose(script);
1076 0 : pg_log(PG_REPORT, "fatal");
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
1084 UBC 0 : check_ok();
1085 UIC 0 : }
1086 :
1087 :
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
1098 GIC 2 : check_for_composite_data_type_usage(ClusterInfo *cluster)
1099 : {
1100 : bool found;
1101 : Oid firstUserOid;
1102 : char output_path[MAXPGPATH];
1103 EUB : char *base_query;
1104 :
1105 GIC 2 : prep_status("Checking for system-defined composite types in user tables");
1106 :
1107 2 : snprintf(output_path, sizeof(output_path), "%s/%s",
1108 : log_opts.basedir,
1109 : "tables_using_composite.txt");
1110 :
1111 : /*
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 : */
1122 GBC 2 : firstUserOid = 16384;
1123 :
1124 2 : base_query = psprintf("SELECT t.oid FROM pg_catalog.pg_type t "
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 :
1129 GIC 2 : found = check_for_data_types_usage(cluster, base_query, output_path);
1130 :
1131 2 : free(base_query);
1132 :
1133 GBC 2 : if (found)
1134 EUB : {
1135 UNC 0 : pg_log(PG_REPORT, "fatal");
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);
1142 EUB : }
1143 : else
1144 GIC 2 : check_ok();
1145 GBC 2 : }
1146 :
1147 : /*
1148 : * check_for_reg_data_type_usage()
1149 EUB : * pg_upgrade only preserves these system values:
1150 : * pg_class.oid
1151 : * pg_type.oid
1152 : * pg_enum.oid
1153 : *
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 : */
1158 : static void
1159 GIC 2 : check_for_reg_data_type_usage(ClusterInfo *cluster)
1160 : {
1161 : bool found;
1162 : char output_path[MAXPGPATH];
1163 EUB :
1164 GBC 2 : prep_status("Checking for reg* data types in user tables");
1165 EUB :
1166 GBC 2 : snprintf(output_path, sizeof(output_path), "%s/%s",
1167 : log_opts.basedir,
1168 EUB : "tables_using_reg.txt");
1169 :
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 : */
1174 GIC 2 : found = check_for_data_types_usage(cluster,
1175 : "SELECT oid FROM pg_catalog.pg_type t "
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 :
1194 GIC 2 : if (found)
1195 : {
1196 UNC 0 : pg_log(PG_REPORT, "fatal");
1197 UIC 0 : pg_fatal("Your installation contains one of the reg* data types in user tables.\n"
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"
1201 : "A list of the problem columns is in the file:\n"
1202 : " %s", output_path);
1203 : }
1204 : else
1205 GIC 2 : check_ok();
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
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()
1238 EUB : *
1239 : * JSONB changed its storage format during 9.4 beta, so check for it.
1240 : */
1241 : static void
1242 UIC 0 : check_for_jsonb_9_4_usage(ClusterInfo *cluster)
1243 : {
1244 : char output_path[MAXPGPATH];
1245 :
1246 0 : prep_status("Checking for incompatible \"jsonb\" data type");
1247 EUB :
1248 UBC 0 : snprintf(output_path, sizeof(output_path), "%s/%s",
1249 : log_opts.basedir,
1250 : "tables_using_jsonb.txt");
1251 :
1252 UIC 0 : if (check_for_data_type_usage(cluster, "pg_catalog.jsonb", output_path))
1253 : {
1254 UNC 0 : pg_log(PG_REPORT, "fatal");
1255 UIC 0 : pg_fatal("Your installation contains the \"jsonb\" data type in user tables.\n"
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 : }
1262 : else
1263 UBC 0 : check_ok();
1264 0 : }
1265 EUB :
1266 : /*
1267 : * check_for_pg_role_prefix()
1268 : *
1269 : * Versions older than 9.6 should not have any pg_* roles
1270 : */
1271 : static void
1272 UBC 0 : check_for_pg_role_prefix(ClusterInfo *cluster)
1273 : {
1274 EUB : PGresult *res;
1275 UBC 0 : PGconn *conn = connectToServer(cluster, "template1");
1276 : int ntups;
1277 : int i_roloid;
1278 : int i_rolname;
1279 UNC 0 : FILE *script = NULL;
1280 : char output_path[MAXPGPATH];
1281 :
1282 UBC 0 : prep_status("Checking for roles starting with \"pg_\"");
1283 :
1284 UNC 0 : snprintf(output_path, sizeof(output_path), "%s/%s",
1285 : log_opts.basedir,
1286 : "pg_role_prefix.txt");
1287 :
1288 UIC 0 : res = executeQueryOrDie(conn,
1289 : "SELECT oid AS roloid, rolname "
1290 : "FROM pg_catalog.pg_roles "
1291 : "WHERE rolname ~ '^pg_'");
1292 EUB :
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++)
1297 EUB : {
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));
1304 EUB : }
1305 :
1306 UBC 0 : PQclear(res);
1307 :
1308 UIC 0 : PQfinish(conn);
1309 :
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();
1322 UIC 0 : }
1323 :
1324 : /*
1325 EUB : * Verify that no user-defined encoding conversions exist.
1326 : */
1327 : static void
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 :
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 */
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)
1373 UNC 0 : pg_fatal("could not open file \"%s\": %s",
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 : {
1393 UNC 0 : fclose(script);
1394 0 : pg_log(PG_REPORT, "fatal");
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 : }
|