PostgreSQL Source Code  git master
check.c File Reference
#include "postgres_fe.h"
#include "catalog/pg_authid_d.h"
#include "catalog/pg_class_d.h"
#include "catalog/pg_collation.h"
#include "fe_utils/string_utils.h"
#include "mb/pg_wchar.h"
#include "pg_upgrade.h"
Include dependency graph for check.c:

Go to the source code of this file.

Data Structures

struct  DataTypesUsageChecks
 

Macros

#define MANUAL_CHECK   1
 
#define ALL_VERSIONS   -1
 

Functions

static void check_new_cluster_is_empty (void)
 
static void check_is_install_user (ClusterInfo *cluster)
 
static void check_proper_datallowconn (ClusterInfo *cluster)
 
static void check_for_prepared_transactions (ClusterInfo *cluster)
 
static void check_for_isn_and_int8_passing_mismatch (ClusterInfo *cluster)
 
static void check_for_user_defined_postfix_ops (ClusterInfo *cluster)
 
static void check_for_incompatible_polymorphics (ClusterInfo *cluster)
 
static void check_for_tables_with_oids (ClusterInfo *cluster)
 
static void check_for_pg_role_prefix (ClusterInfo *cluster)
 
static void check_for_new_tablespace_dir (void)
 
static void check_for_user_defined_encoding_conversions (ClusterInfo *cluster)
 
static void check_new_cluster_logical_replication_slots (void)
 
static void check_new_cluster_subscription_configuration (void)
 
static void check_old_cluster_for_valid_slots (void)
 
static void check_old_cluster_subscription_state (void)
 
static void check_for_data_types_usage (ClusterInfo *cluster, DataTypesUsageChecks *checks)
 
static char * fix_path_separator (char *path)
 
void output_check_banner (void)
 
void check_and_dump_old_cluster (void)
 
void check_new_cluster (void)
 
void report_clusters_compatible (void)
 
void issue_warnings_and_set_wal_level (void)
 
void output_completion_banner (char *deletion_script_file_name)
 
void check_cluster_versions (void)
 
void check_cluster_compatibility (void)
 
void create_script_for_old_cluster_deletion (char **deletion_script_file_name)
 

Variables

static DataTypesUsageChecks data_types_usage_checks []
 

Macro Definition Documentation

◆ ALL_VERSIONS

#define ALL_VERSIONS   -1

Definition at line 62 of file check.c.

◆ MANUAL_CHECK

#define MANUAL_CHECK   1

Definition at line 61 of file check.c.

Function Documentation

◆ check_and_dump_old_cluster()

void check_and_dump_old_cluster ( void  )

Definition at line 576 of file check.c.

577 {
578  /* -- OLD -- */
579 
580  if (!user_opts.live_check)
582 
583  /*
584  * Extract a list of databases, tables, and logical replication slots from
585  * the old cluster.
586  */
588 
590 
592 
593 
594  /*
595  * Check for various failure cases
596  */
601 
603  {
604  /*
605  * Logical replication slots can be migrated since PG17. See comments
606  * atop get_old_cluster_logical_slot_infos().
607  */
609 
610  /*
611  * Subscriptions and their dependencies can be migrated since PG17.
612  * Before that the logical slots are not upgraded, so we will not be
613  * able to upgrade the logical replication clusters completely.
614  */
617  }
618 
620 
621  /*
622  * PG 14 changed the function signature of encoding conversion functions.
623  * Conversions from older versions cannot be upgraded automatically
624  * because the user-defined functions used by the encoding conversions
625  * need to be changed to match the new signature.
626  */
629 
630  /*
631  * Pre-PG 14 allowed user defined postfix operators, which are not
632  * supported anymore. Verify there are none, iff applicable.
633  */
636 
637  /*
638  * PG 14 changed polymorphic functions from anyarray to
639  * anycompatiblearray.
640  */
643 
644  /*
645  * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
646  * supported anymore. Verify there are none, iff applicable.
647  */
650 
651  /*
652  * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
653  * hash indexes
654  */
656  {
657  if (user_opts.check)
659  }
660 
661  /* 9.5 and below should not have roles starting with pg_ */
664 
665  /*
666  * While not a check option, we do this now because this is the only time
667  * the old server is running.
668  */
669  if (!user_opts.check)
671 
672  if (!user_opts.live_check)
673  stop_postmaster(false);
674 }
static void check_for_tables_with_oids(ClusterInfo *cluster)
Definition: check.c:1511
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1586
static DataTypesUsageChecks data_types_usage_checks[]
Definition: check.c:97
static void check_old_cluster_subscription_state(void)
Definition: check.c:1916
static void check_for_data_types_usage(ClusterInfo *cluster, DataTypesUsageChecks *checks)
Definition: check.c:337
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:1029
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:1206
static void check_old_cluster_for_valid_slots(void)
Definition: check.c:1841
static void check_for_user_defined_postfix_ops(ClusterInfo *cluster)
Definition: check.c:1287
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:1171
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:1087
static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
Definition: check.c:1641
static void check_for_incompatible_polymorphics(ClusterInfo *cluster)
Definition: check.c:1385
void generate_old_dump(void)
Definition: dump.c:16
void get_loadable_libraries(void)
Definition: function.c:55
void get_subscription_count(ClusterInfo *cluster)
Definition: info.c:746
void get_db_rel_and_slot_infos(ClusterInfo *cluster)
Definition: info.c:277
static pid_t start_postmaster(void)
Definition: pg_ctl.c:440
ClusterInfo old_cluster
Definition: pg_upgrade.c:71
void init_tablespaces(void)
Definition: tablespace.c:19
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:27
void stop_postmaster(bool in_atexit)
Definition: server.c:342
void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
Definition: version.c:37
UserOpts user_opts
Definition: option.c:30
uint32 major_version
Definition: pg_upgrade.h:293
bool live_check
Definition: pg_upgrade.h:324
bool check
Definition: pg_upgrade.h:323

References UserOpts::check, check_for_data_types_usage(), check_for_incompatible_polymorphics(), check_for_isn_and_int8_passing_mismatch(), check_for_pg_role_prefix(), check_for_prepared_transactions(), check_for_tables_with_oids(), check_for_user_defined_encoding_conversions(), check_for_user_defined_postfix_ops(), check_is_install_user(), check_old_cluster_for_valid_slots(), check_old_cluster_subscription_state(), check_proper_datallowconn(), data_types_usage_checks, generate_old_dump(), get_db_rel_and_slot_infos(), get_loadable_libraries(), GET_MAJOR_VERSION, get_subscription_count(), init_tablespaces(), UserOpts::live_check, ClusterInfo::major_version, old_9_6_invalidate_hash_indexes(), old_cluster, start_postmaster(), stop_postmaster(), and user_opts.

Referenced by main().

◆ check_cluster_compatibility()

void check_cluster_compatibility ( void  )

Definition at line 831 of file check.c.

832 {
833  /* get/check pg_control data of servers */
837 
839  pg_fatal("When checking a live server, "
840  "the old and new port numbers must be different.");
841 }
void get_control_data(ClusterInfo *cluster)
Definition: controldata.c:36
void check_control_data(ControlData *oldctrl, ControlData *newctrl)
Definition: controldata.c:655
#define pg_fatal(...)
ClusterInfo new_cluster
Definition: pg_upgrade.c:72
unsigned short port
Definition: pg_upgrade.h:292
ControlData controldata
Definition: pg_upgrade.h:282

References check_control_data(), ClusterInfo::controldata, get_control_data(), UserOpts::live_check, new_cluster, old_cluster, pg_fatal, ClusterInfo::port, and user_opts.

Referenced by main().

◆ check_cluster_versions()

void check_cluster_versions ( void  )

Definition at line 788 of file check.c.

