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(void);
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  * Private state for check_for_data_types_usage()'s UpgradeTask.
319  */
321 {
322  DataTypesUsageChecks *check; /* the check for this step */
323  bool result; /* true if check failed for any database */
324  PQExpBuffer *report; /* buffer for report on failed checks */
325 };
326 
327 /*
328  * Returns a palloc'd query string for the data type check, for use by
329  * check_for_data_types_usage()'s UpgradeTask.
330  */
331 static char *
333 {
334  DataTypesUsageChecks *check = &data_types_usage_checks[checknum];
335 
336  return psprintf("WITH RECURSIVE oids AS ( "
337  /* start with the type(s) returned by base_query */
338  " %s "
339  " UNION ALL "
340  " SELECT * FROM ( "
341  /* inner WITH because we can only reference the CTE once */
342  " WITH x AS (SELECT oid FROM oids) "
343  /* domains on any type selected so far */
344  " SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typbasetype = x.oid AND typtype = 'd' "
345  " UNION ALL "
346  /* arrays over any type selected so far */
347  " SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typelem = x.oid AND typtype = 'b' "
348  " UNION ALL "
349  /* composite types containing any type selected so far */
350  " SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_class c, pg_catalog.pg_attribute a, x "
351  " WHERE t.typtype = 'c' AND "
352  " t.oid = c.reltype AND "
353  " c.oid = a.attrelid AND "
354  " NOT a.attisdropped AND "
355  " a.atttypid = x.oid "
356  " UNION ALL "
357  /* ranges containing any type selected so far */
358  " SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_range r, x "
359  " WHERE t.typtype = 'r' AND r.rngtypid = t.oid AND r.rngsubtype = x.oid"
360  " ) foo "
361  ") "
362  /* now look for stored columns of any such type */
363  "SELECT n.nspname, c.relname, a.attname "
364  "FROM pg_catalog.pg_class c, "
365  " pg_catalog.pg_namespace n, "
366  " pg_catalog.pg_attribute a "
367  "WHERE c.oid = a.attrelid AND "
368  " NOT a.attisdropped AND "
369  " a.atttypid IN (SELECT oid FROM oids) AND "
370  " c.relkind IN ("
371  CppAsString2(RELKIND_RELATION) ", "
372  CppAsString2(RELKIND_MATVIEW) ", "
373  CppAsString2(RELKIND_INDEX) ") AND "
374  " c.relnamespace = n.oid AND "
375  /* exclude possible orphaned temp tables */
376  " n.nspname !~ '^pg_temp_' AND "
377  " n.nspname !~ '^pg_toast_temp_' AND "
378  /* exclude system catalogs, too */
379  " n.nspname NOT IN ('pg_catalog', 'information_schema')",
380  check->base_query);
381 }
382 
383 /*
384  * Callback function for processing results of queries for
385  * check_for_data_types_usage()'s UpgradeTask. If the query returned any rows
386  * (i.e., the check failed), write the details to the report file.
387  */
388 static void
390 {
392  int ntups = PQntuples(res);
393  char output_path[MAXPGPATH];
394  int i_nspname = PQfnumber(res, "nspname");
395  int i_relname = PQfnumber(res, "relname");
396  int i_attname = PQfnumber(res, "attname");
397  FILE *script = NULL;
398 
400 
401  if (ntups == 0)
402  return;
403 
404  snprintf(output_path, sizeof(output_path), "%s/%s",
406  state->check->report_filename);
407 
408  /*
409  * Make sure we have a buffer to save reports to now that we found a first
410  * failing check.
411  */
412  if (*state->report == NULL)
413  *state->report = createPQExpBuffer();
414 
415  /*
416  * If this is the first time we see an error for the check in question
417  * then print a status message of the failure.
418  */
419  if (!state->result)
420  {
421  pg_log(PG_REPORT, "failed check: %s", _(state->check->status));
422  appendPQExpBuffer(*state->report, "\n%s\n%s %s\n",
423  _(state->check->report_text),
424  _("A list of the problem columns is in the file:"),
425  output_path);
426  }
427  state->result = true;
428 
429  if ((script = fopen_priv(output_path, "a")) == NULL)
430  pg_fatal("could not open file \"%s\": %m", output_path);
431 
432  fprintf(script, "In database: %s\n", dbinfo->db_name);
433 
434  for (int rowno = 0; rowno < ntups; rowno++)
435  fprintf(script, " %s.%s.%s\n",
436  PQgetvalue(res, rowno, i_nspname),
437  PQgetvalue(res, rowno, i_relname),
438  PQgetvalue(res, rowno, i_attname));
439 
440  fclose(script);
441 }
442 
443 /*
444  * check_for_data_types_usage()
445  * Detect whether there are any stored columns depending on given type(s)
446  *
447  * If so, write a report to the given file name and signal a failure to the
448  * user.
449  *
450  * The checks to run are defined in a DataTypesUsageChecks structure where
451  * each check has a metadata for explaining errors to the user, a base_query,
452  * a report filename and a function pointer hook for validating if the check
453  * should be executed given the cluster at hand.
454  *
455  * base_query should be a SELECT yielding a single column named "oid",
456  * containing the pg_type OIDs of one or more types that are known to have
457  * inconsistent on-disk representations across server versions.
458  *
459  * We check for the type(s) in tables, matviews, and indexes, but not views;
460  * there's no storage involved in a view.
461  */
462 static void
464 {
465  PQExpBuffer report = NULL;
467  int n_data_types_usage_checks = 0;
469  char **queries = NULL;
470  struct data_type_check_state *states;
471 
472  prep_status("Checking data type usage");
473 
474  /* Gather number of checks to perform */
475  while (tmp->status != NULL)
476  {
477  n_data_types_usage_checks++;
478  tmp++;
479  }
480 
481  /* Allocate memory for queries and for task states */
482  queries = pg_malloc0(sizeof(char *) * n_data_types_usage_checks);
483  states = pg_malloc0(sizeof(struct data_type_check_state) * n_data_types_usage_checks);
484 
485  for (int i = 0; i < n_data_types_usage_checks; i++)
486  {
488 
490  {
492 
493  /*
494  * Make sure that the check applies to the current cluster version
495  * and skip it if not.
496  */
497  if (!check->version_hook(cluster))
498  continue;
499  }
500  else if (check->threshold_version != ALL_VERSIONS)
501  {
502  if (GET_MAJOR_VERSION(cluster->major_version) > check->threshold_version)
503  continue;
504  }
505  else
507 
508  queries[i] = data_type_check_query(i);
509 
510  states[i].check = check;
511  states[i].report = &report;
512 
514  true, &states[i]);
515  }
516 
517  /*
518  * Connect to each database in the cluster and run all defined checks
519  * against that database before trying the next one.
520  */
521  upgrade_task_run(task, cluster);
522  upgrade_task_free(task);
523 
524  if (report)
525  {
526  pg_fatal("Data type checks failed: %s", report->data);
528  }
529 
530  for (int i = 0; i < n_data_types_usage_checks; i++)
531  {
532  if (queries[i])
533  pg_free(queries[i]);
534  }
535  pg_free(queries);
536  pg_free(states);
537 
538  check_ok();
539 }
540 
541 /*
542  * fix_path_separator
543  * For non-Windows, just return the argument.
544  * For Windows convert any forward slash to a backslash
545  * such as is suitable for arguments to builtin commands
546  * like RMDIR and DEL.
547  */
548 static char *
550 {
551 #ifdef WIN32
552 
553  char *result;
554  char *c;
555 
556  result = pg_strdup(path);
557 
558  for (c = result; *c != '\0'; c++)
559  if (*c == '/')
560  *c = '\\';
561 
562  return result;
563 #else
564 
565  return path;
566 #endif
567 }
568 
569 void
571 {
572  if (user_opts.live_check)
573  {
575  "Performing Consistency Checks on Old Live Server\n"
576  "------------------------------------------------");
577  }
578  else
579  {
581  "Performing Consistency Checks\n"
582  "-----------------------------");
583  }
584 }
585 
586 
587 void
589 {
590  /* -- OLD -- */
591 
592  if (!user_opts.live_check)
594 
595  /*
596  * Extract a list of databases, tables, and logical replication slots from
597  * the old cluster.
598  */
600 
602 
604 
605 
606  /*
607  * Check for various failure cases
608  */
613 
615  {
616  /*
617  * Logical replication slots can be migrated since PG17. See comments
618  * atop get_old_cluster_logical_slot_infos().
619  */
621 
622  /*
623  * Subscriptions and their dependencies can be migrated since PG17.
624  * Before that the logical slots are not upgraded, so we will not be
625  * able to upgrade the logical replication clusters completely.
626  */
629  }
630 
632 
633  /*
634  * PG 14 changed the function signature of encoding conversion functions.
635  * Conversions from older versions cannot be upgraded automatically
636  * because the user-defined functions used by the encoding conversions
637  * need to be changed to match the new signature.
638  */
641 
642  /*
643  * Pre-PG 14 allowed user defined postfix operators, which are not
644  * supported anymore. Verify there are none, iff applicable.
645  */
648 
649  /*
650  * PG 14 changed polymorphic functions from anyarray to
651  * anycompatiblearray.
652  */
655 
656  /*
657  * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
658  * supported anymore. Verify there are none, iff applicable.
659  */
662 
663  /*
664  * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
665  * hash indexes
666  */
668  {
669  if (user_opts.check)
671  }
672 
673  /* 9.5 and below should not have roles starting with pg_ */
676 
677  /*
678  * While not a check option, we do this now because this is the only time
679  * the old server is running.
680  */
681  if (!user_opts.check)
683 
684  if (!user_opts.live_check)
685  stop_postmaster(false);
686 }
687 
688 
689 void
691 {
693 
695 
697 
698  switch (user_opts.transfer_mode)
699  {
700  case TRANSFER_MODE_CLONE:
702  break;
703  case TRANSFER_MODE_COPY:
704  break;
707  break;
708  case TRANSFER_MODE_LINK:
709  check_hard_link();
710  break;
711  }
712 
714 
716 
718 
720 
722 }
723 
724 
725 void
727 {
728  if (user_opts.check)
729  {
730  pg_log(PG_REPORT, "\n*Clusters are compatible*");
731  /* stops new cluster */
732  stop_postmaster(false);
733 
735  exit(0);
736  }
737 
738  pg_log(PG_REPORT, "\n"
739  "If pg_upgrade fails after this point, you must re-initdb the\n"
740  "new cluster before continuing.");
741 }
742 
743 
744 void
746 {
747  /*
748  * We unconditionally start/stop the new server because pg_resetwal -o set
749  * wal_level to 'minimum'. If the user is upgrading standby servers using
750  * the rsync instructions, they will need pg_upgrade to write its final
751  * WAL record showing wal_level as 'replica'.
752  */
754 
755  /* Reindex hash indexes for old < 10.0 */
758 
760 
761  stop_postmaster(false);
762 }
763 
764 
765 void
766 output_completion_banner(char *deletion_script_file_name)
767 {
768  PQExpBufferData user_specification;
769 
770  initPQExpBuffer(&user_specification);
772  {
773  appendPQExpBufferStr(&user_specification, "-U ");
774  appendShellString(&user_specification, os_info.user);
775  appendPQExpBufferChar(&user_specification, ' ');
776  }
777 
779  "Optimizer statistics are not transferred by pg_upgrade.\n"
780  "Once you start the new server, consider running:\n"
781  " %s/vacuumdb %s--all --analyze-in-stages", new_cluster.bindir, user_specification.data);
782 
783  if (deletion_script_file_name)
785  "Running this script will delete the old cluster's data files:\n"
786  " %s",
787  deletion_script_file_name);
788  else
790  "Could not create a script to delete the old cluster's data files\n"
791  "because user-defined tablespaces or the new cluster's data directory\n"
792  "exist in the old cluster directory. The old cluster's contents must\n"
793  "be deleted manually.");
794 
795  termPQExpBuffer(&user_specification);
796 }
797 
798 
799 void
801 {
802  prep_status("Checking cluster versions");
803 
804  /* cluster versions should already have been obtained */
807 
808  /*
809  * We allow upgrades from/to the same major version for alpha/beta
810  * upgrades
811  */
812 
814  pg_fatal("This utility can only upgrade from PostgreSQL version %s and later.",
815  "9.2");
816 
817  /* Only current PG version is supported as a target */
819  pg_fatal("This utility can only upgrade to PostgreSQL version %s.",
820  PG_MAJORVERSION);
821 
822  /*
823  * We can't allow downgrading because we use the target pg_dump, and
824  * pg_dump cannot operate on newer database versions, only current and
825  * older versions.
826  */
828  pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.");
829 
830  /* Ensure binaries match the designated data directories */
833  pg_fatal("Old cluster data and binary directories are from different major versions.");
836  pg_fatal("New cluster data and binary directories are from different major versions.");
837 
838  check_ok();
839 }
840 
841 
842 void
844 {
845  /* get/check pg_control data of servers */
849 
851  pg_fatal("When checking a live server, "
852  "the old and new port numbers must be different.");
853 }
854 
855 
856 static void
858 {
859  int dbnum;
860 
861  for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
862  {
863  int relnum;
864  RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
865 
866  for (relnum = 0; relnum < rel_arr->nrels;
867  relnum++)
868  {
869  /* pg_largeobject and its index should be skipped */
870  if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
871  pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"",
872  new_cluster.dbarr.dbs[dbnum].db_name,
873  rel_arr->rels[relnum].nspname,
874  rel_arr->rels[relnum].relname);
875  }
876  }
877 }
878 
879 /*
880  * A previous run of pg_upgrade might have failed and the new cluster
881  * directory recreated, but they might have forgotten to remove
882  * the new cluster's tablespace directories. Therefore, check that
883  * new cluster tablespace directories do not already exist. If
884  * they do, it would cause an error while restoring global objects.
885  * This allows the failure to be detected at check time, rather than
886  * during schema restore.
887  */
888 static void
890 {
891  int tblnum;
892  char new_tablespace_dir[MAXPGPATH];
893 
894  prep_status("Checking for new cluster tablespace directories");
895 
896  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
897  {
898  struct stat statbuf;
899 
900  snprintf(new_tablespace_dir, MAXPGPATH, "%s%s",
901  os_info.old_tablespaces[tblnum],
903 
904  if (stat(new_tablespace_dir, &statbuf) == 0 || errno != ENOENT)
905  pg_fatal("new cluster tablespace directory already exists: \"%s\"",
906  new_tablespace_dir);
907  }
908 
909  check_ok();
910 }
911 
912 /*
913  * create_script_for_old_cluster_deletion()
914  *
915  * This is particularly useful for tablespace deletion.
916  */
917 void
918 create_script_for_old_cluster_deletion(char **deletion_script_file_name)
919 {
920  FILE *script = NULL;
921  int tblnum;
922  char old_cluster_pgdata[MAXPGPATH],
923  new_cluster_pgdata[MAXPGPATH];
924 
925  *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
927 
928  strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
929  canonicalize_path(old_cluster_pgdata);
930 
931  strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
932  canonicalize_path(new_cluster_pgdata);
933 
934  /* Some people put the new data directory inside the old one. */
935  if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
936  {
938  "\nWARNING: new data directory should not be inside the old data directory, i.e. %s", old_cluster_pgdata);
939 
940  /* Unlink file in case it is left over from a previous run. */
941  unlink(*deletion_script_file_name);
942  pg_free(*deletion_script_file_name);
943  *deletion_script_file_name = NULL;
944  return;
945  }
946 
947  /*
948  * Some users (oddly) create tablespaces inside the cluster data
949  * directory. We can't create a proper old cluster delete script in that
950  * case.
951  */
952  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
953  {
954  char old_tablespace_dir[MAXPGPATH];
955 
956  strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
957  canonicalize_path(old_tablespace_dir);
958  if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
959  {
960  /* reproduce warning from CREATE TABLESPACE that is in the log */
962  "\nWARNING: user-defined tablespace locations should not be inside the data directory, i.e. %s", old_tablespace_dir);
963 
964  /* Unlink file in case it is left over from a previous run. */
965  unlink(*deletion_script_file_name);
966  pg_free(*deletion_script_file_name);
967  *deletion_script_file_name = NULL;
968  return;
969  }
970  }
971 
972  prep_status("Creating script to delete old cluster");
973 
974  if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
975  pg_fatal("could not open file \"%s\": %m",
976  *deletion_script_file_name);
977 
978 #ifndef WIN32
979  /* add shebang header */
980  fprintf(script, "#!/bin/sh\n\n");
981 #endif
982 
983  /* delete old cluster's default tablespace */
984  fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
986 
987  /* delete old cluster's alternate tablespaces */
988  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
989  {
990  /*
991  * Do the old cluster's per-database directories share a directory
992  * with a new version-specific tablespace?
993  */
994  if (strlen(old_cluster.tablespace_suffix) == 0)
995  {
996  /* delete per-database directories */
997  int dbnum;
998 
999  fprintf(script, "\n");
1000 
1001  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
1002  fprintf(script, RMDIR_CMD " %c%s%c%u%c\n", PATH_QUOTE,
1005  PATH_QUOTE);
1006  }
1007  else
1008  {
1009  char *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
1010 
1011  /*
1012  * Simply delete the tablespace directory, which might be ".old"
1013  * or a version-specific subdirectory.
1014  */
1015  fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
1017  fix_path_separator(suffix_path), PATH_QUOTE);
1018  pfree(suffix_path);
1019  }
1020  }
1021 
1022  fclose(script);
1023 
1024 #ifndef WIN32
1025  if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
1026  pg_fatal("could not add execute permission to file \"%s\": %m",
1027  *deletion_script_file_name);
1028 #endif
1029 
1030  check_ok();
1031 }
1032 
1033 
1034 /*
1035  * check_is_install_user()
1036  *
1037  * Check we are the install user, and that the new cluster
1038  * has no other users.
1039  */
1040 static void
1042 {
1043  PGresult *res;
1044  PGconn *conn = connectToServer(cluster, "template1");
1045 
1046  prep_status("Checking database user is the install user");
1047 
1048  /* Can't use pg_authid because only superusers can view it. */
1050  "SELECT rolsuper, oid "
1051  "FROM pg_catalog.pg_roles "
1052  "WHERE rolname = current_user "
1053  "AND rolname !~ '^pg_'");
1054 
1055  /*
1056  * We only allow the install user in the new cluster (see comment below)
1057  * and we preserve pg_authid.oid, so this must be the install user in the
1058  * old cluster too.
1059  */
1060  if (PQntuples(res) != 1 ||
1061  atooid(PQgetvalue(res, 0, 1)) != BOOTSTRAP_SUPERUSERID)
1062  pg_fatal("database user \"%s\" is not the install user",
1063  os_info.user);
1064 
1065  PQclear(res);
1066 
1068  "SELECT COUNT(*) "
1069  "FROM pg_catalog.pg_roles "
1070  "WHERE rolname !~ '^pg_'");
1071 
1072  if (PQntuples(res) != 1)
1073  pg_fatal("could not determine the number of users");
1074 
1075  /*
1076  * We only allow the install user in the new cluster because other defined
1077  * users might match users defined in the old cluster and generate an
1078  * error during pg_dump restore.
1079  */
1080  if (cluster == &new_cluster && strcmp(PQgetvalue(res, 0, 0), "1") != 0)
1081  pg_fatal("Only the install user can be defined in the new cluster.");
1082 
1083  PQclear(res);
1084 
1085  PQfinish(conn);
1086 
1087  check_ok();
1088 }
1089 
1090 
1091 /*
1092  * check_proper_datallowconn
1093  *
1094  * Ensure that all non-template0 databases allow connections since they
1095  * otherwise won't be restored; and that template0 explicitly doesn't allow
1096  * connections since it would make pg_dumpall --globals restore fail.
1097  */
1098 static void
1100 {
1101  int dbnum;
1102  PGconn *conn_template1;
1103  PGresult *dbres;
1104  int ntups;
1105  int i_datname;
1106  int i_datallowconn;
1107  FILE *script = NULL;
1108  char output_path[MAXPGPATH];
1109 
1110  prep_status("Checking database connection settings");
1111 
1112  snprintf(output_path, sizeof(output_path), "%s/%s",
1113  log_opts.basedir,
1114  "databases_with_datallowconn_false.txt");
1115 
1116  conn_template1 = connectToServer(cluster, "template1");
1117 
1118  /* get database names */
1119  dbres = executeQueryOrDie(conn_template1,
1120  "SELECT datname, datallowconn "
1121  "FROM pg_catalog.pg_database");
1122 
1123  i_datname = PQfnumber(dbres, "datname");
1124  i_datallowconn = PQfnumber(dbres, "datallowconn");
1125 
1126  ntups = PQntuples(dbres);
1127  for (dbnum = 0; dbnum < ntups; dbnum++)
1128  {
1129  char *datname = PQgetvalue(dbres, dbnum, i_datname);
1130  char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
1131 
1132  if (strcmp(datname, "template0") == 0)
1133  {
1134  /* avoid restore failure when pg_dumpall tries to create template0 */
1135  if (strcmp(datallowconn, "t") == 0)
1136  pg_fatal("template0 must not allow connections, "
1137  "i.e. its pg_database.datallowconn must be false");
1138  }
1139  else
1140  {
1141  /*
1142  * avoid datallowconn == false databases from being skipped on
1143  * restore
1144  */
1145  if (strcmp(datallowconn, "f") == 0)
1146  {
1147  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1148  pg_fatal("could not open file \"%s\": %m", output_path);
1149 
1150  fprintf(script, "%s\n", datname);
1151  }
1152  }
1153  }
1154 
1155  PQclear(dbres);
1156 
1157  PQfinish(conn_template1);
1158 
1159  if (script)
1160  {
1161  fclose(script);
1162  pg_log(PG_REPORT, "fatal");
1163  pg_fatal("All non-template0 databases must allow connections, i.e. their\n"
1164  "pg_database.datallowconn must be true. Your installation contains\n"
1165  "non-template0 databases with their pg_database.datallowconn set to\n"
1166  "false. Consider allowing connection for all non-template0 databases\n"
1167  "or drop the databases which do not allow connections. A list of\n"
1168  "databases with the problem is in the file:\n"
1169  " %s", output_path);
1170  }
1171  else
1172  check_ok();
1173 }
1174 
1175 
1176 /*
1177  * check_for_prepared_transactions()
1178  *
1179  * Make sure there are no prepared transactions because the storage format
1180  * might have changed.
1181  */
1182 static void
1184 {
1185  PGresult *res;
1186  PGconn *conn = connectToServer(cluster, "template1");
1187 
1188  prep_status("Checking for prepared transactions");
1189 
1191  "SELECT * "
1192  "FROM pg_catalog.pg_prepared_xacts");
1193 
1194  if (PQntuples(res) != 0)
1195  {
1196  if (cluster == &old_cluster)
1197  pg_fatal("The source cluster contains prepared transactions");
1198  else
1199  pg_fatal("The target cluster contains prepared transactions");
1200  }
1201 
1202  PQclear(res);
1203 
1204  PQfinish(conn);
1205 
1206  check_ok();
1207 }
1208 
1209 /*
1210  * Callback function for processing result of query for
1211  * check_for_isn_and_int8_passing_mismatch()'s UpgradeTask. If the query
1212  * returned any rows (i.e., the check failed), write the details to the report
1213  * file.
1214  */
1215 static void
1217 {
1218  int ntups = PQntuples(res);
1219  int i_nspname = PQfnumber(res, "nspname");
1220  int i_proname = PQfnumber(res, "proname");
1221  UpgradeTaskReport *report = (UpgradeTaskReport *) arg;
1222 
1225 
1226  if (ntups == 0)
1227  return;
1228 
1229  if (report->file == NULL &&
1230  (report->file = fopen_priv(report->path, "w")) == NULL)
1231  pg_fatal("could not open file \"%s\": %m", report->path);
1232 
1233  fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1234 
1235  for (int rowno = 0; rowno < ntups; rowno++)
1236  fprintf(report->file, " %s.%s\n",
1237  PQgetvalue(res, rowno, i_nspname),
1238  PQgetvalue(res, rowno, i_proname));
1239 }
1240 
1241 /*
1242  * check_for_isn_and_int8_passing_mismatch()
1243  *
1244  * contrib/isn relies on data type int8, and in 8.4 int8 can now be passed
1245  * by value. The schema dumps the CREATE TYPE PASSEDBYVALUE setting so
1246  * it must match for the old and new servers.
1247  */
1248 static void
1250 {
1251  UpgradeTask *task;
1252  UpgradeTaskReport report;
1253  const char *query = "SELECT n.nspname, p.proname "
1254  "FROM pg_catalog.pg_proc p, "
1255  " pg_catalog.pg_namespace n "
1256  "WHERE p.pronamespace = n.oid AND "
1257  " p.probin = '$libdir/isn'";
1258 
1259  prep_status("Checking for contrib/isn with bigint-passing mismatch");
1260 
1263  {
1264  /* no mismatch */
1265  check_ok();
1266  return;
1267  }
1268 
1269  report.file = NULL;
1270  snprintf(report.path, sizeof(report.path), "%s/%s",
1271  log_opts.basedir,
1272  "contrib_isn_and_int8_pass_by_value.txt");
1273 
1274  task = upgrade_task_create();
1276  true, &report);
1277  upgrade_task_run(task, cluster);
1278  upgrade_task_free(task);
1279 
1280  if (report.file)
1281  {
1282  fclose(report.file);
1283  pg_log(PG_REPORT, "fatal");
1284  pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
1285  "bigint data type. Your old and new clusters pass bigint values\n"
1286  "differently so this cluster cannot currently be upgraded. You can\n"
1287  "manually dump databases in the old cluster that use \"contrib/isn\"\n"
1288  "facilities, drop them, perform the upgrade, and then restore them. A\n"
1289  "list of the problem functions is in the file:\n"
1290  " %s", report.path);
1291  }
1292  else
1293  check_ok();
1294 }
1295 
1296 /*
1297  * Callback function for processing result of query for
1298  * check_for_user_defined_postfix_ops()'s UpgradeTask. If the query returned
1299  * any rows (i.e., the check failed), write the details to the report file.
1300  */
1301 static void
1303 {
1304  UpgradeTaskReport *report = (UpgradeTaskReport *) arg;
1305  int ntups = PQntuples(res);
1306  int i_oproid = PQfnumber(res, "oproid");
1307  int i_oprnsp = PQfnumber(res, "oprnsp");
1308  int i_oprname = PQfnumber(res, "oprname");
1309  int i_typnsp = PQfnumber(res, "typnsp");
1310  int i_typname = PQfnumber(res, "typname");
1311 
1314 
1315  if (ntups == 0)
1316  return;
1317 
1318  if (report->file == NULL &&
1319  (report->file = fopen_priv(report->path, "w")) == NULL)
1320  pg_fatal("could not open file \"%s\": %m", report->path);
1321 
1322  fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1323 
1324  for (int rowno = 0; rowno < ntups; rowno++)
1325  fprintf(report->file, " (oid=%s) %s.%s (%s.%s, NONE)\n",
1326  PQgetvalue(res, rowno, i_oproid),
1327  PQgetvalue(res, rowno, i_oprnsp),
1328  PQgetvalue(res, rowno, i_oprname),
1329  PQgetvalue(res, rowno, i_typnsp),
1330  PQgetvalue(res, rowno, i_typname));
1331 }
1332 
1333 /*
1334  * Verify that no user defined postfix operators exist.
1335  */
1336 static void
1338 {
1339  UpgradeTaskReport report;
1340  UpgradeTask *task = upgrade_task_create();
1341  const char *query;
1342 
1343  /*
1344  * The query below hardcodes FirstNormalObjectId as 16384 rather than
1345  * interpolating that C #define into the query because, if that #define is
1346  * ever changed, the cutoff we want to use is the value used by
1347  * pre-version 14 servers, not that of some future version.
1348  */
1349  query = "SELECT o.oid AS oproid, "
1350  " n.nspname AS oprnsp, "
1351  " o.oprname, "
1352  " tn.nspname AS typnsp, "
1353  " t.typname "
1354  "FROM pg_catalog.pg_operator o, "
1355  " pg_catalog.pg_namespace n, "
1356  " pg_catalog.pg_type t, "
1357  " pg_catalog.pg_namespace tn "
1358  "WHERE o.oprnamespace = n.oid AND "
1359  " o.oprleft = t.oid AND "
1360  " t.typnamespace = tn.oid AND "
1361  " o.oprright = 0 AND "
1362  " o.oid >= 16384";
1363 
1364  prep_status("Checking for user-defined postfix operators");
1365 
1366  report.file = NULL;
1367  snprintf(report.path, sizeof(report.path), "%s/%s",
1368  log_opts.basedir,
1369  "postfix_ops.txt");
1370 
1372  true, &report);
1373  upgrade_task_run(task, cluster);
1374  upgrade_task_free(task);
1375 
1376  if (report.file)
1377  {
1378  fclose(report.file);
1379  pg_log(PG_REPORT, "fatal");
1380  pg_fatal("Your installation contains user-defined postfix operators, which are not\n"
1381  "supported anymore. Consider dropping the postfix operators and replacing\n"
1382  "them with prefix operators or function calls.\n"
1383  "A list of user-defined postfix operators is in the file:\n"
1384  " %s", report.path);
1385  }
1386  else
1387  check_ok();
1388 }
1389 
1390 /*
1391  * Callback function for processing results of query for
1392  * check_for_incompatible_polymorphics()'s UpgradeTask. If the query returned
1393  * any rows (i.e., the check failed), write the details to the report file.
1394  */
1395 static void
1397 {
1398  UpgradeTaskReport *report = (UpgradeTaskReport *) arg;
1399  int ntups = PQntuples(res);
1400  int i_objkind = PQfnumber(res, "objkind");
1401  int i_objname = PQfnumber(res, "objname");
1402 
1405 
1406  if (ntups == 0)
1407  return;
1408 
1409  if (report->file == NULL &&
1410  (report->file = fopen_priv(report->path, "w")) == NULL)
1411  pg_fatal("could not open file \"%s\": %m", report->path);
1412 
1413  fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1414 
1415  for (int rowno = 0; rowno < ntups; rowno++)
1416  fprintf(report->file, " %s: %s\n",
1417  PQgetvalue(res, rowno, i_objkind),
1418  PQgetvalue(res, rowno, i_objname));
1419 }
1420 
1421 /*
1422  * check_for_incompatible_polymorphics()
1423  *
1424  * Make sure nothing is using old polymorphic functions with
1425  * anyarray/anyelement rather than the new anycompatible variants.
1426  */
1427 static void
1429 {
1430  PQExpBufferData old_polymorphics;
1431  UpgradeTask *task = upgrade_task_create();
1432  UpgradeTaskReport report;
1433  char *query;
1434 
1435  prep_status("Checking for incompatible polymorphic functions");
1436 
1437  report.file = NULL;
1438  snprintf(report.path, sizeof(report.path), "%s/%s",
1439  log_opts.basedir,
1440  "incompatible_polymorphics.txt");
1441 
1442  /* The set of problematic functions varies a bit in different versions */
1443  initPQExpBuffer(&old_polymorphics);
1444 
1445  appendPQExpBufferStr(&old_polymorphics,
1446  "'array_append(anyarray,anyelement)'"
1447  ", 'array_cat(anyarray,anyarray)'"
1448  ", 'array_prepend(anyelement,anyarray)'");
1449 
1450  if (GET_MAJOR_VERSION(cluster->major_version) >= 903)
1451  appendPQExpBufferStr(&old_polymorphics,
1452  ", 'array_remove(anyarray,anyelement)'"
1453  ", 'array_replace(anyarray,anyelement,anyelement)'");
1454 
1455  if (GET_MAJOR_VERSION(cluster->major_version) >= 905)
1456  appendPQExpBufferStr(&old_polymorphics,
1457  ", 'array_position(anyarray,anyelement)'"
1458  ", 'array_position(anyarray,anyelement,integer)'"
1459  ", 'array_positions(anyarray,anyelement)'"
1460  ", 'width_bucket(anyelement,anyarray)'");
1461 
1462  /*
1463  * The query below hardcodes FirstNormalObjectId as 16384 rather than
1464  * interpolating that C #define into the query because, if that #define is
1465  * ever changed, the cutoff we want to use is the value used by
1466  * pre-version 14 servers, not that of some future version.
1467  */
1468 
1469  /* Aggregate transition functions */
1470  query = psprintf("SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
1471  "FROM pg_proc AS p "
1472  "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
1473  "JOIN pg_proc AS transfn ON transfn.oid=a.aggtransfn "
1474  "WHERE p.oid >= 16384 "
1475  "AND a.aggtransfn = ANY(ARRAY[%s]::regprocedure[]) "
1476  "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
1477 
1478  /* Aggregate final functions */
1479  "UNION ALL "
1480  "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
1481  "FROM pg_proc AS p "
1482  "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
1483  "JOIN pg_proc AS finalfn ON finalfn.oid=a.aggfinalfn "
1484  "WHERE p.oid >= 16384 "
1485  "AND a.aggfinalfn = ANY(ARRAY[%s]::regprocedure[]) "
1486  "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
1487 
1488  /* Operators */
1489  "UNION ALL "
1490  "SELECT 'operator' AS objkind, op.oid::regoperator::text AS objname "
1491  "FROM pg_operator AS op "
1492  "WHERE op.oid >= 16384 "
1493  "AND oprcode = ANY(ARRAY[%s]::regprocedure[]) "
1494  "AND oprleft = ANY(ARRAY['anyarray', 'anyelement']::regtype[])",
1495  old_polymorphics.data,
1496  old_polymorphics.data,
1497  old_polymorphics.data);
1498 
1500  true, &report);
1501  upgrade_task_run(task, cluster);
1502  upgrade_task_free(task);
1503 
1504  if (report.file)
1505  {
1506  fclose(report.file);
1507  pg_log(PG_REPORT, "fatal");
1508  pg_fatal("Your installation contains user-defined objects that refer to internal\n"
1509  "polymorphic functions with arguments of type \"anyarray\" or \"anyelement\".\n"
1510  "These user-defined objects must be dropped before upgrading and restored\n"
1511  "afterwards, changing them to refer to the new corresponding functions with\n"
1512  "arguments of type \"anycompatiblearray\" and \"anycompatible\".\n"
1513  "A list of the problematic objects is in the file:\n"
1514  " %s", report.path);
1515  }
1516  else
1517  check_ok();
1518 
1519  termPQExpBuffer(&old_polymorphics);
1520  pg_free(query);
1521 }
1522 
1523 /*
1524  * Callback function for processing results of query for
1525  * check_for_tables_with_oids()'s UpgradeTask. If the query returned any rows
1526  * (i.e., the check failed), write the details to the report file.
1527  */
1528 static void
1530 {
1531  UpgradeTaskReport *report = (UpgradeTaskReport *) arg;
1532  int ntups = PQntuples(res);
1533  int i_nspname = PQfnumber(res, "nspname");
1534  int i_relname = PQfnumber(res, "relname");
1535 
1537 
1538  if (ntups == 0)
1539  return;
1540 
1541  if (report->file == NULL &&
1542  (report->file = fopen_priv(report->path, "w")) == NULL)
1543  pg_fatal("could not open file \"%s\": %m", report->path);
1544 
1545  fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1546 
1547  for (int rowno = 0; rowno < ntups; rowno++)
1548  fprintf(report->file, " %s.%s\n",
1549  PQgetvalue(res, rowno, i_nspname),
1550  PQgetvalue(res, rowno, i_relname));
1551 }
1552 
1553 /*
1554  * Verify that no tables are declared WITH OIDS.
1555  */
1556 static void
1558 {
1559  UpgradeTaskReport report;
1560  UpgradeTask *task = upgrade_task_create();
1561  const char *query = "SELECT n.nspname, c.relname "
1562  "FROM pg_catalog.pg_class c, "
1563  " pg_catalog.pg_namespace n "
1564  "WHERE c.relnamespace = n.oid AND "
1565  " c.relhasoids AND"
1566  " n.nspname NOT IN ('pg_catalog')";
1567 
1568  prep_status("Checking for tables WITH OIDS");
1569 
1570  report.file = NULL;
1571  snprintf(report.path, sizeof(report.path), "%s/%s",
1572  log_opts.basedir,
1573  "tables_with_oids.txt");
1574 
1576  true, &report);
1577  upgrade_task_run(task, cluster);
1578  upgrade_task_free(task);
1579 
1580  if (report.file)
1581  {
1582  fclose(report.file);
1583  pg_log(PG_REPORT, "fatal");
1584  pg_fatal("Your installation contains tables declared WITH OIDS, which is not\n"
1585  "supported anymore. Consider removing the oid column using\n"
1586  " ALTER TABLE ... SET WITHOUT OIDS;\n"
1587  "A list of tables with the problem is in the file:\n"
1588  " %s", report.path);
1589  }
1590  else
1591  check_ok();
1592 }
1593 
1594 
1595 /*
1596  * check_for_pg_role_prefix()
1597  *
1598  * Versions older than 9.6 should not have any pg_* roles
1599  */
1600 static void
1602 {
1603  PGresult *res;
1604  PGconn *conn = connectToServer(cluster, "template1");
1605  int ntups;
1606  int i_roloid;
1607  int i_rolname;
1608  FILE *script = NULL;
1609  char output_path[MAXPGPATH];
1610 
1611  prep_status("Checking for roles starting with \"pg_\"");
1612 
1613  snprintf(output_path, sizeof(output_path), "%s/%s",
1614  log_opts.basedir,
1615  "pg_role_prefix.txt");
1616 
1618  "SELECT oid AS roloid, rolname "
1619  "FROM pg_catalog.pg_roles "
1620  "WHERE rolname ~ '^pg_'");
1621 
1622  ntups = PQntuples(res);
1623  i_roloid = PQfnumber(res, "roloid");
1624  i_rolname = PQfnumber(res, "rolname");
1625  for (int rowno = 0; rowno < ntups; rowno++)
1626  {
1627  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1628  pg_fatal("could not open file \"%s\": %m", output_path);
1629  fprintf(script, "%s (oid=%s)\n",
1630  PQgetvalue(res, rowno, i_rolname),
1631  PQgetvalue(res, rowno, i_roloid));
1632  }
1633 
1634  PQclear(res);
1635 
1636  PQfinish(conn);
1637 
1638  if (script)
1639  {
1640  fclose(script);
1641  pg_log(PG_REPORT, "fatal");
1642  pg_fatal("Your installation contains roles starting with \"pg_\".\n"
1643  "\"pg_\" is a reserved prefix for system roles. The cluster\n"
1644  "cannot be upgraded until these roles are renamed.\n"
1645  "A list of roles starting with \"pg_\" is in the file:\n"
1646  " %s", output_path);
1647  }
1648  else
1649  check_ok();
1650 }
1651 
1652 /*
1653  * Callback function for processing results of query for
1654  * check_for_user_defined_encoding_conversions()'s UpgradeTask. If the query
1655  * returned any rows (i.e., the check failed), write the details to the report
1656  * file.
1657  */
1658 static void
1660 {
1661  UpgradeTaskReport *report = (UpgradeTaskReport *) arg;
1662  int ntups = PQntuples(res);
1663  int i_conoid = PQfnumber(res, "conoid");
1664  int i_conname = PQfnumber(res, "conname");
1665  int i_nspname = PQfnumber(res, "nspname");
1666 
1669 
1670  if (ntups == 0)
1671  return;
1672 
1673  if (report->file == NULL &&
1674  (report->file = fopen_priv(report->path, "w")) == NULL)
1675  pg_fatal("could not open file \"%s\": %m", report->path);
1676 
1677  fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1678 
1679  for (int rowno = 0; rowno < ntups; rowno++)
1680  fprintf(report->file, " (oid=%s) %s.%s\n",
1681  PQgetvalue(res, rowno, i_conoid),
1682  PQgetvalue(res, rowno, i_nspname),
1683  PQgetvalue(res, rowno, i_conname));
1684 }
1685 
1686 /*
1687  * Verify that no user-defined encoding conversions exist.
1688  */
1689 static void
1691 {
1692  UpgradeTaskReport report;
1693  UpgradeTask *task = upgrade_task_create();
1694  const char *query;
1695 
1696  prep_status("Checking for user-defined encoding conversions");
1697 
1698  report.file = NULL;
1699  snprintf(report.path, sizeof(report.path), "%s/%s",
1700  log_opts.basedir,
1701  "encoding_conversions.txt");
1702 
1703  /*
1704  * The query below hardcodes FirstNormalObjectId as 16384 rather than
1705  * interpolating that C #define into the query because, if that #define is
1706  * ever changed, the cutoff we want to use is the value used by
1707  * pre-version 14 servers, not that of some future version.
1708  */
1709  query = "SELECT c.oid as conoid, c.conname, n.nspname "
1710  "FROM pg_catalog.pg_conversion c, "
1711  " pg_catalog.pg_namespace n "
1712  "WHERE c.connamespace = n.oid AND "
1713  " c.oid >= 16384";
1714 
1715  upgrade_task_add_step(task, query,
1717  true, &report);
1718  upgrade_task_run(task, cluster);
1719  upgrade_task_free(task);
1720 
1721  if (report.file)
1722  {
1723  fclose(report.file);
1724  pg_log(PG_REPORT, "fatal");
1725  pg_fatal("Your installation contains user-defined encoding conversions.\n"
1726  "The conversion function parameters changed in PostgreSQL version 14\n"
1727  "so this cluster cannot currently be upgraded. You can remove the\n"
1728  "encoding conversions in the old cluster and restart the upgrade.\n"
1729  "A list of user-defined encoding conversions is in the file:\n"
1730  " %s", report.path);
1731  }
1732  else
1733  check_ok();
1734 }
1735 
1736 /*
1737  * check_new_cluster_logical_replication_slots()
1738  *
1739  * Verify that there are no logical replication slots on the new cluster and
1740  * that the parameter settings necessary for creating slots are sufficient.
1741  */
1742 static void
1744 {
1745  PGresult *res;
1746  PGconn *conn;
1747  int nslots_on_old;
1748  int nslots_on_new;
1750  char *wal_level;
1751 
1752  /* Logical slots can be migrated since PG17. */
1754  return;
1755 
1756  nslots_on_old = count_old_cluster_logical_slots();
1757 
1758  /* Quick return if there are no logical slots to be migrated. */
1759  if (nslots_on_old == 0)
1760  return;
1761 
1762  conn = connectToServer(&new_cluster, "template1");
1763 
1764  prep_status("Checking for new cluster logical replication slots");
1765 
1766  res = executeQueryOrDie(conn, "SELECT count(*) "
1767  "FROM pg_catalog.pg_replication_slots "
1768  "WHERE slot_type = 'logical' AND "
1769  "temporary IS FALSE;");
1770 
1771  if (PQntuples(res) != 1)
1772  pg_fatal("could not count the number of logical replication slots");
1773 
1774  nslots_on_new = atoi(PQgetvalue(res, 0, 0));
1775 
1776  if (nslots_on_new)
1777  pg_fatal("expected 0 logical replication slots but found %d",
1778  nslots_on_new);
1779 
1780  PQclear(res);
1781 
1782  res = executeQueryOrDie(conn, "SELECT setting FROM pg_settings "
1783  "WHERE name IN ('wal_level', 'max_replication_slots') "
1784  "ORDER BY name DESC;");
1785 
1786  if (PQntuples(res) != 2)
1787  pg_fatal("could not determine parameter settings on new cluster");
1788 
1789  wal_level = PQgetvalue(res, 0, 0);
1790 
1791  if (strcmp(wal_level, "logical") != 0)
1792  pg_fatal("\"wal_level\" must be \"logical\" but is set to \"%s\"",
1793  wal_level);
1794 
1795  max_replication_slots = atoi(PQgetvalue(res, 1, 0));
1796 
1797  if (nslots_on_old > max_replication_slots)
1798  pg_fatal("\"max_replication_slots\" (%d) must be greater than or equal to the number of "
1799  "logical replication slots (%d) on the old cluster",
1800  max_replication_slots, nslots_on_old);
1801 
1802  PQclear(res);
1803  PQfinish(conn);
1804 
1805  check_ok();
1806 }
1807 
1808 /*
1809  * check_new_cluster_subscription_configuration()
1810  *
1811  * Verify that the max_replication_slots configuration specified is enough for
1812  * creating the subscriptions. This is required to create the replication
1813  * origin for each subscription.
1814  */
1815 static void
1817 {
1818  PGresult *res;
1819  PGconn *conn;
1821 
1822  /* Subscriptions and their dependencies can be migrated since PG17. */
1824  return;
1825 
1826  /* Quick return if there are no subscriptions to be migrated. */
1827  if (old_cluster.nsubs == 0)
1828  return;
1829 
1830  prep_status("Checking for new cluster configuration for subscriptions");
1831 
1832  conn = connectToServer(&new_cluster, "template1");
1833 
1834  res = executeQueryOrDie(conn, "SELECT setting FROM pg_settings "
1835  "WHERE name = 'max_replication_slots';");
1836 
1837  if (PQntuples(res) != 1)
1838  pg_fatal("could not determine parameter settings on new cluster");
1839 
1840  max_replication_slots = atoi(PQgetvalue(res, 0, 0));
1842  pg_fatal("\"max_replication_slots\" (%d) must be greater than or equal to the number of "
1843  "subscriptions (%d) on the old cluster",
1845 
1846  PQclear(res);
1847  PQfinish(conn);
1848 
1849  check_ok();
1850 }
1851 
1852 /*
1853  * check_old_cluster_for_valid_slots()
1854  *
1855  * Verify that all the logical slots are valid and have consumed all the WAL
1856  * before shutdown.
1857  */
1858 static void
1860 {
1861  char output_path[MAXPGPATH];
1862  FILE *script = NULL;
1863 
1864  prep_status("Checking for valid logical replication slots");
1865 
1866  snprintf(output_path, sizeof(output_path), "%s/%s",
1867  log_opts.basedir,
1868  "invalid_logical_slots.txt");
1869 
1870  for (int dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
1871  {
1872  LogicalSlotInfoArr *slot_arr = &old_cluster.dbarr.dbs[dbnum].slot_arr;
1873 
1874  for (int slotnum = 0; slotnum < slot_arr->nslots; slotnum++)
1875  {
1876  LogicalSlotInfo *slot = &slot_arr->slots[slotnum];
1877 
1878  /* Is the slot usable? */
1879  if (slot->invalid)
1880  {
1881  if (script == NULL &&
1882  (script = fopen_priv(output_path, "w")) == NULL)
1883  pg_fatal("could not open file \"%s\": %m", output_path);
1884 
1885  fprintf(script, "The slot \"%s\" is invalid\n",
1886  slot->slotname);
1887 
1888  continue;
1889  }
1890 
1891  /*
1892  * Do additional check to ensure that all logical replication
1893  * slots have consumed all the WAL before shutdown.
1894  *
1895  * Note: This can be satisfied only when the old cluster has been
1896  * shut down, so we skip this for live checks.
1897  */
1898  if (!user_opts.live_check && !slot->caught_up)
1899  {
1900  if (script == NULL &&
1901  (script = fopen_priv(output_path, "w")) == NULL)
1902  pg_fatal("could not open file \"%s\": %m", output_path);
1903 
1904  fprintf(script,
1905  "The slot \"%s\" has not consumed the WAL yet\n",
1906  slot->slotname);
1907  }
1908  }
1909  }
1910 
1911  if (script)
1912  {
1913  fclose(script);
1914 
1915  pg_log(PG_REPORT, "fatal");
1916  pg_fatal("Your installation contains logical replication slots that cannot be upgraded.\n"
1917  "You can remove invalid slots and/or consume the pending WAL for other slots,\n"
1918  "and then restart the upgrade.\n"
1919  "A list of the problematic slots is in the file:\n"
1920  " %s", output_path);
1921  }
1922 
1923  check_ok();
1924 }
1925 
1926 /*
1927  * Callback function for processing results of query for
1928  * check_old_cluster_subscription_state()'s UpgradeTask. If the query returned
1929  * any rows (i.e., the check failed), write the details to the report file.
1930  */
1931 static void
1933 {
1934  UpgradeTaskReport *report = (UpgradeTaskReport *) arg;
1935  int ntups = PQntuples(res);
1936  int i_srsubstate = PQfnumber(res, "srsubstate");
1937  int i_subname = PQfnumber(res, "subname");
1938  int i_nspname = PQfnumber(res, "nspname");
1939  int i_relname = PQfnumber(res, "relname");
1940 
1942 
1943  if (ntups == 0)
1944  return;
1945 
1946  if (report->file == NULL &&
1947  (report->file = fopen_priv(report->path, "w")) == NULL)
1948  pg_fatal("could not open file \"%s\": %m", report->path);
1949 
1950  for (int i = 0; i < ntups; i++)
1951  fprintf(report->file, "The table sync state \"%s\" is not allowed for database:\"%s\" subscription:\"%s\" schema:\"%s\" relation:\"%s\"\n",
1952  PQgetvalue(res, i, i_srsubstate),
1953  dbinfo->db_name,
1954  PQgetvalue(res, i, i_subname),
1955  PQgetvalue(res, i, i_nspname),
1956  PQgetvalue(res, i, i_relname));
1957 }
1958 
1959 /*
1960  * check_old_cluster_subscription_state()
1961  *
1962  * Verify that the replication origin corresponding to each of the
1963  * subscriptions are present and each of the subscribed tables is in
1964  * 'i' (initialize) or 'r' (ready) state.
1965  */
1966 static void
1968 {
1969  UpgradeTask *task = upgrade_task_create();
1970  UpgradeTaskReport report;
1971  const char *query;
1972  PGresult *res;
1973  PGconn *conn;
1974  int ntup;
1975 
1976  prep_status("Checking for subscription state");
1977 
1978  report.file = NULL;
1979  snprintf(report.path, sizeof(report.path), "%s/%s",
1980  log_opts.basedir,
1981  "subs_invalid.txt");
1982 
1983  /*
1984  * Check that all the subscriptions have their respective replication
1985  * origin. This check only needs to run once.
1986  */
1989  "SELECT d.datname, s.subname "
1990  "FROM pg_catalog.pg_subscription s "
1991  "LEFT OUTER JOIN pg_catalog.pg_replication_origin o "
1992  " ON o.roname = 'pg_' || s.oid "
1993  "INNER JOIN pg_catalog.pg_database d "
1994  " ON d.oid = s.subdbid "
1995  "WHERE o.roname IS NULL;");
1996  ntup = PQntuples(res);
1997  for (int i = 0; i < ntup; i++)
1998  {
1999  if (report.file == NULL &&
2000  (report.file = fopen_priv(report.path, "w")) == NULL)
2001  pg_fatal("could not open file \"%s\": %m", report.path);
2002  fprintf(report.file, "The replication origin is missing for database:\"%s\" subscription:\"%s\"\n",
2003  PQgetvalue(res, i, 0),
2004  PQgetvalue(res, i, 1));
2005  }
2006  PQclear(res);
2007  PQfinish(conn);
2008 
2009  /*
2010  * We don't allow upgrade if there is a risk of dangling slot or origin
2011  * corresponding to initial sync after upgrade.
2012  *
2013  * A slot/origin not created yet refers to the 'i' (initialize) state,
2014  * while 'r' (ready) state refers to a slot/origin created previously but
2015  * already dropped. These states are supported for pg_upgrade. The other
2016  * states listed below are not supported:
2017  *
2018  * a) SUBREL_STATE_DATASYNC: A relation upgraded while in this state would
2019  * retain a replication slot, which could not be dropped by the sync
2020  * worker spawned after the upgrade because the subscription ID used for
2021  * the slot name won't match anymore.
2022  *
2023  * b) SUBREL_STATE_SYNCDONE: A relation upgraded while in this state would
2024  * retain the replication origin when there is a failure in tablesync
2025  * worker immediately after dropping the replication slot in the
2026  * publisher.
2027  *
2028  * c) SUBREL_STATE_FINISHEDCOPY: A tablesync worker spawned to work on a
2029  * relation upgraded while in this state would expect an origin ID with
2030  * the OID of the subscription used before the upgrade, causing it to
2031  * fail.
2032  *
2033  * d) SUBREL_STATE_SYNCWAIT, SUBREL_STATE_CATCHUP and
2034  * SUBREL_STATE_UNKNOWN: These states are not stored in the catalog, so we
2035  * need not allow these states.
2036  */
2037  query = "SELECT r.srsubstate, s.subname, n.nspname, c.relname "
2038  "FROM pg_catalog.pg_subscription_rel r "
2039  "LEFT JOIN pg_catalog.pg_subscription s"
2040  " ON r.srsubid = s.oid "
2041  "LEFT JOIN pg_catalog.pg_class c"
2042  " ON r.srrelid = c.oid "
2043  "LEFT JOIN pg_catalog.pg_namespace n"
2044  " ON c.relnamespace = n.oid "
2045  "WHERE r.srsubstate NOT IN ('i', 'r') "
2046  "ORDER BY s.subname";
2047 
2049  true, &report);
2050 
2051  upgrade_task_run(task, &old_cluster);
2052  upgrade_task_free(task);
2053 
2054  if (report.file)
2055  {
2056  fclose(report.file);
2057  pg_log(PG_REPORT, "fatal");
2058  pg_fatal("Your installation contains subscriptions without origin or having relations not in i (initialize) or r (ready) state.\n"
2059  "You can allow the initial sync to finish for all relations and then restart the upgrade.\n"
2060  "A list of the problematic subscriptions is in the file:\n"
2061  " %s", report.path);
2062  }
2063  else
2064  check_ok();
2065 }
#define gettext_noop(x)
Definition: c.h:1199
#define AssertVariableIsOfType(varname, typename)
Definition: c.h:984
#define Assert(condition)
Definition: c.h:861
#define CppAsString2(x)
Definition: c.h:330
void check_cluster_versions(void)
Definition: check.c:800
static void check_for_tables_with_oids(ClusterInfo *cluster)
Definition: check.c:1557
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1601
static void process_old_sub_state_check(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1932
static void check_for_data_types_usage(ClusterInfo *cluster)
Definition: check.c:463
static void process_incompat_polymorphics(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1396
static DataTypesUsageChecks data_types_usage_checks[]
Definition: check.c:97
static void process_with_oids_check(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1529
static void check_new_cluster_logical_replication_slots(void)
Definition: check.c:1743
static void check_old_cluster_subscription_state(void)
Definition: check.c:1967
#define ALL_VERSIONS
Definition: check.c:62
void issue_warnings_and_set_wal_level(void)
Definition: check.c:745
static char * fix_path_separator(char *path)
Definition: check.c:549
void check_cluster_compatibility(void)
Definition: check.c:843
#define MANUAL_CHECK
Definition: check.c:61
void check_new_cluster(void)
Definition: check.c:690
void report_clusters_compatible(void)
Definition: check.c:726
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:1041
static void check_new_cluster_subscription_configuration(void)
Definition: check.c:1816
void create_script_for_old_cluster_deletion(char **deletion_script_file_name)
Definition: check.c:918
static void process_user_defined_encoding_conversions(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1659
static void process_data_type_check(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:389
void check_and_dump_old_cluster(void)
Definition: check.c:588
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:1249
static void check_new_cluster_is_empty(void)
Definition: check.c:857
static void check_old_cluster_for_valid_slots(void)
Definition: check.c:1859
static void process_isn_and_int8_passing_mismatch(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1216
static void check_for_user_defined_postfix_ops(ClusterInfo *cluster)
Definition: check.c:1337
void output_completion_banner(char *deletion_script_file_name)
Definition: check.c:766
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:1183
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:1099
static void check_for_new_tablespace_dir(void)
Definition: check.c:889
static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
Definition: check.c:1690
static char * data_type_check_query(int checknum)
Definition: check.c:332
static void check_for_incompatible_polymorphics(ClusterInfo *cluster)
Definition: check.c:1428
void output_check_banner(void)
Definition: check.c:570
static void process_user_defined_postfix_ops(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1302
void cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:108
void get_control_data(ClusterInfo *cluster)
Definition: controldata.c:36
void check_control_data(ControlData *oldctrl, ControlData *newctrl)
Definition: controldata.c:655
void generate_old_dump(void)
Definition: dump.c:16
#define _(x)
Definition: elog.c:90
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4893
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:165
void get_loadable_libraries(void)
Definition: function.c:79
void get_subscription_count(ClusterInfo *cluster)
Definition: info.c:758
int count_old_cluster_logical_slots(void)
Definition: info.c:742
void get_db_rel_and_slot_infos(ClusterInfo *cluster)
Definition: info.c:280
static void check_ok(void)
Definition: initdb.c:2091
int i
Definition: isn.c:73
exit(1)
void pfree(void *pointer)
Definition: mcxt.c:1521
void * arg
#define pg_fatal(...)
#define MAXPGPATH
static struct LogicalRepInfo * dbinfo
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:69
ClusterInfo new_cluster
Definition: pg_upgrade.c:68
ClusterInfo old_cluster
Definition: pg_upgrade.c:67
#define PATH_SEPARATOR
Definition: pg_upgrade.h:82
void init_tablespaces(void)
Definition: tablespace.c:19
bool(* DataTypesUsageVersionCheck)(ClusterInfo *cluster)
Definition: pg_upgrade.h:355
UpgradeTask * upgrade_task_create(void)
Definition: task.c:117
bool jsonb_9_4_check_applicable(ClusterInfo *cluster)
Definition: version.c:21
void upgrade_task_run(const UpgradeTask *task, const ClusterInfo *cluster)
Definition: task.c:420
#define RMDIR_CMD
Definition: pg_upgrade.h:85
void cleanup_output_dirs(void)
Definition: util.c:63
void report_extension_updates(ClusterInfo *cluster)
Definition: version.c:179
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
@ TRANSFER_MODE_COPY
Definition: pg_upgrade.h: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
void upgrade_task_free(UpgradeTask *task)
Definition: task.c:133
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:419
void(* UpgradeTaskProcessCB)(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: pg_upgrade.h:500
@ 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
void upgrade_task_add_step(UpgradeTask *task, const char *query, UpgradeTaskProcessCB process_cb, bool free_result, void *arg)
Definition: task.c:151
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:560
void canonicalize_path(char *path)
Definition: path.c:265
#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
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: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:347
char * user
Definition: pg_upgrade.h:344
char ** old_tablespaces
Definition: pg_upgrade.h:346
bool user_specified
Definition: pg_upgrade.h:345
RelInfo * rels
Definition: pg_upgrade.h:148
char * nspname
Definition: pg_upgrade.h:135
char * relname
Definition: pg_upgrade.h:136
char path[MAXPGPATH]
Definition: pg_upgrade.h:516
bool live_check
Definition: pg_upgrade.h:324
transferMode transfer_mode
Definition: pg_upgrade.h:326
bool check
Definition: pg_upgrade.h:323
PQExpBuffer * report
Definition: check.c:324
DataTypesUsageChecks * check
Definition: check.c:322
Definition: regguts.h:323
#define stat
Definition: win32_port.h:284
#define S_IRWXU
Definition: win32_port.h:298
int wal_level
Definition: xlog.c:130