PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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-2026, PostgreSQL Global Development Group
7 * src/bin/pg_upgrade/check.c
8 */
9
10#include "postgres_fe.h"
11
12#include "catalog/pg_am_d.h"
13#include "catalog/pg_authid_d.h"
14#include "catalog/pg_class_d.h"
16#include "mb/pg_wchar.h"
17#include "pg_upgrade.h"
19
20static void check_new_cluster_is_empty(void);
32static void check_for_new_tablespace_dir(void);
37static void check_old_cluster_for_valid_slots(void);
40
41/*
42 * DataTypesUsageChecks - definitions of data type checks for the old cluster
43 * in order to determine if an upgrade can be performed. See the comment on
44 * data_types_usage_checks below for a more detailed description.
45 */
46typedef struct
47{
48 /* Status line to print to the user */
49 const char *status;
50 /* Filename to store report to */
51 const char *report_filename;
52 /* Query to extract the oid of the datatype */
53 const char *base_query;
54 /* Text to store to report in case of error */
55 const char *report_text;
56 /* The latest version where the check applies */
58 /* A function pointer for determining if the check applies */
61
62/*
63 * Special values for threshold_version for indicating that a check applies to
64 * all versions, or that a custom function needs to be invoked to determine
65 * if the check applies.
66 */
67#define MANUAL_CHECK 1
68#define ALL_VERSIONS -1
69
70/*--
71 * Data type usage checks. Each check for problematic data type usage is
72 * defined in this array with metadata, SQL query for finding the data type
73 * and functionality for deciding if the check is applicable to the version
74 * of the old cluster. The struct members are described in detail below:
75 *
76 * status A oneline string which can be printed to the user to
77 * inform about progress. Should not end with newline.
78 * report_filename The filename in which the list of problems detected by
79 * the check will be printed.
80 * base_query A query which extracts the Oid of the datatype checked
81 * for.
82 * report_text The text which will be printed to the user to explain
83 * what the check did, and why it failed. The text should
84 * end with a newline, and does not need to refer to the
85 * report_filename as that is automatically appended to
86 * the report with the path to the log folder.
87 * threshold_version The major version of PostgreSQL for which to run the
88 * check. Iff the old cluster is less than, or equal to,
89 * the threshold version then the check will be executed.
90 * If the old version is greater than the threshold then
91 * the check is skipped. If the threshold_version is set
92 * to ALL_VERSIONS then it will be run unconditionally,
93 * if set to MANUAL_CHECK then the version_hook function
94 * will be executed in order to determine whether or not
95 * to run.
96 * version_hook A function pointer to a version check function of type
97 * DataTypesUsageVersionCheck which is used to determine
98 * if the check is applicable to the old cluster. If the
99 * version_hook returns true then the check will be run,
100 * else it will be skipped. The function will only be
101 * executed iff threshold_version is set to MANUAL_CHECK.
102 */
104{
105 /*
106 * Look for composite types that were made during initdb *or* belong to
107 * information_schema; that's important in case information_schema was
108 * dropped and reloaded.
109 *
110 * The cutoff OID here should match the source cluster's value of
111 * FirstNormalObjectId. We hardcode it rather than using that C #define
112 * because, if that #define is ever changed, our own version's value is
113 * NOT what to use. Eventually we may need a test on the source cluster's
114 * version to select the correct value.
115 */
116 {
117 .status = gettext_noop("Checking for system-defined composite types in user tables"),
118 .report_filename = "tables_using_composite.txt",
119 .base_query =
120 "SELECT t.oid FROM pg_catalog.pg_type t "
121 "LEFT JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid "
122 " WHERE typtype = 'c' AND (t.oid < 16384 OR nspname = 'information_schema')",
123 .report_text =
124 gettext_noop("Your installation contains system-defined composite types in user tables.\n"
125 "These type OIDs are not stable across PostgreSQL versions,\n"
126 "so this cluster cannot currently be upgraded. You can drop the\n"
127 "problem columns and restart the upgrade.\n"),
128 .threshold_version = ALL_VERSIONS
129 },
130
131 /*
132 * 9.3 -> 9.4 Fully implement the 'line' data type in 9.4, which
133 * previously returned "not enabled" by default and was only functionally
134 * enabled with a compile-time switch; as of 9.4 "line" has a different
135 * on-disk representation format.
136 */
137 {
138 .status = gettext_noop("Checking for incompatible \"line\" data type"),
139 .report_filename = "tables_using_line.txt",
140 .base_query =
141 "SELECT 'pg_catalog.line'::pg_catalog.regtype AS oid",
142 .report_text =
143 gettext_noop("Your installation contains the \"line\" data type in user tables.\n"
144 "This data type changed its internal and input/output format\n"
145 "between your old and new versions so this\n"
146 "cluster cannot currently be upgraded. You can\n"
147 "drop the problem columns and restart the upgrade.\n"),
148 .threshold_version = 903
149 },
150
151 /*
152 * pg_upgrade only preserves these system values: pg_class.oid pg_type.oid
153 * pg_enum.oid
154 *
155 * Many of the reg* data types reference system catalog info that is not
156 * preserved, and hence these data types cannot be used in user tables
157 * upgraded by pg_upgrade.
158 */
159 {
160 .status = gettext_noop("Checking for reg* data types in user tables"),
161 .report_filename = "tables_using_reg.txt",
162
163 /*
164 * Note: older servers will not have all of these reg* types, so we
165 * have to write the query like this rather than depending on casts to
166 * regtype.
167 */
168 .base_query =
169 "SELECT oid FROM pg_catalog.pg_type t "
170 "WHERE t.typnamespace = "
171 " (SELECT oid FROM pg_catalog.pg_namespace "
172 " WHERE nspname = 'pg_catalog') "
173 " AND t.typname IN ( "
174 /* pg_class.oid is preserved, so 'regclass' is OK */
175 " 'regcollation', "
176 " 'regconfig', "
177 /* pg_database.oid is preserved, so 'regdatabase' is OK */
178 " 'regdictionary', "
179 " 'regnamespace', "
180 " 'regoper', "
181 " 'regoperator', "
182 " 'regproc', "
183 " 'regprocedure' "
184 /* pg_authid.oid is preserved, so 'regrole' is OK */
185 /* pg_type.oid is (mostly) preserved, so 'regtype' is OK */
186 " )",
187 .report_text =
188 gettext_noop("Your installation contains one of the reg* data types in user tables.\n"
189 "These data types reference system OIDs that are not preserved by\n"
190 "pg_upgrade, so this cluster cannot currently be upgraded. You can\n"
191 "drop the problem columns and restart the upgrade.\n"),
192 .threshold_version = ALL_VERSIONS
193 },
194
195 /*
196 * PG 16 increased the size of the 'aclitem' type, which breaks the
197 * on-disk format for existing data.
198 */
199 {
200 .status = gettext_noop("Checking for incompatible \"aclitem\" data type"),
201 .report_filename = "tables_using_aclitem.txt",
202 .base_query =
203 "SELECT 'pg_catalog.aclitem'::pg_catalog.regtype AS oid",
204 .report_text =
205 gettext_noop("Your installation contains the \"aclitem\" data type in user tables.\n"
206 "The internal format of \"aclitem\" changed in PostgreSQL version 16\n"
207 "so this cluster cannot currently be upgraded. You can drop the\n"
208 "problem columns and restart the upgrade.\n"),
209 .threshold_version = 1500
210 },
211
212 /*
213 * It's no longer allowed to create tables or views with "unknown"-type
214 * columns. We do not complain about views with such columns, because
215 * they should get silently converted to "text" columns during the DDL
216 * dump and reload; it seems unlikely to be worth making users do that by
217 * hand. However, if there's a table with such a column, the DDL reload
218 * will fail, so we should pre-detect that rather than failing
219 * mid-upgrade. Worse, if there's a matview with such a column, the DDL
220 * reload will silently change it to "text" which won't match the on-disk
221 * storage (which is like "cstring"). So we *must* reject that.
222 */
223 {
224 .status = gettext_noop("Checking for invalid \"unknown\" user columns"),
225 .report_filename = "tables_using_unknown.txt",
226 .base_query =
227 "SELECT 'pg_catalog.unknown'::pg_catalog.regtype AS oid",
228 .report_text =
229 gettext_noop("Your installation contains the \"unknown\" data type in user tables.\n"
230 "This data type is no longer allowed in tables, so this cluster\n"
231 "cannot currently be upgraded. You can drop the problem columns\n"
232 "and restart the upgrade.\n"),
233 .threshold_version = 906
234 },
235
236 /*
237 * PG 12 changed the 'sql_identifier' type storage to be based on name,
238 * not varchar, which breaks on-disk format for existing data. So we need
239 * to prevent upgrade when used in user objects (tables, indexes, ...). In
240 * 12, the sql_identifier data type was switched from name to varchar,
241 * which does affect the storage (name is by-ref, but not varlena). This
242 * means user tables using sql_identifier for columns are broken because
243 * the on-disk format is different.
244 */
245 {
246 .status = gettext_noop("Checking for invalid \"sql_identifier\" user columns"),
247 .report_filename = "tables_using_sql_identifier.txt",
248 .base_query =
249 "SELECT 'information_schema.sql_identifier'::pg_catalog.regtype AS oid",
250 .report_text =
251 gettext_noop("Your installation contains the \"sql_identifier\" data type in user tables.\n"
252 "The on-disk format for this data type has changed, so this\n"
253 "cluster cannot currently be upgraded. You can drop the problem\n"
254 "columns and restart the upgrade.\n"),
255 .threshold_version = 1100
256 },
257
258 /*
259 * JSONB changed its storage format during 9.4 beta, so check for it.
260 */
261 {
262 .status = gettext_noop("Checking for incompatible \"jsonb\" data type in user tables"),
263 .report_filename = "tables_using_jsonb.txt",
264 .base_query =
265 "SELECT 'pg_catalog.jsonb'::pg_catalog.regtype AS oid",
266 .report_text =
267 gettext_noop("Your installation contains the \"jsonb\" data type in user tables.\n"
268 "The internal format of \"jsonb\" changed during 9.4 beta so this\n"
269 "cluster cannot currently be upgraded. You can drop the problem \n"
270 "columns and restart the upgrade.\n"),
271 .threshold_version = MANUAL_CHECK,
272 .version_hook = jsonb_9_4_check_applicable
273 },
274
275 /*
276 * PG 12 removed types abstime, reltime, tinterval.
277 */
278 {
279 .status = gettext_noop("Checking for removed \"abstime\" data type in user tables"),
280 .report_filename = "tables_using_abstime.txt",
281 .base_query =
282 "SELECT 'pg_catalog.abstime'::pg_catalog.regtype AS oid",
283 .report_text =
284 gettext_noop("Your installation contains the \"abstime\" data type in user tables.\n"
285 "The \"abstime\" type has been removed in PostgreSQL version 12,\n"
286 "so this cluster cannot currently be upgraded. You can drop the\n"
287 "problem columns, or change them to another data type, and restart\n"
288 "the upgrade.\n"),
289 .threshold_version = 1100
290 },
291 {
292 .status = gettext_noop("Checking for removed \"reltime\" data type in user tables"),
293 .report_filename = "tables_using_reltime.txt",
294 .base_query =
295 "SELECT 'pg_catalog.reltime'::pg_catalog.regtype AS oid",
296 .report_text =
297 gettext_noop("Your installation contains the \"reltime\" data type in user tables.\n"
298 "The \"reltime\" type has been removed in PostgreSQL version 12,\n"
299 "so this cluster cannot currently be upgraded. You can drop the\n"
300 "problem columns, or change them to another data type, and restart\n"
301 "the upgrade.\n"),
302 .threshold_version = 1100
303 },
304 {
305 .status = gettext_noop("Checking for removed \"tinterval\" data type in user tables"),
306 .report_filename = "tables_using_tinterval.txt",
307 .base_query =
308 "SELECT 'pg_catalog.tinterval'::pg_catalog.regtype AS oid",
309 .report_text =
310 gettext_noop("Your installation contains the \"tinterval\" data type in user tables.\n"
311 "The \"tinterval\" type has been removed in PostgreSQL version 12,\n"
312 "so this cluster cannot currently be upgraded. You can drop the\n"
313 "problem columns, or change them to another data type, and restart\n"
314 "the upgrade.\n"),
315 .threshold_version = 1100
316 },
317
318 /* End of checks marker, must remain last */
319 {
320 NULL, NULL, NULL, NULL, 0, NULL
321 }
322};
323
324/*
325 * Private state for check_for_data_types_usage()'s UpgradeTask.
326 */
328{
329 DataTypesUsageChecks *check; /* the check for this step */
330 bool result; /* true if check failed for any database */
331 PQExpBuffer *report; /* buffer for report on failed checks */
332};
333
334/*
335 * Returns a palloc'd query string for the data type check, for use by
336 * check_for_data_types_usage()'s UpgradeTask.
337 */
338static char *
340{
342
343 return psprintf("WITH RECURSIVE oids AS ( "
344 /* start with the type(s) returned by base_query */
345 " %s "
346 " UNION ALL "
347 " SELECT * FROM ( "
348 /* inner WITH because we can only reference the CTE once */
349 " WITH x AS (SELECT oid FROM oids) "
350 /* domains on any type selected so far */
351 " SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typbasetype = x.oid AND typtype = 'd' "
352 " UNION ALL "
353 /* arrays over any type selected so far */
354 " SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typelem = x.oid AND typtype = 'b' "
355 " UNION ALL "
356 /* composite types containing any type selected so far */
357 " SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_class c, pg_catalog.pg_attribute a, x "
358 " WHERE t.typtype = 'c' AND "
359 " t.oid = c.reltype AND "
360 " c.oid = a.attrelid AND "
361 " NOT a.attisdropped AND "
362 " a.atttypid = x.oid "
363 " UNION ALL "
364 /* ranges containing any type selected so far */
365 " SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_range r, x "
366 " WHERE t.typtype = 'r' AND r.rngtypid = t.oid AND r.rngsubtype = x.oid"
367 " ) foo "
368 ") "
369 /* now look for stored columns of any such type */
370 "SELECT n.nspname, c.relname, a.attname "
371 "FROM pg_catalog.pg_class c, "
372 " pg_catalog.pg_namespace n, "
373 " pg_catalog.pg_attribute a "
374 "WHERE c.oid = a.attrelid AND "
375 " NOT a.attisdropped AND "
376 " a.atttypid IN (SELECT oid FROM oids) AND "
377 " c.relkind IN ("
381 " c.relnamespace = n.oid AND "
382 /* exclude possible orphaned temp tables */
383 " n.nspname !~ '^pg_temp_' AND "
384 " n.nspname !~ '^pg_toast_temp_' AND "
385 /* exclude system catalogs, too */
386 " n.nspname NOT IN ('pg_catalog', 'information_schema')",
387 check->base_query);
388}
389
390/*
391 * Callback function for processing results of queries for
392 * check_for_data_types_usage()'s UpgradeTask. If the query returned any rows
393 * (i.e., the check failed), write the details to the report file.
394 */
395static void
397{
399 int ntups = PQntuples(res);
401 int i_nspname = PQfnumber(res, "nspname");
402 int i_relname = PQfnumber(res, "relname");
403 int i_attname = PQfnumber(res, "attname");
404 FILE *script = NULL;
405
406 if (ntups == 0)
407 return;
408
409 snprintf(output_path, sizeof(output_path), "%s/%s",
411 state->check->report_filename);
412
413 /*
414 * Make sure we have a buffer to save reports to now that we found a first
415 * failing check.
416 */
417 if (*state->report == NULL)
418 *state->report = createPQExpBuffer();
419
420 /*
421 * If this is the first time we see an error for the check in question
422 * then print a status message of the failure.
423 */
424 if (!state->result)
425 {
426 pg_log(PG_REPORT, "failed check: %s", _(state->check->status));
427 appendPQExpBuffer(*state->report, "\n%s\n%s\n %s\n",
428 _(state->check->report_text),
429 _("A list of the problem columns is in the file:"),
431 }
432 state->result = true;
433
434 if ((script = fopen_priv(output_path, "a")) == NULL)
435 pg_fatal("could not open file \"%s\": %m", output_path);
436
437 fprintf(script, "In database: %s\n", dbinfo->db_name);
438
439 for (int rowno = 0; rowno < ntups; rowno++)
440 fprintf(script, " %s.%s.%s\n",
443 PQgetvalue(res, rowno, i_attname));
444
445 fclose(script);
446}
447
448/*
449 * check_for_data_types_usage()
450 * Detect whether there are any stored columns depending on given type(s)
451 *
452 * If so, write a report to the given file name and signal a failure to the
453 * user.
454 *
455 * The checks to run are defined in a DataTypesUsageChecks structure where
456 * each check has a metadata for explaining errors to the user, a base_query,
457 * a report filename and a function pointer hook for validating if the check
458 * should be executed given the cluster at hand.
459 *
460 * base_query should be a SELECT yielding a single column named "oid",
461 * containing the pg_type OIDs of one or more types that are known to have
462 * inconsistent on-disk representations across server versions.
463 *
464 * We check for the type(s) in tables, matviews, and indexes, but not views;
465 * there's no storage involved in a view.
466 */
467static void
469{
474 char **queries = NULL;
475 struct data_type_check_state *states;
476
477 prep_status("Checking data type usage");
478
479 /* Gather number of checks to perform */
480 while (tmp->status != NULL)
481 {
483 tmp++;
484 }
485
486 /* Allocate memory for queries and for task states */
489
490 for (int i = 0; i < n_data_types_usage_checks; i++)
491 {
493
495 {
497
498 /*
499 * Make sure that the check applies to the current cluster version
500 * and skip it if not.
501 */
503 continue;
504 }
506 {
507 if (GET_MAJOR_VERSION(cluster->major_version) > check->threshold_version)
508 continue;
509 }
510 else
512
513 queries[i] = data_type_check_query(i);
514
515 states[i].check = check;
516 states[i].report = &report;
517
519 true, &states[i]);
520 }
521
522 /*
523 * Connect to each database in the cluster and run all defined checks
524 * against that database before trying the next one.
525 */
528
529 if (report)
530 {
531 pg_fatal("Data type checks failed: %s", report->data);
533 }
534
535 for (int i = 0; i < n_data_types_usage_checks; i++)
536 {
537 if (queries[i])
538 pg_free(queries[i]);
539 }
540 pg_free(queries);
541 pg_free(states);
542
543 check_ok();
544}
545
546/*
547 * fix_path_separator
548 * For non-Windows, just return the argument.
549 * For Windows convert any forward slash to a backslash
550 * such as is suitable for arguments to builtin commands
551 * like RMDIR and DEL.
552 */
553static char *
555{
556#ifdef WIN32
557
558 char *result;
559 char *c;
560
561 result = pg_strdup(path);
562
563 for (c = result; *c != '\0'; c++)
564 if (*c == '/')
565 *c = '\\';
566
567 return result;
568#else
569
570 return path;
571#endif
572}
573
574void
576{
578 {
580 "Performing Consistency Checks on Old Live Server\n"
581 "------------------------------------------------");
582 }
583 else
584 {
586 "Performing Consistency Checks\n"
587 "-----------------------------");
588 }
589}
590
591
592void
594{
595 /* -- OLD -- */
596
599
600 /*
601 * First check that all databases allow connections since we'll otherwise
602 * fail in later stages.
603 */
605
606 /*
607 * Check for encodings that are no longer supported.
608 */
610
611 /*
612 * Validate database, user, role and tablespace names from the old
613 * cluster. No need to check in 19 or newer as newline and carriage return
614 * are not allowed at the creation time of the object.
615 */
618
619 /*
620 * Extract a list of databases, tables, and logical replication slots from
621 * the old cluster.
622 */
624
626
628
629
630 /*
631 * Check for various failure cases
632 */
636
638 {
639 /*
640 * Logical replication slots can be migrated since PG17. See comments
641 * in get_db_rel_and_slot_infos().
642 */
644
645 /*
646 * Subscriptions and their dependencies can be migrated since PG17.
647 * Before that the logical slots are not upgraded, so we will not be
648 * able to upgrade the logical replication clusters completely.
649 */
652 }
653
655
656 /*
657 * Unicode updates can affect some objects that use expressions with
658 * functions dependent on Unicode.
659 */
661
662 /*
663 * PG 14 changed the function signature of encoding conversion functions.
664 * Conversions from older versions cannot be upgraded automatically
665 * because the user-defined functions used by the encoding conversions
666 * need to be changed to match the new signature.
667 */
670
671 /*
672 * Pre-PG 14 allowed user defined postfix operators, which are not
673 * supported anymore. Verify there are none, iff applicable.
674 */
677
678 /*
679 * PG 14 changed polymorphic functions from anyarray to
680 * anycompatiblearray.
681 */
684
685 /*
686 * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
687 * supported anymore. Verify there are none, iff applicable.
688 */
691
692 /*
693 * Pre-PG 18 allowed child tables to omit not-null constraints that their
694 * parents columns have, but schema restore fails for them. Verify there
695 * are none, iff applicable.
696 */
699
700 /*
701 * The btree_gist extension contains gist_inet_ops and gist_cidr_ops
702 * opclasses that do not reliably give correct answers. We want to
703 * deprecate and eventually remove those, and as a first step v19 marks
704 * them not-opcdefault and instead marks the replacement in-core opclass
705 * "inet_ops" as opcdefault. That creates a problem for pg_upgrade: in
706 * versions where those opclasses were marked opcdefault, pg_dump will
707 * dump indexes using them with no explicit opclass specification, so that
708 * restore would create them using the inet_ops opclass. That would be
709 * incompatible with what's actually in the on-disk files. So refuse to
710 * upgrade if there are any such indexes.
711 */
714
715 /*
716 * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
717 * hash indexes
718 */
720 {
721 if (user_opts.check)
723 }
724
725 /* 9.5 and below should not have roles starting with pg_ */
728
729 /*
730 * While not a check option, we do this now because this is the only time
731 * the old server is running.
732 */
733 if (!user_opts.check)
735
737 stop_postmaster(false);
738}
739
740
741void
743{
745
747
749
750 switch (user_opts.transfer_mode)
751 {
754 break;
756 break;
759 break;
762 break;
764
765 /*
766 * We do the hard link check for --swap, too, since it's an easy
767 * way to verify the clusters are in the same file system. This
768 * allows us to take some shortcuts in the file synchronization
769 * step. With some more effort, we could probably support the
770 * separate-file-system use case, but this mode is unlikely to
771 * offer much benefit if we have to copy the files across file
772 * system boundaries.
773 */
775
776 /*
777 * There are a few known issues with using --swap to upgrade from
778 * versions older than 10. For example, the sequence tuple format
779 * changed in v10, and the visibility map format changed in 9.6.
780 * While such problems are not insurmountable (and we may have to
781 * deal with similar problems in the future, anyway), it doesn't
782 * seem worth the effort to support swap mode for upgrades from
783 * long-unsupported versions.
784 */
786 pg_fatal("Swap mode can only upgrade clusters from PostgreSQL version %s and later.",
787 "10");
788
789 break;
790 }
791
793
795
797
799
801}
802
803
804void
806{
807 if (user_opts.check)
808 {
809 pg_log(PG_REPORT, "\n*Clusters are compatible*");
810 /* stops new cluster */
811 stop_postmaster(false);
812
814 exit(0);
815 }
816
817 pg_log(PG_REPORT, "\n"
818 "If pg_upgrade fails after this point, you must re-initdb the\n"
819 "new cluster before continuing.");
820}
821
822
823void
825{
826 /*
827 * We unconditionally start/stop the new server because pg_resetwal -o set
828 * wal_level to 'minimum'. If the user is upgrading standby servers using
829 * the rsync instructions, they will need pg_upgrade to write its final
830 * WAL record showing wal_level as 'replica'.
831 */
833
834 /* Reindex hash indexes for old < 10.0 */
837
839
840 stop_postmaster(false);
841}
842
843
844void
846{
848
851 {
855 }
856
858 "Some statistics are not transferred by pg_upgrade.\n"
859 "Once you start the new server, consider running these two commands:\n"
860 " %s/vacuumdb %s--all --analyze-in-stages --missing-stats-only\n"
861 " %s/vacuumdb %s--all --analyze-only",
864
867 "Running this script will delete the old cluster's data files:\n"
868 " %s",
870 else
872 "Could not create a script to delete the old cluster's data files\n"
873 "because user-defined tablespaces or the new cluster's data directory\n"
874 "exist in the old cluster directory. The old cluster's contents must\n"
875 "be deleted manually.");
876
878}
879
880
881void
883{
884 prep_status("Checking cluster versions");
885
886 /* cluster versions should already have been obtained */
889
890 /*
891 * We allow upgrades from/to the same major version for alpha/beta
892 * upgrades
893 */
894
896 pg_fatal("This utility can only upgrade from PostgreSQL version %s and later.",
897 "9.2");
898
899 /* Only current PG version is supported as a target */
901 pg_fatal("This utility can only upgrade to PostgreSQL version %s.",
903
904 /*
905 * We can't allow downgrading because we use the target pg_dump, and
906 * pg_dump cannot operate on newer database versions, only current and
907 * older versions.
908 */
910 pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.");
911
912 /* Ensure binaries match the designated data directories */
915 pg_fatal("Old cluster data and binary directories are from different major versions.");
918 pg_fatal("New cluster data and binary directories are from different major versions.");
919
920 /*
921 * Since from version 18, newly created database clusters always have
922 * 'signed' default char-signedness, it makes less sense to use
923 * --set-char-signedness option for upgrading from version 18 or later.
924 * Users who want to change the default char signedness of the new
925 * cluster, they can use pg_resetwal manually before the upgrade.
926 */
929 pg_fatal("The option %s cannot be used for upgrades from PostgreSQL %s and later.",
930 "--set-char-signedness", "18");
931
932 check_ok();
933}
934
935
936void
938{
939 /* get/check pg_control data of servers */
943
945 pg_fatal("When checking a live server, "
946 "the old and new port numbers must be different.");
947}
948
949
950static void
952{
953 int dbnum;
954
955 for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
956 {
957 int relnum;
958 RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
959
960 for (relnum = 0; relnum < rel_arr->nrels;
961 relnum++)
962 {
963 /* pg_largeobject and its index should be skipped */
964 if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
965 pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"",
967 rel_arr->rels[relnum].nspname,
968 rel_arr->rels[relnum].relname);
969 }
970 }
971}
972
973/*
974 * A previous run of pg_upgrade might have failed and the new cluster
975 * directory recreated, but they might have forgotten to remove
976 * the new cluster's tablespace directories. Therefore, check that
977 * new cluster tablespace directories do not already exist. If
978 * they do, it would cause an error while restoring global objects.
979 * This allows the failure to be detected at check time, rather than
980 * during schema restore.
981 */
982static void
984{
985 int tblnum;
987
988 prep_status("Checking for new cluster tablespace directories");
989
991 {
992 struct stat statbuf;
993
997
998 if (stat(new_tablespace_dir, &statbuf) == 0 || errno != ENOENT)
999 pg_fatal("new cluster tablespace directory already exists: \"%s\"",
1001 }
1002
1003 check_ok();
1004}
1005
1006/*
1007 * create_script_for_old_cluster_deletion()
1008 *
1009 * This is particularly useful for tablespace deletion.
1010 */
1011void
1013{
1014 FILE *script = NULL;
1015 int tblnum;
1018 char *old_tblspc_suffix;
1019
1020 *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
1022
1025
1028
1029 /* Some people put the new data directory inside the old one. */
1031 {
1033 "\nWARNING: new data directory should not be inside the old data directory, i.e. %s", old_cluster_pgdata);
1034
1035 /* Unlink file in case it is left over from a previous run. */
1039 return;
1040 }
1041
1042 /*
1043 * Some users (oddly) create tablespaces inside the cluster data
1044 * directory. We can't create a proper old cluster delete script in that
1045 * case.
1046 */
1048 {
1050
1054 {
1055 /* reproduce warning from CREATE TABLESPACE that is in the log */
1057 "\nWARNING: user-defined tablespace locations should not be inside the data directory, i.e. %s", new_tablespace_dir);
1058
1059 /* Unlink file in case it is left over from a previous run. */
1063 return;
1064 }
1065 }
1066
1067 prep_status("Creating script to delete old cluster");
1068
1069 if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
1070 pg_fatal("could not open file \"%s\": %m",
1072
1073#ifndef WIN32
1074 /* add shebang header */
1075 fprintf(script, "#!/bin/sh\n\n");
1076#endif
1077
1078 /* delete old cluster's default tablespace */
1079 fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
1081
1082 /* delete old cluster's alternate tablespaces */
1086 fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
1090
1091 fclose(script);
1092
1093#ifndef WIN32
1095 pg_fatal("could not add execute permission to file \"%s\": %m",
1097#endif
1098
1099 check_ok();
1100}
1101
1102
1103/*
1104 * check_is_install_user()
1105 *
1106 * Check we are the install user, and that the new cluster
1107 * has no other users.
1108 */
1109static void
1111{
1112 PGresult *res;
1113 PGconn *conn = connectToServer(cluster, "template1");
1114
1115 prep_status("Checking database user is the install user");
1116
1117 /* Can't use pg_authid because only superusers can view it. */
1118 res = executeQueryOrDie(conn,
1119 "SELECT rolsuper, oid "
1120 "FROM pg_catalog.pg_roles "
1121 "WHERE rolname = current_user "
1122 "AND rolname !~ '^pg_'");
1123
1124 /*
1125 * We only allow the install user in the new cluster (see comment below)
1126 * and we preserve pg_authid.oid, so this must be the install user in the
1127 * old cluster too.
1128 */
1129 if (PQntuples(res) != 1 ||
1131 pg_fatal("database user \"%s\" is not the install user",
1132 os_info.user);
1133
1134 PQclear(res);
1135
1136 res = executeQueryOrDie(conn,
1137 "SELECT COUNT(*) "
1138 "FROM pg_catalog.pg_roles "
1139 "WHERE rolname !~ '^pg_'");
1140
1141 if (PQntuples(res) != 1)
1142 pg_fatal("could not determine the number of users");
1143
1144 /*
1145 * We only allow the install user in the new cluster because other defined
1146 * users might match users defined in the old cluster and generate an
1147 * error during pg_dump restore.
1148 */
1149 if (cluster == &new_cluster && strcmp(PQgetvalue(res, 0, 0), "1") != 0)
1150 pg_fatal("Only the install user can be defined in the new cluster.");
1151
1152 PQclear(res);
1153
1154 PQfinish(conn);
1155
1156 check_ok();
1157}
1158
1159
1160/*
1161 * check_for_connection_status
1162 *
1163 * Ensure that all non-template0 databases allow connections since they
1164 * otherwise won't be restored; and that template0 explicitly doesn't allow
1165 * connections since it would make pg_dumpall --globals restore fail.
1166 */
1167static void
1169{
1170 int dbnum;
1172 PGresult *dbres;
1173 int ntups;
1174 int i_datname;
1175 int i_datallowconn;
1176 int i_datconnlimit;
1177 FILE *script = NULL;
1178 char output_path[MAXPGPATH];
1179
1180 prep_status("Checking database connection settings");
1181
1182 snprintf(output_path, sizeof(output_path), "%s/%s",
1184 "databases_cannot_connect_to.txt");
1185
1186 conn_template1 = connectToServer(cluster, "template1");
1187
1188 /* get database names */
1190 "SELECT datname, datallowconn, datconnlimit "
1191 "FROM pg_catalog.pg_database");
1192
1193 i_datname = PQfnumber(dbres, "datname");
1194 i_datallowconn = PQfnumber(dbres, "datallowconn");
1195 i_datconnlimit = PQfnumber(dbres, "datconnlimit");
1196
1197 ntups = PQntuples(dbres);
1198 for (dbnum = 0; dbnum < ntups; dbnum++)
1199 {
1200 char *datname = PQgetvalue(dbres, dbnum, i_datname);
1203
1204 if (strcmp(datname, "template0") == 0)
1205 {
1206 /* avoid restore failure when pg_dumpall tries to create template0 */
1207 if (strcmp(datallowconn, "t") == 0)
1208 pg_fatal("template0 must not allow connections, "
1209 "i.e. its pg_database.datallowconn must be false");
1210 }
1211 else
1212 {
1213 /*
1214 * Avoid datallowconn == false databases from being skipped on
1215 * restore, and ensure that no databases are marked invalid with
1216 * datconnlimit == -2.
1217 */
1218 if ((strcmp(datallowconn, "f") == 0) || strcmp(datconnlimit, "-2") == 0)
1219 {
1220 if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1221 pg_fatal("could not open file \"%s\": %m", output_path);
1222
1223 fprintf(script, "%s\n", datname);
1224 }
1225 }
1226 }
1227
1228 PQclear(dbres);
1229
1231
1232 if (script)
1233 {
1234 fclose(script);
1235 pg_log(PG_REPORT, "fatal");
1236 pg_fatal("All non-template0 databases must allow connections, i.e. their\n"
1237 "pg_database.datallowconn must be true and pg_database.datconnlimit\n"
1238 "must not be -2. Your installation contains non-template0 databases\n"
1239 "which cannot be connected to. Consider allowing connection for all\n"
1240 "non-template0 databases or drop the databases which do not allow\n"
1241 "connections. A list of databases with the problem is in the file:\n"
1242 " %s", output_path);
1243 }
1244 else
1245 check_ok();
1246}
1247
1248
1249/*
1250 * check_for_unsupported_encodings()
1251 */
1252static void
1254{
1255 int i_datname;
1256 int i_encoding;
1257 int ntups;
1258 PGresult *res;
1259 PGconn *conn;
1260 FILE *script = NULL;
1261 char output_path[MAXPGPATH];
1262
1263 prep_status("Checking for unsupported encodings");
1264
1265 snprintf(output_path, sizeof(output_path), "%s/%s",
1267 "databases_unsupported_encoding.txt");
1268
1269 conn = connectToServer(cluster, "template1");
1270
1271 res = executeQueryOrDie(conn,
1272 "SELECT datname, encoding "
1273 "FROM pg_catalog.pg_database");
1274 ntups = PQntuples(res);
1275 i_datname = PQfnumber(res, "datname");
1276 i_encoding = PQfnumber(res, "encoding");
1277 for (int rowno = 0; rowno < ntups; rowno++)
1278 {
1279 char *datname = PQgetvalue(res, rowno, i_datname);
1280 int encoding = atoi(PQgetvalue(res, rowno, i_encoding));
1281
1283 {
1284 if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1285 pg_fatal("could not open file \"%s\": %m", output_path);
1286
1287 fprintf(script, "%s\n", datname);
1288 }
1289 }
1290 PQclear(res);
1291 PQfinish(conn);
1292
1293 if (script)
1294 {
1295 fclose(script);
1296 pg_log(PG_REPORT, "fatal");
1297 pg_fatal("Your installation contains databases using encodings that are\n"
1298 "no longer supported. Consider dumping and restoring with UTF8.\n"
1299 "A list of databases with unsupported encodings is in the file:\n"
1300 " %s", output_path);
1301 }
1302 else
1303 check_ok();
1304}
1305
1306
1307/*
1308 * check_for_prepared_transactions()
1309 *
1310 * Make sure there are no prepared transactions because the storage format
1311 * might have changed.
1312 */
1313static void
1315{
1316 PGresult *res;
1317 PGconn *conn = connectToServer(cluster, "template1");
1318
1319 prep_status("Checking for prepared transactions");
1320
1321 res = executeQueryOrDie(conn,
1322 "SELECT * "
1323 "FROM pg_catalog.pg_prepared_xacts");
1324
1325 if (PQntuples(res) != 0)
1326 {
1327 if (cluster == &old_cluster)
1328 pg_fatal("The source cluster contains prepared transactions");
1329 else
1330 pg_fatal("The target cluster contains prepared transactions");
1331 }
1332
1333 PQclear(res);
1334
1335 PQfinish(conn);
1336
1337 check_ok();
1338}
1339
1340/*
1341 * Callback function for processing result of query for
1342 * check_for_isn_and_int8_passing_mismatch()'s UpgradeTask. If the query
1343 * returned any rows (i.e., the check failed), write the details to the report
1344 * file.
1345 */
1346static void
1348{
1349 int ntups = PQntuples(res);
1350 int i_nspname = PQfnumber(res, "nspname");
1351 int i_proname = PQfnumber(res, "proname");
1353
1354 if (ntups == 0)
1355 return;
1356
1357 if (report->file == NULL &&
1358 (report->file = fopen_priv(report->path, "w")) == NULL)
1359 pg_fatal("could not open file \"%s\": %m", report->path);
1360
1361 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1362
1363 for (int rowno = 0; rowno < ntups; rowno++)
1364 fprintf(report->file, " %s.%s\n",
1365 PQgetvalue(res, rowno, i_nspname),
1366 PQgetvalue(res, rowno, i_proname));
1367}
1368
1369/*
1370 * check_for_isn_and_int8_passing_mismatch()
1371 *
1372 * contrib/isn relies on data type int8, and in 8.4 int8 can now be passed
1373 * by value. The schema dumps the CREATE TYPE PASSEDBYVALUE setting so
1374 * it must match for the old and new servers.
1375 */
1376static void
1378{
1380 UpgradeTaskReport report;
1381 const char *query = "SELECT n.nspname, p.proname "
1382 "FROM pg_catalog.pg_proc p, "
1383 " pg_catalog.pg_namespace n "
1384 "WHERE p.pronamespace = n.oid AND "
1385 " p.probin = '$libdir/isn'";
1386
1387 prep_status("Checking for contrib/isn with bigint-passing mismatch");
1388
1391 {
1392 /* no mismatch */
1393 check_ok();
1394 return;
1395 }
1396
1397 report.file = NULL;
1398 snprintf(report.path, sizeof(report.path), "%s/%s",
1400 "contrib_isn_and_int8_pass_by_value.txt");
1401
1404 true, &report);
1407
1408 if (report.file)
1409 {
1410 fclose(report.file);
1411 pg_log(PG_REPORT, "fatal");
1412 pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
1413 "bigint data type. Your old and new clusters pass bigint values\n"
1414 "differently so this cluster cannot currently be upgraded. You can\n"
1415 "manually dump databases in the old cluster that use \"contrib/isn\"\n"
1416 "facilities, drop them, perform the upgrade, and then restore them. A\n"
1417 "list of the problem functions is in the file:\n"
1418 " %s", report.path);
1419 }
1420 else
1421 check_ok();
1422}
1423
1424/*
1425 * Callback function for processing result of query for
1426 * check_for_user_defined_postfix_ops()'s UpgradeTask. If the query returned
1427 * any rows (i.e., the check failed), write the details to the report file.
1428 */
1429static void
1431{
1433 int ntups = PQntuples(res);
1434 int i_oproid = PQfnumber(res, "oproid");
1435 int i_oprnsp = PQfnumber(res, "oprnsp");
1436 int i_oprname = PQfnumber(res, "oprname");
1437 int i_typnsp = PQfnumber(res, "typnsp");
1438 int i_typname = PQfnumber(res, "typname");
1439
1440 if (ntups == 0)
1441 return;
1442
1443 if (report->file == NULL &&
1444 (report->file = fopen_priv(report->path, "w")) == NULL)
1445 pg_fatal("could not open file \"%s\": %m", report->path);
1446
1447 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1448
1449 for (int rowno = 0; rowno < ntups; rowno++)
1450 fprintf(report->file, " (oid=%s) %s.%s (%s.%s, NONE)\n",
1451 PQgetvalue(res, rowno, i_oproid),
1452 PQgetvalue(res, rowno, i_oprnsp),
1453 PQgetvalue(res, rowno, i_oprname),
1454 PQgetvalue(res, rowno, i_typnsp),
1455 PQgetvalue(res, rowno, i_typname));
1456}
1457
1458/*
1459 * Verify that no user defined postfix operators exist.
1460 */
1461static void
1463{
1464 UpgradeTaskReport report;
1466 const char *query;
1467
1468 /*
1469 * The query below hardcodes FirstNormalObjectId as 16384 rather than
1470 * interpolating that C #define into the query because, if that #define is
1471 * ever changed, the cutoff we want to use is the value used by
1472 * pre-version 14 servers, not that of some future version.
1473 */
1474 query = "SELECT o.oid AS oproid, "
1475 " n.nspname AS oprnsp, "
1476 " o.oprname, "
1477 " tn.nspname AS typnsp, "
1478 " t.typname "
1479 "FROM pg_catalog.pg_operator o, "
1480 " pg_catalog.pg_namespace n, "
1481 " pg_catalog.pg_type t, "
1482 " pg_catalog.pg_namespace tn "
1483 "WHERE o.oprnamespace = n.oid AND "
1484 " o.oprleft = t.oid AND "
1485 " t.typnamespace = tn.oid AND "
1486 " o.oprright = 0 AND "
1487 " o.oid >= 16384";
1488
1489 prep_status("Checking for user-defined postfix operators");
1490
1491 report.file = NULL;
1492 snprintf(report.path, sizeof(report.path), "%s/%s",
1494 "postfix_ops.txt");
1495
1497 true, &report);
1500
1501 if (report.file)
1502 {
1503 fclose(report.file);
1504 pg_log(PG_REPORT, "fatal");
1505 pg_fatal("Your installation contains user-defined postfix operators, which are not\n"
1506 "supported anymore. Consider dropping the postfix operators and replacing\n"
1507 "them with prefix operators or function calls.\n"
1508 "A list of user-defined postfix operators is in the file:\n"
1509 " %s", report.path);
1510 }
1511 else
1512 check_ok();
1513}
1514
1515/*
1516 * Callback function for processing results of query for
1517 * check_for_incompatible_polymorphics()'s UpgradeTask. If the query returned
1518 * any rows (i.e., the check failed), write the details to the report file.
1519 */
1520static void
1522{
1524 int ntups = PQntuples(res);
1525 int i_objkind = PQfnumber(res, "objkind");
1526 int i_objname = PQfnumber(res, "objname");
1527
1528 if (ntups == 0)
1529 return;
1530
1531 if (report->file == NULL &&
1532 (report->file = fopen_priv(report->path, "w")) == NULL)
1533 pg_fatal("could not open file \"%s\": %m", report->path);
1534
1535 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1536
1537 for (int rowno = 0; rowno < ntups; rowno++)
1538 fprintf(report->file, " %s: %s\n",
1539 PQgetvalue(res, rowno, i_objkind),
1540 PQgetvalue(res, rowno, i_objname));
1541}
1542
1543/*
1544 * check_for_incompatible_polymorphics()
1545 *
1546 * Make sure nothing is using old polymorphic functions with
1547 * anyarray/anyelement rather than the new anycompatible variants.
1548 */
1549static void
1551{
1554 UpgradeTaskReport report;
1555 char *query;
1556
1557 prep_status("Checking for incompatible polymorphic functions");
1558
1559 report.file = NULL;
1560 snprintf(report.path, sizeof(report.path), "%s/%s",
1562 "incompatible_polymorphics.txt");
1563
1564 /* The set of problematic functions varies a bit in different versions */
1566
1568 "'array_append(anyarray,anyelement)'"
1569 ", 'array_cat(anyarray,anyarray)'"
1570 ", 'array_prepend(anyelement,anyarray)'");
1571
1572 if (GET_MAJOR_VERSION(cluster->major_version) >= 903)
1574 ", 'array_remove(anyarray,anyelement)'"
1575 ", 'array_replace(anyarray,anyelement,anyelement)'");
1576
1577 if (GET_MAJOR_VERSION(cluster->major_version) >= 905)
1579 ", 'array_position(anyarray,anyelement)'"
1580 ", 'array_position(anyarray,anyelement,integer)'"
1581 ", 'array_positions(anyarray,anyelement)'"
1582 ", 'width_bucket(anyelement,anyarray)'");
1583
1584 /*
1585 * The query below hardcodes FirstNormalObjectId as 16384 rather than
1586 * interpolating that C #define into the query because, if that #define is
1587 * ever changed, the cutoff we want to use is the value used by
1588 * pre-version 14 servers, not that of some future version.
1589 */
1590
1591 /* Aggregate transition functions */
1592 query = psprintf("SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
1593 "FROM pg_proc AS p "
1594 "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
1595 "JOIN pg_proc AS transfn ON transfn.oid=a.aggtransfn "
1596 "WHERE p.oid >= 16384 "
1597 "AND a.aggtransfn = ANY(ARRAY[%s]::regprocedure[]) "
1598 "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
1599
1600 /* Aggregate final functions */
1601 "UNION ALL "
1602 "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
1603 "FROM pg_proc AS p "
1604 "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
1605 "JOIN pg_proc AS finalfn ON finalfn.oid=a.aggfinalfn "
1606 "WHERE p.oid >= 16384 "
1607 "AND a.aggfinalfn = ANY(ARRAY[%s]::regprocedure[]) "
1608 "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
1609
1610 /* Operators */
1611 "UNION ALL "
1612 "SELECT 'operator' AS objkind, op.oid::regoperator::text AS objname "
1613 "FROM pg_operator AS op "
1614 "WHERE op.oid >= 16384 "
1615 "AND oprcode = ANY(ARRAY[%s]::regprocedure[]) "
1616 "AND oprleft = ANY(ARRAY['anyarray', 'anyelement']::regtype[])",
1617 old_polymorphics.data,
1618 old_polymorphics.data,
1619 old_polymorphics.data);
1620
1622 true, &report);
1625
1626 if (report.file)
1627 {
1628 fclose(report.file);
1629 pg_log(PG_REPORT, "fatal");
1630 pg_fatal("Your installation contains user-defined objects that refer to internal\n"
1631 "polymorphic functions with arguments of type \"anyarray\" or \"anyelement\".\n"
1632 "These user-defined objects must be dropped before upgrading and restored\n"
1633 "afterwards, changing them to refer to the new corresponding functions with\n"
1634 "arguments of type \"anycompatiblearray\" and \"anycompatible\".\n"
1635 "A list of the problematic objects is in the file:\n"
1636 " %s", report.path);
1637 }
1638 else
1639 check_ok();
1640
1642 pg_free(query);
1643}
1644
1645/*
1646 * Callback function for processing results of query for
1647 * check_for_tables_with_oids()'s UpgradeTask. If the query returned any rows
1648 * (i.e., the check failed), write the details to the report file.
1649 */
1650static void
1652{
1654 int ntups = PQntuples(res);
1655 int i_nspname = PQfnumber(res, "nspname");
1656 int i_relname = PQfnumber(res, "relname");
1657
1658 if (ntups == 0)
1659 return;
1660
1661 if (report->file == NULL &&
1662 (report->file = fopen_priv(report->path, "w")) == NULL)
1663 pg_fatal("could not open file \"%s\": %m", report->path);
1664
1665 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1666
1667 for (int rowno = 0; rowno < ntups; rowno++)
1668 fprintf(report->file, " %s.%s\n",
1669 PQgetvalue(res, rowno, i_nspname),
1670 PQgetvalue(res, rowno, i_relname));
1671}
1672
1673/*
1674 * Verify that no tables are declared WITH OIDS.
1675 */
1676static void
1678{
1679 UpgradeTaskReport report;
1681 const char *query = "SELECT n.nspname, c.relname "
1682 "FROM pg_catalog.pg_class c, "
1683 " pg_catalog.pg_namespace n "
1684 "WHERE c.relnamespace = n.oid AND "
1685 " c.relhasoids AND"
1686 " n.nspname NOT IN ('pg_catalog')";
1687
1688 prep_status("Checking for tables WITH OIDS");
1689
1690 report.file = NULL;
1691 snprintf(report.path, sizeof(report.path), "%s/%s",
1693 "tables_with_oids.txt");
1694
1696 true, &report);
1699
1700 if (report.file)
1701 {
1702 fclose(report.file);
1703 pg_log(PG_REPORT, "fatal");
1704 pg_fatal("Your installation contains tables declared WITH OIDS, which is not\n"
1705 "supported anymore. Consider removing the oid column using\n"
1706 " ALTER TABLE ... SET WITHOUT OIDS;\n"
1707 "A list of tables with the problem is in the file:\n"
1708 " %s", report.path);
1709 }
1710 else
1711 check_ok();
1712}
1713
1714/*
1715 * Callback function for processing results of query for
1716 * check_for_not_null_inheritance.
1717 */
1718static void
1720{
1722 int ntups = PQntuples(res);
1723 int i_nspname = PQfnumber(res, "nspname");
1724 int i_relname = PQfnumber(res, "relname");
1725 int i_attname = PQfnumber(res, "attname");
1726
1727 if (ntups == 0)
1728 return;
1729
1730 if (report->file == NULL &&
1731 (report->file = fopen_priv(report->path, "w")) == NULL)
1732 pg_fatal("could not open file \"%s\": %m", report->path);
1733
1734 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1735
1736 for (int rowno = 0; rowno < ntups; rowno++)
1737 {
1738 fprintf(report->file, " %s.%s.%s\n",
1739 PQgetvalue(res, rowno, i_nspname),
1740 PQgetvalue(res, rowno, i_relname),
1741 PQgetvalue(res, rowno, i_attname));
1742 }
1743}
1744
1745/*
1746 * check_for_not_null_inheritance()
1747 *
1748 * An attempt to create child tables lacking not-null constraints that are
1749 * present in their parents errors out. This can no longer occur since 18,
1750 * but previously there were various ways for that to happen. Check that
1751 * the cluster to be upgraded doesn't have any of those problems.
1752 */
1753static void
1755{
1756 UpgradeTaskReport report;
1758 const char *query;
1759
1760 prep_status("Checking for not-null constraint inconsistencies");
1761
1762 report.file = NULL;
1763 snprintf(report.path, sizeof(report.path), "%s/%s",
1765 "not_null_inconsistent_columns.txt");
1766
1767 query = "SELECT nspname, cc.relname, ac.attname "
1768 "FROM pg_catalog.pg_inherits i, pg_catalog.pg_attribute ac, "
1769 " pg_catalog.pg_attribute ap, pg_catalog.pg_class cc, "
1770 " pg_catalog.pg_namespace nc "
1771 "WHERE cc.oid = ac.attrelid AND i.inhrelid = ac.attrelid "
1772 " AND i.inhparent = ap.attrelid AND ac.attname = ap.attname "
1773 " AND cc.relnamespace = nc.oid "
1774 " AND ap.attnum > 0 and ap.attnotnull AND NOT ac.attnotnull";
1775
1779 true, &report);
1782
1783 if (report.file)
1784 {
1785 fclose(report.file);
1786 pg_log(PG_REPORT, "fatal");
1787 pg_fatal("Your installation contains inconsistent NOT NULL constraints.\n"
1788 "If the parent column(s) are NOT NULL, then the child column must\n"
1789 "also be marked NOT NULL, or the upgrade will fail.\n"
1790 "You can fix this by running\n"
1791 " ALTER TABLE tablename ALTER column SET NOT NULL;\n"
1792 "on each column listed in the file:\n"
1793 " %s", report.path);
1794 }
1795 else
1796 check_ok();
1797}
1798
1799/*
1800 * Callback function for processing results of query for
1801 * check_for_gist_inet_ops()'s UpgradeTask. If the query returned any rows
1802 * (i.e., the check failed), write the details to the report file.
1803 */
1804static void
1806{
1808 int ntups = PQntuples(res);
1809 int i_nspname = PQfnumber(res, "nspname");
1810 int i_relname = PQfnumber(res, "relname");
1811
1812 if (ntups == 0)
1813 return;
1814
1815 if (report->file == NULL &&
1816 (report->file = fopen_priv(report->path, "w")) == NULL)
1817 pg_fatal("could not open file \"%s\": %m", report->path);
1818
1819 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1820
1821 for (int rowno = 0; rowno < ntups; rowno++)
1822 fprintf(report->file, " %s.%s\n",
1823 PQgetvalue(res, rowno, i_nspname),
1824 PQgetvalue(res, rowno, i_relname));
1825}
1826
1827/*
1828 * Verify that no indexes use gist_inet_ops/gist_cidr_ops, unless the
1829 * opclasses have been changed to not-opcdefault (which would allow
1830 * the old server to dump the index definitions with explicit opclasses).
1831 */
1832static void
1834{
1835 UpgradeTaskReport report;
1837 const char *query = "SELECT nc.nspname, cc.relname "
1838 "FROM pg_catalog.pg_opclass oc, pg_catalog.pg_index i, "
1839 " pg_catalog.pg_class cc, pg_catalog.pg_namespace nc "
1840 "WHERE oc.opcmethod = " CppAsString2(GIST_AM_OID)
1841 " AND oc.opcname IN ('gist_inet_ops', 'gist_cidr_ops')"
1842 " AND oc.opcdefault"
1843 " AND oc.oid = any(i.indclass)"
1844 " AND i.indexrelid = cc.oid AND cc.relnamespace = nc.oid";
1845
1846 prep_status("Checking for uses of gist_inet_ops/gist_cidr_ops");
1847
1848 report.file = NULL;
1849 snprintf(report.path, sizeof(report.path), "%s/%s",
1851 "gist_inet_ops.txt");
1852
1854 true, &report);
1857
1858 if (report.file)
1859 {
1860 fclose(report.file);
1861 pg_log(PG_REPORT, "fatal");
1862 pg_fatal("Your installation contains indexes that use btree_gist's\n"
1863 "gist_inet_ops or gist_cidr_ops opclasses,\n"
1864 "which cannot be binary-upgraded. Replace them with indexes\n"
1865 "that use the built-in GiST inet_ops opclass.\n"
1866 "A list of indexes with the problem is in the file:\n"
1867 " %s", report.path);
1868 }
1869 else
1870 check_ok();
1871}
1872
1873/*
1874 * check_for_pg_role_prefix()
1875 *
1876 * Versions older than 9.6 should not have any pg_* roles
1877 */
1878static void
1880{
1881 PGresult *res;
1882 PGconn *conn = connectToServer(cluster, "template1");
1883 int ntups;
1884 int i_roloid;
1885 int i_rolname;
1886 FILE *script = NULL;
1887 char output_path[MAXPGPATH];
1888
1889 prep_status("Checking for roles starting with \"pg_\"");
1890
1891 snprintf(output_path, sizeof(output_path), "%s/%s",
1893 "pg_role_prefix.txt");
1894
1895 res = executeQueryOrDie(conn,
1896 "SELECT oid AS roloid, rolname "
1897 "FROM pg_catalog.pg_roles "
1898 "WHERE rolname ~ '^pg_'");
1899
1900 ntups = PQntuples(res);
1901 i_roloid = PQfnumber(res, "roloid");
1902 i_rolname = PQfnumber(res, "rolname");
1903 for (int rowno = 0; rowno < ntups; rowno++)
1904 {
1905 if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1906 pg_fatal("could not open file \"%s\": %m", output_path);
1907 fprintf(script, "%s (oid=%s)\n",
1908 PQgetvalue(res, rowno, i_rolname),
1909 PQgetvalue(res, rowno, i_roloid));
1910 }
1911
1912 PQclear(res);
1913
1914 PQfinish(conn);
1915
1916 if (script)
1917 {
1918 fclose(script);
1919 pg_log(PG_REPORT, "fatal");
1920 pg_fatal("Your installation contains roles starting with \"pg_\".\n"
1921 "\"pg_\" is a reserved prefix for system roles. The cluster\n"
1922 "cannot be upgraded until these roles are renamed.\n"
1923 "A list of roles starting with \"pg_\" is in the file:\n"
1924 " %s", output_path);
1925 }
1926 else
1927 check_ok();
1928}
1929
1930/*
1931 * Callback function for processing results of query for
1932 * check_for_user_defined_encoding_conversions()'s UpgradeTask. If the query
1933 * returned any rows (i.e., the check failed), write the details to the report
1934 * file.
1935 */
1936static void
1938{
1940 int ntups = PQntuples(res);
1941 int i_conoid = PQfnumber(res, "conoid");
1942 int i_conname = PQfnumber(res, "conname");
1943 int i_nspname = PQfnumber(res, "nspname");
1944
1945 if (ntups == 0)
1946 return;
1947
1948 if (report->file == NULL &&
1949 (report->file = fopen_priv(report->path, "w")) == NULL)
1950 pg_fatal("could not open file \"%s\": %m", report->path);
1951
1952 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1953
1954 for (int rowno = 0; rowno < ntups; rowno++)
1955 fprintf(report->file, " (oid=%s) %s.%s\n",
1956 PQgetvalue(res, rowno, i_conoid),
1957 PQgetvalue(res, rowno, i_nspname),
1958 PQgetvalue(res, rowno, i_conname));
1959}
1960
1961/*
1962 * Verify that no user-defined encoding conversions exist.
1963 */
1964static void
1966{
1967 UpgradeTaskReport report;
1969 const char *query;
1970
1971 prep_status("Checking for user-defined encoding conversions");
1972
1973 report.file = NULL;
1974 snprintf(report.path, sizeof(report.path), "%s/%s",
1976 "encoding_conversions.txt");
1977
1978 /*
1979 * The query below hardcodes FirstNormalObjectId as 16384 rather than
1980 * interpolating that C #define into the query because, if that #define is
1981 * ever changed, the cutoff we want to use is the value used by
1982 * pre-version 14 servers, not that of some future version.
1983 */
1984 query = "SELECT c.oid as conoid, c.conname, n.nspname "
1985 "FROM pg_catalog.pg_conversion c, "
1986 " pg_catalog.pg_namespace n "
1987 "WHERE c.connamespace = n.oid AND "
1988 " c.oid >= 16384";
1989
1992 true, &report);
1995
1996 if (report.file)
1997 {
1998 fclose(report.file);
1999 pg_log(PG_REPORT, "fatal");
2000 pg_fatal("Your installation contains user-defined encoding conversions.\n"
2001 "The conversion function parameters changed in PostgreSQL version 14\n"
2002 "so this cluster cannot currently be upgraded. You can remove the\n"
2003 "encoding conversions in the old cluster and restart the upgrade.\n"
2004 "A list of user-defined encoding conversions is in the file:\n"
2005 " %s", report.path);
2006 }
2007 else
2008 check_ok();
2009}
2010
2011/*
2012 * Callback function for processing results of query for
2013 * check_for_unicode_update()'s UpgradeTask. If the query returned any rows
2014 * (i.e., the check failed), write the details to the report file.
2015 */
2016static void
2018{
2020 int ntups = PQntuples(res);
2021 int i_reloid = PQfnumber(res, "reloid");
2022 int i_nspname = PQfnumber(res, "nspname");
2023 int i_relname = PQfnumber(res, "relname");
2024
2025 if (ntups == 0)
2026 return;
2027
2028 if (report->file == NULL &&
2029 (report->file = fopen_priv(report->path, "w")) == NULL)
2030 pg_fatal("could not open file \"%s\": %m", report->path);
2031
2032 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
2033
2034 for (int rowno = 0; rowno < ntups; rowno++)
2035 fprintf(report->file, " (oid=%s) %s.%s\n",
2036 PQgetvalue(res, rowno, i_reloid),
2037 PQgetvalue(res, rowno, i_nspname),
2038 PQgetvalue(res, rowno, i_relname));
2039}
2040
2041/*
2042 * Check if the Unicode version built into Postgres changed between the old
2043 * cluster and the new cluster.
2044 */
2045static bool
2047{
2049 PGresult *res;
2050 char *old_unicode_version;
2051 bool unicode_updated;
2052
2053 res = executeQueryOrDie(conn_template1, "SELECT unicode_version()");
2054 old_unicode_version = PQgetvalue(res, 0, 0);
2056
2057 PQclear(res);
2059
2060 return unicode_updated;
2061}
2062
2063/*
2064 * check_for_unicode_update()
2065 *
2066 * Check if the version of Unicode in the old server and the new server
2067 * differ. If so, check for indexes, partitioned tables, or constraints that
2068 * use expressions with functions dependent on Unicode behavior.
2069 */
2070static void
2072{
2073 UpgradeTaskReport report;
2075 const char *query;
2076
2077 /*
2078 * The builtin provider did not exist prior to version 17. While there are
2079 * still problems that could potentially be caught from earlier versions,
2080 * such as an index on NORMALIZE(), we don't check for that here.
2081 */
2082 if (GET_MAJOR_VERSION(cluster->major_version) < 1700)
2083 return;
2084
2085 prep_status("Checking for objects affected by Unicode update");
2086
2088 {
2089 check_ok();
2090 return;
2091 }
2092
2093 report.file = NULL;
2094 snprintf(report.path, sizeof(report.path), "%s/%s",
2096 "unicode_dependent_rels.txt");
2097
2098 query =
2099 /* collations that use built-in Unicode for character semantics */
2100 "WITH collations(collid) AS ( "
2101 " SELECT oid FROM pg_collation "
2102 " WHERE collprovider='b' AND colllocale IN ('C.UTF-8','PG_UNICODE_FAST') "
2103 /* include default collation, if appropriate */
2104 " UNION "
2105 " SELECT 'pg_catalog.default'::regcollation FROM pg_database "
2106 " WHERE datname = current_database() AND "
2107 " datlocprovider='b' AND datlocale IN ('C.UTF-8','PG_UNICODE_FAST') "
2108 "), "
2109 /* functions that use built-in Unicode */
2110 "functions(procid) AS ( "
2111 " SELECT proc.oid FROM pg_proc proc "
2112 " WHERE proname IN ('normalize','unicode_assigned','unicode_version','is_normalized') AND "
2113 " pronamespace='pg_catalog'::regnamespace "
2114 "), "
2115 /* operators that use the input collation for character semantics */
2116 "coll_operators(operid, procid, collid) AS ( "
2117 " SELECT oper.oid, oper.oprcode, collid FROM pg_operator oper, collations "
2118 " WHERE oprname IN ('~', '~*', '!~', '!~*', '~~*', '!~~*') AND "
2119 " oprnamespace='pg_catalog'::regnamespace AND "
2120 " oprright='pg_catalog.text'::pg_catalog.regtype "
2121 "), "
2122 /* functions that use the input collation for character semantics */
2123 "coll_functions(procid, collid) AS ( "
2124 " SELECT proc.oid, collid FROM pg_proc proc, collations "
2125 " WHERE pronamespace='pg_catalog'::regnamespace AND "
2126 " ((proname IN ('lower','initcap','upper','casefold') AND "
2127 " pronargs = 1 AND "
2128 " proargtypes[0] = 'pg_catalog.text'::pg_catalog.regtype) OR "
2129 " (proname = 'substring' AND pronargs = 2 AND "
2130 " proargtypes[0] = 'pg_catalog.text'::pg_catalog.regtype AND "
2131 " proargtypes[1] = 'pg_catalog.text'::pg_catalog.regtype) OR "
2132 " proname LIKE 'regexp_%') "
2133 /* include functions behind the operators listed above */
2134 " UNION "
2135 " SELECT procid, collid FROM coll_operators "
2136 "), "
2137
2138 /*
2139 * Generate patterns to search a pg_node_tree for the above functions and
2140 * operators.
2141 */
2142 "patterns(p) AS ( "
2143 " SELECT '{FUNCEXPR :funcid ' || procid::text || '[ }]' FROM functions "
2144 " UNION "
2145 " SELECT '{OPEXPR :opno ' || operid::text || ' (:\\w+ \\w+ )*' || "
2146 " ':inputcollid ' || collid::text || '[ }]' FROM coll_operators "
2147 " UNION "
2148 " SELECT '{FUNCEXPR :funcid ' || procid::text || ' (:\\w+ \\w+ )*' || "
2149 " ':inputcollid ' || collid::text || '[ }]' FROM coll_functions "
2150 ") "
2151
2152 /*
2153 * Match the patterns against expressions used for relation contents.
2154 */
2155 "SELECT reloid, relkind, nspname, relname "
2156 " FROM ( "
2157 " SELECT conrelid "
2158 " FROM pg_constraint, patterns WHERE conbin::text ~ p "
2159 " UNION "
2160 " SELECT indexrelid "
2161 " FROM pg_index, patterns WHERE indexprs::text ~ p OR indpred::text ~ p "
2162 " UNION "
2163 " SELECT partrelid "
2164 " FROM pg_partitioned_table, patterns WHERE partexprs::text ~ p "
2165 " UNION "
2166 " SELECT ev_class "
2167 " FROM pg_rewrite, pg_class, patterns "
2168 " WHERE ev_class = pg_class.oid AND relkind = 'm' AND ev_action::text ~ p"
2169 " ) s(reloid), pg_class c, pg_namespace n, pg_database d "
2170 " WHERE s.reloid = c.oid AND c.relnamespace = n.oid AND "
2171 " d.datname = current_database() AND "
2172 " d.encoding = pg_char_to_encoding('UTF8');";
2173
2177 true, &report);
2180
2181 if (report.file)
2182 {
2183 fclose(report.file);
2184 report_status(PG_WARNING, "warning");
2185 pg_log(PG_WARNING, "Your installation contains relations that might be affected by a new version of Unicode.\n"
2186 "A list of potentially-affected relations is in the file:\n"
2187 " %s", report.path);
2188 }
2189 else
2190 check_ok();
2191}
2192
2193/*
2194 * check_new_cluster_replication_slots()
2195 *
2196 * Validate the new cluster's readiness for migrating replication slots:
2197 * - Ensures no existing logical replication slots on the new cluster when
2198 * migrating logical slots.
2199 * - Ensure conflict detection slot does not exist on the new cluster when
2200 * migrating subscriptions with retain_dead_tuples enabled.
2201 * - Ensure that the parameter settings on the new cluster necessary for
2202 * creating slots are sufficient.
2203 */
2204static void
2206{
2207 PGresult *res;
2208 PGconn *conn;
2209 int nslots_on_old;
2210 int nslots_on_new;
2211 int rdt_slot_on_new;
2213 char *wal_level;
2214 int i_nslots_on_new;
2216
2217 /*
2218 * Logical slots can be migrated since PG17 and a physical slot
2219 * CONFLICT_DETECTION_SLOT can be migrated since PG19.
2220 */
2222 return;
2223
2225
2226 /*
2227 * Quick return if there are no slots to be migrated and no subscriptions
2228 * have the retain_dead_tuples option enabled.
2229 */
2231 return;
2232
2233 conn = connectToServer(&new_cluster, "template1");
2234
2235 prep_status("Checking for new cluster replication slots");
2236
2237 res = executeQueryOrDie(conn, "SELECT %s AS nslots_on_new, %s AS rdt_slot_on_new "
2238 "FROM pg_catalog.pg_replication_slots",
2239 nslots_on_old > 0
2240 ? "COUNT(*) FILTER (WHERE slot_type = 'logical' AND temporary IS FALSE)"
2241 : "0",
2243 ? "COUNT(*) FILTER (WHERE slot_name = 'pg_conflict_detection')"
2244 : "0");
2245
2246 if (PQntuples(res) != 1)
2247 pg_fatal("could not count the number of replication slots");
2248
2249 i_nslots_on_new = PQfnumber(res, "nslots_on_new");
2250 i_rdt_slot_on_new = PQfnumber(res, "rdt_slot_on_new");
2251
2253
2254 if (nslots_on_new)
2255 {
2257 pg_fatal("expected 0 logical replication slots but found %d",
2259 }
2260
2262
2263 if (rdt_slot_on_new)
2264 {
2266 pg_fatal("The replication slot \"pg_conflict_detection\" already exists on the new cluster");
2267 }
2268
2269 PQclear(res);
2270
2271 res = executeQueryOrDie(conn, "SELECT setting FROM pg_settings "
2272 "WHERE name IN ('wal_level', 'max_replication_slots') "
2273 "ORDER BY name DESC;");
2274
2275 if (PQntuples(res) != 2)
2276 pg_fatal("could not determine parameter settings on new cluster");
2277
2278 wal_level = PQgetvalue(res, 0, 0);
2279
2281 strcmp(wal_level, "minimal") == 0)
2282 pg_fatal("\"wal_level\" must be \"replica\" or \"logical\" but is set to \"%s\"",
2283 wal_level);
2284
2286
2289 pg_fatal("\"max_replication_slots\" (%d) must be greater than or equal to the number of "
2290 "logical replication slots on the old cluster plus one additional slot required "
2291 "for retaining conflict detection information (%d)",
2293
2295 pg_fatal("\"max_replication_slots\" (%d) must be greater than or equal to the number of "
2296 "logical replication slots (%d) on the old cluster",
2298
2299 PQclear(res);
2300 PQfinish(conn);
2301
2302 check_ok();
2303}
2304
2305/*
2306 * check_new_cluster_subscription_configuration()
2307 *
2308 * Verify that the max_active_replication_origins configuration specified is
2309 * enough for creating the subscriptions. This is required to create the
2310 * replication origin for each subscription.
2311 */
2312static void
2314{
2315 PGresult *res;
2316 PGconn *conn;
2318
2319 /* Subscriptions and their dependencies can be migrated since PG17. */
2321 return;
2322
2323 /* Quick return if there are no subscriptions to be migrated. */
2324 if (old_cluster.nsubs == 0)
2325 return;
2326
2327 prep_status("Checking for new cluster configuration for subscriptions");
2328
2329 conn = connectToServer(&new_cluster, "template1");
2330
2331 res = executeQueryOrDie(conn, "SELECT setting FROM pg_settings "
2332 "WHERE name = 'max_active_replication_origins';");
2333
2334 if (PQntuples(res) != 1)
2335 pg_fatal("could not determine parameter settings on new cluster");
2336
2339 pg_fatal("\"max_active_replication_origins\" (%d) must be greater than or equal to the number of "
2340 "subscriptions (%d) on the old cluster",
2342
2343 PQclear(res);
2344 PQfinish(conn);
2345
2346 check_ok();
2347}
2348
2349/*
2350 * check_old_cluster_for_valid_slots()
2351 *
2352 * Verify that all the logical slots are valid and have consumed all the WAL
2353 * before shutdown.
2354 */
2355static void
2357{
2358 char output_path[MAXPGPATH];
2359 FILE *script = NULL;
2360
2361 prep_status("Checking for valid logical replication slots");
2362
2363 snprintf(output_path, sizeof(output_path), "%s/%s",
2365 "invalid_logical_slots.txt");
2366
2367 for (int dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
2368 {
2369 LogicalSlotInfoArr *slot_arr = &old_cluster.dbarr.dbs[dbnum].slot_arr;
2370
2371 for (int slotnum = 0; slotnum < slot_arr->nslots; slotnum++)
2372 {
2373 LogicalSlotInfo *slot = &slot_arr->slots[slotnum];
2374
2375 /* Is the slot usable? */
2376 if (slot->invalid)
2377 {
2378 if (script == NULL &&
2379 (script = fopen_priv(output_path, "w")) == NULL)
2380 pg_fatal("could not open file \"%s\": %m", output_path);
2381
2382 fprintf(script, "The slot \"%s\" is invalid\n",
2383 slot->slotname);
2384
2385 continue;
2386 }
2387
2388 /*
2389 * Do additional check to ensure that all logical replication
2390 * slots have consumed all the WAL before shutdown.
2391 *
2392 * Note: This can be satisfied only when the old cluster has been
2393 * shut down, so we skip this for live checks.
2394 */
2395 if (!user_opts.live_check && !slot->caught_up)
2396 {
2397 if (script == NULL &&
2398 (script = fopen_priv(output_path, "w")) == NULL)
2399 pg_fatal("could not open file \"%s\": %m", output_path);
2400
2401 fprintf(script,
2402 "The slot \"%s\" has not consumed the WAL yet\n",
2403 slot->slotname);
2404 }
2405
2406 /*
2407 * The name "pg_conflict_detection" (defined as
2408 * CONFLICT_DETECTION_SLOT) has been reserved for logical
2409 * replication conflict detection slot since PG19.
2410 */
2411 if (strcmp(slot->slotname, "pg_conflict_detection") == 0)
2412 {
2413 if (script == NULL &&
2414 (script = fopen_priv(output_path, "w")) == NULL)
2415 pg_fatal("could not open file \"%s\": %m", output_path);
2416
2417 fprintf(script,
2418 "The slot name \"%s\" is reserved\n",
2419 slot->slotname);
2420 }
2421 }
2422 }
2423
2424 if (script)
2425 {
2426 fclose(script);
2427
2428 pg_log(PG_REPORT, "fatal");
2429 pg_fatal("Your installation contains logical replication slots that cannot be upgraded.\n"
2430 "You can remove invalid slots and/or consume the pending WAL for other slots,\n"
2431 "and then restart the upgrade.\n"
2432 "A list of the problematic slots is in the file:\n"
2433 " %s", output_path);
2434 }
2435
2436 check_ok();
2437}
2438
2439/*
2440 * Callback function for processing results of query for
2441 * check_old_cluster_subscription_state()'s UpgradeTask. If the query returned
2442 * any rows (i.e., the check failed), write the details to the report file.
2443 */
2444static void
2446{
2448 int ntups = PQntuples(res);
2449 int i_srsubstate = PQfnumber(res, "srsubstate");
2450 int i_subname = PQfnumber(res, "subname");
2451 int i_nspname = PQfnumber(res, "nspname");
2452 int i_relname = PQfnumber(res, "relname");
2453
2454 if (ntups == 0)
2455 return;
2456
2457 if (report->file == NULL &&
2458 (report->file = fopen_priv(report->path, "w")) == NULL)
2459 pg_fatal("could not open file \"%s\": %m", report->path);
2460
2461 for (int i = 0; i < ntups; i++)
2462 fprintf(report->file, "The table sync state \"%s\" is not allowed for database:\"%s\" subscription:\"%s\" schema:\"%s\" relation:\"%s\"\n",
2463 PQgetvalue(res, i, i_srsubstate),
2464 dbinfo->db_name,
2465 PQgetvalue(res, i, i_subname),
2466 PQgetvalue(res, i, i_nspname),
2467 PQgetvalue(res, i, i_relname));
2468}
2469
2470/*
2471 * check_old_cluster_subscription_state()
2472 *
2473 * Verify that the replication origin corresponding to each of the
2474 * subscriptions are present and each of the subscribed tables is in
2475 * 'i' (initialize) or 'r' (ready) state.
2476 */
2477static void
2479{
2481 UpgradeTaskReport report;
2482 const char *query;
2483 PGresult *res;
2484 PGconn *conn;
2485 int ntup;
2486
2487 prep_status("Checking for subscription state");
2488
2489 report.file = NULL;
2490 snprintf(report.path, sizeof(report.path), "%s/%s",
2492 "subs_invalid.txt");
2493
2494 /*
2495 * Check that all the subscriptions have their respective replication
2496 * origin. This check only needs to run once.
2497 */
2499 res = executeQueryOrDie(conn,
2500 "SELECT d.datname, s.subname "
2501 "FROM pg_catalog.pg_subscription s "
2502 "LEFT OUTER JOIN pg_catalog.pg_replication_origin o "
2503 " ON o.roname = 'pg_' || s.oid "
2504 "INNER JOIN pg_catalog.pg_database d "
2505 " ON d.oid = s.subdbid "
2506 "WHERE o.roname IS NULL;");
2507 ntup = PQntuples(res);
2508 for (int i = 0; i < ntup; i++)
2509 {
2510 if (report.file == NULL &&
2511 (report.file = fopen_priv(report.path, "w")) == NULL)
2512 pg_fatal("could not open file \"%s\": %m", report.path);
2513 fprintf(report.file, "The replication origin is missing for database:\"%s\" subscription:\"%s\"\n",
2514 PQgetvalue(res, i, 0),
2515 PQgetvalue(res, i, 1));
2516 }
2517 PQclear(res);
2518 PQfinish(conn);
2519
2520 /*
2521 * We don't allow upgrade if there is a risk of dangling slot or origin
2522 * corresponding to initial sync after upgrade.
2523 *
2524 * A slot/origin not created yet refers to the 'i' (initialize) state,
2525 * while 'r' (ready) state refers to a slot/origin created previously but
2526 * already dropped. These states are supported for pg_upgrade. The other
2527 * states listed below are not supported:
2528 *
2529 * a) SUBREL_STATE_DATASYNC: A relation upgraded while in this state would
2530 * retain a replication slot and origin. The sync worker spawned after the
2531 * upgrade cannot drop them because the subscription ID used for the slot
2532 * and origin name no longer matches.
2533 *
2534 * b) SUBREL_STATE_SYNCDONE: A relation upgraded while in this state would
2535 * retain the replication origin when there is a failure in tablesync
2536 * worker immediately after dropping the replication slot in the
2537 * publisher.
2538 *
2539 * c) SUBREL_STATE_FINISHEDCOPY: A tablesync worker spawned to work on a
2540 * relation upgraded while in this state would expect an origin ID with
2541 * the OID of the subscription used before the upgrade, causing it to
2542 * fail.
2543 *
2544 * d) SUBREL_STATE_SYNCWAIT, SUBREL_STATE_CATCHUP and
2545 * SUBREL_STATE_UNKNOWN: These states are not stored in the catalog, so we
2546 * need not allow these states.
2547 */
2548 query = "SELECT r.srsubstate, s.subname, n.nspname, c.relname "
2549 "FROM pg_catalog.pg_subscription_rel r "
2550 "LEFT JOIN pg_catalog.pg_subscription s"
2551 " ON r.srsubid = s.oid "
2552 "LEFT JOIN pg_catalog.pg_class c"
2553 " ON r.srrelid = c.oid "
2554 "LEFT JOIN pg_catalog.pg_namespace n"
2555 " ON c.relnamespace = n.oid "
2556 "WHERE r.srsubstate NOT IN ('i', 'r') "
2557 "ORDER BY s.subname";
2558
2560 true, &report);
2561
2564
2565 if (report.file)
2566 {
2567 fclose(report.file);
2568 pg_log(PG_REPORT, "fatal");
2569 pg_fatal("Your installation contains subscriptions without origin or having relations not in i (initialize) or r (ready) state.\n"
2570 "You can allow the initial sync to finish for all relations and then restart the upgrade.\n"
2571 "A list of the problematic subscriptions is in the file:\n"
2572 " %s", report.path);
2573 }
2574 else
2575 check_ok();
2576}
2577
2578/*
2579 * check_old_cluster_global_names()
2580 *
2581 * Raise an error if any database, role, or tablespace name contains a newline
2582 * or carriage return character. Such names are not allowed in v19 and later.
2583 */
2584static void
2586{
2587 int i;
2589 PGresult *res;
2590 int ntups;
2591 FILE *script = NULL;
2592 char output_path[MAXPGPATH];
2593 int count = 0;
2594
2595 prep_status("Checking names of databases, roles and tablespaces");
2596
2597 snprintf(output_path, sizeof(output_path), "%s/%s",
2599 "db_role_tablespace_invalid_names.txt");
2600
2601 conn_template1 = connectToServer(cluster, "template1");
2602
2603 /*
2604 * Get database, user/role and tablespacenames from cluster. Can't use
2605 * pg_authid because only superusers can view it.
2606 */
2608 "SELECT datname AS objname, 'database' AS objtype "
2609 "FROM pg_catalog.pg_database UNION ALL "
2610 "SELECT rolname AS objname, 'role' AS objtype "
2611 "FROM pg_catalog.pg_roles UNION ALL "
2612 "SELECT spcname AS objname, 'tablespace' AS objtype "
2613 "FROM pg_catalog.pg_tablespace ORDER BY 2 ");
2614
2615 ntups = PQntuples(res);
2616 for (i = 0; i < ntups; i++)
2617 {
2618 char *objname = PQgetvalue(res, i, 0);
2619 char *objtype = PQgetvalue(res, i, 1);
2620
2621 /* If name has \n or \r, then report it. */
2622 if (strpbrk(objname, "\n\r"))
2623 {
2624 if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
2625 pg_fatal("could not open file \"%s\": %m", output_path);
2626
2627 fprintf(script, "%d : %s name = \"%s\"\n", ++count, objtype, objname);
2628 }
2629 }
2630
2631 PQclear(res);
2633
2634 if (script)
2635 {
2636 fclose(script);
2637 pg_log(PG_REPORT, "fatal");
2638 pg_fatal("All the database, role and tablespace names should have only valid characters. A newline or \n"
2639 "carriage return character is not allowed in these object names. To fix this, please \n"
2640 "rename these names with valid names. \n"
2641 "To see all %d invalid object names, refer db_role_tablespace_invalid_names.txt file. \n"
2642 " %s", count, output_path);
2643 }
2644 else
2645 check_ok();
2646}
#define gettext_noop(x)
Definition c.h:1285
#define Assert(condition)
Definition c.h:943
#define CppAsString2(x)
Definition c.h:506
void check_cluster_versions(void)
Definition check.c:882
static void check_for_tables_with_oids(ClusterInfo *cluster)
Definition check.c:1677
static void process_inconsistent_notnull(DbInfo *dbinfo, PGresult *res, void *arg)
Definition check.c:1719
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition check.c:1879
static void process_old_sub_state_check(DbInfo *dbinfo, PGresult *res, void *arg)
Definition check.c:2445
static void check_for_data_types_usage(ClusterInfo *cluster)
Definition check.c:468
static bool unicode_version_changed(ClusterInfo *cluster)
Definition check.c:2046
static char * data_type_check_query(int checknum)
Definition check.c:339
static void process_incompat_polymorphics(DbInfo *dbinfo, PGresult *res, void *arg)
Definition check.c:1521
static DataTypesUsageChecks data_types_usage_checks[]
Definition check.c:103
static void process_with_oids_check(DbInfo *dbinfo, PGresult *res, void *arg)
Definition check.c:1651
static void check_for_gist_inet_ops(ClusterInfo *cluster)
Definition check.c:1833
static void check_old_cluster_subscription_state(void)
Definition check.c:2478
#define ALL_VERSIONS
Definition check.c:68
static void process_gist_inet_ops_check(DbInfo *dbinfo, PGresult *res, void *arg)
Definition check.c:1805
void issue_warnings_and_set_wal_level(void)
Definition check.c:824
static void process_unicode_update(DbInfo *dbinfo, PGresult *res, void *arg)
Definition check.c:2017
static void check_for_unicode_update(ClusterInfo *cluster)
Definition check.c:2071
void check_cluster_compatibility(void)
Definition check.c:937
static void check_new_cluster_replication_slots(void)
Definition check.c:2205
#define MANUAL_CHECK
Definition check.c:67
void check_new_cluster(void)
Definition check.c:742
void report_clusters_compatible(void)
Definition check.c:805
static void check_is_install_user(ClusterInfo *cluster)
Definition check.c:1110
static void check_for_not_null_inheritance(ClusterInfo *cluster)
Definition check.c:1754
static void check_new_cluster_subscription_configuration(void)
Definition check.c:2313
void create_script_for_old_cluster_deletion(char **deletion_script_file_name)
Definition check.c:1012
static void check_for_connection_status(ClusterInfo *cluster)
Definition check.c:1168
static void process_user_defined_encoding_conversions(DbInfo *dbinfo, PGresult *res, void *arg)
Definition check.c:1937
static void process_data_type_check(DbInfo *dbinfo, PGresult *res, void *arg)
Definition check.c:396
void check_and_dump_old_cluster(void)
Definition check.c:593
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition check.c:1377
static char * fix_path_separator(char *path)
Definition check.c:554
static void check_for_unsupported_encodings(ClusterInfo *cluster)
Definition check.c:1253
static void check_new_cluster_is_empty(void)
Definition check.c:951
static void check_old_cluster_for_valid_slots(void)
Definition check.c:2356
static void process_isn_and_int8_passing_mismatch(DbInfo *dbinfo, PGresult *res, void *arg)
Definition check.c:1347
static void check_for_user_defined_postfix_ops(ClusterInfo *cluster)
Definition check.c:1462
void output_completion_banner(char *deletion_script_file_name)
Definition check.c:845
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition check.c:1314
static void check_for_new_tablespace_dir(void)
Definition check.c:983
static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
Definition check.c:1965
static void check_old_cluster_global_names(ClusterInfo *cluster)
Definition check.c:2585
static void check_for_incompatible_polymorphics(ClusterInfo *cluster)
Definition check.c:1550
void output_check_banner(void)
Definition check.c:575
static void process_user_defined_postfix_ops(DbInfo *dbinfo, PGresult *res, void *arg)
Definition check.c:1430
uint32 result
void get_control_data(ClusterInfo *cluster)
Definition controldata.c:39
void check_control_data(ControlData *oldctrl, ControlData *newctrl)
#define fprintf(file, fmt, msg)
Definition cubescan.l:21
void generate_old_dump(void)
Definition dump.c:16
Datum arg
Definition elog.c:1322
#define _(x)
Definition elog.c:95
void PQfinish(PGconn *conn)
int PQfnumber(const PGresult *res, const char *field_name)
Definition fe-exec.c:3606
char * pg_strdup(const char *in)
Definition fe_memutils.c:85
void pg_free(void *ptr)
#define pg_malloc0_array(type, count)
Definition fe_memutils.h:57
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:171
void get_loadable_libraries(void)
Definition function.c:77
void get_subscription_info(ClusterInfo *cluster)
Definition info.c:840
int count_old_cluster_logical_slots(void)
Definition info.c:824
void get_db_rel_and_slot_infos(ClusterInfo *cluster)
Definition info.c:279
static char * encoding
Definition initdb.c:139
static void check_ok(void)
Definition initdb.c:2132
int i
Definition isn.c:77
#define PQgetvalue
#define PQclear
#define PQntuples
void pfree(void *pointer)
Definition mcxt.c:1616
int max_active_replication_origins
Definition origin.c:106
#define pg_fatal(...)
#define MAXPGPATH
static pid_t start_postmaster(void)
Definition pg_ctl.c:441
NameData datname
Definition pg_database.h:37
bool datallowconn
Definition pg_database.h:52
int32 datconnlimit
Definition pg_database.h:61
static void stop_postmaster(void)
Definition pg_regress.c:444
OSInfo os_info
Definition pg_upgrade.c:75
ClusterInfo new_cluster
Definition pg_upgrade.c:74
ClusterInfo old_cluster
Definition pg_upgrade.c:73
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:375
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:421
#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:195
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
@ TRANSFER_MODE_COPY
Definition pg_upgrade.h:269
@ TRANSFER_MODE_LINK
Definition pg_upgrade.h:271
@ TRANSFER_MODE_SWAP
Definition pg_upgrade.h:272
@ TRANSFER_MODE_CLONE
Definition pg_upgrade.h:268
@ TRANSFER_MODE_COPY_FILE_RANGE
Definition pg_upgrade.h:270
#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:439
@ PG_WARNING
Definition pg_upgrade.h:284
@ PG_REPORT
Definition pg_upgrade.h:283
#define GET_MAJOR_VERSION(v)
Definition pg_upgrade.h:27
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:55
void upgrade_task_add_step(UpgradeTask *task, const char *query, UpgradeTaskProcessCB process_cb, bool free_result, void *arg)
Definition task.c:151
#define PG_VALID_BE_ENCODING(_enc)
Definition pg_wchar.h:134
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:260
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
#define atooid(x)
PQExpBuffer createPQExpBuffer(void)
Definition pqexpbuffer.c:72
void initPQExpBuffer(PQExpBuffer str)
Definition pqexpbuffer.c:90
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void destroyPQExpBuffer(PQExpBuffer str)
void appendPQExpBufferChar(PQExpBuffer str, char ch)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
void termPQExpBuffer(PQExpBuffer str)
char * c
static int fb(int x)
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
int max_replication_slots
Definition slot.c:161
UserOpts user_opts
Definition option.c:30
PGconn * conn
Definition streamutil.c:52
void appendShellString(PQExpBuffer buf, const char *str)
char * pgdata
Definition pg_upgrade.h:299
unsigned short port
Definition pg_upgrade.h:306
int num_tablespaces
Definition pg_upgrade.h:311
ControlData controldata
Definition pg_upgrade.h:296
char * bindir
Definition pg_upgrade.h:302
uint32 bin_version
Definition pg_upgrade.h:309
DbInfoArr dbarr
Definition pg_upgrade.h:298
uint32 major_version
Definition pg_upgrade.h:307
bool sub_retain_dead_tuples
Definition pg_upgrade.h:314
char ** tablespaces
Definition pg_upgrade.h:310
const char * tablespace_suffix
Definition pg_upgrade.h:312
bool float8_pass_by_value
Definition pg_upgrade.h:258
const char * report_text
Definition check.c:55
DataTypesUsageVersionCheck version_hook
Definition check.c:59
const char * status
Definition check.c:49
const char * report_filename
Definition check.c:51
const char * base_query
Definition check.c:53
DbInfo * dbs
Definition pg_upgrade.h:227
LogicalSlotInfoArr slot_arr
Definition pg_upgrade.h:210
char * db_name
Definition pg_upgrade.h:206
RelInfoArr rel_arr
Definition pg_upgrade.h:209
char * basedir
Definition pg_upgrade.h:329
LogicalSlotInfo * slots
Definition pg_upgrade.h:181
char * user
Definition pg_upgrade.h:366
bool user_specified
Definition pg_upgrade.h:367
RelInfo * rels
Definition pg_upgrade.h:160
char * nspname
Definition pg_upgrade.h:147
char * relname
Definition pg_upgrade.h:148
char path[MAXPGPATH]
Definition pg_upgrade.h:539
bool live_check
Definition pg_upgrade.h:342
int char_signedness
Definition pg_upgrade.h:349
transferMode transfer_mode
Definition pg_upgrade.h:344
bool check
Definition pg_upgrade.h:341
PQExpBuffer * report
Definition check.c:331
DataTypesUsageChecks * check
Definition check.c:329
#define PG_UNICODE_VERSION
#define stat
Definition win32_port.h:74
#define S_IRWXU
Definition win32_port.h:288
int wal_level
Definition xlog.c:138