789 {
790  prep_status("Checking cluster versions");
791 
792  /* cluster versions should already have been obtained */
795 
796  /*
797  * We allow upgrades from/to the same major version for alpha/beta
798  * upgrades
799  */
800 
802  pg_fatal("This utility can only upgrade from PostgreSQL version %s and later.",
803  "9.2");
804 
805  /* Only current PG version is supported as a target */
807  pg_fatal("This utility can only upgrade to PostgreSQL version %s.",
808  PG_MAJORVERSION);
809 
810  /*
811  * We can't allow downgrading because we use the target pg_dump, and
812  * pg_dump cannot operate on newer database versions, only current and
813  * older versions.
814  */
816  pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.");
817 
818  /* Ensure binaries match the designated data directories */
821  pg_fatal("Old cluster data and binary directories are from different major versions.");
824  pg_fatal("New cluster data and binary directories are from different major versions.");
825 
826  check_ok();
827 }
#define Assert(condition)
Definition: c.h:858
static void check_ok(void)
Definition: initdb.c:2036
void prep_status(const char *fmt,...) pg_attribute_printf(1
uint32 bin_version
Definition: pg_upgrade.h:295

References Assert, ClusterInfo::bin_version, check_ok(), GET_MAJOR_VERSION, ClusterInfo::major_version, new_cluster, old_cluster, pg_fatal, and prep_status().

Referenced by main().

◆ check_for_data_types_usage()

static void check_for_data_types_usage ( ClusterInfo cluster,
DataTypesUsageChecks checks 
)
static

Definition at line 337 of file check.c.

338 {
339  bool found = false;
340  bool *results;
341  PQExpBufferData report;
342  DataTypesUsageChecks *tmp = checks;
343  int n_data_types_usage_checks = 0;
344 
345  prep_status("Checking for data type usage");
346 
347  /* Gather number of checks to perform */
348  while (tmp->status != NULL)
349  {
350  n_data_types_usage_checks++;
351  tmp++;
352  }
353 
354  /* Prepare an array to store the results of checks in */
355  results = pg_malloc0(sizeof(bool) * n_data_types_usage_checks);
356 
357  /*
358  * Connect to each database in the cluster and run all defined checks
359  * against that database before trying the next one.
360  */
361  for (int dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
362  {
363  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
364  PGconn *conn = connectToServer(cluster, active_db->db_name);
365 
366  for (int checknum = 0; checknum < n_data_types_usage_checks; checknum++)
367  {
368  PGresult *res;
369  int ntups;
370  int i_nspname;
371  int i_relname;
372  int i_attname;
373  FILE *script = NULL;
374  bool db_used = false;
375  char output_path[MAXPGPATH];
376  DataTypesUsageChecks *cur_check = &checks[checknum];
377 
378  if (cur_check->threshold_version == MANUAL_CHECK)
379  {
380  Assert(cur_check->version_hook);
381 
382  /*
383  * Make sure that the check applies to the current cluster
384  * version and skip if not. If no check hook has been defined
385  * we run the check for all versions.
386  */
387  if (!cur_check->version_hook(cluster))
388  continue;
389  }
390  else if (cur_check->threshold_version != ALL_VERSIONS)
391  {
392  if (GET_MAJOR_VERSION(cluster->major_version) > cur_check->threshold_version)
393  continue;
394  }
395  else
396  Assert(cur_check->threshold_version == ALL_VERSIONS);
397 
398  snprintf(output_path, sizeof(output_path), "%s/%s",
400  cur_check->report_filename);
401 
402  /*
403  * The type(s) of interest might be wrapped in a domain, array,
404  * composite, or range, and these container types can be nested
405  * (to varying extents depending on server version, but that's not
406  * of concern here). To handle all these cases we need a
407  * recursive CTE.
408  */
410  "WITH RECURSIVE oids AS ( "
411  /* start with the type(s) returned by base_query */
412  " %s "
413  " UNION ALL "
414  " SELECT * FROM ( "
415  /* inner WITH because we can only reference the CTE once */
416  " WITH x AS (SELECT oid FROM oids) "
417  /* domains on any type selected so far */
418  " SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typbasetype = x.oid AND typtype = 'd' "
419  " UNION ALL "
420  /* arrays over any type selected so far */
421  " SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typelem = x.oid AND typtype = 'b' "
422  " UNION ALL "
423  /* composite types containing any type selected so far */
424  " SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_class c, pg_catalog.pg_attribute a, x "
425  " WHERE t.typtype = 'c' AND "
426  " t.oid = c.reltype AND "
427  " c.oid = a.attrelid AND "
428  " NOT a.attisdropped AND "
429  " a.atttypid = x.oid "
430  " UNION ALL "
431  /* ranges containing any type selected so far */
432  " SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_range r, x "
433  " WHERE t.typtype = 'r' AND r.rngtypid = t.oid AND r.rngsubtype = x.oid"
434  " ) foo "
435  ") "
436  /* now look for stored columns of any such type */
437  "SELECT n.nspname, c.relname, a.attname "
438  "FROM pg_catalog.pg_class c, "
439  " pg_catalog.pg_namespace n, "
440  " pg_catalog.pg_attribute a "
441  "WHERE c.oid = a.attrelid AND "
442  " NOT a.attisdropped AND "
443  " a.atttypid IN (SELECT oid FROM oids) AND "
444  " c.relkind IN ("
445  CppAsString2(RELKIND_RELATION) ", "
446  CppAsString2(RELKIND_MATVIEW) ", "
447  CppAsString2(RELKIND_INDEX) ") AND "
448  " c.relnamespace = n.oid AND "
449  /* exclude possible orphaned temp tables */
450  " n.nspname !~ '^pg_temp_' AND "
451  " n.nspname !~ '^pg_toast_temp_' AND "
452  /* exclude system catalogs, too */
453  " n.nspname NOT IN ('pg_catalog', 'information_schema')",
454  cur_check->base_query);
455 
456  ntups = PQntuples(res);
457 
458  /*
459  * The datatype was found, so extract the data and log to the
460  * requested filename. We need to open the file for appending
461  * since the check might have already found the type in another
462  * database earlier in the loop.
463  */
464  if (ntups)
465  {
466  /*
467  * Make sure we have a buffer to save reports to now that we
468  * found a first failing check.
469  */
470  if (!found)
471  initPQExpBuffer(&report);
472  found = true;
473 
474  /*
475  * If this is the first time we see an error for the check in
476  * question then print a status message of the failure.
477  */
478  if (!results[checknum])
479  {
480  pg_log(PG_REPORT, " failed check: %s", _(cur_check->status));
481  appendPQExpBuffer(&report, "\n%s\n%s %s\n",
482  _(cur_check->report_text),
483  _("A list of the problem columns is in the file:"),
484  output_path);
485  }
486  results[checknum] = true;
487 
488  i_nspname = PQfnumber(res, "nspname");
489  i_relname = PQfnumber(res, "relname");
490  i_attname = PQfnumber(res, "attname");
491 
492  for (int rowno = 0; rowno < ntups; rowno++)
493  {
494  if (script == NULL && (script = fopen_priv(output_path, "a")) == NULL)
495  pg_fatal("could not open file \"%s\": %m", output_path);
496 
497  if (!db_used)
498  {
499  fprintf(script, "In database: %s\n", active_db->db_name);
500  db_used = true;
501  }
502  fprintf(script, " %s.%s.%s\n",
503  PQgetvalue(res, rowno, i_nspname),
504  PQgetvalue(res, rowno, i_relname),
505  PQgetvalue(res, rowno, i_attname));
506  }
507 
508  if (script)
509  {
510  fclose(script);
511  script = NULL;
512  }
513  }
514 
515  PQclear(res);
516  }
517 
518  PQfinish(conn);
519  }
520 
521  if (found)
522  pg_fatal("Data type checks failed: %s", report.data);
523 
524  pg_free(results);
525 
526  check_ok();
527 }
#define CppAsString2(x)
Definition: c.h:327
#define ALL_VERSIONS
Definition: check.c:62
#define MANUAL_CHECK
Definition: check.c:61
void cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:108
#define _(x)
Definition: elog.c:90
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4892
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3481
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3876
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3589
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#define MAXPGPATH
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
LogOpts log_opts
Definition: util.c:17
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:419
@ PG_REPORT
Definition: pg_upgrade.h:269
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:28
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define snprintf
Definition: port.h:238
#define fprintf
Definition: port.h:242
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
PGconn * conn
Definition: streamutil.c:55
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
char * db_name
Definition: pg_upgrade.h:194
char * basedir
Definition: pg_upgrade.h:311

References _, ALL_VERSIONS, appendPQExpBuffer(), Assert, DataTypesUsageChecks::base_query, LogOpts::basedir, check_ok(), cluster(), conn, connectToServer(), CppAsString2, PQExpBufferData::data, DbInfo::db_name, executeQueryOrDie(), fopen_priv, fprintf, GET_MAJOR_VERSION, initPQExpBuffer(), log_opts, MANUAL_CHECK, MAXPGPATH, pg_fatal, pg_free(), pg_log(), pg_malloc0(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), DataTypesUsageChecks::report_filename, DataTypesUsageChecks::report_text, res, snprintf, DataTypesUsageChecks::status, DataTypesUsageChecks::threshold_version, and DataTypesUsageChecks::version_hook.

Referenced by check_and_dump_old_cluster().

◆ check_for_incompatible_polymorphics()

static void check_for_incompatible_polymorphics ( ClusterInfo cluster)
static

Definition at line 1385 of file check.c.

1386 {
1387  PGresult *res;
1388  FILE *script = NULL;
1389  char output_path[MAXPGPATH];
1390  PQExpBufferData old_polymorphics;
1391 
1392  prep_status("Checking for incompatible polymorphic functions");
1393 
1394  snprintf(output_path, sizeof(output_path), "%s/%s",
1395  log_opts.basedir,
1396  "incompatible_polymorphics.txt");
1397 
1398  /* The set of problematic functions varies a bit in different versions */
1399  initPQExpBuffer(&old_polymorphics);
1400 
1401  appendPQExpBufferStr(&old_polymorphics,
1402  "'array_append(anyarray,anyelement)'"
1403  ", 'array_cat(anyarray,anyarray)'"
1404  ", 'array_prepend(anyelement,anyarray)'");
1405 
1406  if (GET_MAJOR_VERSION(cluster->major_version) >= 903)
1407  appendPQExpBufferStr(&old_polymorphics,
1408  ", 'array_remove(anyarray,anyelement)'"
1409  ", 'array_replace(anyarray,anyelement,anyelement)'");
1410 
1411  if (GET_MAJOR_VERSION(cluster->major_version) >= 905)
1412  appendPQExpBufferStr(&old_polymorphics,
1413  ", 'array_position(anyarray,anyelement)'"
1414  ", 'array_position(anyarray,anyelement,integer)'"
1415  ", 'array_positions(anyarray,anyelement)'"
1416  ", 'width_bucket(anyelement,anyarray)'");
1417 
1418  for (int dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1419  {
1420  bool db_used = false;
1421  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1422  PGconn *conn = connectToServer(cluster, active_db->db_name);
1423  int ntups;
1424  int i_objkind,
1425  i_objname;
1426 
1427  /*
1428  * The query below hardcodes FirstNormalObjectId as 16384 rather than
1429  * interpolating that C #define into the query because, if that
1430  * #define is ever changed, the cutoff we want to use is the value
1431  * used by pre-version 14 servers, not that of some future version.
1432  */
1434  /* Aggregate transition functions */
1435  "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
1436  "FROM pg_proc AS p "
1437  "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
1438  "JOIN pg_proc AS transfn ON transfn.oid=a.aggtransfn "
1439  "WHERE p.oid >= 16384 "
1440  "AND a.aggtransfn = ANY(ARRAY[%s]::regprocedure[]) "
1441  "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
1442 
1443  /* Aggregate final functions */
1444  "UNION ALL "
1445  "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
1446  "FROM pg_proc AS p "
1447  "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
1448  "JOIN pg_proc AS finalfn ON finalfn.oid=a.aggfinalfn "
1449  "WHERE p.oid >= 16384 "
1450  "AND a.aggfinalfn = ANY(ARRAY[%s]::regprocedure[]) "
1451  "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
1452 
1453  /* Operators */
1454  "UNION ALL "
1455  "SELECT 'operator' AS objkind, op.oid::regoperator::text AS objname "
1456  "FROM pg_operator AS op "
1457  "WHERE op.oid >= 16384 "
1458  "AND oprcode = ANY(ARRAY[%s]::regprocedure[]) "
1459  "AND oprleft = ANY(ARRAY['anyarray', 'anyelement']::regtype[]);",
1460  old_polymorphics.data,
1461  old_polymorphics.data,
1462  old_polymorphics.data);
1463 
1464  ntups = PQntuples(res);
1465 
1466  i_objkind = PQfnumber(res, "objkind");
1467  i_objname = PQfnumber(res, "objname");
1468 
1469  for (int rowno = 0; rowno < ntups; rowno++)
1470  {
1471  if (script == NULL &&
1472  (script = fopen_priv(output_path, "w")) == NULL)
1473  pg_fatal("could not open file \"%s\": %m", output_path);
1474  if (!db_used)
1475  {
1476  fprintf(script, "In database: %s\n", active_db->db_name);
1477  db_used = true;
1478  }
1479 
1480  fprintf(script, " %s: %s\n",
1481  PQgetvalue(res, rowno, i_objkind),
1482  PQgetvalue(res, rowno, i_objname));
1483  }
1484 
1485  PQclear(res);
1486  PQfinish(conn);
1487  }
1488 
1489  if (script)
1490  {
1491  fclose(script);
1492  pg_log(PG_REPORT, "fatal");
1493  pg_fatal("Your installation contains user-defined objects that refer to internal\n"
1494  "polymorphic functions with arguments of type \"anyarray\" or \"anyelement\".\n"
1495  "These user-defined objects must be dropped before upgrading and restored\n"
1496  "afterwards, changing them to refer to the new corresponding functions with\n"
1497  "arguments of type \"anycompatiblearray\" and \"anycompatible\".\n"
1498  "A list of the problematic objects is in the file:\n"
1499  " %s", output_path);
1500  }
1501  else
1502  check_ok();
1503 
1504  termPQExpBuffer(&old_polymorphics);
1505 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129

References appendPQExpBufferStr(), LogOpts::basedir, check_ok(), cluster(), conn, connectToServer(), PQExpBufferData::data, DbInfo::db_name, executeQueryOrDie(), fopen_priv, fprintf, GET_MAJOR_VERSION, initPQExpBuffer(), log_opts, MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), res, snprintf, and termPQExpBuffer().

Referenced by check_and_dump_old_cluster().

◆ check_for_isn_and_int8_passing_mismatch()

static void check_for_isn_and_int8_passing_mismatch ( ClusterInfo cluster)
static

Definition at line 1206 of file check.c.

1207 {
1208  int dbnum;
1209  FILE *script = NULL;
1210  char output_path[MAXPGPATH];
1211 
1212  prep_status("Checking for contrib/isn with bigint-passing mismatch");
1213 
1216  {
1217  /* no mismatch */
1218  check_ok();
1219  return;
1220  }
1221 
1222  snprintf(output_path, sizeof(output_path), "%s/%s",
1223  log_opts.basedir,
1224  "contrib_isn_and_int8_pass_by_value.txt");
1225 
1226  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1227  {
1228  PGresult *res;
1229  bool db_used = false;
1230  int ntups;
1231  int rowno;
1232  int i_nspname,
1233  i_proname;
1234  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1235  PGconn *conn = connectToServer(cluster, active_db->db_name);
1236 
1237  /* Find any functions coming from contrib/isn */
1239  "SELECT n.nspname, p.proname "
1240  "FROM pg_catalog.pg_proc p, "
1241  " pg_catalog.pg_namespace n "
1242  "WHERE p.pronamespace = n.oid AND "
1243  " p.probin = '$libdir/isn'");
1244 
1245  ntups = PQntuples(res);
1246  i_nspname = PQfnumber(res, "nspname");
1247  i_proname = PQfnumber(res, "proname");
1248  for (rowno = 0; rowno < ntups; rowno++)
1249  {
1250  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1251  pg_fatal("could not open file \"%s\": %m", output_path);
1252  if (!db_used)
1253  {
1254  fprintf(script, "In database: %s\n", active_db->db_name);
1255  db_used = true;
1256  }
1257  fprintf(script, " %s.%s\n",
1258  PQgetvalue(res, rowno, i_nspname),
1259  PQgetvalue(res, rowno, i_proname));
1260  }
1261 
1262  PQclear(res);
1263 
1264  PQfinish(conn);
1265  }
1266 
1267  if (script)
1268  {
1269  fclose(script);
1270  pg_log(PG_REPORT, "fatal");
1271  pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
1272  "bigint data type. Your old and new clusters pass bigint values\n"
1273  "differently so this cluster cannot currently be upgraded. You can\n"
1274  "manually dump databases in the old cluster that use \"contrib/isn\"\n"
1275  "facilities, drop them, perform the upgrade, and then restore them. A\n"
1276  "list of the problem functions is in the file:\n"
1277  " %s", output_path);
1278  }
1279  else
1280  check_ok();
1281 }
bool float8_pass_by_value
Definition: pg_upgrade.h:246

