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_collation.h"
14 #include "fe_utils/string_utils.h"
15 #include "mb/pg_wchar.h"
16 #include "pg_upgrade.h"
17 
18 static void check_new_cluster_is_empty(void);
30  const char *version,
31  const char *datatype);
34 static void check_for_new_tablespace_dir(void);
38 static void check_old_cluster_for_valid_slots(bool live_check);
39 static void check_old_cluster_subscription_state(void);
40 
41 
42 /*
43  * fix_path_separator
44  * For non-Windows, just return the argument.
45  * For Windows convert any forward slash to a backslash
46  * such as is suitable for arguments to builtin commands
47  * like RMDIR and DEL.
48  */
49 static char *
50 fix_path_separator(char *path)
51 {
52 #ifdef WIN32
53 
54  char *result;
55  char *c;
56 
57  result = pg_strdup(path);
58 
59  for (c = result; *c != '\0'; c++)
60  if (*c == '/')
61  *c = '\\';
62 
63  return result;
64 #else
65 
66  return path;
67 #endif
68 }
69 
70 void
71 output_check_banner(bool live_check)
72 {
73  if (user_opts.check && live_check)
74  {
76  "Performing Consistency Checks on Old Live Server\n"
77  "------------------------------------------------");
78  }
79  else
80  {
82  "Performing Consistency Checks\n"
83  "-----------------------------");
84  }
85 }
86 
87 
88 void
90 {
91  /* -- OLD -- */
92 
93  if (!live_check)
95 
96  /*
97  * Extract a list of databases, tables, and logical replication slots from
98  * the old cluster.
99  */
101 
103 
105 
106 
107  /*
108  * Check for various failure cases
109  */
116 
118  {
119  /*
120  * Logical replication slots can be migrated since PG17. See comments
121  * atop get_old_cluster_logical_slot_infos().
122  */
124 
125  /*
126  * Subscriptions and their dependencies can be migrated since PG17.
127  * See comments atop get_db_subscription_count().
128  */
130  }
131 
132  /*
133  * PG 16 increased the size of the 'aclitem' type, which breaks the
134  * on-disk format for existing data.
135  */
138 
139  /*
140  * PG 12 removed types abstime, reltime, tinterval.
141  */
143  {
146  check_for_removed_data_type_usage(&old_cluster, "12", "tinterval");
147  }
148 
149  /*
150  * PG 14 changed the function signature of encoding conversion functions.
151  * Conversions from older versions cannot be upgraded automatically
152  * because the user-defined functions used by the encoding conversions
153  * need to be changed to match the new signature.
154  */
157 
158  /*
159  * Pre-PG 14 allowed user defined postfix operators, which are not
160  * supported anymore. Verify there are none, iff applicable.
161  */
164 
165  /*
166  * PG 14 changed polymorphic functions from anyarray to
167  * anycompatiblearray.
168  */
171 
172  /*
173  * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
174  * supported anymore. Verify there are none, iff applicable.
175  */
178 
179  /*
180  * PG 12 changed the 'sql_identifier' type storage to be based on name,
181  * not varchar, which breaks on-disk format for existing data. So we need
182  * to prevent upgrade when used in user objects (tables, indexes, ...).
183  */
186 
187  /*
188  * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
189  * hash indexes
190  */
192  {
194  if (user_opts.check)
196  }
197 
198  /* 9.5 and below should not have roles starting with pg_ */
201 
205 
206  /* Pre-PG 9.4 had a different 'line' data type internal format */
209 
210  /*
211  * While not a check option, we do this now because this is the only time
212  * the old server is running.
213  */
214  if (!user_opts.check)
216 
217  if (!live_check)
218  stop_postmaster(false);
219 }
220 
221 
222 void
224 {
226 
228 
230 
231  switch (user_opts.transfer_mode)
232  {
233  case TRANSFER_MODE_CLONE:
235  break;
236  case TRANSFER_MODE_COPY:
237  break;
240  break;
241  case TRANSFER_MODE_LINK:
242  check_hard_link();
243  break;
244  }
245 
247 
249 
251 
253 
255 }
256 
257 
258 void
260 {
261  if (user_opts.check)
262  {
263  pg_log(PG_REPORT, "\n*Clusters are compatible*");
264  /* stops new cluster */
265  stop_postmaster(false);
266 
268  exit(0);
269  }
270 
271  pg_log(PG_REPORT, "\n"
272  "If pg_upgrade fails after this point, you must re-initdb the\n"
273  "new cluster before continuing.");
274 }
275 
276 
277 void
279 {
280  /*
281  * We unconditionally start/stop the new server because pg_resetwal -o set
282  * wal_level to 'minimum'. If the user is upgrading standby servers using
283  * the rsync instructions, they will need pg_upgrade to write its final
284  * WAL record showing wal_level as 'replica'.
285  */
287 
288  /* Reindex hash indexes for old < 10.0 */
291 
293 
294  stop_postmaster(false);
295 }
296 
297 
298 void
299 output_completion_banner(char *deletion_script_file_name)
300 {
301  PQExpBufferData user_specification;
302 
303  initPQExpBuffer(&user_specification);
305  {
306  appendPQExpBufferStr(&user_specification, "-U ");
307  appendShellString(&user_specification, os_info.user);
308  appendPQExpBufferChar(&user_specification, ' ');
309  }
310 
312  "Optimizer statistics are not transferred by pg_upgrade.\n"
313  "Once you start the new server, consider running:\n"
314  " %s/vacuumdb %s--all --analyze-in-stages", new_cluster.bindir, user_specification.data);
315 
316  if (deletion_script_file_name)
318  "Running this script will delete the old cluster's data files:\n"
319  " %s",
320  deletion_script_file_name);
321  else
323  "Could not create a script to delete the old cluster's data files\n"
324  "because user-defined tablespaces or the new cluster's data directory\n"
325  "exist in the old cluster directory. The old cluster's contents must\n"
326  "be deleted manually.");
327 
328  termPQExpBuffer(&user_specification);
329 }
330 
331 
332 void
334 {
335  prep_status("Checking cluster versions");
336 
337  /* cluster versions should already have been obtained */
340 
341  /*
342  * We allow upgrades from/to the same major version for alpha/beta
343  * upgrades
344  */
345 
347  pg_fatal("This utility can only upgrade from PostgreSQL version %s and later.",
348  "9.2");
349 
350  /* Only current PG version is supported as a target */
352  pg_fatal("This utility can only upgrade to PostgreSQL version %s.",
353  PG_MAJORVERSION);
354 
355  /*
356  * We can't allow downgrading because we use the target pg_dump, and
357  * pg_dump cannot operate on newer database versions, only current and
358  * older versions.
359  */
361  pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.");
362 
363  /* Ensure binaries match the designated data directories */
366  pg_fatal("Old cluster data and binary directories are from different major versions.");
369  pg_fatal("New cluster data and binary directories are from different major versions.");
370 
371  check_ok();
372 }
373 
374 
375 void
377 {
378  /* get/check pg_control data of servers */
379  get_control_data(&old_cluster, live_check);
380  get_control_data(&new_cluster, false);
382 
383  if (live_check && old_cluster.port == new_cluster.port)
384  pg_fatal("When checking a live server, "
385  "the old and new port numbers must be different.");
386 }
387 
388 
389 static void
391 {
392  int dbnum;
393 
394  for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
395  {
396  int relnum;
397  RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
398 
399  for (relnum = 0; relnum < rel_arr->nrels;
400  relnum++)
401  {
402  /* pg_largeobject and its index should be skipped */
403  if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
404  pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"",
405  new_cluster.dbarr.dbs[dbnum].db_name,
406  rel_arr->rels[relnum].nspname,
407  rel_arr->rels[relnum].relname);
408  }
409  }
410 }
411 
412 /*
413  * A previous run of pg_upgrade might have failed and the new cluster
414  * directory recreated, but they might have forgotten to remove
415  * the new cluster's tablespace directories. Therefore, check that
416  * new cluster tablespace directories do not already exist. If
417  * they do, it would cause an error while restoring global objects.
418  * This allows the failure to be detected at check time, rather than
419  * during schema restore.
420  */
421 static void
423 {
424  int tblnum;
425  char new_tablespace_dir[MAXPGPATH];
426 
427  prep_status("Checking for new cluster tablespace directories");
428 
429  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
430  {
431  struct stat statbuf;
432 
433  snprintf(new_tablespace_dir, MAXPGPATH, "%s%s",
434  os_info.old_tablespaces[tblnum],
436 
437  if (stat(new_tablespace_dir, &statbuf) == 0 || errno != ENOENT)
438  pg_fatal("new cluster tablespace directory already exists: \"%s\"",
439  new_tablespace_dir);
440  }
441 
442  check_ok();
443 }
444 
445 /*
446  * create_script_for_old_cluster_deletion()
447  *
448  * This is particularly useful for tablespace deletion.
449  */
450 void
451 create_script_for_old_cluster_deletion(char **deletion_script_file_name)
452 {
453  FILE *script = NULL;
454  int tblnum;
455  char old_cluster_pgdata[MAXPGPATH],
456  new_cluster_pgdata[MAXPGPATH];
457 
458  *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
460 
461  strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
462  canonicalize_path(old_cluster_pgdata);
463 
464  strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
465  canonicalize_path(new_cluster_pgdata);
466 
467  /* Some people put the new data directory inside the old one. */
468  if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
469  {
471  "\nWARNING: new data directory should not be inside the old data directory, i.e. %s", old_cluster_pgdata);
472 
473  /* Unlink file in case it is left over from a previous run. */
474  unlink(*deletion_script_file_name);
475  pg_free(*deletion_script_file_name);
476  *deletion_script_file_name = NULL;
477  return;
478  }
479 
480  /*
481  * Some users (oddly) create tablespaces inside the cluster data
482  * directory. We can't create a proper old cluster delete script in that
483  * case.
484  */
485  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
486  {
487  char old_tablespace_dir[MAXPGPATH];
488 
489  strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
490  canonicalize_path(old_tablespace_dir);
491  if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
492  {
493  /* reproduce warning from CREATE TABLESPACE that is in the log */
495  "\nWARNING: user-defined tablespace locations should not be inside the data directory, i.e. %s", old_tablespace_dir);
496 
497  /* Unlink file in case it is left over from a previous run. */
498  unlink(*deletion_script_file_name);
499  pg_free(*deletion_script_file_name);
500  *deletion_script_file_name = NULL;
501  return;
502  }
503  }
504 
505  prep_status("Creating script to delete old cluster");
506 
507  if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
508  pg_fatal("could not open file \"%s\": %m",
509  *deletion_script_file_name);
510 
511 #ifndef WIN32
512  /* add shebang header */
513  fprintf(script, "#!/bin/sh\n\n");
514 #endif
515 
516  /* delete old cluster's default tablespace */
517  fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
519 
520  /* delete old cluster's alternate tablespaces */
521  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
522  {
523  /*
524  * Do the old cluster's per-database directories share a directory
525  * with a new version-specific tablespace?
526  */
527  if (strlen(old_cluster.tablespace_suffix) == 0)
528  {
529  /* delete per-database directories */
530  int dbnum;
531 
532  fprintf(script, "\n");
533 
534  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
535  fprintf(script, RMDIR_CMD " %c%s%c%u%c\n", PATH_QUOTE,
538  PATH_QUOTE);
539  }
540  else
541  {
542  char *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
543 
544  /*
545  * Simply delete the tablespace directory, which might be ".old"
546  * or a version-specific subdirectory.
547  */
548  fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
550  fix_path_separator(suffix_path), PATH_QUOTE);
551  pfree(suffix_path);
552  }
553  }
554 
555  fclose(script);
556 
557 #ifndef WIN32
558  if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
559  pg_fatal("could not add execute permission to file \"%s\": %m",
560  *deletion_script_file_name);
561 #endif
562 
563  check_ok();
564 }
565 
566 
567 /*
568  * check_is_install_user()
569  *
570  * Check we are the install user, and that the new cluster
571  * has no other users.
572  */
573 static void
575 {
576  PGresult *res;
577  PGconn *conn = connectToServer(cluster, "template1");
578 
579  prep_status("Checking database user is the install user");
580 
581  /* Can't use pg_authid because only superusers can view it. */
583  "SELECT rolsuper, oid "
584  "FROM pg_catalog.pg_roles "
585  "WHERE rolname = current_user "
586  "AND rolname !~ '^pg_'");
587 
588  /*
589  * We only allow the install user in the new cluster (see comment below)
590  * and we preserve pg_authid.oid, so this must be the install user in the
591  * old cluster too.
592  */
593  if (PQntuples(res) != 1 ||
594  atooid(PQgetvalue(res, 0, 1)) != BOOTSTRAP_SUPERUSERID)
595  pg_fatal("database user \"%s\" is not the install user",
596  os_info.user);
597 
598  PQclear(res);
599 
601  "SELECT COUNT(*) "
602  "FROM pg_catalog.pg_roles "
603  "WHERE rolname !~ '^pg_'");
604 
605  if (PQntuples(res) != 1)
606  pg_fatal("could not determine the number of users");
607 
608  /*
609  * We only allow the install user in the new cluster because other defined
610  * users might match users defined in the old cluster and generate an
611  * error during pg_dump restore.
612  */
613  if (cluster == &new_cluster && strcmp(PQgetvalue(res, 0, 0), "1") != 0)
614  pg_fatal("Only the install user can be defined in the new cluster.");
615 
616  PQclear(res);
617 
618  PQfinish(conn);
619 
620  check_ok();
621 }
622 
623 
624 /*
625  * check_proper_datallowconn
626  *
627  * Ensure that all non-template0 databases allow connections since they
628  * otherwise won't be restored; and that template0 explicitly doesn't allow
629  * connections since it would make pg_dumpall --globals restore fail.
630  */
631 static void
633 {
634  int dbnum;
635  PGconn *conn_template1;
636  PGresult *dbres;
637  int ntups;
638  int i_datname;
639  int i_datallowconn;
640  FILE *script = NULL;
641  char output_path[MAXPGPATH];
642 
643  prep_status("Checking database connection settings");
644 
645  snprintf(output_path, sizeof(output_path), "%s/%s",
647  "databases_with_datallowconn_false.txt");
648 
649  conn_template1 = connectToServer(cluster, "template1");
650 
651  /* get database names */
652  dbres = executeQueryOrDie(conn_template1,
653  "SELECT datname, datallowconn "
654  "FROM pg_catalog.pg_database");
655 
656  i_datname = PQfnumber(dbres, "datname");
657  i_datallowconn = PQfnumber(dbres, "datallowconn");
658 
659  ntups = PQntuples(dbres);
660  for (dbnum = 0; dbnum < ntups; dbnum++)
661  {
662  char *datname = PQgetvalue(dbres, dbnum, i_datname);
663  char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
664 
665  if (strcmp(datname, "template0") == 0)
666  {
667  /* avoid restore failure when pg_dumpall tries to create template0 */
668  if (strcmp(datallowconn, "t") == 0)
669  pg_fatal("template0 must not allow connections, "
670  "i.e. its pg_database.datallowconn must be false");
671  }
672  else
673  {
674  /*
675  * avoid datallowconn == false databases from being skipped on
676  * restore
677  */
678  if (strcmp(datallowconn, "f") == 0)
679  {
680  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
681  pg_fatal("could not open file \"%s\": %m", output_path);
682 
683  fprintf(script, "%s\n", datname);
684  }
685  }
686  }
687 
688  PQclear(dbres);
689 
690  PQfinish(conn_template1);
691 
692  if (script)
693  {
694  fclose(script);
695  pg_log(PG_REPORT, "fatal");
696  pg_fatal("All non-template0 databases must allow connections, i.e. their\n"
697  "pg_database.datallowconn must be true. Your installation contains\n"
698  "non-template0 databases with their pg_database.datallowconn set to\n"
699  "false. Consider allowing connection for all non-template0 databases\n"
700  "or drop the databases which do not allow connections. A list of\n"
701  "databases with the problem is in the file:\n"
702  " %s", output_path);
703  }
704  else
705  check_ok();
706 }
707 
708 
709 /*
710  * check_for_prepared_transactions()
711  *
712  * Make sure there are no prepared transactions because the storage format
713  * might have changed.
714  */
715 static void
717 {
718  PGresult *res;
719  PGconn *conn = connectToServer(cluster, "template1");
720 
721  prep_status("Checking for prepared transactions");
722 
724  "SELECT * "
725  "FROM pg_catalog.pg_prepared_xacts");
726 
727  if (PQntuples(res) != 0)
728  {
729  if (cluster == &old_cluster)
730  pg_fatal("The source cluster contains prepared transactions");
731  else
732  pg_fatal("The target cluster contains prepared transactions");
733  }
734 
735  PQclear(res);
736 
737  PQfinish(conn);
738 
739  check_ok();
740 }
741 
742 
743 /*
744  * check_for_isn_and_int8_passing_mismatch()
745  *
746  * contrib/isn relies on data type int8, and in 8.4 int8 can now be passed
747  * by value. The schema dumps the CREATE TYPE PASSEDBYVALUE setting so
748  * it must match for the old and new servers.
749  */
750 static void
752 {
753  int dbnum;
754  FILE *script = NULL;
755  char output_path[MAXPGPATH];
756 
757  prep_status("Checking for contrib/isn with bigint-passing mismatch");
758 
761  {
762  /* no mismatch */
763  check_ok();
764  return;
765  }
766 
767  snprintf(output_path, sizeof(output_path), "%s/%s",
769  "contrib_isn_and_int8_pass_by_value.txt");
770 
771  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
772  {
773  PGresult *res;
774  bool db_used = false;
775  int ntups;
776  int rowno;
777  int i_nspname,
778  i_proname;
779  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
780  PGconn *conn = connectToServer(cluster, active_db->db_name);
781 
782  /* Find any functions coming from contrib/isn */
784  "SELECT n.nspname, p.proname "
785  "FROM pg_catalog.pg_proc p, "
786  " pg_catalog.pg_namespace n "
787  "WHERE p.pronamespace = n.oid AND "
788  " p.probin = '$libdir/isn'");
789 
790  ntups = PQntuples(res);
791  i_nspname = PQfnumber(res, "nspname");
792  i_proname = PQfnumber(res, "proname");
793  for (rowno = 0; rowno < ntups; rowno++)
794  {
795  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
796  pg_fatal("could not open file \"%s\": %m", output_path);
797  if (!db_used)
798  {
799  fprintf(script, "In database: %s\n", active_db->db_name);
800  db_used = true;
801  }
802  fprintf(script, " %s.%s\n",
803  PQgetvalue(res, rowno, i_nspname),
804  PQgetvalue(res, rowno, i_proname));
805  }
806 
807  PQclear(res);
808 
809  PQfinish(conn);
810  }
811 
812  if (script)
813  {
814  fclose(script);
815  pg_log(PG_REPORT, "fatal");
816  pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
817  "bigint data type. Your old and new clusters pass bigint values\n"
818  "differently so this cluster cannot currently be upgraded. You can\n"
819  "manually dump databases in the old cluster that use \"contrib/isn\"\n"
820  "facilities, drop them, perform the upgrade, and then restore them. A\n"
821  "list of the problem functions is in the file:\n"
822  " %s", output_path);
823  }
824  else
825  check_ok();
826 }
827 
828 /*
829  * Verify that no user defined postfix operators exist.
830  */
831 static void
833 {
834  int dbnum;
835  FILE *script = NULL;
836  char output_path[MAXPGPATH];
837 
838  prep_status("Checking for user-defined postfix operators");
839 
840  snprintf(output_path, sizeof(output_path), "%s/%s",
842  "postfix_ops.txt");
843 
844  /* Find any user defined postfix operators */
845  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
846  {
847  PGresult *res;
848  bool db_used = false;
849  int ntups;
850  int rowno;
851  int i_oproid,
852  i_oprnsp,
853  i_oprname,
854  i_typnsp,
855  i_typname;
856  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
857  PGconn *conn = connectToServer(cluster, active_db->db_name);
858 
859  /*
860  * The query below hardcodes FirstNormalObjectId as 16384 rather than
861  * interpolating that C #define into the query because, if that
862  * #define is ever changed, the cutoff we want to use is the value
863  * used by pre-version 14 servers, not that of some future version.
864  */
866  "SELECT o.oid AS oproid, "
867  " n.nspname AS oprnsp, "
868  " o.oprname, "
869  " tn.nspname AS typnsp, "
870  " t.typname "
871  "FROM pg_catalog.pg_operator o, "
872  " pg_catalog.pg_namespace n, "
873  " pg_catalog.pg_type t, "
874  " pg_catalog.pg_namespace tn "
875  "WHERE o.oprnamespace = n.oid AND "
876  " o.oprleft = t.oid AND "
877  " t.typnamespace = tn.oid AND "
878  " o.oprright = 0 AND "
879  " o.oid >= 16384");
880  ntups = PQntuples(res);
881  i_oproid = PQfnumber(res, "oproid");
882  i_oprnsp = PQfnumber(res, "oprnsp");
883  i_oprname = PQfnumber(res, "oprname");
884  i_typnsp = PQfnumber(res, "typnsp");
885  i_typname = PQfnumber(res, "typname");
886  for (rowno = 0; rowno < ntups; rowno++)
887  {
888  if (script == NULL &&
889  (script = fopen_priv(output_path, "w")) == NULL)
890  pg_fatal("could not open file \"%s\": %m", output_path);
891  if (!db_used)
892  {
893  fprintf(script, "In database: %s\n", active_db->db_name);
894  db_used = true;
895  }
896  fprintf(script, " (oid=%s) %s.%s (%s.%s, NONE)\n",
897  PQgetvalue(res, rowno, i_oproid),
898  PQgetvalue(res, rowno, i_oprnsp),
899  PQgetvalue(res, rowno, i_oprname),
900  PQgetvalue(res, rowno, i_typnsp),
901  PQgetvalue(res, rowno, i_typname));
902  }
903 
904  PQclear(res);
905 
906  PQfinish(conn);
907  }
908 
909  if (script)
910  {
911  fclose(script);
912  pg_log(PG_REPORT, "fatal");
913  pg_fatal("Your installation contains user-defined postfix operators, which are not\n"
914  "supported anymore. Consider dropping the postfix operators and replacing\n"
915  "them with prefix operators or function calls.\n"
916  "A list of user-defined postfix operators is in the file:\n"
917  " %s", output_path);
918  }
919  else
920  check_ok();
921 }
922 
923 /*
924  * check_for_incompatible_polymorphics()
925  *
926  * Make sure nothing is using old polymorphic functions with
927  * anyarray/anyelement rather than the new anycompatible variants.
928  */
929 static void
931 {
932  PGresult *res;
933  FILE *script = NULL;
934  char output_path[MAXPGPATH];
935  PQExpBufferData old_polymorphics;
936 
937  prep_status("Checking for incompatible polymorphic functions");
938 
939  snprintf(output_path, sizeof(output_path), "%s/%s",
941  "incompatible_polymorphics.txt");
942 
943  /* The set of problematic functions varies a bit in different versions */
944  initPQExpBuffer(&old_polymorphics);
945 
946  appendPQExpBufferStr(&old_polymorphics,
947  "'array_append(anyarray,anyelement)'"
948  ", 'array_cat(anyarray,anyarray)'"
949  ", 'array_prepend(anyelement,anyarray)'");
950 
951  if (GET_MAJOR_VERSION(cluster->major_version) >= 903)
952  appendPQExpBufferStr(&old_polymorphics,
953  ", 'array_remove(anyarray,anyelement)'"
954  ", 'array_replace(anyarray,anyelement,anyelement)'");
955 
956  if (GET_MAJOR_VERSION(cluster->major_version) >= 905)
957  appendPQExpBufferStr(&old_polymorphics,
958  ", 'array_position(anyarray,anyelement)'"
959  ", 'array_position(anyarray,anyelement,integer)'"
960  ", 'array_positions(anyarray,anyelement)'"
961  ", 'width_bucket(anyelement,anyarray)'");
962 
963  for (int dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
964  {
965  bool db_used = false;
966  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
967  PGconn *conn = connectToServer(cluster, active_db->db_name);
968  int ntups;
969  int i_objkind,
970  i_objname;
971 
972  /*
973  * The query below hardcodes FirstNormalObjectId as 16384 rather than
974  * interpolating that C #define into the query because, if that
975  * #define is ever changed, the cutoff we want to use is the value
976  * used by pre-version 14 servers, not that of some future version.
977  */
979  /* Aggregate transition functions */
980  "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
981  "FROM pg_proc AS p "
982  "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
983  "JOIN pg_proc AS transfn ON transfn.oid=a.aggtransfn "
984  "WHERE p.oid >= 16384 "
985  "AND a.aggtransfn = ANY(ARRAY[%s]::regprocedure[]) "
986  "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
987 
988  /* Aggregate final functions */
989  "UNION ALL "
990  "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
991  "FROM pg_proc AS p "
992  "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
993  "JOIN pg_proc AS finalfn ON finalfn.oid=a.aggfinalfn "
994  "WHERE p.oid >= 16384 "
995  "AND a.aggfinalfn = ANY(ARRAY[%s]::regprocedure[]) "
996  "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
997 
998  /* Operators */
999  "UNION ALL "
1000  "SELECT 'operator' AS objkind, op.oid::regoperator::text AS objname "
1001  "FROM pg_operator AS op "
1002  "WHERE op.oid >= 16384 "
1003  "AND oprcode = ANY(ARRAY[%s]::regprocedure[]) "
1004  "AND oprleft = ANY(ARRAY['anyarray', 'anyelement']::regtype[]);",
1005  old_polymorphics.data,
1006  old_polymorphics.data,
1007  old_polymorphics.data);
1008 
1009  ntups = PQntuples(res);
1010 
1011  i_objkind = PQfnumber(res, "objkind");
1012  i_objname = PQfnumber(res, "objname");
1013 
1014  for (int rowno = 0; rowno < ntups; rowno++)
1015  {
1016  if (script == NULL &&
1017  (script = fopen_priv(output_path, "w")) == NULL)
1018  pg_fatal("could not open file \"%s\": %m", output_path);
1019  if (!db_used)
1020  {
1021  fprintf(script, "In database: %s\n", active_db->db_name);
1022  db_used = true;
1023  }
1024 
1025  fprintf(script, " %s: %s\n",
1026  PQgetvalue(res, rowno, i_objkind),
1027  PQgetvalue(res, rowno, i_objname));
1028  }
1029 
1030  PQclear(res);
1031  PQfinish(conn);
1032  }
1033 
1034  if (script)
1035  {
1036  fclose(script);
1037  pg_log(PG_REPORT, "fatal");
1038  pg_fatal("Your installation contains user-defined objects that refer to internal\n"
1039  "polymorphic functions with arguments of type \"anyarray\" or \"anyelement\".\n"
1040  "These user-defined objects must be dropped before upgrading and restored\n"
1041  "afterwards, changing them to refer to the new corresponding functions with\n"
1042  "arguments of type \"anycompatiblearray\" and \"anycompatible\".\n"
1043  "A list of the problematic objects is in the file:\n"
1044  " %s", output_path);
1045  }
1046  else
1047  check_ok();
1048 
1049  termPQExpBuffer(&old_polymorphics);
1050 }
1051 
1052 /*
1053  * Verify that no tables are declared WITH OIDS.
1054  */
1055 static void
1057 {
1058  int dbnum;
1059  FILE *script = NULL;
1060  char output_path[MAXPGPATH];
1061 
1062  prep_status("Checking for tables WITH OIDS");
1063 
1064  snprintf(output_path, sizeof(output_path), "%s/%s",
1065  log_opts.basedir,
1066  "tables_with_oids.txt");
1067 
1068  /* Find any tables declared WITH OIDS */
1069  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1070  {
1071  PGresult *res;
1072  bool db_used = false;
1073  int ntups;
1074  int rowno;
1075  int i_nspname,
1076  i_relname;
1077  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1078  PGconn *conn = connectToServer(cluster, active_db->db_name);
1079 
1081  "SELECT n.nspname, c.relname "
1082  "FROM pg_catalog.pg_class c, "
1083  " pg_catalog.pg_namespace n "
1084  "WHERE c.relnamespace = n.oid AND "
1085  " c.relhasoids AND"
1086  " n.nspname NOT IN ('pg_catalog')");
1087 
1088  ntups = PQntuples(res);
1089  i_nspname = PQfnumber(res, "nspname");
1090  i_relname = PQfnumber(res, "relname");
1091  for (rowno = 0; rowno < ntups; rowno++)
1092  {
1093  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1094  pg_fatal("could not open file \"%s\": %m", output_path);
1095  if (!db_used)
1096  {
1097  fprintf(script, "In database: %s\n", active_db->db_name);
1098  db_used = true;
1099  }
1100  fprintf(script, " %s.%s\n",
1101  PQgetvalue(res, rowno, i_nspname),
1102  PQgetvalue(res, rowno, i_relname));
1103  }
1104 
1105  PQclear(res);
1106 
1107  PQfinish(conn);
1108  }
1109 
1110  if (script)
1111  {
1112  fclose(script);
1113  pg_log(PG_REPORT, "fatal");
1114  pg_fatal("Your installation contains tables declared WITH OIDS, which is not\n"
1115  "supported anymore. Consider removing the oid column using\n"
1116  " ALTER TABLE ... SET WITHOUT OIDS;\n"
1117  "A list of tables with the problem is in the file:\n"
1118  " %s", output_path);
1119  }
1120  else
1121  check_ok();
1122 }
1123 
1124 
1125 /*
1126  * check_for_composite_data_type_usage()
1127  * Check for system-defined composite types used in user tables.
1128  *
1129  * The OIDs of rowtypes of system catalogs and information_schema views
1130  * can change across major versions; unlike user-defined types, we have
1131  * no mechanism for forcing them to be the same in the new cluster.
1132  * Hence, if any user table uses one, that's problematic for pg_upgrade.
1133  */
1134 static void
1136 {
1137  bool found;
1138  Oid firstUserOid;
1139  char output_path[MAXPGPATH];
1140  char *base_query;
1141 
1142  prep_status("Checking for system-defined composite types in user tables");
1143 
1144  snprintf(output_path, sizeof(output_path), "%s/%s",
1145  log_opts.basedir,
1146  "tables_using_composite.txt");
1147 
1148  /*
1149  * Look for composite types that were made during initdb *or* belong to
1150  * information_schema; that's important in case information_schema was
1151  * dropped and reloaded.
1152  *
1153  * The cutoff OID here should match the source cluster's value of
1154  * FirstNormalObjectId. We hardcode it rather than using that C #define
1155  * because, if that #define is ever changed, our own version's value is
1156  * NOT what to use. Eventually we may need a test on the source cluster's
1157  * version to select the correct value.
1158  */
1159  firstUserOid = 16384;
1160 
1161  base_query = psprintf("SELECT t.oid FROM pg_catalog.pg_type t "
1162  "LEFT JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid "
1163  " WHERE typtype = 'c' AND (t.oid < %u OR nspname = 'information_schema')",
1164  firstUserOid);
1165 
1166  found = check_for_data_types_usage(cluster, base_query, output_path);
1167 
1168  free(base_query);
1169 
1170  if (found)
1171  {
1172  pg_log(PG_REPORT, "fatal");
1173  pg_fatal("Your installation contains system-defined composite types in user tables.\n"
1174  "These type OIDs are not stable across PostgreSQL versions,\n"
1175  "so this cluster cannot currently be upgraded. You can\n"
1176  "drop the problem columns and restart the upgrade.\n"
1177  "A list of the problem columns is in the file:\n"
1178  " %s", output_path);
1179  }
1180  else
1181  check_ok();
1182 }
1183 
1184 /*
1185  * check_for_reg_data_type_usage()
1186  * pg_upgrade only preserves these system values:
1187  * pg_class.oid
1188  * pg_type.oid
1189  * pg_enum.oid
1190  *
1191  * Many of the reg* data types reference system catalog info that is
1192  * not preserved, and hence these data types cannot be used in user
1193  * tables upgraded by pg_upgrade.
1194  */
1195 static void
1197 {
1198  bool found;
1199  char output_path[MAXPGPATH];
1200 
1201  prep_status("Checking for reg* data types in user tables");
1202 
1203  snprintf(output_path, sizeof(output_path), "%s/%s",
1204  log_opts.basedir,
1205  "tables_using_reg.txt");
1206 
1207  /*
1208  * Note: older servers will not have all of these reg* types, so we have
1209  * to write the query like this rather than depending on casts to regtype.
1210  */
1212  "SELECT oid FROM pg_catalog.pg_type t "
1213  "WHERE t.typnamespace = "
1214  " (SELECT oid FROM pg_catalog.pg_namespace "
1215  " WHERE nspname = 'pg_catalog') "
1216  " AND t.typname IN ( "
1217  /* pg_class.oid is preserved, so 'regclass' is OK */
1218  " 'regcollation', "
1219  " 'regconfig', "
1220  " 'regdictionary', "
1221  " 'regnamespace', "
1222  " 'regoper', "
1223  " 'regoperator', "
1224  " 'regproc', "
1225  " 'regprocedure' "
1226  /* pg_authid.oid is preserved, so 'regrole' is OK */
1227  /* pg_type.oid is (mostly) preserved, so 'regtype' is OK */
1228  " )",
1229  output_path);
1230 
1231  if (found)
1232  {
1233  pg_log(PG_REPORT, "fatal");
1234  pg_fatal("Your installation contains one of the reg* data types in user tables.\n"
1235  "These data types reference system OIDs that are not preserved by\n"
1236  "pg_upgrade, so this cluster cannot currently be upgraded. You can\n"
1237  "drop the problem columns and restart the upgrade.\n"
1238  "A list of the problem columns is in the file:\n"
1239  " %s", output_path);
1240  }
1241  else
1242  check_ok();
1243 }
1244 
1245 /*
1246  * check_for_aclitem_data_type_usage
1247  *
1248  * aclitem changed its storage format in 16, so check for it.
1249  */
1250 static void
1252 {
1253  char output_path[MAXPGPATH];
1254 
1255  prep_status("Checking for incompatible \"%s\" data type in user tables",
1256  "aclitem");
1257 
1258  snprintf(output_path, sizeof(output_path), "tables_using_aclitem.txt");
1259 
1260  if (check_for_data_type_usage(cluster, "pg_catalog.aclitem", output_path))
1261  {
1262  pg_log(PG_REPORT, "fatal");
1263  pg_fatal("Your installation contains the \"aclitem\" data type in user tables.\n"
1264  "The internal format of \"aclitem\" changed in PostgreSQL version 16\n"
1265  "so this cluster cannot currently be upgraded. You can drop the\n"
1266  "problem columns and restart the upgrade. A list of the problem\n"
1267  "columns is in the file:\n"
1268  " %s", output_path);
1269  }
1270  else
1271  check_ok();
1272 }
1273 
1274 /*
1275  * check_for_removed_data_type_usage
1276  *
1277  * Check for in-core data types that have been removed. Callers know
1278  * the exact list.
1279  */
1280 static void
1282  const char *datatype)
1283 {
1284  char output_path[MAXPGPATH];
1285  char typename[NAMEDATALEN];
1286 
1287  prep_status("Checking for removed \"%s\" data type in user tables",
1288  datatype);
1289 
1290  snprintf(output_path, sizeof(output_path), "tables_using_%s.txt",
1291  datatype);
1292  snprintf(typename, sizeof(typename), "pg_catalog.%s", datatype);
1293 
1294  if (check_for_data_type_usage(cluster, typename, output_path))
1295  {
1296  pg_log(PG_REPORT, "fatal");
1297  pg_fatal("Your installation contains the \"%s\" data type in user tables.\n"
1298  "The \"%s\" type has been removed in PostgreSQL version %s,\n"
1299  "so this cluster cannot currently be upgraded. You can drop the\n"
1300  "problem columns, or change them to another data type, and restart\n"
1301  "the upgrade. A list of the problem columns is in the file:\n"
1302  " %s", datatype, datatype, version, output_path);
1303  }
1304  else
1305  check_ok();
1306 }
1307 
1308 
1309 /*
1310  * check_for_jsonb_9_4_usage()
1311  *
1312  * JSONB changed its storage format during 9.4 beta, so check for it.
1313  */
1314 static void
1316 {
1317  char output_path[MAXPGPATH];
1318 
1319  prep_status("Checking for incompatible \"jsonb\" data type");
1320 
1321  snprintf(output_path, sizeof(output_path), "%s/%s",
1322  log_opts.basedir,
1323  "tables_using_jsonb.txt");
1324 
1325  if (check_for_data_type_usage(cluster, "pg_catalog.jsonb", output_path))
1326  {
1327  pg_log(PG_REPORT, "fatal");
1328  pg_fatal("Your installation contains the \"jsonb\" data type in user tables.\n"
1329  "The internal format of \"jsonb\" changed during 9.4 beta so this\n"
1330  "cluster cannot currently be upgraded. You can\n"
1331  "drop the problem columns and restart the upgrade.\n"
1332  "A list of the problem columns is in the file:\n"
1333  " %s", output_path);
1334  }
1335  else
1336  check_ok();
1337 }
1338 
1339 /*
1340  * check_for_pg_role_prefix()
1341  *
1342  * Versions older than 9.6 should not have any pg_* roles
1343  */
1344 static void
1346 {
1347  PGresult *res;
1348  PGconn *conn = connectToServer(cluster, "template1");
1349  int ntups;
1350  int i_roloid;
1351  int i_rolname;
1352  FILE *script = NULL;
1353  char output_path[MAXPGPATH];
1354 
1355  prep_status("Checking for roles starting with \"pg_\"");
1356 
1357  snprintf(output_path, sizeof(output_path), "%s/%s",
1358  log_opts.basedir,
1359  "pg_role_prefix.txt");
1360 
1362  "SELECT oid AS roloid, rolname "
1363  "FROM pg_catalog.pg_roles "
1364  "WHERE rolname ~ '^pg_'");
1365 
1366  ntups = PQntuples(res);
1367  i_roloid = PQfnumber(res, "roloid");
1368  i_rolname = PQfnumber(res, "rolname");
1369  for (int rowno = 0; rowno < ntups; rowno++)
1370  {
1371  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1372  pg_fatal("could not open file \"%s\": %m", output_path);
1373  fprintf(script, "%s (oid=%s)\n",
1374  PQgetvalue(res, rowno, i_rolname),
1375  PQgetvalue(res, rowno, i_roloid));
1376  }
1377 
1378  PQclear(res);
1379 
1380  PQfinish(conn);
1381 
1382  if (script)
1383  {
1384  fclose(script);
1385  pg_log(PG_REPORT, "fatal");
1386  pg_fatal("Your installation contains roles starting with \"pg_\".\n"
1387  "\"pg_\" is a reserved prefix for system roles. The cluster\n"
1388  "cannot be upgraded until these roles are renamed.\n"
1389  "A list of roles starting with \"pg_\" is in the file:\n"
1390  " %s", output_path);
1391  }
1392  else
1393  check_ok();
1394 }
1395 
1396 /*
1397  * Verify that no user-defined encoding conversions exist.
1398  */
1399 static void
1401 {
1402  int dbnum;
1403  FILE *script = NULL;
1404  char output_path[MAXPGPATH];
1405 
1406  prep_status("Checking for user-defined encoding conversions");
1407 
1408  snprintf(output_path, sizeof(output_path), "%s/%s",
1409  log_opts.basedir,
1410  "encoding_conversions.txt");
1411 
1412  /* Find any user defined encoding conversions */
1413  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1414  {
1415  PGresult *res;
1416  bool db_used = false;
1417  int ntups;
1418  int rowno;
1419  int i_conoid,
1420  i_conname,
1421  i_nspname;
1422  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1423  PGconn *conn = connectToServer(cluster, active_db->db_name);
1424 
1425  /*
1426  * The query below hardcodes FirstNormalObjectId as 16384 rather than
1427  * interpolating that C #define into the query because, if that
1428  * #define is ever changed, the cutoff we want to use is the value
1429  * used by pre-version 14 servers, not that of some future version.
1430  */
1432  "SELECT c.oid as conoid, c.conname, n.nspname "
1433  "FROM pg_catalog.pg_conversion c, "
1434  " pg_catalog.pg_namespace n "
1435  "WHERE c.connamespace = n.oid AND "
1436  " c.oid >= 16384");
1437  ntups = PQntuples(res);
1438  i_conoid = PQfnumber(res, "conoid");
1439  i_conname = PQfnumber(res, "conname");
1440  i_nspname = PQfnumber(res, "nspname");
1441  for (rowno = 0; rowno < ntups; rowno++)
1442  {
1443  if (script == NULL &&
1444  (script = fopen_priv(output_path, "w")) == NULL)
1445  pg_fatal("could not open file \"%s\": %m", output_path);
1446  if (!db_used)
1447  {
1448  fprintf(script, "In database: %s\n", active_db->db_name);
1449  db_used = true;
1450  }
1451  fprintf(script, " (oid=%s) %s.%s\n",
1452  PQgetvalue(res, rowno, i_conoid),
1453  PQgetvalue(res, rowno, i_nspname),
1454  PQgetvalue(res, rowno, i_conname));
1455  }
1456 
1457  PQclear(res);
1458 
1459  PQfinish(conn);
1460  }
1461 
1462  if (script)
1463  {
1464  fclose(script);
1465  pg_log(PG_REPORT, "fatal");
1466  pg_fatal("Your installation contains user-defined encoding conversions.\n"
1467  "The conversion function parameters changed in PostgreSQL version 14\n"
1468  "so this cluster cannot currently be upgraded. You can remove the\n"
1469  "encoding conversions in the old cluster and restart the upgrade.\n"
1470  "A list of user-defined encoding conversions is in the file:\n"
1471  " %s", output_path);
1472  }
1473  else
1474  check_ok();
1475 }
1476 
1477 /*
1478  * check_new_cluster_logical_replication_slots()
1479  *
1480  * Verify that there are no logical replication slots on the new cluster and
1481  * that the parameter settings necessary for creating slots are sufficient.
1482  */
1483 static void
1485 {
1486  PGresult *res;
1487  PGconn *conn;
1488  int nslots_on_old;
1489  int nslots_on_new;
1491  char *wal_level;
1492 
1493  /* Logical slots can be migrated since PG17. */
1495  return;
1496 
1497  nslots_on_old = count_old_cluster_logical_slots();
1498 
1499  /* Quick return if there are no logical slots to be migrated. */
1500  if (nslots_on_old == 0)
1501  return;
1502 
1503  conn = connectToServer(&new_cluster, "template1");
1504 
1505  prep_status("Checking for new cluster logical replication slots");
1506 
1507  res = executeQueryOrDie(conn, "SELECT count(*) "
1508  "FROM pg_catalog.pg_replication_slots "
1509  "WHERE slot_type = 'logical' AND "
1510  "temporary IS FALSE;");
1511 
1512  if (PQntuples(res) != 1)
1513  pg_fatal("could not count the number of logical replication slots");
1514 
1515  nslots_on_new = atoi(PQgetvalue(res, 0, 0));
1516 
1517  if (nslots_on_new)
1518  pg_fatal("Expected 0 logical replication slots but found %d.",
1519  nslots_on_new);
1520 
1521  PQclear(res);
1522 
1523  res = executeQueryOrDie(conn, "SELECT setting FROM pg_settings "
1524  "WHERE name IN ('wal_level', 'max_replication_slots') "
1525  "ORDER BY name DESC;");
1526 
1527  if (PQntuples(res) != 2)
1528  pg_fatal("could not determine parameter settings on new cluster");
1529 
1530  wal_level = PQgetvalue(res, 0, 0);
1531 
1532  if (strcmp(wal_level, "logical") != 0)
1533  pg_fatal("wal_level must be \"logical\", but is set to \"%s\"",
1534  wal_level);
1535 
1536  max_replication_slots = atoi(PQgetvalue(res, 1, 0));
1537 
1538  if (nslots_on_old > max_replication_slots)
1539  pg_fatal("max_replication_slots (%d) must be greater than or equal to the number of "
1540  "logical replication slots (%d) on the old cluster",
1541  max_replication_slots, nslots_on_old);
1542 
1543  PQclear(res);
1544  PQfinish(conn);
1545 
1546  check_ok();
1547 }
1548 
1549 /*
1550  * check_new_cluster_subscription_configuration()
1551  *
1552  * Verify that the max_replication_slots configuration specified is enough for
1553  * creating the subscriptions. This is required to create the replication
1554  * origin for each subscription.
1555  */
1556 static void
1558 {
1559  PGresult *res;
1560  PGconn *conn;
1561  int nsubs_on_old;
1563 
1564  /* Subscriptions and their dependencies can be migrated since PG17. */
1566  return;
1567 
1568  nsubs_on_old = count_old_cluster_subscriptions();
1569 
1570  /* Quick return if there are no subscriptions to be migrated. */
1571  if (nsubs_on_old == 0)
1572  return;
1573 
1574  prep_status("Checking for new cluster configuration for subscriptions");
1575 
1576  conn = connectToServer(&new_cluster, "template1");
1577 
1578  res = executeQueryOrDie(conn, "SELECT setting FROM pg_settings "
1579  "WHERE name = 'max_replication_slots';");
1580 
1581  if (PQntuples(res) != 1)
1582  pg_fatal("could not determine parameter settings on new cluster");
1583 
1584  max_replication_slots = atoi(PQgetvalue(res, 0, 0));
1585  if (nsubs_on_old > max_replication_slots)
1586  pg_fatal("max_replication_slots (%d) must be greater than or equal to the number of "
1587  "subscriptions (%d) on the old cluster",
1588  max_replication_slots, nsubs_on_old);
1589 
1590  PQclear(res);
1591  PQfinish(conn);
1592 
1593  check_ok();
1594 }
1595 
1596 /*
1597  * check_old_cluster_for_valid_slots()
1598  *
1599  * Verify that all the logical slots are valid and have consumed all the WAL
1600  * before shutdown.
1601  */
1602 static void
1604 {
1605  char output_path[MAXPGPATH];
1606  FILE *script = NULL;
1607 
1608  prep_status("Checking for valid logical replication slots");
1609 
1610  snprintf(output_path, sizeof(output_path), "%s/%s",
1611  log_opts.basedir,
1612  "invalid_logical_slots.txt");
1613 
1614  for (int dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
1615  {
1616  LogicalSlotInfoArr *slot_arr = &old_cluster.dbarr.dbs[dbnum].slot_arr;
1617 
1618  for (int slotnum = 0; slotnum < slot_arr->nslots; slotnum++)
1619  {
1620  LogicalSlotInfo *slot = &slot_arr->slots[slotnum];
1621 
1622  /* Is the slot usable? */
1623  if (slot->invalid)
1624  {
1625  if (script == NULL &&
1626  (script = fopen_priv(output_path, "w")) == NULL)
1627  pg_fatal("could not open file \"%s\": %m", output_path);
1628 
1629  fprintf(script, "The slot \"%s\" is invalid\n",
1630  slot->slotname);
1631 
1632  continue;
1633  }
1634 
1635  /*
1636  * Do additional check to ensure that all logical replication
1637  * slots have consumed all the WAL before shutdown.
1638  *
1639  * Note: This can be satisfied only when the old cluster has been
1640  * shut down, so we skip this for live checks.
1641  */
1642  if (!live_check && !slot->caught_up)
1643  {
1644  if (script == NULL &&
1645  (script = fopen_priv(output_path, "w")) == NULL)
1646  pg_fatal("could not open file \"%s\": %m", output_path);
1647 
1648  fprintf(script,
1649  "The slot \"%s\" has not consumed the WAL yet\n",
1650  slot->slotname);
1651  }
1652  }
1653  }
1654 
1655  if (script)
1656  {
1657  fclose(script);
1658 
1659  pg_log(PG_REPORT, "fatal");
1660  pg_fatal("Your installation contains logical replication slots that can't be upgraded.\n"
1661  "You can remove invalid slots and/or consume the pending WAL for other slots,\n"
1662  "and then restart the upgrade.\n"
1663  "A list of the problematic slots is in the file:\n"
1664  " %s", output_path);
1665  }
1666 
1667  check_ok();
1668 }
1669 
1670 /*
1671  * check_old_cluster_subscription_state()
1672  *
1673  * Verify that the replication origin corresponding to each of the
1674  * subscriptions are present and each of the subscribed tables is in
1675  * 'i' (initialize) or 'r' (ready) state.
1676  */
1677 static void
1679 {
1680  FILE *script = NULL;
1681  char output_path[MAXPGPATH];
1682  int ntup;
1683 
1684  prep_status("Checking for subscription state");
1685 
1686  snprintf(output_path, sizeof(output_path), "%s/%s",
1687  log_opts.basedir,
1688  "subs_invalid.txt");
1689  for (int dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
1690  {
1691  PGresult *res;
1692  DbInfo *active_db = &old_cluster.dbarr.dbs[dbnum];
1693  PGconn *conn = connectToServer(&old_cluster, active_db->db_name);
1694 
1695  /* We need to check for pg_replication_origin only once. */
1696  if (dbnum == 0)
1697  {
1698  /*
1699  * Check that all the subscriptions have their respective
1700  * replication origin.
1701  */
1703  "SELECT d.datname, s.subname "
1704  "FROM pg_catalog.pg_subscription s "
1705  "LEFT OUTER JOIN pg_catalog.pg_replication_origin o "
1706  " ON o.roname = 'pg_' || s.oid "
1707  "INNER JOIN pg_catalog.pg_database d "
1708  " ON d.oid = s.subdbid "
1709  "WHERE o.roname iS NULL;");
1710 
1711  ntup = PQntuples(res);
1712  for (int i = 0; i < ntup; i++)
1713  {
1714  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1715  pg_fatal("could not open file \"%s\": %m", output_path);
1716  fprintf(script, "The replication origin is missing for database:\"%s\" subscription:\"%s\"\n",
1717  PQgetvalue(res, i, 0),
1718  PQgetvalue(res, i, 1));
1719  }
1720  PQclear(res);
1721  }
1722 
1723  /*
1724  * We don't allow upgrade if there is a risk of dangling slot or
1725  * origin corresponding to initial sync after upgrade.
1726  *
1727  * A slot/origin not created yet refers to the 'i' (initialize) state,
1728  * while 'r' (ready) state refers to a slot/origin created previously
1729  * but already dropped. These states are supported for pg_upgrade. The
1730  * other states listed below are not supported:
1731  *
1732  * a) SUBREL_STATE_DATASYNC: A relation upgraded while in this state
1733  * would retain a replication slot, which could not be dropped by the
1734  * sync worker spawned after the upgrade because the subscription ID
1735  * used for the slot name won't match anymore.
1736  *
1737  * b) SUBREL_STATE_SYNCDONE: A relation upgraded while in this state
1738  * would retain the replication origin when there is a failure in
1739  * tablesync worker immediately after dropping the replication slot in
1740  * the publisher.
1741  *
1742  * c) SUBREL_STATE_FINISHEDCOPY: A tablesync worker spawned to work on
1743  * a relation upgraded while in this state would expect an origin ID
1744  * with the OID of the subscription used before the upgrade, causing
1745  * it to fail.
1746  *
1747  * d) SUBREL_STATE_SYNCWAIT, SUBREL_STATE_CATCHUP and
1748  * SUBREL_STATE_UNKNOWN: These states are not stored in the catalog,
1749  * so we need not allow these states.
1750  */
1752  "SELECT r.srsubstate, s.subname, n.nspname, c.relname "
1753  "FROM pg_catalog.pg_subscription_rel r "
1754  "LEFT JOIN pg_catalog.pg_subscription s"
1755  " ON r.srsubid = s.oid "
1756  "LEFT JOIN pg_catalog.pg_class c"
1757  " ON r.srrelid = c.oid "
1758  "LEFT JOIN pg_catalog.pg_namespace n"
1759  " ON c.relnamespace = n.oid "
1760  "WHERE r.srsubstate NOT IN ('i', 'r') "
1761  "ORDER BY s.subname");
1762 
1763  ntup = PQntuples(res);
1764  for (int i = 0; i < ntup; i++)
1765  {
1766  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1767  pg_fatal("could not open file \"%s\": %m", output_path);
1768 
1769  fprintf(script, "The table sync state \"%s\" is not allowed for database:\"%s\" subscription:\"%s\" schema:\"%s\" relation:\"%s\"\n",
1770  PQgetvalue(res, i, 0),
1771  active_db->db_name,
1772  PQgetvalue(res, i, 1),
1773  PQgetvalue(res, i, 2),
1774  PQgetvalue(res, i, 3));
1775  }
1776 
1777  PQclear(res);
1778  PQfinish(conn);
1779  }
1780 
1781  if (script)
1782  {
1783  fclose(script);
1784  pg_log(PG_REPORT, "fatal");
1785  pg_fatal("Your installation contains subscriptions without origin or having relations not in i (initialize) or r (ready) state.\n"
1786  "You can allow the initial sync to finish for all relations and then restart the upgrade.\n"
1787  "A list of the problematic subscriptions is in the file:\n"
1788  " %s", output_path);
1789  }
1790  else
1791  check_ok();
1792 }
void output_check_banner(bool live_check)
Definition: check.c:71
void check_cluster_versions(void)
Definition: check.c:333
static void check_for_tables_with_oids(ClusterInfo *cluster)
Definition: check.c:1056
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1345
void check_cluster_compatibility(bool live_check)
Definition: check.c:376
static void check_new_cluster_logical_replication_slots(void)
Definition: check.c:1484
static void check_old_cluster_subscription_state(void)
Definition: check.c:1678
static void check_for_composite_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1135
void check_and_dump_old_cluster(bool live_check)
Definition: check.c:89
void issue_warnings_and_set_wal_level(void)
Definition: check.c:278
static char * fix_path_separator(char *path)
Definition: check.c:50
static void check_for_removed_data_type_usage(ClusterInfo *cluster, const char *version, const char *datatype)
Definition: check.c:1281
static void check_old_cluster_for_valid_slots(bool live_check)
Definition: check.c:1603
void check_new_cluster(void)
Definition: check.c:223
void report_clusters_compatible(void)
Definition: check.c:259
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:574
static void check_new_cluster_subscription_configuration(void)
Definition: check.c:1557
void create_script_for_old_cluster_deletion(char **deletion_script_file_name)
Definition: check.c:451
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:751
static void check_new_cluster_is_empty(void)
Definition: check.c:390
static void check_for_user_defined_postfix_ops(ClusterInfo *cluster)
Definition: check.c:832
void output_completion_banner(char *deletion_script_file_name)
Definition: check.c:299
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:716
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:632
static void check_for_new_tablespace_dir(void)
Definition: check.c:422
static void check_for_aclitem_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1251
static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
Definition: check.c:1400
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster)
Definition: check.c:1315
static void check_for_incompatible_polymorphics(ClusterInfo *cluster)
Definition: check.c:930
static void check_for_reg_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1196
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
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4669
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3441
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3836
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3549
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
#define free(a)
Definition: header.h:65
int count_old_cluster_subscriptions(void)
Definition: info.c:789
void get_db_rel_and_slot_infos(ClusterInfo *cluster, bool live_check)
Definition: info.c:280
int count_old_cluster_logical_slots(void)
Definition: info.c:740
static void check_ok(void)
Definition: initdb.c:2036
int i
Definition: isn.c:73
Assert(fmt[strlen(fmt) - 1] !='\n')
exit(1)
void pfree(void *pointer)
Definition: mcxt.c:1508
#define pg_fatal(...)
#define NAMEDATALEN
#define MAXPGPATH
static pid_t start_postmaster(void)
Definition: pg_ctl.c:439
NameData datname
Definition: pg_database.h:35
bool datallowconn
Definition: pg_database.h:50
OSInfo os_info
Definition: pg_upgrade.c:66
ClusterInfo new_cluster
Definition: pg_upgrade.c:65
ClusterInfo old_cluster
Definition: pg_upgrade.c:64
#define PATH_SEPARATOR
Definition: pg_upgrade.h:82
void init_tablespaces(void)
Definition: tablespace.c:19
bool check_for_data_types_usage(ClusterInfo *cluster, const char *base_query, const char *output_path)
Definition: version.c:31
void old_11_check_for_sql_identifier_data_type_usage(ClusterInfo *cluster)
Definition: version.c:363
bool check_for_data_type_usage(ClusterInfo *cluster, const char *type_name, const char *output_path)
Definition: version.c:152
#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:394
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster)
Definition: version.c:179
@ TRANSFER_MODE_COPY
Definition: pg_upgrade.h:258
@ TRANSFER_MODE_LINK
Definition: pg_upgrade.h:260
@ TRANSFER_MODE_CLONE
Definition: pg_upgrade.h:257
@ TRANSFER_MODE_COPY_FILE_RANGE
Definition: pg_upgrade.h:259
void old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster)
Definition: version.c:219
#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:417
@ PG_WARNING
Definition: pg_upgrade.h:272
@ PG_REPORT
Definition: pg_upgrade.h:271
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:249
#define JSONB_FORMAT_CHANGE_CAT_VER
Definition: pg_upgrade.h:127
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
unsigned int Oid
Definition: postgres_ext.h:31
#define atooid(x)
Definition: postgres_ext.h:42
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
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:54
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:429
char * pgdata
Definition: pg_upgrade.h:287
unsigned short port
Definition: pg_upgrade.h:294
ControlData controldata
Definition: pg_upgrade.h:284
char * bindir
Definition: pg_upgrade.h:290
uint32 bin_version
Definition: pg_upgrade.h:297
DbInfoArr dbarr
Definition: pg_upgrade.h:286
uint32 major_version
Definition: pg_upgrade.h:295
const char * tablespace_suffix
Definition: pg_upgrade.h:298
bool float8_pass_by_value
Definition: pg_upgrade.h:248
uint32 cat_ver
Definition: pg_upgrade.h:229
DbInfo * dbs
Definition: pg_upgrade.h:217
LogicalSlotInfoArr slot_arr
Definition: pg_upgrade.h:199
char * db_name
Definition: pg_upgrade.h:195
RelInfoArr rel_arr
Definition: pg_upgrade.h:198
Oid db_oid
Definition: pg_upgrade.h:194
char * basedir
Definition: pg_upgrade.h:312
LogicalSlotInfo * slots
Definition: pg_upgrade.h:170
int num_old_tablespaces
Definition: pg_upgrade.h:348
char * user
Definition: pg_upgrade.h:345
char ** old_tablespaces
Definition: pg_upgrade.h:347
bool user_specified
Definition: pg_upgrade.h:346
RelInfo * rels
Definition: pg_upgrade.h:149
char * nspname
Definition: pg_upgrade.h:136
char * relname
Definition: pg_upgrade.h:137
transferMode transfer_mode
Definition: pg_upgrade.h:327
bool check
Definition: pg_upgrade.h:324
#define stat
Definition: win32_port.h:284
#define S_IRWXU
Definition: win32_port.h:298
int wal_level
Definition: xlog.c:131