PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
check.c
Go to the documentation of this file.
1/*
2 * check.c
3 *
4 * server checks and output routines
5 *
6 * Copyright (c) 2010-2025, 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_class_d.h"
15#include "pg_upgrade.h"
17
18static void check_new_cluster_is_empty(void);
27static void check_for_new_tablespace_dir(void);
32static void check_old_cluster_for_valid_slots(void);
34
35/*
36 * DataTypesUsageChecks - definitions of data type checks for the old cluster
37 * in order to determine if an upgrade can be performed. See the comment on
38 * data_types_usage_checks below for a more detailed description.
39 */
40typedef struct
41{
42 /* Status line to print to the user */
43 const char *status;
44 /* Filename to store report to */
45 const char *report_filename;
46 /* Query to extract the oid of the datatype */
47 const char *base_query;
48 /* Text to store to report in case of error */
49 const char *report_text;
50 /* The latest version where the check applies */
52 /* A function pointer for determining if the check applies */
55
56/*
57 * Special values for threshold_version for indicating that a check applies to
58 * all versions, or that a custom function needs to be invoked to determine
59 * if the check applies.
60 */
61#define MANUAL_CHECK 1
62#define ALL_VERSIONS -1
63
64/*--
65 * Data type usage checks. Each check for problematic data type usage is
66 * defined in this array with metadata, SQL query for finding the data type
67 * and functionality for deciding if the check is applicable to the version
68 * of the old cluster. The struct members are described in detail below:
69 *
70 * status A oneline string which can be printed to the user to
71 * inform about progress. Should not end with newline.
72 * report_filename The filename in which the list of problems detected by
73 * the check will be printed.
74 * base_query A query which extracts the Oid of the datatype checked
75 * for.
76 * report_text The text which will be printed to the user to explain
77 * what the check did, and why it failed. The text should
78 * end with a newline, and does not need to refer to the
79 * report_filename as that is automatically appended to
80 * the report with the path to the log folder.
81 * threshold_version The major version of PostgreSQL for which to run the
82 * check. Iff the old cluster is less than, or equal to,
83 * the threshold version then the check will be executed.
84 * If the old version is greater than the threshold then
85 * the check is skipped. If the threshold_version is set
86 * to ALL_VERSIONS then it will be run unconditionally,
87 * if set to MANUAL_CHECK then the version_hook function
88 * will be executed in order to determine whether or not
89 * to run.
90 * version_hook A function pointer to a version check function of type
91 * DataTypesUsageVersionCheck which is used to determine
92 * if the check is applicable to the old cluster. If the
93 * version_hook returns true then the check will be run,
94 * else it will be skipped. The function will only be
95 * executed iff threshold_version is set to MANUAL_CHECK.
96 */
98{
99 /*
100 * Look for composite types that were made during initdb *or* belong to
101 * information_schema; that's important in case information_schema was
102 * dropped and reloaded.
103 *
104 * The cutoff OID here should match the source cluster's value of
105 * FirstNormalObjectId. We hardcode it rather than using that C #define
106 * because, if that #define is ever changed, our own version's value is
107 * NOT what to use. Eventually we may need a test on the source cluster's
108 * version to select the correct value.
109 */
110 {
111 .status = gettext_noop("Checking for system-defined composite types in user tables"),
112 .report_filename = "tables_using_composite.txt",
113 .base_query =
114 "SELECT t.oid FROM pg_catalog.pg_type t "
115 "LEFT JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid "
116 " WHERE typtype = 'c' AND (t.oid < 16384 OR nspname = 'information_schema')",
117 .report_text =
118 gettext_noop("Your installation contains system-defined composite types in user tables.\n"
119 "These type OIDs are not stable across PostgreSQL versions,\n"
120 "so this cluster cannot currently be upgraded. You can drop the\n"
121 "problem columns and restart the upgrade.\n"),
122 .threshold_version = ALL_VERSIONS
123 },
124
125 /*
126 * 9.3 -> 9.4 Fully implement the 'line' data type in 9.4, which
127 * previously returned "not enabled" by default and was only functionally
128 * enabled with a compile-time switch; as of 9.4 "line" has a different
129 * on-disk representation format.
130 */
131 {
132 .status = gettext_noop("Checking for incompatible \"line\" data type"),
133 .report_filename = "tables_using_line.txt",
134 .base_query =
135 "SELECT 'pg_catalog.line'::pg_catalog.regtype AS oid",
136 .report_text =
137 gettext_noop("Your installation contains the \"line\" data type in user tables.\n"
138 "This data type changed its internal and input/output format\n"
139 "between your old and new versions so this\n"
140 "cluster cannot currently be upgraded. You can\n"
141 "drop the problem columns and restart the upgrade.\n"),
142 .threshold_version = 903
143 },
144
145 /*
146 * pg_upgrade only preserves these system values: pg_class.oid pg_type.oid
147 * pg_enum.oid
148 *
149 * Many of the reg* data types reference system catalog info that is not
150 * preserved, and hence these data types cannot be used in user tables
151 * upgraded by pg_upgrade.
152 */
153 {
154 .status = gettext_noop("Checking for reg* data types in user tables"),
155 .report_filename = "tables_using_reg.txt",
156
157 /*
158 * Note: older servers will not have all of these reg* types, so we
159 * have to write the query like this rather than depending on casts to
160 * regtype.
161 */
162 .base_query =
163 "SELECT oid FROM pg_catalog.pg_type t "
164 "WHERE t.typnamespace = "
165 " (SELECT oid FROM pg_catalog.pg_namespace "
166 " WHERE nspname = 'pg_catalog') "
167 " AND t.typname IN ( "
168 /* pg_class.oid is preserved, so 'regclass' is OK */
169 " 'regcollation', "
170 " 'regconfig', "
171 " 'regdictionary', "
172 " 'regnamespace', "
173 " 'regoper', "
174 " 'regoperator', "
175 " 'regproc', "
176 " 'regprocedure' "
177 /* pg_authid.oid is preserved, so 'regrole' is OK */
178 /* pg_type.oid is (mostly) preserved, so 'regtype' is OK */
179 " )",
180 .report_text =
181 gettext_noop("Your installation contains one of the reg* data types in user tables.\n"
182 "These data types reference system OIDs that are not preserved by\n"
183 "pg_upgrade, so this cluster cannot currently be upgraded. You can\n"
184 "drop the problem columns and restart the upgrade.\n"),
185 .threshold_version = ALL_VERSIONS
186 },
187
188 /*
189 * PG 16 increased the size of the 'aclitem' type, which breaks the
190 * on-disk format for existing data.
191 */
192 {
193 .status = gettext_noop("Checking for incompatible \"aclitem\" data type"),
194 .report_filename = "tables_using_aclitem.txt",
195 .base_query =
196 "SELECT 'pg_catalog.aclitem'::pg_catalog.regtype AS oid",
197 .report_text =
198 gettext_noop("Your installation contains the \"aclitem\" data type in user tables.\n"
199 "The internal format of \"aclitem\" changed in PostgreSQL version 16\n"
200 "so this cluster cannot currently be upgraded. You can drop the\n"
201 "problem columns and restart the upgrade.\n"),
202 .threshold_version = 1500
203 },
204
205 /*
206 * It's no longer allowed to create tables or views with "unknown"-type
207 * columns. We do not complain about views with such columns, because
208 * they should get silently converted to "text" columns during the DDL
209 * dump and reload; it seems unlikely to be worth making users do that by
210 * hand. However, if there's a table with such a column, the DDL reload
211 * will fail, so we should pre-detect that rather than failing
212 * mid-upgrade. Worse, if there's a matview with such a column, the DDL
213 * reload will silently change it to "text" which won't match the on-disk
214 * storage (which is like "cstring"). So we *must* reject that.
215 */
216 {
217 .status = gettext_noop("Checking for invalid \"unknown\" user columns"),
218 .report_filename = "tables_using_unknown.txt",
219 .base_query =
220 "SELECT 'pg_catalog.unknown'::pg_catalog.regtype AS oid",
221 .report_text =
222 gettext_noop("Your installation contains the \"unknown\" data type in user tables.\n"
223 "This data type is no longer allowed in tables, so this cluster\n"
224 "cannot currently be upgraded. You can drop the problem columns\n"
225 "and restart the upgrade.\n"),
226 .threshold_version = 906
227 },
228
229 /*
230 * PG 12 changed the 'sql_identifier' type storage to be based on name,
231 * not varchar, which breaks on-disk format for existing data. So we need
232 * to prevent upgrade when used in user objects (tables, indexes, ...). In
233 * 12, the sql_identifier data type was switched from name to varchar,
234 * which does affect the storage (name is by-ref, but not varlena). This
235 * means user tables using sql_identifier for columns are broken because
236 * the on-disk format is different.
237 */
238 {
239 .status = gettext_noop("Checking for invalid \"sql_identifier\" user columns"),
240 .report_filename = "tables_using_sql_identifier.txt",
241 .base_query =
242 "SELECT 'information_schema.sql_identifier'::pg_catalog.regtype AS oid",
243 .report_text =
244 gettext_noop("Your installation contains the \"sql_identifier\" data type in user tables.\n"
245 "The on-disk format for this data type has changed, so this\n"
246 "cluster cannot currently be upgraded. You can drop the problem\n"
247 "columns and restart the upgrade.\n"),
248 .threshold_version = 1100
249 },
250
251 /*
252 * JSONB changed its storage format during 9.4 beta, so check for it.
253 */
254 {
255 .status = gettext_noop("Checking for incompatible \"jsonb\" data type in user tables"),
256 .report_filename = "tables_using_jsonb.txt",
257 .base_query =
258 "SELECT 'pg_catalog.jsonb'::pg_catalog.regtype AS oid",
259 .report_text =
260 gettext_noop("Your installation contains the \"jsonb\" data type in user tables.\n"
261 "The internal format of \"jsonb\" changed during 9.4 beta so this\n"
262 "cluster cannot currently be upgraded. You can drop the problem \n"
263 "columns and restart the upgrade.\n"),
264 .threshold_version = MANUAL_CHECK,
265 .version_hook = jsonb_9_4_check_applicable
266 },
267
268 /*
269 * PG 12 removed types abstime, reltime, tinterval.
270 */
271 {
272 .status = gettext_noop("Checking for removed \"abstime\" data type in user tables"),
273 .report_filename = "tables_using_abstime.txt",
274 .base_query =
275 "SELECT 'pg_catalog.abstime'::pg_catalog.regtype AS oid",
276 .report_text =
277 gettext_noop("Your installation contains the \"abstime\" data type in user tables.\n"
278 "The \"abstime\" type has been removed in PostgreSQL version 12,\n"
279 "so this cluster cannot currently be upgraded. You can drop the\n"
280 "problem columns, or change them to another data type, and restart\n"
281 "the upgrade.\n"),
282 .threshold_version = 1100
283 },
284 {
285 .status = gettext_noop("Checking for removed \"reltime\" data type in user tables"),
286 .report_filename = "tables_using_reltime.txt",
287 .base_query =
288 "SELECT 'pg_catalog.reltime'::pg_catalog.regtype AS oid",
289 .report_text =
290 gettext_noop("Your installation contains the \"reltime\" data type in user tables.\n"
291 "The \"reltime\" type has been removed in PostgreSQL version 12,\n"
292 "so this cluster cannot currently be upgraded. You can drop the\n"
293 "problem columns, or change them to another data type, and restart\n"
294 "the upgrade.\n"),
295 .threshold_version = 1100
296 },
297 {
298 .status = gettext_noop("Checking for removed \"tinterval\" data type in user tables"),
299 .report_filename = "tables_using_tinterval.txt",
300 .base_query =
301 "SELECT 'pg_catalog.tinterval'::pg_catalog.regtype AS oid",
302 .report_text =
303 gettext_noop("Your installation contains the \"tinterval\" data type in user tables.\n"
304 "The \"tinterval\" type has been removed in PostgreSQL version 12,\n"
305 "so this cluster cannot currently be upgraded. You can drop the\n"
306 "problem columns, or change them to another data type, and restart\n"
307 "the upgrade.\n"),
308 .threshold_version = 1100
309 },
310
311 /* End of checks marker, must remain last */
312 {
313 NULL, NULL, NULL, NULL, 0, NULL
314 }
315};
316
317/*
318 * Private state for check_for_data_types_usage()'s UpgradeTask.
319 */
321{
322 DataTypesUsageChecks *check; /* the check for this step */
323 bool result; /* true if check failed for any database */
324 PQExpBuffer *report; /* buffer for report on failed checks */
325};
326
327/*
328 * Returns a palloc'd query string for the data type check, for use by
329 * check_for_data_types_usage()'s UpgradeTask.
330 */
331static char *
333{
335
336 return psprintf("WITH RECURSIVE oids AS ( "
337 /* start with the type(s) returned by base_query */
338 " %s "
339 " UNION ALL "
340 " SELECT * FROM ( "
341 /* inner WITH because we can only reference the CTE once */
342 " WITH x AS (SELECT oid FROM oids) "
343 /* domains on any type selected so far */
344 " SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typbasetype = x.oid AND typtype = 'd' "
345 " UNION ALL "
346 /* arrays over any type selected so far */
347 " SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typelem = x.oid AND typtype = 'b' "
348 " UNION ALL "
349 /* composite types containing any type selected so far */
350 " SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_class c, pg_catalog.pg_attribute a, x "
351 " WHERE t.typtype = 'c' AND "
352 " t.oid = c.reltype AND "
353 " c.oid = a.attrelid AND "
354 " NOT a.attisdropped AND "
355 " a.atttypid = x.oid "
356 " UNION ALL "
357 /* ranges containing any type selected so far */
358 " SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_range r, x "
359 " WHERE t.typtype = 'r' AND r.rngtypid = t.oid AND r.rngsubtype = x.oid"
360 " ) foo "
361 ") "
362 /* now look for stored columns of any such type */
363 "SELECT n.nspname, c.relname, a.attname "
364 "FROM pg_catalog.pg_class c, "
365 " pg_catalog.pg_namespace n, "
366 " pg_catalog.pg_attribute a "
367 "WHERE c.oid = a.attrelid AND "
368 " NOT a.attisdropped AND "
369 " a.atttypid IN (SELECT oid FROM oids) AND "
370 " c.relkind IN ("
371 CppAsString2(RELKIND_RELATION) ", "
372 CppAsString2(RELKIND_MATVIEW) ", "
373 CppAsString2(RELKIND_INDEX) ") AND "
374 " c.relnamespace = n.oid AND "
375 /* exclude possible orphaned temp tables */
376 " n.nspname !~ '^pg_temp_' AND "
377 " n.nspname !~ '^pg_toast_temp_' AND "
378 /* exclude system catalogs, too */
379 " n.nspname NOT IN ('pg_catalog', 'information_schema')",
380 check->base_query);
381}
382
383/*
384 * Callback function for processing results of queries for
385 * check_for_data_types_usage()'s UpgradeTask. If the query returned any rows
386 * (i.e., the check failed), write the details to the report file.
387 */
388static void
390{
392 int ntups = PQntuples(res);
393 char output_path[MAXPGPATH];
394 int i_nspname = PQfnumber(res, "nspname");
395 int i_relname = PQfnumber(res, "relname");
396 int i_attname = PQfnumber(res, "attname");
397 FILE *script = NULL;
398
400
401 if (ntups == 0)
402 return;
403
404 snprintf(output_path, sizeof(output_path), "%s/%s",
406 state->check->report_filename);
407
408 /*
409 * Make sure we have a buffer to save reports to now that we found a first
410 * failing check.
411 */
412 if (*state->report == NULL)
413 *state->report = createPQExpBuffer();
414
415 /*
416 * If this is the first time we see an error for the check in question
417 * then print a status message of the failure.
418 */
419 if (!state->result)
420 {
421 pg_log(PG_REPORT, "failed check: %s", _(state->check->status));
422 appendPQExpBuffer(*state->report, "\n%s\n%s %s\n",
423 _(state->check->report_text),
424 _("A list of the problem columns is in the file:"),
425 output_path);
426 }
427 state->result = true;
428
429 if ((script = fopen_priv(output_path, "a")) == NULL)
430 pg_fatal("could not open file \"%s\": %m", output_path);
431
432 fprintf(script, "In database: %s\n", dbinfo->db_name);
433
434 for (int rowno = 0; rowno < ntups; rowno++)
435 fprintf(script, " %s.%s.%s\n",
436 PQgetvalue(res, rowno, i_nspname),
437 PQgetvalue(res, rowno, i_relname),
438 PQgetvalue(res, rowno, i_attname));
439
440 fclose(script);
441}
442
443/*
444 * check_for_data_types_usage()
445 * Detect whether there are any stored columns depending on given type(s)
446 *
447 * If so, write a report to the given file name and signal a failure to the
448 * user.
449 *
450 * The checks to run are defined in a DataTypesUsageChecks structure where
451 * each check has a metadata for explaining errors to the user, a base_query,
452 * a report filename and a function pointer hook for validating if the check
453 * should be executed given the cluster at hand.
454 *
455 * base_query should be a SELECT yielding a single column named "oid",
456 * containing the pg_type OIDs of one or more types that are known to have
457 * inconsistent on-disk representations across server versions.
458 *
459 * We check for the type(s) in tables, matviews, and indexes, but not views;
460 * there's no storage involved in a view.
461 */
462static void
464{
465 PQExpBuffer report = NULL;
467 int n_data_types_usage_checks = 0;
469 char **queries = NULL;
470 struct data_type_check_state *states;
471
472 prep_status("Checking data type usage");
473
474 /* Gather number of checks to perform */
475 while (tmp->status != NULL)
476 {
477 n_data_types_usage_checks++;
478 tmp++;
479 }
480
481 /* Allocate memory for queries and for task states */
482 queries = pg_malloc0(sizeof(char *) * n_data_types_usage_checks);
483 states = pg_malloc0(sizeof(struct data_type_check_state) * n_data_types_usage_checks);
484
485 for (int i = 0; i < n_data_types_usage_checks; i++)
486 {
488
490 {
492
493 /*
494 * Make sure that the check applies to the current cluster version
495 * and skip it if not.
496 */
498 continue;
499 }
501 {
502 if (GET_MAJOR_VERSION(cluster->major_version) > check->threshold_version)
503 continue;
504 }
505 else
507
508 queries[i] = data_type_check_query(i);
509
510 states[i].check = check;
511 states[i].report = &report;
512
514 true, &states[i]);
515 }
516
517 /*
518 * Connect to each database in the cluster and run all defined checks
519 * against that database before trying the next one.
520 */
522 upgrade_task_free(task);
523
524 if (report)
525 {
526 pg_fatal("Data type checks failed: %s", report->data);
528 }
529
530 for (int i = 0; i < n_data_types_usage_checks; i++)
531 {
532 if (queries[i])
533 pg_free(queries[i]);
534 }
535 pg_free(queries);
536 pg_free(states);
537
538 check_ok();
539}
540
541/*
542 * fix_path_separator
543 * For non-Windows, just return the argument.
544 * For Windows convert any forward slash to a backslash
545 * such as is suitable for arguments to builtin commands
546 * like RMDIR and DEL.
547 */
548static char *
550{
551#ifdef WIN32
552
553 char *result;
554 char *c;
555
556 result = pg_strdup(path);
557
558 for (c = result; *c != '\0'; c++)
559 if (*c == '/')
560 *c = '\\';
561
562 return result;
563#else
564
565 return path;
566#endif
567}
568
569void
571{
573 {
575 "Performing Consistency Checks on Old Live Server\n"
576 "------------------------------------------------");
577 }
578 else
579 {
581 "Performing Consistency Checks\n"
582 "-----------------------------");
583 }
584}
585
586
587void
589{
590 /* -- OLD -- */
591
594
595 /*
596 * First check that all databases allow connections since we'll otherwise
597 * fail in later stages.
598 */
600
601 /*
602 * Extract a list of databases, tables, and logical replication slots from
603 * the old cluster.
604 */
606
608
610
611
612 /*
613 * Check for various failure cases
614 */
618
620 {
621 /*
622 * Logical replication slots can be migrated since PG17. See comments
623 * atop get_old_cluster_logical_slot_infos().
624 */
626
627 /*
628 * Subscriptions and their dependencies can be migrated since PG17.
629 * Before that the logical slots are not upgraded, so we will not be
630 * able to upgrade the logical replication clusters completely.
631 */
634 }
635
637
638 /*
639 * Unicode updates can affect some objects that use expressions with
640 * functions dependent on Unicode.
641 */
643
644 /*
645 * PG 14 changed the function signature of encoding conversion functions.
646 * Conversions from older versions cannot be upgraded automatically
647 * because the user-defined functions used by the encoding conversions
648 * need to be changed to match the new signature.
649 */
652
653 /*
654 * Pre-PG 14 allowed user defined postfix operators, which are not
655 * supported anymore. Verify there are none, iff applicable.
656 */
659
660 /*
661 * PG 14 changed polymorphic functions from anyarray to
662 * anycompatiblearray.
663 */
666
667 /*
668 * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
669 * supported anymore. Verify there are none, iff applicable.
670 */
673
674 /*
675 * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
676 * hash indexes
677 */
679 {
680 if (user_opts.check)
682 }
683
684 /* 9.5 and below should not have roles starting with pg_ */
687
688 /*
689 * While not a check option, we do this now because this is the only time
690 * the old server is running.
691 */
692 if (!user_opts.check)
694
696 stop_postmaster(false);
697}
698
699
700void
702{
704
706
708
709 switch (user_opts.transfer_mode)
710 {
713 break;
715 break;
718 break;
721 break;
723
724 /*
725 * We do the hard link check for --swap, too, since it's an easy
726 * way to verify the clusters are in the same file system. This
727 * allows us to take some shortcuts in the file synchronization
728 * step. With some more effort, we could probably support the
729 * separate-file-system use case, but this mode is unlikely to
730 * offer much benefit if we have to copy the files across file
731 * system boundaries.
732 */
734
735 /*
736 * There are a few known issues with using --swap to upgrade from
737 * versions older than 10. For example, the sequence tuple format
738 * changed in v10, and the visibility map format changed in 9.6.
739 * While such problems are not insurmountable (and we may have to
740 * deal with similar problems in the future, anyway), it doesn't
741 * seem worth the effort to support swap mode for upgrades from
742 * long-unsupported versions.
743 */
745 pg_fatal("Swap mode can only upgrade clusters from PostgreSQL version %s and later.",
746 "10");
747
748 break;
749 }
750
752
754
756
758
760}
761
762
763void
765{
766 if (user_opts.check)
767 {
768 pg_log(PG_REPORT, "\n*Clusters are compatible*");
769 /* stops new cluster */
770 stop_postmaster(false);
771
773 exit(0);
774 }
775
776 pg_log(PG_REPORT, "\n"
777 "If pg_upgrade fails after this point, you must re-initdb the\n"
778 "new cluster before continuing.");
779}
780
781
782void
784{
785 /*
786 * We unconditionally start/stop the new server because pg_resetwal -o set
787 * wal_level to 'minimum'. If the user is upgrading standby servers using
788 * the rsync instructions, they will need pg_upgrade to write its final
789 * WAL record showing wal_level as 'replica'.
790 */
792
793 /* Reindex hash indexes for old < 10.0 */
796
798
799 stop_postmaster(false);
800}
801
802
803void
804output_completion_banner(char *deletion_script_file_name)
805{
806 PQExpBufferData user_specification;
807
808 initPQExpBuffer(&user_specification);
810 {
811 appendPQExpBufferStr(&user_specification, "-U ");
812 appendShellString(&user_specification, os_info.user);
813 appendPQExpBufferChar(&user_specification, ' ');
814 }
815
817 "Some optimizer statistics may not have been transferred by pg_upgrade.\n"
818 "Once you start the new server, consider running:\n"
819 " %s/vacuumdb %s--all --analyze-in-stages --missing-stats-only", new_cluster.bindir, user_specification.data);
820
821 if (deletion_script_file_name)
823 "Running this script will delete the old cluster's data files:\n"
824 " %s",
825 deletion_script_file_name);
826 else
828 "Could not create a script to delete the old cluster's data files\n"
829 "because user-defined tablespaces or the new cluster's data directory\n"
830 "exist in the old cluster directory. The old cluster's contents must\n"
831 "be deleted manually.");
832
833 termPQExpBuffer(&user_specification);
834}
835
836
837void
839{
840 prep_status("Checking cluster versions");
841
842 /* cluster versions should already have been obtained */
845
846 /*
847 * We allow upgrades from/to the same major version for alpha/beta
848 * upgrades
849 */
850
852 pg_fatal("This utility can only upgrade from PostgreSQL version %s and later.",
853 "9.2");
854
855 /* Only current PG version is supported as a target */
857 pg_fatal("This utility can only upgrade to PostgreSQL version %s.",
858 PG_MAJORVERSION);
859
860 /*
861 * We can't allow downgrading because we use the target pg_dump, and
862 * pg_dump cannot operate on newer database versions, only current and
863 * older versions.
864 */
866 pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.");
867
868 /* Ensure binaries match the designated data directories */
871 pg_fatal("Old cluster data and binary directories are from different major versions.");
874 pg_fatal("New cluster data and binary directories are from different major versions.");
875
876 /*
877 * Since from version 18, newly created database clusters always have
878 * 'signed' default char-signedness, it makes less sense to use
879 * --set-char-signedness option for upgrading from version 18 or later.
880 * Users who want to change the default char signedness of the new
881 * cluster, they can use pg_resetwal manually before the upgrade.
882 */
885 pg_fatal("%s option cannot be used to upgrade from PostgreSQL %s and later.",
886 "--set-char-signedness", "18");
887
888 check_ok();
889}
890
891
892void
894{
895 /* get/check pg_control data of servers */
899
901 pg_fatal("When checking a live server, "
902 "the old and new port numbers must be different.");
903}
904
905
906static void
908{
909 int dbnum;
910
911 for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
912 {
913 int relnum;
914 RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
915
916 for (relnum = 0; relnum < rel_arr->nrels;
917 relnum++)
918 {
919 /* pg_largeobject and its index should be skipped */
920 if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
921 pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"",
923 rel_arr->rels[relnum].nspname,
924 rel_arr->rels[relnum].relname);
925 }
926 }
927}
928
929/*
930 * A previous run of pg_upgrade might have failed and the new cluster
931 * directory recreated, but they might have forgotten to remove
932 * the new cluster's tablespace directories. Therefore, check that
933 * new cluster tablespace directories do not already exist. If
934 * they do, it would cause an error while restoring global objects.
935 * This allows the failure to be detected at check time, rather than
936 * during schema restore.
937 */
938static void
940{
941 int tblnum;
942 char new_tablespace_dir[MAXPGPATH];
943
944 prep_status("Checking for new cluster tablespace directories");
945
946 for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
947 {
948 struct stat statbuf;
949
950 snprintf(new_tablespace_dir, MAXPGPATH, "%s%s",
951 os_info.old_tablespaces[tblnum],
953
954 if (stat(new_tablespace_dir, &statbuf) == 0 || errno != ENOENT)
955 pg_fatal("new cluster tablespace directory already exists: \"%s\"",
956 new_tablespace_dir);
957 }
958
959 check_ok();
960}
961
962/*
963 * create_script_for_old_cluster_deletion()
964 *
965 * This is particularly useful for tablespace deletion.
966 */
967void
968create_script_for_old_cluster_deletion(char **deletion_script_file_name)
969{
970 FILE *script = NULL;
971 int tblnum;
972 char old_cluster_pgdata[MAXPGPATH],
973 new_cluster_pgdata[MAXPGPATH];
974 char *old_tblspc_suffix;
975
976 *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
978
979 strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
980 canonicalize_path(old_cluster_pgdata);
981
982 strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
983 canonicalize_path(new_cluster_pgdata);
984
985 /* Some people put the new data directory inside the old one. */
986 if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
987 {
989 "\nWARNING: new data directory should not be inside the old data directory, i.e. %s", old_cluster_pgdata);
990
991 /* Unlink file in case it is left over from a previous run. */
992 unlink(*deletion_script_file_name);
993 pg_free(*deletion_script_file_name);
994 *deletion_script_file_name = NULL;
995 return;
996 }
997
998 /*
999 * Some users (oddly) create tablespaces inside the cluster data
1000 * directory. We can't create a proper old cluster delete script in that
1001 * case.
1002 */
1003 for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
1004 {
1005 char old_tablespace_dir[MAXPGPATH];
1006
1007 strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
1008 canonicalize_path(old_tablespace_dir);
1009 if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
1010 {
1011 /* reproduce warning from CREATE TABLESPACE that is in the log */
1013 "\nWARNING: user-defined tablespace locations should not be inside the data directory, i.e. %s", old_tablespace_dir);
1014
1015 /* Unlink file in case it is left over from a previous run. */
1016 unlink(*deletion_script_file_name);
1017 pg_free(*deletion_script_file_name);
1018 *deletion_script_file_name = NULL;
1019 return;
1020 }
1021 }
1022
1023 prep_status("Creating script to delete old cluster");
1024
1025 if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
1026 pg_fatal("could not open file \"%s\": %m",
1027 *deletion_script_file_name);
1028
1029#ifndef WIN32
1030 /* add shebang header */
1031 fprintf(script, "#!/bin/sh\n\n");
1032#endif
1033
1034 /* delete old cluster's default tablespace */
1035 fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
1037
1038 /* delete old cluster's alternate tablespaces */
1039 old_tblspc_suffix = pg_strdup(old_cluster.tablespace_suffix);
1040 fix_path_separator(old_tblspc_suffix);
1041 for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
1042 fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
1044 old_tblspc_suffix, PATH_QUOTE);
1045 pfree(old_tblspc_suffix);
1046
1047 fclose(script);
1048
1049#ifndef WIN32
1050 if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
1051 pg_fatal("could not add execute permission to file \"%s\": %m",
1052 *deletion_script_file_name);
1053#endif
1054
1055 check_ok();
1056}
1057
1058
1059/*
1060 * check_is_install_user()
1061 *
1062 * Check we are the install user, and that the new cluster
1063 * has no other users.
1064 */
1065static void
1067{
1068 PGresult *res;
1069 PGconn *conn = connectToServer(cluster, "template1");
1070
1071 prep_status("Checking database user is the install user");
1072
1073 /* Can't use pg_authid because only superusers can view it. */
1074 res = executeQueryOrDie(conn,
1075 "SELECT rolsuper, oid "
1076 "FROM pg_catalog.pg_roles "
1077 "WHERE rolname = current_user "
1078 "AND rolname !~ '^pg_'");
1079
1080 /*
1081 * We only allow the install user in the new cluster (see comment below)
1082 * and we preserve pg_authid.oid, so this must be the install user in the
1083 * old cluster too.
1084 */
1085 if (PQntuples(res) != 1 ||
1086 atooid(PQgetvalue(res, 0, 1)) != BOOTSTRAP_SUPERUSERID)
1087 pg_fatal("database user \"%s\" is not the install user",
1088 os_info.user);
1089
1090 PQclear(res);
1091
1092 res = executeQueryOrDie(conn,
1093 "SELECT COUNT(*) "
1094 "FROM pg_catalog.pg_roles "
1095 "WHERE rolname !~ '^pg_'");
1096
1097 if (PQntuples(res) != 1)
1098 pg_fatal("could not determine the number of users");
1099
1100 /*
1101 * We only allow the install user in the new cluster because other defined
1102 * users might match users defined in the old cluster and generate an
1103 * error during pg_dump restore.
1104 */
1105 if (cluster == &new_cluster && strcmp(PQgetvalue(res, 0, 0), "1") != 0)
1106 pg_fatal("Only the install user can be defined in the new cluster.");
1107
1108 PQclear(res);
1109
1110 PQfinish(conn);
1111
1112 check_ok();
1113}
1114
1115
1116/*
1117 * check_for_connection_status
1118 *
1119 * Ensure that all non-template0 databases allow connections since they
1120 * otherwise won't be restored; and that template0 explicitly doesn't allow
1121 * connections since it would make pg_dumpall --globals restore fail.
1122 */
1123static void
1125{
1126 int dbnum;
1127 PGconn *conn_template1;
1128 PGresult *dbres;
1129 int ntups;
1130 int i_datname;
1131 int i_datallowconn;
1132 int i_datconnlimit;
1133 FILE *script = NULL;
1134 char output_path[MAXPGPATH];
1135
1136 prep_status("Checking database connection settings");
1137
1138 snprintf(output_path, sizeof(output_path), "%s/%s",
1140 "databases_cannot_connect_to.txt");
1141
1142 conn_template1 = connectToServer(cluster, "template1");
1143
1144 /* get database names */
1145 dbres = executeQueryOrDie(conn_template1,
1146 "SELECT datname, datallowconn, datconnlimit "
1147 "FROM pg_catalog.pg_database");
1148
1149 i_datname = PQfnumber(dbres, "datname");
1150 i_datallowconn = PQfnumber(dbres, "datallowconn");
1151 i_datconnlimit = PQfnumber(dbres, "datconnlimit");
1152
1153 ntups = PQntuples(dbres);
1154 for (dbnum = 0; dbnum < ntups; dbnum++)
1155 {
1156 char *datname = PQgetvalue(dbres, dbnum, i_datname);
1157 char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
1158 char *datconnlimit = PQgetvalue(dbres, dbnum, i_datconnlimit);
1159
1160 if (strcmp(datname, "template0") == 0)
1161 {
1162 /* avoid restore failure when pg_dumpall tries to create template0 */
1163 if (strcmp(datallowconn, "t") == 0)
1164 pg_fatal("template0 must not allow connections, "
1165 "i.e. its pg_database.datallowconn must be false");
1166 }
1167 else
1168 {
1169 /*
1170 * Avoid datallowconn == false databases from being skipped on
1171 * restore, and ensure that no databases are marked invalid with
1172 * datconnlimit == -2.
1173 */
1174 if ((strcmp(datallowconn, "f") == 0) || strcmp(datconnlimit, "-2") == 0)
1175 {
1176 if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1177 pg_fatal("could not open file \"%s\": %m", output_path);
1178
1179 fprintf(script, "%s\n", datname);
1180 }
1181 }
1182 }
1183
1184 PQclear(dbres);
1185
1186 PQfinish(conn_template1);
1187
1188 if (script)
1189 {
1190 fclose(script);
1191 pg_log(PG_REPORT, "fatal");
1192 pg_fatal("All non-template0 databases must allow connections, i.e. their\n"
1193 "pg_database.datallowconn must be true and pg_database.datconnlimit\n"
1194 "must not be -2. Your installation contains non-template0 databases\n"
1195 "which cannot be connected to. Consider allowing connection for all\n"
1196 "non-template0 databases or drop the databases which do not allow\n"
1197 "connections. A list of databases with the problem is in the file:\n"
1198 " %s", output_path);
1199 }
1200 else
1201 check_ok();
1202}
1203
1204
1205/*
1206 * check_for_prepared_transactions()
1207 *
1208 * Make sure there are no prepared transactions because the storage format
1209 * might have changed.
1210 */
1211static void
1213{
1214 PGresult *res;
1215 PGconn *conn = connectToServer(cluster, "template1");
1216
1217 prep_status("Checking for prepared transactions");
1218
1219 res = executeQueryOrDie(conn,
1220 "SELECT * "
1221 "FROM pg_catalog.pg_prepared_xacts");
1222
1223 if (PQntuples(res) != 0)
1224 {
1225 if (cluster == &old_cluster)
1226 pg_fatal("The source cluster contains prepared transactions");
1227 else
1228 pg_fatal("The target cluster contains prepared transactions");
1229 }
1230
1231 PQclear(res);
1232
1233 PQfinish(conn);
1234
1235 check_ok();
1236}
1237
1238/*
1239 * Callback function for processing result of query for
1240 * check_for_isn_and_int8_passing_mismatch()'s UpgradeTask. If the query
1241 * returned any rows (i.e., the check failed), write the details to the report
1242 * file.
1243 */
1244static void
1246{
1247 int ntups = PQntuples(res);
1248 int i_nspname = PQfnumber(res, "nspname");
1249 int i_proname = PQfnumber(res, "proname");
1251
1254
1255 if (ntups == 0)
1256 return;
1257
1258 if (report->file == NULL &&
1259 (report->file = fopen_priv(report->path, "w")) == NULL)
1260 pg_fatal("could not open file \"%s\": %m", report->path);
1261
1262 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1263
1264 for (int rowno = 0; rowno < ntups; rowno++)
1265 fprintf(report->file, " %s.%s\n",
1266 PQgetvalue(res, rowno, i_nspname),
1267 PQgetvalue(res, rowno, i_proname));
1268}
1269
1270/*
1271 * check_for_isn_and_int8_passing_mismatch()
1272 *
1273 * contrib/isn relies on data type int8, and in 8.4 int8 can now be passed
1274 * by value. The schema dumps the CREATE TYPE PASSEDBYVALUE setting so
1275 * it must match for the old and new servers.
1276 */
1277static void
1279{
1280 UpgradeTask *task;
1281 UpgradeTaskReport report;
1282 const char *query = "SELECT n.nspname, p.proname "
1283 "FROM pg_catalog.pg_proc p, "
1284 " pg_catalog.pg_namespace n "
1285 "WHERE p.pronamespace = n.oid AND "
1286 " p.probin = '$libdir/isn'";
1287
1288 prep_status("Checking for contrib/isn with bigint-passing mismatch");
1289
1292 {
1293 /* no mismatch */
1294 check_ok();
1295 return;
1296 }
1297
1298 report.file = NULL;
1299 snprintf(report.path, sizeof(report.path), "%s/%s",
1301 "contrib_isn_and_int8_pass_by_value.txt");
1302
1303 task = upgrade_task_create();
1305 true, &report);
1307 upgrade_task_free(task);
1308
1309 if (report.file)
1310 {
1311 fclose(report.file);
1312 pg_log(PG_REPORT, "fatal");
1313 pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
1314 "bigint data type. Your old and new clusters pass bigint values\n"
1315 "differently so this cluster cannot currently be upgraded. You can\n"
1316 "manually dump databases in the old cluster that use \"contrib/isn\"\n"
1317 "facilities, drop them, perform the upgrade, and then restore them. A\n"
1318 "list of the problem functions is in the file:\n"
1319 " %s", report.path);
1320 }
1321 else
1322 check_ok();
1323}
1324
1325/*
1326 * Callback function for processing result of query for
1327 * check_for_user_defined_postfix_ops()'s UpgradeTask. If the query returned
1328 * any rows (i.e., the check failed), write the details to the report file.
1329 */
1330static void
1332{
1334 int ntups = PQntuples(res);
1335 int i_oproid = PQfnumber(res, "oproid");
1336 int i_oprnsp = PQfnumber(res, "oprnsp");
1337 int i_oprname = PQfnumber(res, "oprname");
1338 int i_typnsp = PQfnumber(res, "typnsp");
1339 int i_typname = PQfnumber(res, "typname");
1340
1343
1344 if (ntups == 0)
1345 return;
1346
1347 if (report->file == NULL &&
1348 (report->file = fopen_priv(report->path, "w")) == NULL)
1349 pg_fatal("could not open file \"%s\": %m", report->path);
1350
1351 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1352
1353 for (int rowno = 0; rowno < ntups; rowno++)
1354 fprintf(report->file, " (oid=%s) %s.%s (%s.%s, NONE)\n",
1355 PQgetvalue(res, rowno, i_oproid),
1356 PQgetvalue(res, rowno, i_oprnsp),
1357 PQgetvalue(res, rowno, i_oprname),
1358 PQgetvalue(res, rowno, i_typnsp),
1359 PQgetvalue(res, rowno, i_typname));
1360}
1361
1362/*
1363 * Verify that no user defined postfix operators exist.
1364 */
1365static void
1367{
1368 UpgradeTaskReport report;
1370 const char *query;
1371
1372 /*
1373 * The query below hardcodes FirstNormalObjectId as 16384 rather than
1374 * interpolating that C #define into the query because, if that #define is
1375 * ever changed, the cutoff we want to use is the value used by
1376 * pre-version 14 servers, not that of some future version.
1377 */
1378 query = "SELECT o.oid AS oproid, "
1379 " n.nspname AS oprnsp, "
1380 " o.oprname, "
1381 " tn.nspname AS typnsp, "
1382 " t.typname "
1383 "FROM pg_catalog.pg_operator o, "
1384 " pg_catalog.pg_namespace n, "
1385 " pg_catalog.pg_type t, "
1386 " pg_catalog.pg_namespace tn "
1387 "WHERE o.oprnamespace = n.oid AND "
1388 " o.oprleft = t.oid AND "
1389 " t.typnamespace = tn.oid AND "
1390 " o.oprright = 0 AND "
1391 " o.oid >= 16384";
1392
1393 prep_status("Checking for user-defined postfix operators");
1394
1395 report.file = NULL;
1396 snprintf(report.path, sizeof(report.path), "%s/%s",
1398 "postfix_ops.txt");
1399
1401 true, &report);
1403 upgrade_task_free(task);
1404
1405 if (report.file)
1406 {
1407 fclose(report.file);
1408 pg_log(PG_REPORT, "fatal");
1409 pg_fatal("Your installation contains user-defined postfix operators, which are not\n"
1410 "supported anymore. Consider dropping the postfix operators and replacing\n"
1411 "them with prefix operators or function calls.\n"
1412 "A list of user-defined postfix operators is in the file:\n"
1413 " %s", report.path);
1414 }
1415 else
1416 check_ok();
1417}
1418
1419/*
1420 * Callback function for processing results of query for
1421 * check_for_incompatible_polymorphics()'s UpgradeTask. If the query returned
1422 * any rows (i.e., the check failed), write the details to the report file.
1423 */
1424static void
1426{
1428 int ntups = PQntuples(res);
1429 int i_objkind = PQfnumber(res, "objkind");
1430 int i_objname = PQfnumber(res, "objname");
1431
1434
1435 if (ntups == 0)
1436 return;
1437
1438 if (report->file == NULL &&
1439 (report->file = fopen_priv(report->path, "w")) == NULL)
1440 pg_fatal("could not open file \"%s\": %m", report->path);
1441
1442 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1443
1444 for (int rowno = 0; rowno < ntups; rowno++)
1445 fprintf(report->file, " %s: %s\n",
1446 PQgetvalue(res, rowno, i_objkind),
1447 PQgetvalue(res, rowno, i_objname));
1448}
1449
1450/*
1451 * check_for_incompatible_polymorphics()
1452 *
1453 * Make sure nothing is using old polymorphic functions with
1454 * anyarray/anyelement rather than the new anycompatible variants.
1455 */
1456static void
1458{
1459 PQExpBufferData old_polymorphics;
1461 UpgradeTaskReport report;
1462 char *query;
1463
1464 prep_status("Checking for incompatible polymorphic functions");
1465
1466 report.file = NULL;
1467 snprintf(report.path, sizeof(report.path), "%s/%s",
1469 "incompatible_polymorphics.txt");
1470
1471 /* The set of problematic functions varies a bit in different versions */
1472 initPQExpBuffer(&old_polymorphics);
1473
1474 appendPQExpBufferStr(&old_polymorphics,
1475 "'array_append(anyarray,anyelement)'"
1476 ", 'array_cat(anyarray,anyarray)'"
1477 ", 'array_prepend(anyelement,anyarray)'");
1478
1479 if (GET_MAJOR_VERSION(cluster->major_version) >= 903)
1480 appendPQExpBufferStr(&old_polymorphics,
1481 ", 'array_remove(anyarray,anyelement)'"
1482 ", 'array_replace(anyarray,anyelement,anyelement)'");
1483
1484 if (GET_MAJOR_VERSION(cluster->major_version) >= 905)
1485 appendPQExpBufferStr(&old_polymorphics,
1486 ", 'array_position(anyarray,anyelement)'"
1487 ", 'array_position(anyarray,anyelement,integer)'"
1488 ", 'array_positions(anyarray,anyelement)'"
1489 ", 'width_bucket(anyelement,anyarray)'");
1490
1491 /*
1492 * The query below hardcodes FirstNormalObjectId as 16384 rather than
1493 * interpolating that C #define into the query because, if that #define is
1494 * ever changed, the cutoff we want to use is the value used by
1495 * pre-version 14 servers, not that of some future version.
1496 */
1497
1498 /* Aggregate transition functions */
1499 query = psprintf("SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
1500 "FROM pg_proc AS p "
1501 "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
1502 "JOIN pg_proc AS transfn ON transfn.oid=a.aggtransfn "
1503 "WHERE p.oid >= 16384 "
1504 "AND a.aggtransfn = ANY(ARRAY[%s]::regprocedure[]) "
1505 "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
1506
1507 /* Aggregate final functions */
1508 "UNION ALL "
1509 "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
1510 "FROM pg_proc AS p "
1511 "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
1512 "JOIN pg_proc AS finalfn ON finalfn.oid=a.aggfinalfn "
1513 "WHERE p.oid >= 16384 "
1514 "AND a.aggfinalfn = ANY(ARRAY[%s]::regprocedure[]) "
1515 "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
1516
1517 /* Operators */
1518 "UNION ALL "
1519 "SELECT 'operator' AS objkind, op.oid::regoperator::text AS objname "
1520 "FROM pg_operator AS op "
1521 "WHERE op.oid >= 16384 "
1522 "AND oprcode = ANY(ARRAY[%s]::regprocedure[]) "
1523 "AND oprleft = ANY(ARRAY['anyarray', 'anyelement']::regtype[])",
1524 old_polymorphics.data,
1525 old_polymorphics.data,
1526 old_polymorphics.data);
1527
1529 true, &report);
1531 upgrade_task_free(task);
1532
1533 if (report.file)
1534 {
1535 fclose(report.file);
1536 pg_log(PG_REPORT, "fatal");
1537 pg_fatal("Your installation contains user-defined objects that refer to internal\n"
1538 "polymorphic functions with arguments of type \"anyarray\" or \"anyelement\".\n"
1539 "These user-defined objects must be dropped before upgrading and restored\n"
1540 "afterwards, changing them to refer to the new corresponding functions with\n"
1541 "arguments of type \"anycompatiblearray\" and \"anycompatible\".\n"
1542 "A list of the problematic objects is in the file:\n"
1543 " %s", report.path);
1544 }
1545 else
1546 check_ok();
1547
1548 termPQExpBuffer(&old_polymorphics);
1549 pg_free(query);
1550}
1551
1552/*
1553 * Callback function for processing results of query for
1554 * check_for_tables_with_oids()'s UpgradeTask. If the query returned any rows
1555 * (i.e., the check failed), write the details to the report file.
1556 */
1557static void
1559{
1561 int ntups = PQntuples(res);
1562 int i_nspname = PQfnumber(res, "nspname");
1563 int i_relname = PQfnumber(res, "relname");
1564
1566
1567 if (ntups == 0)
1568 return;
1569
1570 if (report->file == NULL &&
1571 (report->file = fopen_priv(report->path, "w")) == NULL)
1572 pg_fatal("could not open file \"%s\": %m", report->path);
1573
1574 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1575
1576 for (int rowno = 0; rowno < ntups; rowno++)
1577 fprintf(report->file, " %s.%s\n",
1578 PQgetvalue(res, rowno, i_nspname),
1579 PQgetvalue(res, rowno, i_relname));
1580}
1581
1582/*
1583 * Verify that no tables are declared WITH OIDS.
1584 */
1585static void
1587{
1588 UpgradeTaskReport report;
1590 const char *query = "SELECT n.nspname, c.relname "
1591 "FROM pg_catalog.pg_class c, "
1592 " pg_catalog.pg_namespace n "
1593 "WHERE c.relnamespace = n.oid AND "
1594 " c.relhasoids AND"
1595 " n.nspname NOT IN ('pg_catalog')";
1596
1597 prep_status("Checking for tables WITH OIDS");
1598
1599 report.file = NULL;
1600 snprintf(report.path, sizeof(report.path), "%s/%s",
1602 "tables_with_oids.txt");
1603
1605 true, &report);
1607 upgrade_task_free(task);
1608
1609 if (report.file)
1610 {
1611 fclose(report.file);
1612 pg_log(PG_REPORT, "fatal");
1613 pg_fatal("Your installation contains tables declared WITH OIDS, which is not\n"
1614 "supported anymore. Consider removing the oid column using\n"
1615 " ALTER TABLE ... SET WITHOUT OIDS;\n"
1616 "A list of tables with the problem is in the file:\n"
1617 " %s", report.path);
1618 }
1619 else
1620 check_ok();
1621}
1622
1623
1624/*
1625 * check_for_pg_role_prefix()
1626 *
1627 * Versions older than 9.6 should not have any pg_* roles
1628 */
1629static void
1631{
1632 PGresult *res;
1633 PGconn *conn = connectToServer(cluster, "template1");
1634 int ntups;
1635 int i_roloid;
1636 int i_rolname;
1637 FILE *script = NULL;
1638 char output_path[MAXPGPATH];
1639
1640 prep_status("Checking for roles starting with \"pg_\"");
1641
1642 snprintf(output_path, sizeof(output_path), "%s/%s",
1644 "pg_role_prefix.txt");
1645
1646 res = executeQueryOrDie(conn,
1647 "SELECT oid AS roloid, rolname "
1648 "FROM pg_catalog.pg_roles "
1649 "WHERE rolname ~ '^pg_'");
1650
1651 ntups = PQntuples(res);
1652 i_roloid = PQfnumber(res, "roloid");
1653 i_rolname = PQfnumber(res, "rolname");
1654 for (int rowno = 0; rowno < ntups; rowno++)
1655 {
1656 if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1657 pg_fatal("could not open file \"%s\": %m", output_path);
1658 fprintf(script, "%s (oid=%s)\n",
1659 PQgetvalue(res, rowno, i_rolname),
1660 PQgetvalue(res, rowno, i_roloid));
1661 }
1662
1663 PQclear(res);
1664
1665 PQfinish(conn);
1666
1667 if (script)
1668 {
1669 fclose(script);
1670 pg_log(PG_REPORT, "fatal");
1671 pg_fatal("Your installation contains roles starting with \"pg_\".\n"
1672 "\"pg_\" is a reserved prefix for system roles. The cluster\n"
1673 "cannot be upgraded until these roles are renamed.\n"
1674 "A list of roles starting with \"pg_\" is in the file:\n"
1675 " %s", output_path);
1676 }
1677 else
1678 check_ok();
1679}
1680
1681/*
1682 * Callback function for processing results of query for
1683 * check_for_user_defined_encoding_conversions()'s UpgradeTask. If the query
1684 * returned any rows (i.e., the check failed), write the details to the report
1685 * file.
1686 */
1687static void
1689{
1691 int ntups = PQntuples(res);
1692 int i_conoid = PQfnumber(res, "conoid");
1693 int i_conname = PQfnumber(res, "conname");
1694 int i_nspname = PQfnumber(res, "nspname");
1695
1698
1699 if (ntups == 0)
1700 return;
1701
1702 if (report->file == NULL &&
1703 (report->file = fopen_priv(report->path, "w")) == NULL)
1704 pg_fatal("could not open file \"%s\": %m", report->path);
1705
1706 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1707
1708 for (int rowno = 0; rowno < ntups; rowno++)
1709 fprintf(report->file, " (oid=%s) %s.%s\n",
1710 PQgetvalue(res, rowno, i_conoid),
1711 PQgetvalue(res, rowno, i_nspname),
1712 PQgetvalue(res, rowno, i_conname));
1713}
1714
1715/*
1716 * Verify that no user-defined encoding conversions exist.
1717 */
1718static void
1720{
1721 UpgradeTaskReport report;
1723 const char *query;
1724
1725 prep_status("Checking for user-defined encoding conversions");
1726
1727 report.file = NULL;
1728 snprintf(report.path, sizeof(report.path), "%s/%s",
1730 "encoding_conversions.txt");
1731
1732 /*
1733 * The query below hardcodes FirstNormalObjectId as 16384 rather than
1734 * interpolating that C #define into the query because, if that #define is
1735 * ever changed, the cutoff we want to use is the value used by
1736 * pre-version 14 servers, not that of some future version.
1737 */
1738 query = "SELECT c.oid as conoid, c.conname, n.nspname "
1739 "FROM pg_catalog.pg_conversion c, "
1740 " pg_catalog.pg_namespace n "
1741 "WHERE c.connamespace = n.oid AND "
1742 " c.oid >= 16384";
1743
1744 upgrade_task_add_step(task, query,
1746 true, &report);
1748 upgrade_task_free(task);
1749
1750 if (report.file)
1751 {
1752 fclose(report.file);
1753 pg_log(PG_REPORT, "fatal");
1754 pg_fatal("Your installation contains user-defined encoding conversions.\n"
1755 "The conversion function parameters changed in PostgreSQL version 14\n"
1756 "so this cluster cannot currently be upgraded. You can remove the\n"
1757 "encoding conversions in the old cluster and restart the upgrade.\n"
1758 "A list of user-defined encoding conversions is in the file:\n"
1759 " %s", report.path);
1760 }
1761 else
1762 check_ok();
1763}
1764
1765/*
1766 * Callback function for processing results of query for
1767 * check_for_unicode_update()'s UpgradeTask. If the query returned any rows
1768 * (i.e., the check failed), write the details to the report file.
1769 */
1770static void
1772{
1774 int ntups = PQntuples(res);
1775 int i_reloid = PQfnumber(res, "reloid");
1776 int i_nspname = PQfnumber(res, "nspname");
1777 int i_relname = PQfnumber(res, "relname");
1778
1779 if (ntups == 0)
1780 return;
1781
1782 if (report->file == NULL &&
1783 (report->file = fopen_priv(report->path, "w")) == NULL)
1784 pg_fatal("could not open file \"%s\": %m", report->path);
1785
1786 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1787
1788 for (int rowno = 0; rowno < ntups; rowno++)
1789 fprintf(report->file, " (oid=%s) %s.%s\n",
1790 PQgetvalue(res, rowno, i_reloid),
1791 PQgetvalue(res, rowno, i_nspname),
1792 PQgetvalue(res, rowno, i_relname));
1793}
1794
1795/*
1796 * Check if the Unicode version built into Postgres changed between the old
1797 * cluster and the new cluster.
1798 */
1799static bool
1801{
1802 PGconn *conn_template1 = connectToServer(cluster, "template1");
1803 PGresult *res;
1804 char *old_unicode_version;
1805 bool unicode_updated;
1806
1807 res = executeQueryOrDie(conn_template1, "SELECT unicode_version()");
1808 old_unicode_version = PQgetvalue(res, 0, 0);
1809 unicode_updated = (strcmp(old_unicode_version, PG_UNICODE_VERSION) != 0);
1810
1811 PQclear(res);
1812 PQfinish(conn_template1);
1813
1814 return unicode_updated;
1815}
1816
1817/*
1818 * check_for_unicode_update()
1819 *
1820 * Check if the version of Unicode in the old server and the new server
1821 * differ. If so, check for indexes, partitioned tables, or constraints that
1822 * use expressions with functions dependent on Unicode behavior.
1823 */
1824static void
1826{
1827 UpgradeTaskReport report;
1828 UpgradeTask *task;
1829 const char *query;
1830
1831 /*
1832 * The builtin provider did not exist prior to version 17. While there are
1833 * still problems that could potentially be caught from earlier versions,
1834 * such as an index on NORMALIZE(), we don't check for that here.
1835 */
1836 if (GET_MAJOR_VERSION(cluster->major_version) < 1700)
1837 return;
1838
1839 prep_status("Checking for objects affected by Unicode update");
1840
1842 {
1843 check_ok();
1844 return;
1845 }
1846
1847 report.file = NULL;
1848 snprintf(report.path, sizeof(report.path), "%s/%s",
1850 "unicode_dependent_rels.txt");
1851
1852 query =
1853 /* collations that use built-in Unicode for character semantics */
1854 "WITH collations(collid) AS ( "
1855 " SELECT oid FROM pg_collation "
1856 " WHERE collprovider='b' AND colllocale IN ('C.UTF-8','PG_UNICODE_FAST') "
1857 /* include default collation, if appropriate */
1858 " UNION "
1859 " SELECT 'pg_catalog.default'::regcollation FROM pg_database "
1860 " WHERE datname = current_database() AND "
1861 " datlocprovider='b' AND datlocale IN ('C.UTF-8','PG_UNICODE_FAST') "
1862 "), "
1863 /* functions that use built-in Unicode */
1864 "functions(procid) AS ( "
1865 " SELECT proc.oid FROM pg_proc proc "
1866 " WHERE proname IN ('normalize','unicode_assigned','unicode_version','is_normalized') AND "
1867 " pronamespace='pg_catalog'::regnamespace "
1868 "), "
1869 /* operators that use the input collation for character semantics */
1870 "coll_operators(operid, procid, collid) AS ( "
1871 " SELECT oper.oid, oper.oprcode, collid FROM pg_operator oper, collations "
1872 " WHERE oprname IN ('~', '~*', '!~', '!~*', '~~*', '!~~*') AND "
1873 " oprnamespace='pg_catalog'::regnamespace AND "
1874 " oprright='text'::regtype "
1875 "), "
1876 /* functions that use the input collation for character semantics */
1877 "coll_functions(procid, collid) AS ( "
1878 " SELECT proc.oid, collid FROM pg_proc proc, collations "
1879 " WHERE proname IN ('lower','initcap','upper') AND "
1880 " pronamespace='pg_catalog'::regnamespace AND "
1881 " proargtypes[0] = 'text'::regtype "
1882 /* include functions behind the operators listed above */
1883 " UNION "
1884 " SELECT procid, collid FROM coll_operators "
1885 "), "
1886
1887 /*
1888 * Generate patterns to search a pg_node_tree for the above functions and
1889 * operators.
1890 */
1891 "patterns(p) AS ( "
1892 " SELECT '{FUNCEXPR :funcid ' || procid::text || '[ }]' FROM functions "
1893 " UNION "
1894 " SELECT '{OPEXPR :opno ' || operid::text || ' (:\\w+ \\w+ )*' || "
1895 " ':inputcollid ' || collid::text || '[ }]' FROM coll_operators "
1896 " UNION "
1897 " SELECT '{FUNCEXPR :funcid ' || procid::text || ' (:\\w+ \\w+ )*' || "
1898 " ':inputcollid ' || collid::text || '[ }]' FROM coll_functions "
1899 ") "
1900
1901 /*
1902 * Match the patterns against expressions used for relation contents.
1903 */
1904 "SELECT reloid, relkind, nspname, relname "
1905 " FROM ( "
1906 " SELECT conrelid "
1907 " FROM pg_constraint, patterns WHERE conbin::text ~ p "
1908 " UNION "
1909 " SELECT indexrelid "
1910 " FROM pg_index, patterns WHERE indexprs::text ~ p OR indpred::text ~ p "
1911 " UNION "
1912 " SELECT partrelid "
1913 " FROM pg_partitioned_table, patterns WHERE partexprs::text ~ p "
1914 " UNION "
1915 " SELECT ev_class "
1916 " FROM pg_rewrite, pg_class, patterns "
1917 " WHERE ev_class = pg_class.oid AND relkind = 'm' AND ev_action::text ~ p"
1918 " ) s(reloid), pg_class c, pg_namespace n, pg_database d "
1919 " WHERE s.reloid = c.oid AND c.relnamespace = n.oid AND "
1920 " d.datname = current_database() AND "
1921 " d.encoding = pg_char_to_encoding('UTF8');";
1922
1923 task = upgrade_task_create();
1924 upgrade_task_add_step(task, query,
1926 true, &report);
1928 upgrade_task_free(task);
1929
1930 if (report.file)
1931 {
1932 fclose(report.file);
1933 report_status(PG_WARNING, "warning");
1934 pg_log(PG_WARNING, "Your installation contains relations that may be affected by a new version of Unicode.\n"
1935 "A list of potentially-affected relations is in the file:\n"
1936 " %s", report.path);
1937 }
1938 else
1939 check_ok();
1940}
1941
1942/*
1943 * check_new_cluster_logical_replication_slots()
1944 *
1945 * Verify that there are no logical replication slots on the new cluster and
1946 * that the parameter settings necessary for creating slots are sufficient.
1947 */
1948static void
1950{
1951 PGresult *res;
1952 PGconn *conn;
1953 int nslots_on_old;
1954 int nslots_on_new;
1956 char *wal_level;
1957
1958 /* Logical slots can be migrated since PG17. */
1960 return;
1961
1962 nslots_on_old = count_old_cluster_logical_slots();
1963
1964 /* Quick return if there are no logical slots to be migrated. */
1965 if (nslots_on_old == 0)
1966 return;
1967
1968 conn = connectToServer(&new_cluster, "template1");
1969
1970 prep_status("Checking for new cluster logical replication slots");
1971
1972 res = executeQueryOrDie(conn, "SELECT count(*) "
1973 "FROM pg_catalog.pg_replication_slots "
1974 "WHERE slot_type = 'logical' AND "
1975 "temporary IS FALSE;");
1976
1977 if (PQntuples(res) != 1)
1978 pg_fatal("could not count the number of logical replication slots");
1979
1980 nslots_on_new = atoi(PQgetvalue(res, 0, 0));
1981
1982 if (nslots_on_new)
1983 pg_fatal("expected 0 logical replication slots but found %d",
1984 nslots_on_new);
1985
1986 PQclear(res);
1987
1988 res = executeQueryOrDie(conn, "SELECT setting FROM pg_settings "
1989 "WHERE name IN ('wal_level', 'max_replication_slots') "
1990 "ORDER BY name DESC;");
1991
1992 if (PQntuples(res) != 2)
1993 pg_fatal("could not determine parameter settings on new cluster");
1994
1995 wal_level = PQgetvalue(res, 0, 0);
1996
1997 if (strcmp(wal_level, "logical") != 0)
1998 pg_fatal("\"wal_level\" must be \"logical\" but is set to \"%s\"",
1999 wal_level);
2000
2001 max_replication_slots = atoi(PQgetvalue(res, 1, 0));
2002
2003 if (nslots_on_old > max_replication_slots)
2004 pg_fatal("\"max_replication_slots\" (%d) must be greater than or equal to the number of "
2005 "logical replication slots (%d) on the old cluster",
2006 max_replication_slots, nslots_on_old);
2007
2008 PQclear(res);
2009 PQfinish(conn);
2010
2011 check_ok();
2012}
2013
2014/*
2015 * check_new_cluster_subscription_configuration()
2016 *
2017 * Verify that the max_active_replication_origins configuration specified is
2018 * enough for creating the subscriptions. This is required to create the
2019 * replication origin for each subscription.
2020 */
2021static void
2023{
2024 PGresult *res;
2025 PGconn *conn;
2027
2028 /* Subscriptions and their dependencies can be migrated since PG17. */
2030 return;
2031
2032 /* Quick return if there are no subscriptions to be migrated. */
2033 if (old_cluster.nsubs == 0)
2034 return;
2035
2036 prep_status("Checking for new cluster configuration for subscriptions");
2037
2038 conn = connectToServer(&new_cluster, "template1");
2039
2040 res = executeQueryOrDie(conn, "SELECT setting FROM pg_settings "
2041 "WHERE name = 'max_active_replication_origins';");
2042
2043 if (PQntuples(res) != 1)
2044 pg_fatal("could not determine parameter settings on new cluster");
2045
2046 max_active_replication_origins = atoi(PQgetvalue(res, 0, 0));
2048 pg_fatal("\"max_active_replication_origins\" (%d) must be greater than or equal to the number of "
2049 "subscriptions (%d) on the old cluster",
2051
2052 PQclear(res);
2053 PQfinish(conn);
2054
2055 check_ok();
2056}
2057
2058/*
2059 * check_old_cluster_for_valid_slots()
2060 *
2061 * Verify that all the logical slots are valid and have consumed all the WAL
2062 * before shutdown.
2063 */
2064static void
2066{
2067 char output_path[MAXPGPATH];
2068 FILE *script = NULL;
2069
2070 prep_status("Checking for valid logical replication slots");
2071
2072 snprintf(output_path, sizeof(output_path), "%s/%s",
2074 "invalid_logical_slots.txt");
2075
2076 for (int dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
2077 {
2078 LogicalSlotInfoArr *slot_arr = &old_cluster.dbarr.dbs[dbnum].slot_arr;
2079
2080 for (int slotnum = 0; slotnum < slot_arr->nslots; slotnum++)
2081 {
2082 LogicalSlotInfo *slot = &slot_arr->slots[slotnum];
2083
2084 /* Is the slot usable? */
2085 if (slot->invalid)
2086 {
2087 if (script == NULL &&
2088 (script = fopen_priv(output_path, "w")) == NULL)
2089 pg_fatal("could not open file \"%s\": %m", output_path);
2090
2091 fprintf(script, "The slot \"%s\" is invalid\n",
2092 slot->slotname);
2093
2094 continue;
2095 }
2096
2097 /*
2098 * Do additional check to ensure that all logical replication
2099 * slots have consumed all the WAL before shutdown.
2100 *
2101 * Note: This can be satisfied only when the old cluster has been
2102 * shut down, so we skip this for live checks.
2103 */
2104 if (!user_opts.live_check && !slot->caught_up)
2105 {
2106 if (script == NULL &&
2107 (script = fopen_priv(output_path, "w")) == NULL)
2108 pg_fatal("could not open file \"%s\": %m", output_path);
2109
2110 fprintf(script,
2111 "The slot \"%s\" has not consumed the WAL yet\n",
2112 slot->slotname);
2113 }
2114 }
2115 }
2116
2117 if (script)
2118 {
2119 fclose(script);
2120
2121 pg_log(PG_REPORT, "fatal");
2122 pg_fatal("Your installation contains logical replication slots that cannot be upgraded.\n"
2123 "You can remove invalid slots and/or consume the pending WAL for other slots,\n"
2124 "and then restart the upgrade.\n"
2125 "A list of the problematic slots is in the file:\n"
2126 " %s", output_path);
2127 }
2128
2129 check_ok();
2130}
2131
2132/*
2133 * Callback function for processing results of query for
2134 * check_old_cluster_subscription_state()'s UpgradeTask. If the query returned
2135 * any rows (i.e., the check failed), write the details to the report file.
2136 */
2137static void
2139{
2141 int ntups = PQntuples(res);
2142 int i_srsubstate = PQfnumber(res, "srsubstate");
2143 int i_subname = PQfnumber(res, "subname");
2144 int i_nspname = PQfnumber(res, "nspname");
2145 int i_relname = PQfnumber(res, "relname");
2146
2148
2149 if (ntups == 0)
2150 return;
2151
2152 if (report->file == NULL &&
2153 (report->file = fopen_priv(report->path, "w")) == NULL)
2154 pg_fatal("could not open file \"%s\": %m", report->path);
2155
2156 for (int i = 0; i < ntups; i++)
2157 fprintf(report->file, "The table sync state \"%s\" is not allowed for database:\"%s\" subscription:\"%s\" schema:\"%s\" relation:\"%s\"\n",
2158 PQgetvalue(res, i, i_srsubstate),
2159 dbinfo->db_name,
2160 PQgetvalue(res, i, i_subname),
2161 PQgetvalue(res, i, i_nspname),
2162 PQgetvalue(res, i, i_relname));
2163}
2164
2165/*
2166 * check_old_cluster_subscription_state()
2167 *
2168 * Verify that the replication origin corresponding to each of the
2169 * subscriptions are present and each of the subscribed tables is in
2170 * 'i' (initialize) or 'r' (ready) state.
2171 */
2172static void
2174{
2176 UpgradeTaskReport report;
2177 const char *query;
2178 PGresult *res;
2179 PGconn *conn;
2180 int ntup;
2181
2182 prep_status("Checking for subscription state");
2183
2184 report.file = NULL;
2185 snprintf(report.path, sizeof(report.path), "%s/%s",
2187 "subs_invalid.txt");
2188
2189 /*
2190 * Check that all the subscriptions have their respective replication
2191 * origin. This check only needs to run once.
2192 */
2194 res = executeQueryOrDie(conn,
2195 "SELECT d.datname, s.subname "
2196 "FROM pg_catalog.pg_subscription s "
2197 "LEFT OUTER JOIN pg_catalog.pg_replication_origin o "
2198 " ON o.roname = 'pg_' || s.oid "
2199 "INNER JOIN pg_catalog.pg_database d "
2200 " ON d.oid = s.subdbid "
2201 "WHERE o.roname IS NULL;");
2202 ntup = PQntuples(res);
2203 for (int i = 0; i < ntup; i++)
2204 {
2205 if (report.file == NULL &&
2206 (report.file = fopen_priv(report.path, "w")) == NULL)
2207 pg_fatal("could not open file \"%s\": %m", report.path);
2208 fprintf(report.file, "The replication origin is missing for database:\"%s\" subscription:\"%s\"\n",
2209 PQgetvalue(res, i, 0),
2210 PQgetvalue(res, i, 1));
2211 }
2212 PQclear(res);
2213 PQfinish(conn);
2214
2215 /*
2216 * We don't allow upgrade if there is a risk of dangling slot or origin
2217 * corresponding to initial sync after upgrade.
2218 *
2219 * A slot/origin not created yet refers to the 'i' (initialize) state,
2220 * while 'r' (ready) state refers to a slot/origin created previously but
2221 * already dropped. These states are supported for pg_upgrade. The other
2222 * states listed below are not supported:
2223 *
2224 * a) SUBREL_STATE_DATASYNC: A relation upgraded while in this state would
2225 * retain a replication slot, which could not be dropped by the sync
2226 * worker spawned after the upgrade because the subscription ID used for
2227 * the slot name won't match anymore.
2228 *
2229 * b) SUBREL_STATE_SYNCDONE: A relation upgraded while in this state would
2230 * retain the replication origin when there is a failure in tablesync
2231 * worker immediately after dropping the replication slot in the
2232 * publisher.
2233 *
2234 * c) SUBREL_STATE_FINISHEDCOPY: A tablesync worker spawned to work on a
2235 * relation upgraded while in this state would expect an origin ID with
2236 * the OID of the subscription used before the upgrade, causing it to
2237 * fail.
2238 *
2239 * d) SUBREL_STATE_SYNCWAIT, SUBREL_STATE_CATCHUP and
2240 * SUBREL_STATE_UNKNOWN: These states are not stored in the catalog, so we
2241 * need not allow these states.
2242 */
2243 query = "SELECT r.srsubstate, s.subname, n.nspname, c.relname "
2244 "FROM pg_catalog.pg_subscription_rel r "
2245 "LEFT JOIN pg_catalog.pg_subscription s"
2246 " ON r.srsubid = s.oid "
2247 "LEFT JOIN pg_catalog.pg_class c"
2248 " ON r.srrelid = c.oid "
2249 "LEFT JOIN pg_catalog.pg_namespace n"
2250 " ON c.relnamespace = n.oid "
2251 "WHERE r.srsubstate NOT IN ('i', 'r') "
2252 "ORDER BY s.subname";
2253
2255 true, &report);
2256
2258 upgrade_task_free(task);
2259
2260 if (report.file)
2261 {
2262 fclose(report.file);
2263 pg_log(PG_REPORT, "fatal");
2264 pg_fatal("Your installation contains subscriptions without origin or having relations not in i (initialize) or r (ready) state.\n"
2265 "You can allow the initial sync to finish for all relations and then restart the upgrade.\n"
2266 "A list of the problematic subscriptions is in the file:\n"
2267 " %s", report.path);
2268 }
2269 else
2270 check_ok();
2271}
#define gettext_noop(x)
Definition: c.h:1167
#define AssertVariableIsOfType(varname, typename)
Definition: c.h:952
#define CppAsString2(x)
Definition: c.h:363
void check_cluster_versions(void)
Definition: check.c:838
static void check_for_tables_with_oids(ClusterInfo *cluster)
Definition: check.c:1586
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1630
static void process_old_sub_state_check(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:2138
static void check_for_data_types_usage(ClusterInfo *cluster)
Definition: check.c:463
static bool unicode_version_changed(ClusterInfo *cluster)
Definition: check.c:1800
static char * data_type_check_query(int checknum)
Definition: check.c:332
static void process_incompat_polymorphics(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1425
static DataTypesUsageChecks data_types_usage_checks[]
Definition: check.c:97
static void process_with_oids_check(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1558
static void check_new_cluster_logical_replication_slots(void)
Definition: check.c:1949
static void check_old_cluster_subscription_state(void)
Definition: check.c:2173
#define ALL_VERSIONS
Definition: check.c:62
void issue_warnings_and_set_wal_level(void)
Definition: check.c:783
static void process_unicode_update(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1771
static void check_for_unicode_update(ClusterInfo *cluster)
Definition: check.c:1825
void check_cluster_compatibility(void)
Definition: check.c:893
#define MANUAL_CHECK
Definition: check.c:61
void check_new_cluster(void)
Definition: check.c:701
void report_clusters_compatible(void)
Definition: check.c:764
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:1066
static void check_new_cluster_subscription_configuration(void)
Definition: check.c:2022
void create_script_for_old_cluster_deletion(char **deletion_script_file_name)
Definition: check.c:968
static void check_for_connection_status(ClusterInfo *cluster)
Definition: check.c:1124
static void process_user_defined_encoding_conversions(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1688
static void process_data_type_check(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:389
void check_and_dump_old_cluster(void)
Definition: check.c:588
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:1278
static char * fix_path_separator(char *path)
Definition: check.c:549
static void check_new_cluster_is_empty(void)
Definition: check.c:907
static void check_old_cluster_for_valid_slots(void)
Definition: check.c:2065
static void process_isn_and_int8_passing_mismatch(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1245
static void check_for_user_defined_postfix_ops(ClusterInfo *cluster)
Definition: check.c:1366
void output_completion_banner(char *deletion_script_file_name)
Definition: check.c:804
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:1212
static void check_for_new_tablespace_dir(void)
Definition: check.c:939
static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
Definition: check.c:1719
static void check_for_incompatible_polymorphics(ClusterInfo *cluster)
Definition: check.c:1457
void output_check_banner(void)
Definition: check.c:570
static void process_user_defined_postfix_ops(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1331
void cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:107
void get_control_data(ClusterInfo *cluster)
Definition: controldata.c:38
void check_control_data(ControlData *oldctrl, ControlData *newctrl)
Definition: controldata.c:698
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
void generate_old_dump(void)
Definition: dump.c:16
#define _(x)
Definition: elog.c:91
void PQfinish(PGconn *conn)
Definition: fe-connect.c:5290
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3876
void PQclear(PGresult *res)
Definition: fe-exec.c:721
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3481
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3589
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
void pg_free(void *ptr)
Definition: fe_memutils.c:105
void check_file_clone(void)
Definition: file.c:360
void check_hard_link(transferMode transfer_mode)
Definition: file.c:437
void check_copy_file_range(void)
Definition: file.c:400
void check_loadable_libraries(void)
Definition: function.c:165
void get_loadable_libraries(void)
Definition: function.c:79
Assert(PointerIsAligned(start, uint64))
void get_subscription_count(ClusterInfo *cluster)
Definition: info.c:760
int count_old_cluster_logical_slots(void)
Definition: info.c:744
void get_db_rel_and_slot_infos(ClusterInfo *cluster)
Definition: info.c:280
static void check_ok(void)
Definition: initdb.c:2117
int i
Definition: isn.c:77
void pfree(void *pointer)
Definition: mcxt.c:2146
int max_active_replication_origins
Definition: origin.c:104
void * arg
#define pg_fatal(...)
#define MAXPGPATH
static pid_t start_postmaster(void)
Definition: pg_ctl.c:440
NameData datname
Definition: pg_database.h:35
bool datallowconn
Definition: pg_database.h:50
int32 datconnlimit
Definition: pg_database.h:59
OSInfo os_info
Definition: pg_upgrade.c:73
ClusterInfo new_cluster
Definition: pg_upgrade.c:72
ClusterInfo old_cluster
Definition: pg_upgrade.c:71
UpgradeTask * upgrade_task_create(void)
Definition: task.c:117
void init_tablespaces(void)
Definition: tablespace.c:19
bool(* DataTypesUsageVersionCheck)(ClusterInfo *cluster)
Definition: pg_upgrade.h:366
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:28
bool jsonb_9_4_check_applicable(ClusterInfo *cluster)
Definition: version.c:21
void upgrade_task_run(const UpgradeTask *task, const ClusterInfo *cluster)
Definition: task.c:420
#define RMDIR_CMD
Definition: pg_upgrade.h:85
void cleanup_output_dirs(void)
Definition: util.c:63
void report_extension_updates(ClusterInfo *cluster)
Definition: version.c:179
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
@ TRANSFER_MODE_COPY
Definition: pg_upgrade.h:262
@ TRANSFER_MODE_LINK
Definition: pg_upgrade.h:264
@ TRANSFER_MODE_SWAP
Definition: pg_upgrade.h:265
@ TRANSFER_MODE_CLONE
Definition: pg_upgrade.h:261
@ TRANSFER_MODE_COPY_FILE_RANGE
Definition: pg_upgrade.h:263
#define SCRIPT_EXT
Definition: pg_upgrade.h:87
#define SCRIPT_PREFIX
Definition: pg_upgrade.h:86
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define PATH_QUOTE
Definition: pg_upgrade.h:83
LogOpts log_opts
Definition: util.c:17
void upgrade_task_free(UpgradeTask *task)
Definition: task.c:133
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:430
void(* UpgradeTaskProcessCB)(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: pg_upgrade.h:511
@ PG_WARNING
Definition: pg_upgrade.h:277
@ PG_REPORT
Definition: pg_upgrade.h:276
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:27
void stop_postmaster(bool in_atexit)
Definition: server.c:349
void prep_status(const char *fmt,...) pg_attribute_printf(1
void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2
void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
Definition: version.c:37
void upgrade_task_add_step(UpgradeTask *task, const char *query, UpgradeTaskProcessCB process_cb, bool free_result, void *arg)
Definition: task.c:151
bool path_is_prefix_of_path(const char *path1, const char *path2)
Definition: path.c:637
void canonicalize_path(char *path)
Definition: path.c:337
#define snprintf
Definition: port.h:239
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define atooid(x)
Definition: postgres_ext.h:41
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:72
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:114
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129
char * c
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
int max_replication_slots
Definition: slot.c:150
UserOpts user_opts
Definition: option.c:30
PGconn * conn
Definition: streamutil.c:52
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:582
char * pgdata
Definition: pg_upgrade.h:292
unsigned short port
Definition: pg_upgrade.h:299
ControlData controldata
Definition: pg_upgrade.h:289
char * bindir
Definition: pg_upgrade.h:295
uint32 bin_version
Definition: pg_upgrade.h:302
DbInfoArr dbarr
Definition: pg_upgrade.h:291
uint32 major_version
Definition: pg_upgrade.h:300
const char * tablespace_suffix
Definition: pg_upgrade.h:303
bool float8_pass_by_value
Definition: pg_upgrade.h:251
const char * report_text
Definition: check.c:49
int threshold_version
Definition: check.c:51
DataTypesUsageVersionCheck version_hook
Definition: check.c:53
const char * status
Definition: check.c:43
const char * report_filename
Definition: check.c:45
const char * base_query
Definition: check.c:47
DbInfo * dbs
Definition: pg_upgrade.h:220
LogicalSlotInfoArr slot_arr
Definition: pg_upgrade.h:203
char * db_name
Definition: pg_upgrade.h:199
RelInfoArr rel_arr
Definition: pg_upgrade.h:202
char * basedir
Definition: pg_upgrade.h:318
LogicalSlotInfo * slots
Definition: pg_upgrade.h:174
int num_old_tablespaces
Definition: pg_upgrade.h:358
char * user
Definition: pg_upgrade.h:355
char ** old_tablespaces
Definition: pg_upgrade.h:357
bool user_specified
Definition: pg_upgrade.h:356
RelInfo * rels
Definition: pg_upgrade.h:153
char * nspname
Definition: pg_upgrade.h:140
char * relname
Definition: pg_upgrade.h:141
char path[MAXPGPATH]
Definition: pg_upgrade.h:527
bool live_check
Definition: pg_upgrade.h:331
int char_signedness
Definition: pg_upgrade.h:338
transferMode transfer_mode
Definition: pg_upgrade.h:333
bool check
Definition: pg_upgrade.h:330
PQExpBuffer * report
Definition: check.c:324
DataTypesUsageChecks * check
Definition: check.c:322
Definition: regguts.h:323
#define PG_UNICODE_VERSION
#define stat
Definition: win32_port.h:274
#define S_IRWXU
Definition: win32_port.h:288
int wal_level
Definition: xlog.c:131