References LogOpts::basedir, check_ok(), cluster(), conn, connectToServer(), ClusterInfo::controldata, DbInfo::db_name, executeQueryOrDie(), ControlData::float8_pass_by_value, fopen_priv, fprintf, log_opts, MAXPGPATH, new_cluster, old_cluster, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), res, and snprintf.

Referenced by check_and_dump_old_cluster().

◆ check_for_new_tablespace_dir()

static void check_for_new_tablespace_dir ( void  )
static

Definition at line 877 of file check.c.

878 {
879  int tblnum;
880  char new_tablespace_dir[MAXPGPATH];
881 
882  prep_status("Checking for new cluster tablespace directories");
883 
884  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
885  {
886  struct stat statbuf;
887 
888  snprintf(new_tablespace_dir, MAXPGPATH, "%s%s",
889  os_info.old_tablespaces[tblnum],
891 
892  if (stat(new_tablespace_dir, &statbuf) == 0 || errno != ENOENT)
893  pg_fatal("new cluster tablespace directory already exists: \"%s\"",
894  new_tablespace_dir);
895  }
896 
897  check_ok();
898 }
OSInfo os_info
Definition: pg_upgrade.c:73
const char * tablespace_suffix
Definition: pg_upgrade.h:296
int num_old_tablespaces
Definition: pg_upgrade.h:347
char ** old_tablespaces
Definition: pg_upgrade.h:346
#define stat
Definition: win32_port.h:284

References check_ok(), MAXPGPATH, new_cluster, OSInfo::num_old_tablespaces, OSInfo::old_tablespaces, os_info, pg_fatal, prep_status(), snprintf, stat, and ClusterInfo::tablespace_suffix.

Referenced by check_new_cluster().

◆ check_for_pg_role_prefix()

static void check_for_pg_role_prefix ( ClusterInfo cluster)
static

Definition at line 1586 of file check.c.

1587 {
1588  PGresult *res;
1589  PGconn *conn = connectToServer(cluster, "template1");
1590  int ntups;
1591  int i_roloid;
1592  int i_rolname;
1593  FILE *script = NULL;
1594  char output_path[MAXPGPATH];
1595 
1596  prep_status("Checking for roles starting with \"pg_\"");
1597 
1598  snprintf(output_path, sizeof(output_path), "%s/%s",
1599  log_opts.basedir,
1600  "pg_role_prefix.txt");
1601 
1603  "SELECT oid AS roloid, rolname "
1604  "FROM pg_catalog.pg_roles "
1605  "WHERE rolname ~ '^pg_'");
1606 
1607  ntups = PQntuples(res);
1608  i_roloid = PQfnumber(res, "roloid");
1609  i_rolname = PQfnumber(res, "rolname");
1610  for (int rowno = 0; rowno < ntups; rowno++)
1611  {
1612  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1613  pg_fatal("could not open file \"%s\": %m", output_path);
1614  fprintf(script, "%s (oid=%s)\n",
1615  PQgetvalue(res, rowno, i_rolname),
1616  PQgetvalue(res, rowno, i_roloid));
1617  }
1618 
1619  PQclear(res);
1620 
1621  PQfinish(conn);
1622 
1623  if (script)
1624  {
1625  fclose(script);
1626  pg_log(PG_REPORT, "fatal");
1627  pg_fatal("Your installation contains roles starting with \"pg_\".\n"
1628  "\"pg_\" is a reserved prefix for system roles. The cluster\n"
1629  "cannot be upgraded until these roles are renamed.\n"
1630  "A list of roles starting with \"pg_\" is in the file:\n"
1631  " %s", output_path);
1632  }
1633  else
1634  check_ok();
1635 }

