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