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