References LogOpts::basedir, check_ok(), cluster(), conn, connectToServer(), executeQueryOrDie(), fopen_priv, fprintf, log_opts, MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), res, and snprintf.

Referenced by check_and_dump_old_cluster().

◆ check_for_prepared_transactions()

static void check_for_prepared_transactions ( ClusterInfo cluster)
static

Definition at line 1171 of file check.c.

1172 {
1173  PGresult *res;
1174  PGconn *conn = connectToServer(cluster, "template1");
1175 
1176  prep_status("Checking for prepared transactions");
1177 
1179  "SELECT * "
1180  "FROM pg_catalog.pg_prepared_xacts");
1181 
1182  if (PQntuples(res) != 0)
1183  {
1184  if (cluster == &old_cluster)
1185  pg_fatal("The source cluster contains prepared transactions");
1186  else
1187  pg_fatal("The target cluster contains prepared transactions");
1188  }
1189 
1190  PQclear(res);
1191 
1192  PQfinish(conn);
1193 
1194  check_ok();
1195 }

References check_ok(), cluster(), conn, connectToServer(), executeQueryOrDie(), old_cluster, pg_fatal, PQclear(), PQfinish(), PQntuples(), prep_status(), and res.

Referenced by check_and_dump_old_cluster(), and check_new_cluster().

◆ check_for_tables_with_oids()

static void check_for_tables_with_oids ( ClusterInfo cluster)
static

Definition at line 1511 of file check.c.

1512 {
1513  int dbnum;
1514  FILE *script = NULL;
1515  char output_path[MAXPGPATH];
1516 
1517  prep_status("Checking for tables WITH OIDS");
1518 
1519  snprintf(output_path, sizeof(output_path), "%s/%s",
1520  log_opts.basedir,
1521  "tables_with_oids.txt");
1522 
1523  /* Find any tables declared WITH OIDS */
1524  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1525  {
1526  PGresult *res;
1527  bool db_used = false;
1528  int ntups;
1529  int rowno;
1530  int i_nspname,
1531  i_relname;
1532  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1533  PGconn *conn = connectToServer(cluster, active_db->db_name);
1534 
1536  "SELECT n.nspname, c.relname "
1537  "FROM pg_catalog.pg_class c, "
1538  " pg_catalog.pg_namespace n "
1539  "WHERE c.relnamespace = n.oid AND "
1540  " c.relhasoids AND"
1541  " n.nspname NOT IN ('pg_catalog')");
1542 
1543  ntups = PQntuples(res);
1544  i_nspname = PQfnumber(res, "nspname");
1545  i_relname = PQfnumber(res, "relname");
1546  for (rowno = 0; rowno < ntups; rowno++)
1547  {
1548  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1549  pg_fatal("could not open file \"%s\": %m", output_path);
1550  if (!db_used)
1551  {
1552  fprintf(script, "In database: %s\n", active_db->db_name);
1553  db_used = true;
1554  }
1555  fprintf(script, " %s.%s\n",
1556  PQgetvalue(res, rowno, i_nspname),
1557  PQgetvalue(res, rowno, i_relname));
1558  }
1559 
1560  PQclear(res);
1561 
1562  PQfinish(conn);
1563  }
1564 
1565  if (script)
1566  {
1567  fclose(script);
1568  pg_log(PG_REPORT, "fatal");
1569  pg_fatal("Your installation contains tables declared WITH OIDS, which is not\n"
1570  "supported anymore. Consider removing the oid column using\n"
1571  " ALTER TABLE ... SET WITHOUT OIDS;\n"
1572  "A list of tables with the problem is in the file:\n"
1573  " %s", output_path);
1574  }
1575  else
1576  check_ok();
1577 }

References LogOpts::basedir, check_ok(), cluster(), conn, connectToServer(), DbInfo::db_name, executeQueryOrDie(), fopen_priv, fprintf, log_opts, MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), res, and snprintf.

Referenced by check_and_dump_old_cluster().

◆ check_for_user_defined_encoding_conversions()

static void check_for_user_defined_encoding_conversions ( ClusterInfo cluster)
static

Definition at line 1641 of file check.c.

1642 {
1643  int dbnum;
1644  FILE *script = NULL;
1645  char output_path[MAXPGPATH];
1646 
1647  prep_status("Checking for user-defined encoding conversions");
1648 
1649  snprintf(output_path, sizeof(output_path), "%s/%s",
1650  log_opts.basedir,
1651  "encoding_conversions.txt");
1652 
1653  /* Find any user defined encoding conversions */
1654  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1655  {
1656  PGresult *res;
1657  bool db_used = false;
1658  int ntups;
1659  int rowno;
1660  int i_conoid,
1661  i_conname,
1662  i_nspname;
1663  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1664  PGconn *conn = connectToServer(cluster, active_db->db_name);
1665 
1666  /*
1667  * The query below hardcodes FirstNormalObjectId as 16384 rather than
1668  * interpolating that C #define into the query because, if that
1669  * #define is ever changed, the cutoff we want to use is the value
1670  * used by pre-version 14 servers, not that of some future version.
1671  */
1673  "SELECT c.oid as conoid, c.conname, n.nspname "
1674  "FROM pg_catalog.pg_conversion c, "
1675  " pg_catalog.pg_namespace n "
1676  "WHERE c.connamespace = n.oid AND "
1677  " c.oid >= 16384");
1678  ntups = PQntuples(res);
1679  i_conoid = PQfnumber(res, "conoid");
1680  i_conname = PQfnumber(res, "conname");
1681  i_nspname = PQfnumber(res, "nspname");
1682  for (rowno = 0; rowno < ntups; rowno++)
1683  {
1684  if (script == NULL &&
1685  (script = fopen_priv(output_path, "w")) == NULL)
1686  pg_fatal("could not open file \"%s\": %m", output_path);
1687  if (!db_used)
1688  {
1689  fprintf(script, "In database: %s\n", active_db->db_name);
1690  db_used = true;
1691  }
1692  fprintf(script, " (oid=%s) %s.%s\n",
1693  PQgetvalue(res, rowno, i_conoid),
1694  PQgetvalue(res, rowno, i_nspname),
1695  PQgetvalue(res, rowno, i_conname));
1696  }
1697 
1698  PQclear(res);
1699 
1700  PQfinish(conn);
1701  }
1702 
1703  if (script)
1704  {
1705  fclose(script);
1706  pg_log(PG_REPORT, "fatal");
1707  pg_fatal("Your installation contains user-defined encoding conversions.\n"
1708  "The conversion function parameters changed in PostgreSQL version 14\n"
1709  "so this cluster cannot currently be upgraded. You can remove the\n"
1710  "encoding conversions in the old cluster and restart the upgrade.\n"
1711  "A list of user-defined encoding conversions is in the file:\n"
1712  " %s", output_path);
1713  }
1714  else
1715  check_ok();
1716 }

