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