References LogOpts::basedir, check_ok(), cluster(), conn, connectToServer(), DbInfo::db_name, executeQueryOrDie(), fopen_priv, fprintf, log_opts, MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), res, and snprintf.

Referenced by check_and_dump_old_cluster().

◆ check_for_user_defined_postfix_ops()

static void check_for_user_defined_postfix_ops ( ClusterInfo cluster)
static

Definition at line 1287 of file check.c.

1288 {
1289  int dbnum;
1290  FILE *script = NULL;
1291  char output_path[MAXPGPATH];
1292 
1293  prep_status("Checking for user-defined postfix operators");
1294 
1295  snprintf(output_path, sizeof(output_path), "%s/%s",
1296  log_opts.basedir,
1297  "postfix_ops.txt");
1298 
1299  /* Find any user defined postfix operators */
1300  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1301  {
1302  PGresult *res;
1303  bool db_used = false;
1304  int ntups;
1305  int rowno;
1306  int i_oproid,
1307  i_oprnsp,
1308  i_oprname,
1309  i_typnsp,
1310  i_typname;
1311  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1312  PGconn *conn = connectToServer(cluster, active_db->db_name);
1313 
1314  /*
1315  * The query below hardcodes FirstNormalObjectId as 16384 rather than
1316  * interpolating that C #define into the query because, if that
1317  * #define is ever changed, the cutoff we want to use is the value
1318  * used by pre-version 14 servers, not that of some future version.
1319  */
1321  "SELECT o.oid AS oproid, "
1322  " n.nspname AS oprnsp, "
1323  " o.oprname, "
1324  " tn.nspname AS typnsp, "
1325  " t.typname "
1326  "FROM pg_catalog.pg_operator o, "
1327  " pg_catalog.pg_namespace n, "
1328  " pg_catalog.pg_type t, "
1329  " pg_catalog.pg_namespace tn "
1330  "WHERE o.oprnamespace = n.oid AND "
1331  " o.oprleft = t.oid AND "
1332  " t.typnamespace = tn.oid AND "
1333  " o.oprright = 0 AND "
1334  " o.oid >= 16384");
1335  ntups = PQntuples(res);
1336  i_oproid = PQfnumber(res, "oproid");
1337  i_oprnsp = PQfnumber(res, "oprnsp");
1338  i_oprname = PQfnumber(res, "oprname");
1339  i_typnsp = PQfnumber(res, "typnsp");
1340  i_typname = PQfnumber(res, "typname");
1341  for (rowno = 0; rowno < ntups; rowno++)
1342  {
1343  if (script == NULL &&
1344  (script = fopen_priv(output_path, "w")) == NULL)
1345  pg_fatal("could not open file \"%s\": %m", output_path);
1346  if (!db_used)
1347  {
1348  fprintf(script, "In database: %s\n", active_db->db_name);
1349  db_used = true;
1350  }
1351  fprintf(script, " (oid=%s) %s.%s (%s.%s, NONE)\n",
1352  PQgetvalue(res, rowno, i_oproid),
1353  PQgetvalue(res, rowno, i_oprnsp),
1354  PQgetvalue(res, rowno, i_oprname),
1355  PQgetvalue(res, rowno, i_typnsp),
1356  PQgetvalue(res, rowno, i_typname));
1357  }
1358 
1359  PQclear(res);
1360 
1361  PQfinish(conn);
1362  }
1363 
1364  if (script)
1365  {
1366  fclose(script);
1367  pg_log(PG_REPORT, "fatal");
1368  pg_fatal("Your installation contains user-defined postfix operators, which are not\n"
1369  "supported anymore. Consider dropping the postfix operators and replacing\n"
1370  "them with prefix operators or function calls.\n"
1371  "A list of user-defined postfix operators is in the file:\n"
1372  " %s", output_path);
1373  }
1374  else
1375  check_ok();
1376 }

References LogOpts::basedir, check_ok(), cluster(), conn, connectToServer(), DbInfo::db_name, executeQueryOrDie(), fopen_priv, fprintf, log_opts, MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), res, and snprintf.

Referenced by check_and_dump_old_cluster().

◆ check_is_install_user()

static void check_is_install_user ( ClusterInfo cluster)
static

Definition at line 1029 of file check.c.

1030 {
1031  PGresult *res;
1032  PGconn *conn = connectToServer(cluster, "template1");
1033 
1034  prep_status("Checking database user is the install user");
1035 
1036  /* Can't use pg_authid because only superusers can view it. */
1038  "SELECT rolsuper, oid "
1039  "FROM pg_catalog.pg_roles "
1040  "WHERE rolname = current_user "
1041  "AND rolname !~ '^pg_'");
1042 
1043  /*
1044  * We only allow the install user in the new cluster (see comment below)
1045  * and we preserve pg_authid.oid, so this must be the install user in the
1046  * old cluster too.
1047  */
1048  if (PQntuples(res) != 1 ||
1049  atooid(PQgetvalue(res, 0, 1)) != BOOTSTRAP_SUPERUSERID)
1050  pg_fatal("database user \"%s\" is not the install user",
1051  os_info.user);
1052 
1053  PQclear(res);
1054 
1056  "SELECT COUNT(*) "
1057  "FROM pg_catalog.pg_roles "
1058  "WHERE rolname !~ '^pg_'");
1059 
1060  if (PQntuples(res) != 1)
1061  pg_fatal("could not determine the number of users");
1062 
1063  /*
1064  * We only allow the install user in the new cluster because other defined
1065  * users might match users defined in the old cluster and generate an
1066  * error during pg_dump restore.
1067  */
1068  if (cluster == &new_cluster && strcmp(PQgetvalue(res, 0, 0), "1") != 0)
1069  pg_fatal("Only the install user can be defined in the new cluster.");
1070 
1071  PQclear(res);
1072 
1073  PQfinish(conn);
1074 
1075  check_ok();
1076 }
#define atooid(x)
Definition: postgres_ext.h:42
char * user
Definition: pg_upgrade.h:344

References atooid, check_ok(), cluster(), conn, connectToServer(), executeQueryOrDie(), new_cluster, os_info, pg_fatal, PQclear(), PQfinish(), PQgetvalue(), PQntuples(), prep_status(), res, and OSInfo::user.

Referenced by check_and_dump_old_cluster(), and check_new_cluster().

◆ check_new_cluster()

void check_new_cluster ( void  )

Definition at line 678 of file check.c.

679 {
681 
683 
685 
686  switch (user_opts.transfer_mode)
687  {
688  case TRANSFER_MODE_CLONE:
690  break;
691  case TRANSFER_MODE_COPY:
692  break;
695  break;
696  case TRANSFER_MODE_LINK:
697  check_hard_link();
698  break;
699  }
700 
702 
704 
706 
708 
710 }
static void check_new_cluster_logical_replication_slots(void)
Definition: check.c:1725
static void check_new_cluster_subscription_configuration(void)
Definition: check.c:1798
static void check_new_cluster_is_empty(void)
Definition: check.c:845
static void check_for_new_tablespace_dir(void)
Definition: check.c:877
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
@ 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
transferMode transfer_mode
Definition: pg_upgrade.h:326

References check_copy_file_range(), check_file_clone(), check_for_new_tablespace_dir(), check_for_prepared_transactions(), check_hard_link(), check_is_install_user(), check_loadable_libraries(), check_new_cluster_is_empty(), check_new_cluster_logical_replication_slots(), check_new_cluster_subscription_configuration(), get_db_rel_and_slot_infos(), new_cluster, UserOpts::transfer_mode, TRANSFER_MODE_CLONE, TRANSFER_MODE_COPY, TRANSFER_MODE_COPY_FILE_RANGE, TRANSFER_MODE_LINK, and user_opts.

Referenced by main().

◆ check_new_cluster_is_empty()

static void check_new_cluster_is_empty ( void  )
static

Definition at line 845 of file check.c.

846 {
847  int dbnum;
848 
849  for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
850  {
851  int relnum;
852  RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
853 
854  for (relnum = 0; relnum < rel_arr->nrels;
855  relnum++)
856  {
857  /* pg_largeobject and its index should be skipped */
858  if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
859  pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"",
860  new_cluster.dbarr.dbs[dbnum].db_name,
861  rel_arr->rels[relnum].nspname,
862  rel_arr->rels[relnum].relname);
863  }
864  }
865 }
DbInfoArr dbarr
Definition: pg_upgrade.h:284
DbInfo * dbs
Definition: pg_upgrade.h:215
RelInfoArr rel_arr
Definition: pg_upgrade.h:197
RelInfo * rels
Definition: pg_upgrade.h:148
char * nspname
Definition: pg_upgrade.h:135
char * relname
Definition: pg_upgrade.h:136

References DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, DbInfoArr::ndbs, new_cluster, RelInfoArr::nrels, RelInfo::nspname, pg_fatal, DbInfo::rel_arr, RelInfo::relname, and RelInfoArr::rels.

Referenced by check_new_cluster().

◆ check_new_cluster_logical_replication_slots()

static void check_new_cluster_logical_replication_slots ( void  )
static

Definition at line 1725 of file check.c.

1726 {
1727  PGresult *res;
1728  PGconn *conn;
1729  int nslots_on_old;
1730  int nslots_on_new;
1732  char *wal_level;
1733 
1734  /* Logical slots can be migrated since PG17. */
1736  return;
1737 
1738  nslots_on_old = count_old_cluster_logical_slots();
1739 
1740  /* Quick return if there are no logical slots to be migrated. */
1741  if (nslots_on_old == 0)
1742  return;
1743 
1744  conn = connectToServer(&new_cluster, "template1");
1745 
1746  prep_status("Checking for new cluster logical replication slots");
1747 
1748  res = executeQueryOrDie(conn, "SELECT count(*) "
1749  "FROM pg_catalog.pg_replication_slots "
1750  "WHERE slot_type = 'logical' AND "
1751  "temporary IS FALSE;");
1752 
1753  if (PQntuples(res) != 1)
1754  pg_fatal("could not count the number of logical replication slots");
1755 
1756  nslots_on_new = atoi(PQgetvalue(res, 0, 0));
1757 
1758  if (nslots_on_new)
1759  pg_fatal("Expected 0 logical replication slots but found %d.",
1760  nslots_on_new);
1761 
1762  PQclear(res);
1763 
1764  res = executeQueryOrDie(conn, "SELECT setting FROM pg_settings "
1765  "WHERE name IN ('wal_level', 'max_replication_slots') "
1766  "ORDER BY name DESC;");
1767 
1768  if (PQntuples(res) != 2)
1769  pg_fatal("could not determine parameter settings on new cluster");
1770 
1771  wal_level = PQgetvalue(res, 0, 0);
1772 
1773  if (strcmp(wal_level, "logical") != 0)
1774  pg_fatal("\"wal_level\" must be \"logical\", but is set to \"%s\"",
1775  wal_level);
1776 
1777  max_replication_slots = atoi(PQgetvalue(res, 1, 0));
1778 
1779  if (nslots_on_old > max_replication_slots)
1780  pg_fatal("\"max_replication_slots\" (%d) must be greater than or equal to the number of "
1781  "logical replication slots (%d) on the old cluster",
1782  max_replication_slots, nslots_on_old);
1783 
1784  PQclear(res);
1785  PQfinish(conn);
1786 
1787  check_ok();
1788 }
int count_old_cluster_logical_slots(void)
Definition: info.c:730
int max_replication_slots
Definition: slot.c:141
int wal_level
Definition: xlog.c:129

References check_ok(), conn, connectToServer(), count_old_cluster_logical_slots(), executeQueryOrDie(), GET_MAJOR_VERSION, ClusterInfo::major_version, max_replication_slots, new_cluster, old_cluster, pg_fatal, PQclear(), PQfinish(), PQgetvalue(), PQntuples(), prep_status(), res, and wal_level.

Referenced by check_new_cluster().

◆ check_new_cluster_subscription_configuration()

static void check_new_cluster_subscription_configuration ( void  )
static

Definition at line 1798 of file check.c.

1799 {
1800  PGresult *res;
1801  PGconn *conn;
1803 
1804  /* Subscriptions and their dependencies can be migrated since PG17. */
1806  return;
1807 
1808  /* Quick return if there are no subscriptions to be migrated. */
1809  if (old_cluster.nsubs == 0)
1810  return;
1811 
1812  prep_status("Checking for new cluster configuration for subscriptions");
1813 
1814  conn = connectToServer(&new_cluster, "template1");
1815 
1816  res = executeQueryOrDie(conn, "SELECT setting FROM pg_settings "
1817  "WHERE name = 'max_replication_slots';");
1818 
1819  if (PQntuples(res) != 1)
1820  pg_fatal("could not determine parameter settings on new cluster");
1821 
1822  max_replication_slots = atoi(PQgetvalue(res, 0, 0));
1824  pg_fatal("\"max_replication_slots\" (%d) must be greater than or equal to the number of "
1825  "subscriptions (%d) on the old cluster",
1827 
1828  PQclear(res);
1829  PQfinish(conn);
1830 
1831  check_ok();
1832 }

References check_ok(), conn, connectToServer(), executeQueryOrDie(), GET_MAJOR_VERSION, ClusterInfo::major_version, max_replication_slots, new_cluster, ClusterInfo::nsubs, old_cluster, pg_fatal, PQclear(), PQfinish(), PQgetvalue(), PQntuples(), prep_status(), and res.

Referenced by check_new_cluster().

◆ check_old_cluster_for_valid_slots()

static void check_old_cluster_for_valid_slots ( void  )
static

Definition at line 1841 of file check.c.

1842 {
1843  char output_path[MAXPGPATH];
1844  FILE *script = NULL;
1845 
1846  prep_status("Checking for valid logical replication slots");
1847 
1848  snprintf(output_path, sizeof(output_path), "%s/%s",
1849  log_opts.basedir,
1850  "invalid_logical_slots.txt");
1851 
1852  for (int dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
1853  {
1854  LogicalSlotInfoArr *slot_arr = &old_cluster.dbarr.dbs[dbnum].slot_arr;
1855 
1856  for (int slotnum = 0; slotnum < slot_arr->nslots; slotnum++)
1857  {
1858  LogicalSlotInfo *slot = &slot_arr->slots[slotnum];
1859 
1860  /* Is the slot usable? */
1861  if (slot->invalid)
1862  {
1863  if (script == NULL &&
1864  (script = fopen_priv(output_path, "w")) == NULL)
1865  pg_fatal("could not open file \"%s\": %m", output_path);
1866 
1867  fprintf(script, "The slot \"%s\" is invalid\n",
1868  slot->slotname);
1869 
1870  continue;
1871  }
1872 
1873  /*
1874  * Do additional check to ensure that all logical replication
1875  * slots have consumed all the WAL before shutdown.
1876  *
1877  * Note: This can be satisfied only when the old cluster has been
1878  * shut down, so we skip this for live checks.
1879  */
1880  if (!user_opts.live_check && !slot->caught_up)
1881  {
1882  if (script == NULL &&
1883  (script = fopen_priv(output_path, "w")) == NULL)
1884  pg_fatal("could not open file \"%s\": %m", output_path);
1885 
1886  fprintf(script,
1887  "The slot \"%s\" has not consumed the WAL yet\n",
1888  slot->slotname);
1889  }
1890  }
1891  }
1892 
1893  if (script)
1894  {
1895  fclose(script);
1896 
1897  pg_log(PG_REPORT, "fatal");
1898  pg_fatal("Your installation contains logical replication slots that can't be upgraded.\n"
1899  "You can remove invalid slots and/or consume the pending WAL for other slots,\n"
1900  "and then restart the upgrade.\n"
1901  "A list of the problematic slots is in the file:\n"
1902  " %s", output_path);
1903  }
1904 
1905  check_ok();
1906 }
LogicalSlotInfoArr slot_arr
Definition: pg_upgrade.h:198
LogicalSlotInfo * slots
Definition: pg_upgrade.h:169

References LogOpts::basedir, LogicalSlotInfo::caught_up, check_ok(), ClusterInfo::dbarr, DbInfoArr::dbs, fopen_priv, fprintf, LogicalSlotInfo::invalid, UserOpts::live_check, log_opts, MAXPGPATH, DbInfoArr::ndbs, LogicalSlotInfoArr::nslots, old_cluster, pg_fatal, pg_log(), PG_REPORT, prep_status(), DbInfo::slot_arr, LogicalSlotInfo::slotname, LogicalSlotInfoArr::slots, snprintf, and user_opts.

Referenced by check_and_dump_old_cluster().

◆ check_old_cluster_subscription_state()

static void check_old_cluster_subscription_state ( void  )
static

Definition at line 1916 of file check.c.

1917 {
1918  FILE *script = NULL;
1919  char output_path[MAXPGPATH];
1920  int ntup;
1921 
1922  prep_status("Checking for subscription state");
1923 
1924  snprintf(output_path, sizeof(output_path), "%s/%s",
1925  log_opts.basedir,
1926  "subs_invalid.txt");
1927  for (int dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
1928  {
1929  PGresult *res;
1930  DbInfo *active_db = &old_cluster.dbarr.dbs[dbnum];
1931  PGconn *conn = connectToServer(&old_cluster, active_db->db_name);
1932 
1933  /* We need to check for pg_replication_origin only once. */
1934  if (dbnum == 0)
1935  {
1936  /*
1937  * Check that all the subscriptions have their respective
1938  * replication origin.
1939  */
1941  "SELECT d.datname, s.subname "
1942  "FROM pg_catalog.pg_subscription s "
1943  "LEFT OUTER JOIN pg_catalog.pg_replication_origin o "
1944  " ON o.roname = 'pg_' || s.oid "
1945  "INNER JOIN pg_catalog.pg_database d "
1946  " ON d.oid = s.subdbid "
1947  "WHERE o.roname IS NULL;");
1948 
1949  ntup = PQntuples(res);
1950  for (int i = 0; i < ntup; i++)
1951  {
1952  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1953  pg_fatal("could not open file \"%s\": %m", output_path);
1954  fprintf(script, "The replication origin is missing for database:\"%s\" subscription:\"%s\"\n",
1955  PQgetvalue(res, i, 0),
1956  PQgetvalue(res, i, 1));
1957  }
1958  PQclear(res);
1959  }
1960 
1961  /*
1962  * We don't allow upgrade if there is a risk of dangling slot or
1963  * origin corresponding to initial sync after upgrade.
1964  *
1965  * A slot/origin not created yet refers to the 'i' (initialize) state,
1966  * while 'r' (ready) state refers to a slot/origin created previously
1967  * but already dropped. These states are supported for pg_upgrade. The
1968  * other states listed below are not supported:
1969  *
1970  * a) SUBREL_STATE_DATASYNC: A relation upgraded while in this state
1971  * would retain a replication slot, which could not be dropped by the
1972  * sync worker spawned after the upgrade because the subscription ID
1973  * used for the slot name won't match anymore.
1974  *
1975  * b) SUBREL_STATE_SYNCDONE: A relation upgraded while in this state
1976  * would retain the replication origin when there is a failure in
1977  * tablesync worker immediately after dropping the replication slot in
1978  * the publisher.
1979  *
1980  * c) SUBREL_STATE_FINISHEDCOPY: A tablesync worker spawned to work on
1981  * a relation upgraded while in this state would expect an origin ID
1982  * with the OID of the subscription used before the upgrade, causing
1983  * it to fail.
1984  *
1985  * d) SUBREL_STATE_SYNCWAIT, SUBREL_STATE_CATCHUP and
1986  * SUBREL_STATE_UNKNOWN: These states are not stored in the catalog,
1987  * so we need not allow these states.
1988  */
1990  "SELECT r.srsubstate, s.subname, n.nspname, c.relname "
1991  "FROM pg_catalog.pg_subscription_rel r "
1992  "LEFT JOIN pg_catalog.pg_subscription s"
1993  " ON r.srsubid = s.oid "
1994  "LEFT JOIN pg_catalog.pg_class c"
1995  " ON r.srrelid = c.oid "
1996  "LEFT JOIN pg_catalog.pg_namespace n"
1997  " ON c.relnamespace = n.oid "
1998  "WHERE r.srsubstate NOT IN ('i', 'r') "
1999  "ORDER BY s.subname");
2000 
2001  ntup = PQntuples(res);
2002  for (int i = 0; i < ntup; i++)
2003  {
2004  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
2005  pg_fatal("could not open file \"%s\": %m", output_path);
2006 
2007  fprintf(script, "The table sync state \"%s\" is not allowed for database:\"%s\" subscription:\"%s\" schema:\"%s\" relation:\"%s\"\n",
2008  PQgetvalue(res, i, 0),
2009  active_db->db_name,
2010  PQgetvalue(res, i, 1),
2011  PQgetvalue(res, i, 2),
2012  PQgetvalue(res, i, 3));
2013  }
2014 
2015  PQclear(res);
2016  PQfinish(conn);
2017  }
2018 
2019  if (script)
2020  {
2021  fclose(script);
2022  pg_log(PG_REPORT, "fatal");
2023  pg_fatal("Your installation contains subscriptions without origin or having relations not in i (initialize) or r (ready) state.\n"
2024  "You can allow the initial sync to finish for all relations and then restart the upgrade.\n"
2025  "A list of the problematic subscriptions is in the file:\n"
2026  " %s", output_path);
2027  }
2028  else
2029  check_ok();
2030 }
int i
Definition: isn.c:73

References LogOpts::basedir, check_ok(), conn, connectToServer(), DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), fopen_priv, fprintf, i, log_opts, MAXPGPATH, DbInfoArr::ndbs, old_cluster, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQgetvalue(), PQntuples(), prep_status(), res, and snprintf.

Referenced by check_and_dump_old_cluster().

◆ check_proper_datallowconn()

static void check_proper_datallowconn ( ClusterInfo cluster)
static

Definition at line 1087 of file check.c.

1088 {
1089  int dbnum;
1090  PGconn *conn_template1;
1091  PGresult *dbres;
1092  int ntups;
1093  int i_datname;
1094  int i_datallowconn;
1095  FILE *script = NULL;
1096  char output_path[MAXPGPATH];
1097 
1098  prep_status("Checking database connection settings");
1099 
1100  snprintf(output_path, sizeof(output_path), "%s/%s",
1101  log_opts.basedir,
1102  "databases_with_datallowconn_false.txt");
1103 
1104  conn_template1 = connectToServer(cluster, "template1");
1105 
1106  /* get database names */
1107  dbres = executeQueryOrDie(conn_template1,
1108  "SELECT datname, datallowconn "
1109  "FROM pg_catalog.pg_database");
1110 
1111  i_datname = PQfnumber(dbres, "datname");
1112  i_datallowconn = PQfnumber(dbres, "datallowconn");
1113 
1114  ntups = PQntuples(dbres);
1115  for (dbnum = 0; dbnum < ntups; dbnum++)
1116  {
1117  char *datname = PQgetvalue(dbres, dbnum, i_datname);
1118  char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
1119 
1120  if (strcmp(datname, "template0") == 0)
1121  {
1122  /* avoid restore failure when pg_dumpall tries to create template0 */
1123  if (strcmp(datallowconn, "t") == 0)
1124  pg_fatal("template0 must not allow connections, "
1125  "i.e. its pg_database.datallowconn must be false");
1126  }
1127  else
1128  {
1129  /*
1130  * avoid datallowconn == false databases from being skipped on
1131  * restore
1132  */
1133  if (strcmp(datallowconn, "f") == 0)
1134  {
1135  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1136  pg_fatal("could not open file \"%s\": %m", output_path);
1137 
1138  fprintf(script, "%s\n", datname);
1139  }
1140  }
1141  }
1142 
1143  PQclear(dbres);
1144 
1145  PQfinish(conn_template1);
1146 
1147  if (script)
1148  {
1149  fclose(script);
1150  pg_log(PG_REPORT, "fatal");
1151  pg_fatal("All non-template0 databases must allow connections, i.e. their\n"
1152  "pg_database.datallowconn must be true. Your installation contains\n"
1153  "non-template0 databases with their pg_database.datallowconn set to\n"
1154  "false. Consider allowing connection for all non-template0 databases\n"
1155  "or drop the databases which do not allow connections. A list of\n"
1156  "databases with the problem is in the file:\n"
1157  " %s", output_path);
1158  }
1159  else
1160  check_ok();
1161 }
NameData datname
Definition: pg_database.h:35
bool datallowconn
Definition: pg_database.h:50

References LogOpts::basedir, check_ok(), cluster(), connectToServer(), datallowconn, datname, executeQueryOrDie(), fopen_priv, fprintf, log_opts, MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), and snprintf.

Referenced by check_and_dump_old_cluster().

◆ create_script_for_old_cluster_deletion()

void create_script_for_old_cluster_deletion ( char **  deletion_script_file_name)

Definition at line 906 of file check.c.

907 {
908  FILE *script = NULL;
909  int tblnum;
910  char old_cluster_pgdata[MAXPGPATH],
911  new_cluster_pgdata[MAXPGPATH];
912 
913  *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
915 
916  strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
917  canonicalize_path(old_cluster_pgdata);
918 
919  strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
920  canonicalize_path(new_cluster_pgdata);
921 
922  /* Some people put the new data directory inside the old one. */
923  if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
924  {
926  "\nWARNING: new data directory should not be inside the old data directory, i.e. %s", old_cluster_pgdata);
927 
928  /* Unlink file in case it is left over from a previous run. */
929  unlink(*deletion_script_file_name);
930  pg_free(*deletion_script_file_name);
931  *deletion_script_file_name = NULL;
932  return;
933  }
934 
935  /*
936  * Some users (oddly) create tablespaces inside the cluster data
937  * directory. We can't create a proper old cluster delete script in that
938  * case.
939  */
940  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
941  {
942  char old_tablespace_dir[MAXPGPATH];
943 
944  strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
945  canonicalize_path(old_tablespace_dir);
946  if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
947  {
948  /* reproduce warning from CREATE TABLESPACE that is in the log */
950  "\nWARNING: user-defined tablespace locations should not be inside the data directory, i.e. %s", old_tablespace_dir);
951 
952  /* Unlink file in case it is left over from a previous run. */
953  unlink(*deletion_script_file_name);
954  pg_free(*deletion_script_file_name);
955  *deletion_script_file_name = NULL;
956  return;
957  }
958  }
959 
960  prep_status("Creating script to delete old cluster");
961 
962  if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
963  pg_fatal("could not open file \"%s\": %m",
964  *deletion_script_file_name);
965 
966 #ifndef WIN32
967  /* add shebang header */
968  fprintf(script, "#!/bin/sh\n\n");
969 #endif
970 
971  /* delete old cluster's default tablespace */
972  fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
974 
975  /* delete old cluster's alternate tablespaces */
976  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
977  {
978  /*
979  * Do the old cluster's per-database directories share a directory
980  * with a new version-specific tablespace?
981  */
982  if (strlen(old_cluster.tablespace_suffix) == 0)
983  {
984  /* delete per-database directories */
985  int dbnum;
986 
987  fprintf(script, "\n");
988 
989  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
990  fprintf(script, RMDIR_CMD " %c%s%c%u%c\n", PATH_QUOTE,
993  PATH_QUOTE);
994  }
995  else
996  {
997  char *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
998 
999  /*
1000  * Simply delete the tablespace directory, which might be ".old"
1001  * or a version-specific subdirectory.
1002  */
1003  fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
1005  fix_path_separator(suffix_path), PATH_QUOTE);
1006  pfree(suffix_path);
1007  }
1008  }
1009 
1010  fclose(script);
1011 
1012 #ifndef WIN32
1013  if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
1014  pg_fatal("could not add execute permission to file \"%s\": %m",
1015  *deletion_script_file_name);
1016 #endif
1017 
1018  check_ok();
1019 }
static char * fix_path_separator(char *path)
Definition: check.c:537
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void pfree(void *pointer)
Definition: mcxt.c:1521
#define PATH_SEPARATOR
Definition: pg_upgrade.h:82
#define RMDIR_CMD
Definition: pg_upgrade.h:85
#define SCRIPT_EXT
Definition: pg_upgrade.h:87
#define SCRIPT_PREFIX
Definition: pg_upgrade.h:86
#define PATH_QUOTE
Definition: pg_upgrade.h:83
@ PG_WARNING
Definition: pg_upgrade.h:270
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
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
char * pgdata
Definition: pg_upgrade.h:285
Oid db_oid
Definition: pg_upgrade.h:193
#define S_IRWXU
Definition: win32_port.h:298

References canonicalize_path(), check_ok(), DbInfo::db_oid, ClusterInfo::dbarr, DbInfoArr::dbs, fix_path_separator(), fopen_priv, fprintf, MAXPGPATH, DbInfoArr::ndbs, new_cluster, OSInfo::num_old_tablespaces, old_cluster, OSInfo::old_tablespaces, os_info, path_is_prefix_of_path(), PATH_QUOTE, PATH_SEPARATOR, pfree(), pg_fatal, pg_free(), pg_log(), pg_strdup(), PG_WARNING, ClusterInfo::pgdata, prep_status(), psprintf(), RMDIR_CMD, S_IRWXU, SCRIPT_EXT, SCRIPT_PREFIX, strlcpy(), and ClusterInfo::tablespace_suffix.

Referenced by main().

◆ fix_path_separator()

static char* fix_path_separator ( char *  path)
static

Definition at line 537 of file check.c.

538 {
539 #ifdef WIN32
540 
541  char *result;
542  char *c;
543 
544  result = pg_strdup(path);
545 
546  for (c = result; *c != '\0'; c++)
547  if (*c == '/')
548  *c = '\\';
549 
550  return result;
551 #else
552 
553  return path;
554 #endif
555 }
char * c

References pg_strdup().

Referenced by create_script_for_old_cluster_deletion().

◆ issue_warnings_and_set_wal_level()

void issue_warnings_and_set_wal_level ( void  )

Definition at line 733 of file check.c.

734 {
735  /*
736  * We unconditionally start/stop the new server because pg_resetwal -o set
737  * wal_level to 'minimum'. If the user is upgrading standby servers using
738  * the rsync instructions, they will need pg_upgrade to write its final
739  * WAL record showing wal_level as 'replica'.
740  */
742 
743  /* Reindex hash indexes for old < 10.0 */
746 
748 
749  stop_postmaster(false);
750 }
void report_extension_updates(ClusterInfo *cluster)
Definition: version.c:147

References GET_MAJOR_VERSION, ClusterInfo::major_version, new_cluster, old_9_6_invalidate_hash_indexes(), old_cluster, report_extension_updates(), start_postmaster(), and stop_postmaster().

Referenced by main().

◆ output_check_banner()

void output_check_banner ( void  )

Definition at line 558 of file check.c.

559 {
560  if (user_opts.live_check)
561  {
563  "Performing Consistency Checks on Old Live Server\n"
564  "------------------------------------------------");
565  }
566  else
567  {
569  "Performing Consistency Checks\n"
570  "-----------------------------");
571  }
572 }

References UserOpts::live_check, pg_log(), PG_REPORT, and user_opts.

Referenced by main().

◆ output_completion_banner()

void output_completion_banner ( char *  deletion_script_file_name)

Definition at line 754 of file check.c.

755 {
756  PQExpBufferData user_specification;
757 
758  initPQExpBuffer(&user_specification);
760  {
761  appendPQExpBufferStr(&user_specification, "-U ");
762  appendShellString(&user_specification, os_info.user);
763  appendPQExpBufferChar(&user_specification, ' ');
764  }
765 
767  "Optimizer statistics are not transferred by pg_upgrade.\n"
768  "Once you start the new server, consider running:\n"
769  " %s/vacuumdb %s--all --analyze-in-stages", new_cluster.bindir, user_specification.data);
770 
771  if (deletion_script_file_name)
773  "Running this script will delete the old cluster's data files:\n"
774  " %s",
775  deletion_script_file_name);
776  else
778  "Could not create a script to delete the old cluster's data files\n"
779  "because user-defined tablespaces or the new cluster's data directory\n"
780  "exist in the old cluster directory. The old cluster's contents must\n"
781  "be deleted manually.");
782 
783  termPQExpBuffer(&user_specification);
784 }
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:429
char * bindir
Definition: pg_upgrade.h:288
bool user_specified
Definition: pg_upgrade.h:345

References appendPQExpBufferChar(), appendPQExpBufferStr(), appendShellString(), ClusterInfo::bindir, PQExpBufferData::data, initPQExpBuffer(), new_cluster, os_info, pg_log(), PG_REPORT, termPQExpBuffer(), OSInfo::user, and OSInfo::user_specified.

Referenced by main().

◆ report_clusters_compatible()

void report_clusters_compatible ( void  )

Definition at line 714 of file check.c.

715 {
716  if (user_opts.check)
717  {
718  pg_log(PG_REPORT, "\n*Clusters are compatible*");
719  /* stops new cluster */
720  stop_postmaster(false);
721 
723  exit(0);
724  }
725 
726  pg_log(PG_REPORT, "\n"
727  "If pg_upgrade fails after this point, you must re-initdb the\n"
728  "new cluster before continuing.");
729 }
exit(1)
void cleanup_output_dirs(void)
Definition: util.c:63

References UserOpts::check, cleanup_output_dirs(), exit(), pg_log(), PG_REPORT, stop_postmaster(), and user_opts.

Referenced by main().

Variable Documentation

◆ data_types_usage_checks

DataTypesUsageChecks data_types_usage_checks[]
static

Definition at line 97 of file check.c.

Referenced by check_and_dump_old_cluster().