PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
check.c File Reference
#include "postgres_fe.h"
#include "catalog/pg_authid_d.h"
#include "catalog/pg_class_d.h"
#include "fe_utils/string_utils.h"
#include "pg_upgrade.h"
#include "common/unicode_version.h"
Include dependency graph for check.c:

Go to the source code of this file.

Data Structures

struct  DataTypesUsageChecks
 
struct  data_type_check_state
 

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_for_connection_status (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_for_unicode_update (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 char * data_type_check_query (int checknum)
 
static void process_data_type_check (DbInfo *dbinfo, PGresult *res, void *arg)
 
static void check_for_data_types_usage (ClusterInfo *cluster)
 
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)
 
static void process_isn_and_int8_passing_mismatch (DbInfo *dbinfo, PGresult *res, void *arg)
 
static void process_user_defined_postfix_ops (DbInfo *dbinfo, PGresult *res, void *arg)
 
static void process_incompat_polymorphics (DbInfo *dbinfo, PGresult *res, void *arg)
 
static void process_with_oids_check (DbInfo *dbinfo, PGresult *res, void *arg)
 
static void process_user_defined_encoding_conversions (DbInfo *dbinfo, PGresult *res, void *arg)
 
static void process_unicode_update (DbInfo *dbinfo, PGresult *res, void *arg)
 
static bool unicode_version_changed (ClusterInfo *cluster)
 
static void process_old_sub_state_check (DbInfo *dbinfo, PGresult *res, void *arg)
 

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 588 of file check.c.

589{
590 /* -- OLD -- */
591
594
595 /*
596 * First check that all databases allow connections since we'll otherwise
597 * fail in later stages.
598 */
600
601 /*
602 * Extract a list of databases, tables, and logical replication slots from
603 * the old cluster.
604 */
606
608
610
611
612 /*
613 * Check for various failure cases
614 */
618
620 {
621 /*
622 * Logical replication slots can be migrated since PG17. See comments
623 * atop get_old_cluster_logical_slot_infos().
624 */
626
627 /*
628 * Subscriptions and their dependencies can be migrated since PG17.
629 * Before that the logical slots are not upgraded, so we will not be
630 * able to upgrade the logical replication clusters completely.
631 */
634 }
635
637
638 /*
639 * Unicode updates can affect some objects that use expressions with
640 * functions dependent on Unicode.
641 */
643
644 /*
645 * PG 14 changed the function signature of encoding conversion functions.
646 * Conversions from older versions cannot be upgraded automatically
647 * because the user-defined functions used by the encoding conversions
648 * need to be changed to match the new signature.
649 */
652
653 /*
654 * Pre-PG 14 allowed user defined postfix operators, which are not
655 * supported anymore. Verify there are none, iff applicable.
656 */
659
660 /*
661 * PG 14 changed polymorphic functions from anyarray to
662 * anycompatiblearray.
663 */
666
667 /*
668 * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
669 * supported anymore. Verify there are none, iff applicable.
670 */
673
674 /*
675 * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
676 * hash indexes
677 */
679 {
680 if (user_opts.check)
682 }
683
684 /* 9.5 and below should not have roles starting with pg_ */
687
688 /*
689 * While not a check option, we do this now because this is the only time
690 * the old server is running.
691 */
692 if (!user_opts.check)
694
696 stop_postmaster(false);
697}
static void check_for_tables_with_oids(ClusterInfo *cluster)
Definition: check.c:1589
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1633
static void check_for_data_types_usage(ClusterInfo *cluster)
Definition: check.c:463
static void check_old_cluster_subscription_state(void)
Definition: check.c:2176
static void check_for_unicode_update(ClusterInfo *cluster)
Definition: check.c:1828
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:1069
static void check_for_connection_status(ClusterInfo *cluster)
Definition: check.c:1127
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:1281
static void check_old_cluster_for_valid_slots(void)
Definition: check.c:2068
static void check_for_user_defined_postfix_ops(ClusterInfo *cluster)
Definition: check.c:1369
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:1215
static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
Definition: check.c:1722
static void check_for_incompatible_polymorphics(ClusterInfo *cluster)
Definition: check.c:1460
void generate_old_dump(void)
Definition: dump.c:16
void get_loadable_libraries(void)
Definition: function.c:79
void get_subscription_count(ClusterInfo *cluster)
Definition: info.c:760
void get_db_rel_and_slot_infos(ClusterInfo *cluster)
Definition: info.c:280
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:349
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:300
bool live_check
Definition: pg_upgrade.h:331
bool check
Definition: pg_upgrade.h:330

References UserOpts::check, check_for_connection_status(), 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_unicode_update(), 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(), 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 896 of file check.c.

897{
898 /* get/check pg_control data of servers */
902
904 pg_fatal("When checking a live server, "
905 "the old and new port numbers must be different.");
906}
void get_control_data(ClusterInfo *cluster)
Definition: controldata.c:38
void check_control_data(ControlData *oldctrl, ControlData *newctrl)
Definition: controldata.c:698
#define pg_fatal(...)
ClusterInfo new_cluster
Definition: pg_upgrade.c:72
unsigned short port
Definition: pg_upgrade.h:299
ControlData controldata
Definition: pg_upgrade.h:289

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 841 of file check.c.

842{
843 prep_status("Checking cluster versions");
844
845 /* cluster versions should already have been obtained */
848
849 /*
850 * We allow upgrades from/to the same major version for alpha/beta
851 * upgrades
852 */
853
855 pg_fatal("This utility can only upgrade from PostgreSQL version %s and later.",
856 "9.2");
857
858 /* Only current PG version is supported as a target */
860 pg_fatal("This utility can only upgrade to PostgreSQL version %s.",
861 PG_MAJORVERSION);
862
863 /*
864 * We can't allow downgrading because we use the target pg_dump, and
865 * pg_dump cannot operate on newer database versions, only current and
866 * older versions.
867 */
869 pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.");
870
871 /* Ensure binaries match the designated data directories */
874 pg_fatal("Old cluster data and binary directories are from different major versions.");
877 pg_fatal("New cluster data and binary directories are from different major versions.");
878
879 /*
880 * Since from version 18, newly created database clusters always have
881 * 'signed' default char-signedness, it makes less sense to use
882 * --set-char-signedness option for upgrading from version 18 or later.
883 * Users who want to change the default char signedness of the new
884 * cluster, they can use pg_resetwal manually before the upgrade.
885 */
888 pg_fatal("%s option cannot be used to upgrade from PostgreSQL %s and later.",
889 "--set-char-signedness", "18");
890
891 check_ok();
892}
Assert(PointerIsAligned(start, uint64))
static void check_ok(void)
Definition: initdb.c:2109
void prep_status(const char *fmt,...) pg_attribute_printf(1
uint32 bin_version
Definition: pg_upgrade.h:302
int char_signedness
Definition: pg_upgrade.h:338

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

Referenced by main().

◆ check_for_connection_status()

static void check_for_connection_status ( ClusterInfo cluster)
static

Definition at line 1127 of file check.c.

1128{
1129 int dbnum;
1130 PGconn *conn_template1;
1131 PGresult *dbres;
1132 int ntups;
1133 int i_datname;
1134 int i_datallowconn;
1135 int i_datconnlimit;
1136 FILE *script = NULL;
1137 char output_path[MAXPGPATH];
1138
1139 prep_status("Checking database connection settings");
1140
1141 snprintf(output_path, sizeof(output_path), "%s/%s",
1143 "databases_cannot_connect_to.txt");
1144
1145 conn_template1 = connectToServer(cluster, "template1");
1146
1147 /* get database names */
1148 dbres = executeQueryOrDie(conn_template1,
1149 "SELECT datname, datallowconn, datconnlimit "
1150 "FROM pg_catalog.pg_database");
1151
1152 i_datname = PQfnumber(dbres, "datname");
1153 i_datallowconn = PQfnumber(dbres, "datallowconn");
1154 i_datconnlimit = PQfnumber(dbres, "datconnlimit");
1155
1156 ntups = PQntuples(dbres);
1157 for (dbnum = 0; dbnum < ntups; dbnum++)
1158 {
1159 char *datname = PQgetvalue(dbres, dbnum, i_datname);
1160 char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
1161 char *datconnlimit = PQgetvalue(dbres, dbnum, i_datconnlimit);
1162
1163 if (strcmp(datname, "template0") == 0)
1164 {
1165 /* avoid restore failure when pg_dumpall tries to create template0 */
1166 if (strcmp(datallowconn, "t") == 0)
1167 pg_fatal("template0 must not allow connections, "
1168 "i.e. its pg_database.datallowconn must be false");
1169 }
1170 else
1171 {
1172 /*
1173 * Avoid datallowconn == false databases from being skipped on
1174 * restore, and ensure that no databases are marked invalid with
1175 * datconnlimit == -2.
1176 */
1177 if ((strcmp(datallowconn, "f") == 0) || strcmp(datconnlimit, "-2") == 0)
1178 {
1179 if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1180 pg_fatal("could not open file \"%s\": %m", output_path);
1181
1182 fprintf(script, "%s\n", datname);
1183 }
1184 }
1185 }
1186
1187 PQclear(dbres);
1188
1189 PQfinish(conn_template1);
1190
1191 if (script)
1192 {
1193 fclose(script);
1194 pg_log(PG_REPORT, "fatal");
1195 pg_fatal("All non-template0 databases must allow connections, i.e. their\n"
1196 "pg_database.datallowconn must be true and pg_database.datconnlimit\n"
1197 "must not be -2. Your installation contains non-template0 databases\n"
1198 "which cannot be connected to. Consider allowing connection for all\n"
1199 "non-template0 databases or drop the databases which do not allow\n"
1200 "connections. A list of databases with the problem is in the file:\n"
1201 " %s", output_path);
1202 }
1203 else
1204 check_ok();
1205}
void cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:107
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
void PQfinish(PGconn *conn)
Definition: fe-connect.c:5296
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3876
void PQclear(PGresult *res)
Definition: fe-exec.c:721
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3481
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3589
#define MAXPGPATH
NameData datname
Definition: pg_database.h:35
bool datallowconn
Definition: pg_database.h:50
int32 datconnlimit
Definition: pg_database.h:59
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:28
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
LogOpts log_opts
Definition: util.c:17
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:430
@ PG_REPORT
Definition: pg_upgrade.h:276
#define snprintf
Definition: port.h:239
char * basedir
Definition: pg_upgrade.h:318

References LogOpts::basedir, check_ok(), cluster(), connectToServer(), datallowconn, datconnlimit, 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().

◆ check_for_data_types_usage()

static void check_for_data_types_usage ( ClusterInfo cluster)
static

Definition at line 463 of file check.c.

464{
465 PQExpBuffer report = NULL;
467 int n_data_types_usage_checks = 0;
469 char **queries = NULL;
470 struct data_type_check_state *states;
471
472 prep_status("Checking data type usage");
473
474 /* Gather number of checks to perform */
475 while (tmp->status != NULL)
476 {
477 n_data_types_usage_checks++;
478 tmp++;
479 }
480
481 /* Allocate memory for queries and for task states */
482 queries = pg_malloc0(sizeof(char *) * n_data_types_usage_checks);
483 states = pg_malloc0(sizeof(struct data_type_check_state) * n_data_types_usage_checks);
484
485 for (int i = 0; i < n_data_types_usage_checks; i++)
486 {
488
490 {
492
493 /*
494 * Make sure that the check applies to the current cluster version
495 * and skip it if not.
496 */
498 continue;
499 }
501 {
502 if (GET_MAJOR_VERSION(cluster->major_version) > check->threshold_version)
503 continue;
504 }
505 else
507
508 queries[i] = data_type_check_query(i);
509
510 states[i].check = check;
511 states[i].report = &report;
512
514 true, &states[i]);
515 }
516
517 /*
518 * Connect to each database in the cluster and run all defined checks
519 * against that database before trying the next one.
520 */
522 upgrade_task_free(task);
523
524 if (report)
525 {
526 pg_fatal("Data type checks failed: %s", report->data);
528 }
529
530 for (int i = 0; i < n_data_types_usage_checks; i++)
531 {
532 if (queries[i])
533 pg_free(queries[i]);
534 }
535 pg_free(queries);
536 pg_free(states);
537
538 check_ok();
539}
static char * data_type_check_query(int checknum)
Definition: check.c:332
static DataTypesUsageChecks data_types_usage_checks[]
Definition: check.c:97
#define ALL_VERSIONS
Definition: check.c:62
#define MANUAL_CHECK
Definition: check.c:61
static void process_data_type_check(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:389
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
void pg_free(void *ptr)
Definition: fe_memutils.c:105
int i
Definition: isn.c:77
UpgradeTask * upgrade_task_create(void)
Definition: task.c:117
void upgrade_task_run(const UpgradeTask *task, const ClusterInfo *cluster)
Definition: task.c:420
void upgrade_task_free(UpgradeTask *task)
Definition: task.c:133
void upgrade_task_add_step(UpgradeTask *task, const char *query, UpgradeTaskProcessCB process_cb, bool free_result, void *arg)
Definition: task.c:151
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:114
int threshold_version
Definition: check.c:51
DataTypesUsageVersionCheck version_hook
Definition: check.c:53
const char * status
Definition: check.c:43
PQExpBuffer * report
Definition: check.c:324
DataTypesUsageChecks * check
Definition: check.c:322

References ALL_VERSIONS, Assert(), data_type_check_state::check, check_ok(), cluster(), PQExpBufferData::data, data_type_check_query(), data_types_usage_checks, destroyPQExpBuffer(), GET_MAJOR_VERSION, i, MANUAL_CHECK, pg_fatal, pg_free(), pg_malloc0(), prep_status(), process_data_type_check(), data_type_check_state::report, DataTypesUsageChecks::status, DataTypesUsageChecks::threshold_version, upgrade_task_add_step(), upgrade_task_create(), upgrade_task_free(), upgrade_task_run(), 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 1460 of file check.c.

1461{
1462 PQExpBufferData old_polymorphics;
1464 UpgradeTaskReport report;
1465 char *query;
1466
1467 prep_status("Checking for incompatible polymorphic functions");
1468
1469 report.file = NULL;
1470 snprintf(report.path, sizeof(report.path), "%s/%s",
1472 "incompatible_polymorphics.txt");
1473
1474 /* The set of problematic functions varies a bit in different versions */
1475 initPQExpBuffer(&old_polymorphics);
1476
1477 appendPQExpBufferStr(&old_polymorphics,
1478 "'array_append(anyarray,anyelement)'"
1479 ", 'array_cat(anyarray,anyarray)'"
1480 ", 'array_prepend(anyelement,anyarray)'");
1481
1482 if (GET_MAJOR_VERSION(cluster->major_version) >= 903)
1483 appendPQExpBufferStr(&old_polymorphics,
1484 ", 'array_remove(anyarray,anyelement)'"
1485 ", 'array_replace(anyarray,anyelement,anyelement)'");
1486
1487 if (GET_MAJOR_VERSION(cluster->major_version) >= 905)
1488 appendPQExpBufferStr(&old_polymorphics,
1489 ", 'array_position(anyarray,anyelement)'"
1490 ", 'array_position(anyarray,anyelement,integer)'"
1491 ", 'array_positions(anyarray,anyelement)'"
1492 ", 'width_bucket(anyelement,anyarray)'");
1493
1494 /*
1495 * The query below hardcodes FirstNormalObjectId as 16384 rather than
1496 * interpolating that C #define into the query because, if that #define is
1497 * ever changed, the cutoff we want to use is the value used by
1498 * pre-version 14 servers, not that of some future version.
1499 */
1500
1501 /* Aggregate transition functions */
1502 query = psprintf("SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
1503 "FROM pg_proc AS p "
1504 "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
1505 "JOIN pg_proc AS transfn ON transfn.oid=a.aggtransfn "
1506 "WHERE p.oid >= 16384 "
1507 "AND a.aggtransfn = ANY(ARRAY[%s]::regprocedure[]) "
1508 "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
1509
1510 /* Aggregate final functions */
1511 "UNION ALL "
1512 "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
1513 "FROM pg_proc AS p "
1514 "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
1515 "JOIN pg_proc AS finalfn ON finalfn.oid=a.aggfinalfn "
1516 "WHERE p.oid >= 16384 "
1517 "AND a.aggfinalfn = ANY(ARRAY[%s]::regprocedure[]) "
1518 "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
1519
1520 /* Operators */
1521 "UNION ALL "
1522 "SELECT 'operator' AS objkind, op.oid::regoperator::text AS objname "
1523 "FROM pg_operator AS op "
1524 "WHERE op.oid >= 16384 "
1525 "AND oprcode = ANY(ARRAY[%s]::regprocedure[]) "
1526 "AND oprleft = ANY(ARRAY['anyarray', 'anyelement']::regtype[])",
1527 old_polymorphics.data,
1528 old_polymorphics.data,
1529 old_polymorphics.data);
1530
1532 true, &report);
1534 upgrade_task_free(task);
1535
1536 if (report.file)
1537 {
1538 fclose(report.file);
1539 pg_log(PG_REPORT, "fatal");
1540 pg_fatal("Your installation contains user-defined objects that refer to internal\n"
1541 "polymorphic functions with arguments of type \"anyarray\" or \"anyelement\".\n"
1542 "These user-defined objects must be dropped before upgrading and restored\n"
1543 "afterwards, changing them to refer to the new corresponding functions with\n"
1544 "arguments of type \"anycompatiblearray\" and \"anycompatible\".\n"
1545 "A list of the problematic objects is in the file:\n"
1546 " %s", report.path);
1547 }
1548 else
1549 check_ok();
1550
1551 termPQExpBuffer(&old_polymorphics);
1552 pg_free(query);
1553}
static void process_incompat_polymorphics(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1428
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
char path[MAXPGPATH]
Definition: pg_upgrade.h:527

References appendPQExpBufferStr(), LogOpts::basedir, check_ok(), cluster(), PQExpBufferData::data, UpgradeTaskReport::file, GET_MAJOR_VERSION, initPQExpBuffer(), log_opts, UpgradeTaskReport::path, pg_fatal, pg_free(), pg_log(), PG_REPORT, prep_status(), process_incompat_polymorphics(), psprintf(), snprintf, termPQExpBuffer(), upgrade_task_add_step(), upgrade_task_create(), upgrade_task_free(), and upgrade_task_run().

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 1281 of file check.c.

1282{
1283 UpgradeTask *task;
1284 UpgradeTaskReport report;
1285 const char *query = "SELECT n.nspname, p.proname "
1286 "FROM pg_catalog.pg_proc p, "
1287 " pg_catalog.pg_namespace n "
1288 "WHERE p.pronamespace = n.oid AND "
1289 " p.probin = '$libdir/isn'";
1290
1291 prep_status("Checking for contrib/isn with bigint-passing mismatch");
1292
1295 {
1296 /* no mismatch */
1297 check_ok();
1298 return;
1299 }
1300
1301 report.file = NULL;
1302 snprintf(report.path, sizeof(report.path), "%s/%s",
1304 "contrib_isn_and_int8_pass_by_value.txt");
1305
1306 task = upgrade_task_create();
1308 true, &report);
1310 upgrade_task_free(task);
1311
1312 if (report.file)
1313 {
1314 fclose(report.file);
1315 pg_log(PG_REPORT, "fatal");
1316 pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
1317 "bigint data type. Your old and new clusters pass bigint values\n"
1318 "differently so this cluster cannot currently be upgraded. You can\n"
1319 "manually dump databases in the old cluster that use \"contrib/isn\"\n"
1320 "facilities, drop them, perform the upgrade, and then restore them. A\n"
1321 "list of the problem functions is in the file:\n"
1322 " %s", report.path);
1323 }
1324 else
1325 check_ok();
1326}
static void process_isn_and_int8_passing_mismatch(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1248
bool float8_pass_by_value
Definition: pg_upgrade.h:251

References LogOpts::basedir, check_ok(), cluster(), ClusterInfo::controldata, UpgradeTaskReport::file, ControlData::float8_pass_by_value, log_opts, new_cluster, old_cluster, UpgradeTaskReport::path, pg_fatal, pg_log(), PG_REPORT, prep_status(), process_isn_and_int8_passing_mismatch(), snprintf, upgrade_task_add_step(), upgrade_task_create(), upgrade_task_free(), and upgrade_task_run().

Referenced by check_and_dump_old_cluster().

◆ check_for_new_tablespace_dir()

static void check_for_new_tablespace_dir ( void  )
static

Definition at line 942 of file check.c.

943{
944 int tblnum;
945 char new_tablespace_dir[MAXPGPATH];
946
947 prep_status("Checking for new cluster tablespace directories");
948
949 for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
950 {
951 struct stat statbuf;
952
953 snprintf(new_tablespace_dir, MAXPGPATH, "%s%s",
954 os_info.old_tablespaces[tblnum],
956
957 if (stat(new_tablespace_dir, &statbuf) == 0 || errno != ENOENT)
958 pg_fatal("new cluster tablespace directory already exists: \"%s\"",
959 new_tablespace_dir);
960 }
961
962 check_ok();
963}
OSInfo os_info
Definition: pg_upgrade.c:73
const char * tablespace_suffix
Definition: pg_upgrade.h:303
int num_old_tablespaces
Definition: pg_upgrade.h:358
char ** old_tablespaces
Definition: pg_upgrade.h:357
#define stat
Definition: win32_port.h:274

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 1633 of file check.c.

1634{
1635 PGresult *res;
1636 PGconn *conn = connectToServer(cluster, "template1");
1637 int ntups;
1638 int i_roloid;
1639 int i_rolname;
1640 FILE *script = NULL;
1641 char output_path[MAXPGPATH];
1642
1643 prep_status("Checking for roles starting with \"pg_\"");
1644
1645 snprintf(output_path, sizeof(output_path), "%s/%s",
1647 "pg_role_prefix.txt");
1648
1649 res = executeQueryOrDie(conn,
1650 "SELECT oid AS roloid, rolname "
1651 "FROM pg_catalog.pg_roles "
1652 "WHERE rolname ~ '^pg_'");
1653
1654 ntups = PQntuples(res);
1655 i_roloid = PQfnumber(res, "roloid");
1656 i_rolname = PQfnumber(res, "rolname");
1657 for (int rowno = 0; rowno < ntups; rowno++)
1658 {
1659 if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1660 pg_fatal("could not open file \"%s\": %m", output_path);
1661 fprintf(script, "%s (oid=%s)\n",
1662 PQgetvalue(res, rowno, i_rolname),
1663 PQgetvalue(res, rowno, i_roloid));
1664 }
1665
1666 PQclear(res);
1667
1668 PQfinish(conn);
1669
1670 if (script)
1671 {
1672 fclose(script);
1673 pg_log(PG_REPORT, "fatal");
1674 pg_fatal("Your installation contains roles starting with \"pg_\".\n"
1675 "\"pg_\" is a reserved prefix for system roles. The cluster\n"
1676 "cannot be upgraded until these roles are renamed.\n"
1677 "A list of roles starting with \"pg_\" is in the file:\n"
1678 " %s", output_path);
1679 }
1680 else
1681 check_ok();
1682}
PGconn * conn
Definition: streamutil.c:52

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(), 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 1215 of file check.c.

1216{
1217 PGresult *res;
1218 PGconn *conn = connectToServer(cluster, "template1");
1219
1220 prep_status("Checking for prepared transactions");
1221
1222 res = executeQueryOrDie(conn,
1223 "SELECT * "
1224 "FROM pg_catalog.pg_prepared_xacts");
1225
1226 if (PQntuples(res) != 0)
1227 {
1228 if (cluster == &old_cluster)
1229 pg_fatal("The source cluster contains prepared transactions");
1230 else
1231 pg_fatal("The target cluster contains prepared transactions");
1232 }
1233
1234 PQclear(res);
1235
1236 PQfinish(conn);
1237
1238 check_ok();
1239}

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

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 1589 of file check.c.

1590{
1591 UpgradeTaskReport report;
1593 const char *query = "SELECT n.nspname, c.relname "
1594 "FROM pg_catalog.pg_class c, "
1595 " pg_catalog.pg_namespace n "
1596 "WHERE c.relnamespace = n.oid AND "
1597 " c.relhasoids AND"
1598 " n.nspname NOT IN ('pg_catalog')";
1599
1600 prep_status("Checking for tables WITH OIDS");
1601
1602 report.file = NULL;
1603 snprintf(report.path, sizeof(report.path), "%s/%s",
1605 "tables_with_oids.txt");
1606
1608 true, &report);
1610 upgrade_task_free(task);
1611
1612 if (report.file)
1613 {
1614 fclose(report.file);
1615 pg_log(PG_REPORT, "fatal");
1616 pg_fatal("Your installation contains tables declared WITH OIDS, which is not\n"
1617 "supported anymore. Consider removing the oid column using\n"
1618 " ALTER TABLE ... SET WITHOUT OIDS;\n"
1619 "A list of tables with the problem is in the file:\n"
1620 " %s", report.path);
1621 }
1622 else
1623 check_ok();
1624}
static void process_with_oids_check(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1561

References LogOpts::basedir, check_ok(), cluster(), UpgradeTaskReport::file, log_opts, UpgradeTaskReport::path, pg_fatal, pg_log(), PG_REPORT, prep_status(), process_with_oids_check(), snprintf, upgrade_task_add_step(), upgrade_task_create(), upgrade_task_free(), and upgrade_task_run().

Referenced by check_and_dump_old_cluster().

◆ check_for_unicode_update()

static void check_for_unicode_update ( ClusterInfo cluster)
static

Definition at line 1828 of file check.c.

1829{
1830 UpgradeTaskReport report;
1831 UpgradeTask *task;
1832 const char *query;
1833
1834 /*
1835 * The builtin provider did not exist prior to version 17. While there are
1836 * still problems that could potentially be caught from earlier versions,
1837 * such as an index on NORMALIZE(), we don't check for that here.
1838 */
1839 if (GET_MAJOR_VERSION(cluster->major_version) < 1700)
1840 return;
1841
1842 prep_status("Checking for objects affected by Unicode update");
1843
1845 {
1846 check_ok();
1847 return;
1848 }
1849
1850 report.file = NULL;
1851 snprintf(report.path, sizeof(report.path), "%s/%s",
1853 "unicode_dependent_rels.txt");
1854
1855 query =
1856 /* collations that use built-in Unicode for character semantics */
1857 "WITH collations(collid) AS ( "
1858 " SELECT oid FROM pg_collation "
1859 " WHERE collprovider='b' AND colllocale IN ('C.UTF-8','PG_UNICODE_FAST') "
1860 /* include default collation, if appropriate */
1861 " UNION "
1862 " SELECT 'pg_catalog.default'::regcollation FROM pg_database "
1863 " WHERE datname = current_database() AND "
1864 " datlocprovider='b' AND datlocale IN ('C.UTF-8','PG_UNICODE_FAST') "
1865 "), "
1866 /* functions that use built-in Unicode */
1867 "functions(procid) AS ( "
1868 " SELECT proc.oid FROM pg_proc proc "
1869 " WHERE proname IN ('normalize','unicode_assigned','unicode_version','is_normalized') AND "
1870 " pronamespace='pg_catalog'::regnamespace "
1871 "), "
1872 /* operators that use the input collation for character semantics */
1873 "coll_operators(operid, procid, collid) AS ( "
1874 " SELECT oper.oid, oper.oprcode, collid FROM pg_operator oper, collations "
1875 " WHERE oprname IN ('~', '~*', '!~', '!~*', '~~*', '!~~*') AND "
1876 " oprnamespace='pg_catalog'::regnamespace AND "
1877 " oprright='text'::regtype "
1878 "), "
1879 /* functions that use the input collation for character semantics */
1880 "coll_functions(procid, collid) AS ( "
1881 " SELECT proc.oid, collid FROM pg_proc proc, collations "
1882 " WHERE proname IN ('lower','initcap','upper') AND "
1883 " pronamespace='pg_catalog'::regnamespace AND "
1884 " proargtypes[0] = 'text'::regtype "
1885 /* include functions behind the operators listed above */
1886 " UNION "
1887 " SELECT procid, collid FROM coll_operators "
1888 "), "
1889
1890 /*
1891 * Generate patterns to search a pg_node_tree for the above functions and
1892 * operators.
1893 */
1894 "patterns(p) AS ( "
1895 " SELECT '{FUNCEXPR :funcid ' || procid::text || '[ }]' FROM functions "
1896 " UNION "
1897 " SELECT '{OPEXPR :opno ' || operid::text || ' (:\\w+ \\w+ )*' || "
1898 " ':inputcollid ' || collid::text || '[ }]' FROM coll_operators "
1899 " UNION "
1900 " SELECT '{FUNCEXPR :funcid ' || procid::text || ' (:\\w+ \\w+ )*' || "
1901 " ':inputcollid ' || collid::text || '[ }]' FROM coll_functions "
1902 ") "
1903
1904 /*
1905 * Match the patterns against expressions used for relation contents.
1906 */
1907 "SELECT reloid, relkind, nspname, relname "
1908 " FROM ( "
1909 " SELECT conrelid "
1910 " FROM pg_constraint, patterns WHERE conbin::text ~ p "
1911 " UNION "
1912 " SELECT indexrelid "
1913 " FROM pg_index, patterns WHERE indexprs::text ~ p OR indpred::text ~ p "
1914 " UNION "
1915 " SELECT partrelid "
1916 " FROM pg_partitioned_table, patterns WHERE partexprs::text ~ p "
1917 " UNION "
1918 " SELECT ev_class "
1919 " FROM pg_rewrite, pg_class, patterns "
1920 " WHERE ev_class = pg_class.oid AND relkind = 'm' AND ev_action::text ~ p"
1921 " ) s(reloid), pg_class c, pg_namespace n, pg_database d "
1922 " WHERE s.reloid = c.oid AND c.relnamespace = n.oid AND "
1923 " d.datname = current_database() AND "
1924 " d.encoding = pg_char_to_encoding('UTF8');";
1925
1926 task = upgrade_task_create();
1927 upgrade_task_add_step(task, query,
1929 true, &report);
1931 upgrade_task_free(task);
1932
1933 if (report.file)
1934 {
1935 fclose(report.file);
1936 report_status(PG_WARNING, "warning");
1937 pg_log(PG_WARNING, "Your installation contains relations that may be affected by a new version of Unicode.\n"
1938 "A list of potentially-affected relations is in the file:\n"
1939 " %s", report.path);
1940 }
1941 else
1942 check_ok();
1943}
static bool unicode_version_changed(ClusterInfo *cluster)
Definition: check.c:1803
static void process_unicode_update(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1774
@ PG_WARNING
Definition: pg_upgrade.h:277
void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2

References LogOpts::basedir, check_ok(), cluster(), UpgradeTaskReport::file, GET_MAJOR_VERSION, log_opts, UpgradeTaskReport::path, pg_log(), PG_WARNING, prep_status(), process_unicode_update(), report_status(), snprintf, unicode_version_changed(), upgrade_task_add_step(), upgrade_task_create(), upgrade_task_free(), and upgrade_task_run().

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 1722 of file check.c.

1723{
1724 UpgradeTaskReport report;
1726 const char *query;
1727
1728 prep_status("Checking for user-defined encoding conversions");
1729
1730 report.file = NULL;
1731 snprintf(report.path, sizeof(report.path), "%s/%s",
1733 "encoding_conversions.txt");
1734
1735 /*
1736 * The query below hardcodes FirstNormalObjectId as 16384 rather than
1737 * interpolating that C #define into the query because, if that #define is
1738 * ever changed, the cutoff we want to use is the value used by
1739 * pre-version 14 servers, not that of some future version.
1740 */
1741 query = "SELECT c.oid as conoid, c.conname, n.nspname "
1742 "FROM pg_catalog.pg_conversion c, "
1743 " pg_catalog.pg_namespace n "
1744 "WHERE c.connamespace = n.oid AND "
1745 " c.oid >= 16384";
1746
1747 upgrade_task_add_step(task, query,
1749 true, &report);
1751 upgrade_task_free(task);
1752
1753 if (report.file)
1754 {
1755 fclose(report.file);
1756 pg_log(PG_REPORT, "fatal");
1757 pg_fatal("Your installation contains user-defined encoding conversions.\n"
1758 "The conversion function parameters changed in PostgreSQL version 14\n"
1759 "so this cluster cannot currently be upgraded. You can remove the\n"
1760 "encoding conversions in the old cluster and restart the upgrade.\n"
1761 "A list of user-defined encoding conversions is in the file:\n"
1762 " %s", report.path);
1763 }
1764 else
1765 check_ok();
1766}
static void process_user_defined_encoding_conversions(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1691

References LogOpts::basedir, check_ok(), cluster(), UpgradeTaskReport::file, log_opts, UpgradeTaskReport::path, pg_fatal, pg_log(), PG_REPORT, prep_status(), process_user_defined_encoding_conversions(), snprintf, upgrade_task_add_step(), upgrade_task_create(), upgrade_task_free(), and upgrade_task_run().

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 1369 of file check.c.

1370{
1371 UpgradeTaskReport report;
1373 const char *query;
1374
1375 /*
1376 * The query below hardcodes FirstNormalObjectId as 16384 rather than
1377 * interpolating that C #define into the query because, if that #define is
1378 * ever changed, the cutoff we want to use is the value used by
1379 * pre-version 14 servers, not that of some future version.
1380 */
1381 query = "SELECT o.oid AS oproid, "
1382 " n.nspname AS oprnsp, "
1383 " o.oprname, "
1384 " tn.nspname AS typnsp, "
1385 " t.typname "
1386 "FROM pg_catalog.pg_operator o, "
1387 " pg_catalog.pg_namespace n, "
1388 " pg_catalog.pg_type t, "
1389 " pg_catalog.pg_namespace tn "
1390 "WHERE o.oprnamespace = n.oid AND "
1391 " o.oprleft = t.oid AND "
1392 " t.typnamespace = tn.oid AND "
1393 " o.oprright = 0 AND "
1394 " o.oid >= 16384";
1395
1396 prep_status("Checking for user-defined postfix operators");
1397
1398 report.file = NULL;
1399 snprintf(report.path, sizeof(report.path), "%s/%s",
1401 "postfix_ops.txt");
1402
1404 true, &report);
1406 upgrade_task_free(task);
1407
1408 if (report.file)
1409 {
1410 fclose(report.file);
1411 pg_log(PG_REPORT, "fatal");
1412 pg_fatal("Your installation contains user-defined postfix operators, which are not\n"
1413 "supported anymore. Consider dropping the postfix operators and replacing\n"
1414 "them with prefix operators or function calls.\n"
1415 "A list of user-defined postfix operators is in the file:\n"
1416 " %s", report.path);
1417 }
1418 else
1419 check_ok();
1420}
static void process_user_defined_postfix_ops(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:1334

References LogOpts::basedir, check_ok(), cluster(), UpgradeTaskReport::file, log_opts, UpgradeTaskReport::path, pg_fatal, pg_log(), PG_REPORT, prep_status(), process_user_defined_postfix_ops(), snprintf, upgrade_task_add_step(), upgrade_task_create(), upgrade_task_free(), and upgrade_task_run().

Referenced by check_and_dump_old_cluster().

◆ check_is_install_user()

static void check_is_install_user ( ClusterInfo cluster)
static

Definition at line 1069 of file check.c.

1070{
1071 PGresult *res;
1072 PGconn *conn = connectToServer(cluster, "template1");
1073
1074 prep_status("Checking database user is the install user");
1075
1076 /* Can't use pg_authid because only superusers can view it. */
1077 res = executeQueryOrDie(conn,
1078 "SELECT rolsuper, oid "
1079 "FROM pg_catalog.pg_roles "
1080 "WHERE rolname = current_user "
1081 "AND rolname !~ '^pg_'");
1082
1083 /*
1084 * We only allow the install user in the new cluster (see comment below)
1085 * and we preserve pg_authid.oid, so this must be the install user in the
1086 * old cluster too.
1087 */
1088 if (PQntuples(res) != 1 ||
1089 atooid(PQgetvalue(res, 0, 1)) != BOOTSTRAP_SUPERUSERID)
1090 pg_fatal("database user \"%s\" is not the install user",
1091 os_info.user);
1092
1093 PQclear(res);
1094
1095 res = executeQueryOrDie(conn,
1096 "SELECT COUNT(*) "
1097 "FROM pg_catalog.pg_roles "
1098 "WHERE rolname !~ '^pg_'");
1099
1100 if (PQntuples(res) != 1)
1101 pg_fatal("could not determine the number of users");
1102
1103 /*
1104 * We only allow the install user in the new cluster because other defined
1105 * users might match users defined in the old cluster and generate an
1106 * error during pg_dump restore.
1107 */
1108 if (cluster == &new_cluster && strcmp(PQgetvalue(res, 0, 0), "1") != 0)
1109 pg_fatal("Only the install user can be defined in the new cluster.");
1110
1111 PQclear(res);
1112
1113 PQfinish(conn);
1114
1115 check_ok();
1116}
#define atooid(x)
Definition: postgres_ext.h:41
char * user
Definition: pg_upgrade.h:355

References atooid, check_ok(), cluster(), conn, connectToServer(), executeQueryOrDie(), new_cluster, os_info, pg_fatal, PQclear(), PQfinish(), PQgetvalue(), PQntuples(), prep_status(), 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 701 of file check.c.

702{
704
706
708
709 switch (user_opts.transfer_mode)
710 {
713 break;
715 break;
718 break;
721 break;
723
724 /*
725 * We do the hard link check for --swap, too, since it's an easy
726 * way to verify the clusters are in the same file system. This
727 * allows us to take some shortcuts in the file synchronization
728 * step. With some more effort, we could probably support the
729 * separate-file-system use case, but this mode is unlikely to
730 * offer much benefit if we have to copy the files across file
731 * system boundaries.
732 */
734
735 /*
736 * There are a few known issues with using --swap to upgrade from
737 * versions older than 10. For example, the sequence tuple format
738 * changed in v10, and the visibility map format changed in 9.6.
739 * While such problems are not insurmountable (and we may have to
740 * deal with similar problems in the future, anyway), it doesn't
741 * seem worth the effort to support swap mode for upgrades from
742 * long-unsupported versions.
743 */
745 pg_fatal("Swap mode can only upgrade clusters from PostgreSQL version %s and later.",
746 "10");
747
748 break;
749 }
750
752
754
756
758
760}
static void check_new_cluster_logical_replication_slots(void)
Definition: check.c:1952
static void check_new_cluster_subscription_configuration(void)
Definition: check.c:2025
static void check_new_cluster_is_empty(void)
Definition: check.c:910
static void check_for_new_tablespace_dir(void)
Definition: check.c:942
void check_file_clone(void)
Definition: file.c:360
void check_hard_link(transferMode transfer_mode)
Definition: file.c:437
void check_copy_file_range(void)
Definition: file.c:400
void check_loadable_libraries(void)
Definition: function.c:165
@ TRANSFER_MODE_COPY
Definition: pg_upgrade.h:262
@ TRANSFER_MODE_LINK
Definition: pg_upgrade.h:264
@ TRANSFER_MODE_SWAP
Definition: pg_upgrade.h:265
@ TRANSFER_MODE_CLONE
Definition: pg_upgrade.h:261
@ TRANSFER_MODE_COPY_FILE_RANGE
Definition: pg_upgrade.h:263
transferMode transfer_mode
Definition: pg_upgrade.h:333

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(), GET_MAJOR_VERSION, ClusterInfo::major_version, new_cluster, old_cluster, pg_fatal, UserOpts::transfer_mode, TRANSFER_MODE_CLONE, TRANSFER_MODE_COPY, TRANSFER_MODE_COPY_FILE_RANGE, TRANSFER_MODE_LINK, TRANSFER_MODE_SWAP, and user_opts.

Referenced by main().

◆ check_new_cluster_is_empty()

static void check_new_cluster_is_empty ( void  )
static

Definition at line 910 of file check.c.

911{
912 int dbnum;
913
914 for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
915 {
916 int relnum;
917 RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
918
919 for (relnum = 0; relnum < rel_arr->nrels;
920 relnum++)
921 {
922 /* pg_largeobject and its index should be skipped */
923 if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
924 pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"",
926 rel_arr->rels[relnum].nspname,
927 rel_arr->rels[relnum].relname);
928 }
929 }
930}
DbInfoArr dbarr
Definition: pg_upgrade.h:291
DbInfo * dbs
Definition: pg_upgrade.h:220
char * db_name
Definition: pg_upgrade.h:199
RelInfoArr rel_arr
Definition: pg_upgrade.h:202
RelInfo * rels
Definition: pg_upgrade.h:153
char * nspname
Definition: pg_upgrade.h:140
char * relname
Definition: pg_upgrade.h:141

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 1952 of file check.c.

1953{
1954 PGresult *res;
1955 PGconn *conn;
1956 int nslots_on_old;
1957 int nslots_on_new;
1959 char *wal_level;
1960
1961 /* Logical slots can be migrated since PG17. */
1963 return;
1964
1965 nslots_on_old = count_old_cluster_logical_slots();
1966
1967 /* Quick return if there are no logical slots to be migrated. */
1968 if (nslots_on_old == 0)
1969 return;
1970
1971 conn = connectToServer(&new_cluster, "template1");
1972
1973 prep_status("Checking for new cluster logical replication slots");
1974
1975 res = executeQueryOrDie(conn, "SELECT count(*) "
1976 "FROM pg_catalog.pg_replication_slots "
1977 "WHERE slot_type = 'logical' AND "
1978 "temporary IS FALSE;");
1979
1980 if (PQntuples(res) != 1)
1981 pg_fatal("could not count the number of logical replication slots");
1982
1983 nslots_on_new = atoi(PQgetvalue(res, 0, 0));
1984
1985 if (nslots_on_new)
1986 pg_fatal("expected 0 logical replication slots but found %d",
1987 nslots_on_new);
1988
1989 PQclear(res);
1990
1991 res = executeQueryOrDie(conn, "SELECT setting FROM pg_settings "
1992 "WHERE name IN ('wal_level', 'max_replication_slots') "
1993 "ORDER BY name DESC;");
1994
1995 if (PQntuples(res) != 2)
1996 pg_fatal("could not determine parameter settings on new cluster");
1997
1998 wal_level = PQgetvalue(res, 0, 0);
1999
2000 if (strcmp(wal_level, "logical") != 0)
2001 pg_fatal("\"wal_level\" must be \"logical\" but is set to \"%s\"",
2002 wal_level);
2003
2004 max_replication_slots = atoi(PQgetvalue(res, 1, 0));
2005
2006 if (nslots_on_old > max_replication_slots)
2007 pg_fatal("\"max_replication_slots\" (%d) must be greater than or equal to the number of "
2008 "logical replication slots (%d) on the old cluster",
2009 max_replication_slots, nslots_on_old);
2010
2011 PQclear(res);
2012 PQfinish(conn);
2013
2014 check_ok();
2015}
int count_old_cluster_logical_slots(void)
Definition: info.c:744
int max_replication_slots
Definition: slot.c:150
int wal_level
Definition: xlog.c:131

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(), 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 2025 of file check.c.

2026{
2027 PGresult *res;
2028 PGconn *conn;
2030
2031 /* Subscriptions and their dependencies can be migrated since PG17. */
2033 return;
2034
2035 /* Quick return if there are no subscriptions to be migrated. */
2036 if (old_cluster.nsubs == 0)
2037 return;
2038
2039 prep_status("Checking for new cluster configuration for subscriptions");
2040
2041 conn = connectToServer(&new_cluster, "template1");
2042
2043 res = executeQueryOrDie(conn, "SELECT setting FROM pg_settings "
2044 "WHERE name = 'max_active_replication_origins';");
2045
2046 if (PQntuples(res) != 1)
2047 pg_fatal("could not determine parameter settings on new cluster");
2048
2049 max_active_replication_origins = atoi(PQgetvalue(res, 0, 0));
2051 pg_fatal("\"max_active_replication_origins\" (%d) must be greater than or equal to the number of "
2052 "subscriptions (%d) on the old cluster",
2054
2055 PQclear(res);
2056 PQfinish(conn);
2057
2058 check_ok();
2059}
int max_active_replication_origins
Definition: origin.c:104

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

Referenced by check_new_cluster().

◆ check_old_cluster_for_valid_slots()

static void check_old_cluster_for_valid_slots ( void  )
static

Definition at line 2068 of file check.c.

2069{
2070 char output_path[MAXPGPATH];
2071 FILE *script = NULL;
2072
2073 prep_status("Checking for valid logical replication slots");
2074
2075 snprintf(output_path, sizeof(output_path), "%s/%s",
2077 "invalid_logical_slots.txt");
2078
2079 for (int dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
2080 {
2081 LogicalSlotInfoArr *slot_arr = &old_cluster.dbarr.dbs[dbnum].slot_arr;
2082
2083 for (int slotnum = 0; slotnum < slot_arr->nslots; slotnum++)
2084 {
2085 LogicalSlotInfo *slot = &slot_arr->slots[slotnum];
2086
2087 /* Is the slot usable? */
2088 if (slot->invalid)
2089 {
2090 if (script == NULL &&
2091 (script = fopen_priv(output_path, "w")) == NULL)
2092 pg_fatal("could not open file \"%s\": %m", output_path);
2093
2094 fprintf(script, "The slot \"%s\" is invalid\n",
2095 slot->slotname);
2096
2097 continue;
2098 }
2099
2100 /*
2101 * Do additional check to ensure that all logical replication
2102 * slots have consumed all the WAL before shutdown.
2103 *
2104 * Note: This can be satisfied only when the old cluster has been
2105 * shut down, so we skip this for live checks.
2106 */
2107 if (!user_opts.live_check && !slot->caught_up)
2108 {
2109 if (script == NULL &&
2110 (script = fopen_priv(output_path, "w")) == NULL)
2111 pg_fatal("could not open file \"%s\": %m", output_path);
2112
2113 fprintf(script,
2114 "The slot \"%s\" has not consumed the WAL yet\n",
2115 slot->slotname);
2116 }
2117 }
2118 }
2119
2120 if (script)
2121 {
2122 fclose(script);
2123
2124 pg_log(PG_REPORT, "fatal");
2125 pg_fatal("Your installation contains logical replication slots that cannot be upgraded.\n"
2126 "You can remove invalid slots and/or consume the pending WAL for other slots,\n"
2127 "and then restart the upgrade.\n"
2128 "A list of the problematic slots is in the file:\n"
2129 " %s", output_path);
2130 }
2131
2132 check_ok();
2133}
LogicalSlotInfoArr slot_arr
Definition: pg_upgrade.h:203
LogicalSlotInfo * slots
Definition: pg_upgrade.h:174

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 2176 of file check.c.

2177{
2179 UpgradeTaskReport report;
2180 const char *query;
2181 PGresult *res;
2182 PGconn *conn;
2183 int ntup;
2184
2185 prep_status("Checking for subscription state");
2186
2187 report.file = NULL;
2188 snprintf(report.path, sizeof(report.path), "%s/%s",
2190 "subs_invalid.txt");
2191
2192 /*
2193 * Check that all the subscriptions have their respective replication
2194 * origin. This check only needs to run once.
2195 */
2197 res = executeQueryOrDie(conn,
2198 "SELECT d.datname, s.subname "
2199 "FROM pg_catalog.pg_subscription s "
2200 "LEFT OUTER JOIN pg_catalog.pg_replication_origin o "
2201 " ON o.roname = 'pg_' || s.oid "
2202 "INNER JOIN pg_catalog.pg_database d "
2203 " ON d.oid = s.subdbid "
2204 "WHERE o.roname IS NULL;");
2205 ntup = PQntuples(res);
2206 for (int i = 0; i < ntup; i++)
2207 {
2208 if (report.file == NULL &&
2209 (report.file = fopen_priv(report.path, "w")) == NULL)
2210 pg_fatal("could not open file \"%s\": %m", report.path);
2211 fprintf(report.file, "The replication origin is missing for database:\"%s\" subscription:\"%s\"\n",
2212 PQgetvalue(res, i, 0),
2213 PQgetvalue(res, i, 1));
2214 }
2215 PQclear(res);
2216 PQfinish(conn);
2217
2218 /*
2219 * We don't allow upgrade if there is a risk of dangling slot or origin
2220 * corresponding to initial sync after upgrade.
2221 *
2222 * A slot/origin not created yet refers to the 'i' (initialize) state,
2223 * while 'r' (ready) state refers to a slot/origin created previously but
2224 * already dropped. These states are supported for pg_upgrade. The other
2225 * states listed below are not supported:
2226 *
2227 * a) SUBREL_STATE_DATASYNC: A relation upgraded while in this state would
2228 * retain a replication slot, which could not be dropped by the sync
2229 * worker spawned after the upgrade because the subscription ID used for
2230 * the slot name won't match anymore.
2231 *
2232 * b) SUBREL_STATE_SYNCDONE: A relation upgraded while in this state would
2233 * retain the replication origin when there is a failure in tablesync
2234 * worker immediately after dropping the replication slot in the
2235 * publisher.
2236 *
2237 * c) SUBREL_STATE_FINISHEDCOPY: A tablesync worker spawned to work on a
2238 * relation upgraded while in this state would expect an origin ID with
2239 * the OID of the subscription used before the upgrade, causing it to
2240 * fail.
2241 *
2242 * d) SUBREL_STATE_SYNCWAIT, SUBREL_STATE_CATCHUP and
2243 * SUBREL_STATE_UNKNOWN: These states are not stored in the catalog, so we
2244 * need not allow these states.
2245 */
2246 query = "SELECT r.srsubstate, s.subname, n.nspname, c.relname "
2247 "FROM pg_catalog.pg_subscription_rel r "
2248 "LEFT JOIN pg_catalog.pg_subscription s"
2249 " ON r.srsubid = s.oid "
2250 "LEFT JOIN pg_catalog.pg_class c"
2251 " ON r.srrelid = c.oid "
2252 "LEFT JOIN pg_catalog.pg_namespace n"
2253 " ON c.relnamespace = n.oid "
2254 "WHERE r.srsubstate NOT IN ('i', 'r') "
2255 "ORDER BY s.subname";
2256
2258 true, &report);
2259
2261 upgrade_task_free(task);
2262
2263 if (report.file)
2264 {
2265 fclose(report.file);
2266 pg_log(PG_REPORT, "fatal");
2267 pg_fatal("Your installation contains subscriptions without origin or having relations not in i (initialize) or r (ready) state.\n"
2268 "You can allow the initial sync to finish for all relations and then restart the upgrade.\n"
2269 "A list of the problematic subscriptions is in the file:\n"
2270 " %s", report.path);
2271 }
2272 else
2273 check_ok();
2274}
static void process_old_sub_state_check(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: check.c:2141

References LogOpts::basedir, check_ok(), conn, connectToServer(), DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), UpgradeTaskReport::file, fopen_priv, fprintf, i, log_opts, old_cluster, UpgradeTaskReport::path, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQgetvalue(), PQntuples(), prep_status(), process_old_sub_state_check(), snprintf, upgrade_task_add_step(), upgrade_task_create(), upgrade_task_free(), and upgrade_task_run().

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 971 of file check.c.

972{
973 FILE *script = NULL;
974 int tblnum;
975 char old_cluster_pgdata[MAXPGPATH],
976 new_cluster_pgdata[MAXPGPATH];
977 char *old_tblspc_suffix;
978
979 *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
981
982 strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
983 canonicalize_path(old_cluster_pgdata);
984
985 strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
986 canonicalize_path(new_cluster_pgdata);
987
988 /* Some people put the new data directory inside the old one. */
989 if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
990 {
992 "\nWARNING: new data directory should not be inside the old data directory, i.e. %s", old_cluster_pgdata);
993
994 /* Unlink file in case it is left over from a previous run. */
995 unlink(*deletion_script_file_name);
996 pg_free(*deletion_script_file_name);
997 *deletion_script_file_name = NULL;
998 return;
999 }
1000
1001 /*
1002 * Some users (oddly) create tablespaces inside the cluster data
1003 * directory. We can't create a proper old cluster delete script in that
1004 * case.
1005 */
1006 for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
1007 {
1008 char old_tablespace_dir[MAXPGPATH];
1009
1010 strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
1011 canonicalize_path(old_tablespace_dir);
1012 if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
1013 {
1014 /* reproduce warning from CREATE TABLESPACE that is in the log */
1016 "\nWARNING: user-defined tablespace locations should not be inside the data directory, i.e. %s", old_tablespace_dir);
1017
1018 /* Unlink file in case it is left over from a previous run. */
1019 unlink(*deletion_script_file_name);
1020 pg_free(*deletion_script_file_name);
1021 *deletion_script_file_name = NULL;
1022 return;
1023 }
1024 }
1025
1026 prep_status("Creating script to delete old cluster");
1027
1028 if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
1029 pg_fatal("could not open file \"%s\": %m",
1030 *deletion_script_file_name);
1031
1032#ifndef WIN32
1033 /* add shebang header */
1034 fprintf(script, "#!/bin/sh\n\n");
1035#endif
1036
1037 /* delete old cluster's default tablespace */
1038 fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
1040
1041 /* delete old cluster's alternate tablespaces */
1042 old_tblspc_suffix = pg_strdup(old_cluster.tablespace_suffix);
1043 fix_path_separator(old_tblspc_suffix);
1044 for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
1045 fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
1047 old_tblspc_suffix, PATH_QUOTE);
1048 pfree(old_tblspc_suffix);
1049
1050 fclose(script);
1051
1052#ifndef WIN32
1053 if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
1054 pg_fatal("could not add execute permission to file \"%s\": %m",
1055 *deletion_script_file_name);
1056#endif
1057
1058 check_ok();
1059}
static char * fix_path_separator(char *path)
Definition: check.c:549
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void pfree(void *pointer)
Definition: mcxt.c:2152
#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
bool path_is_prefix_of_path(const char *path1, const char *path2)
Definition: path.c:637
void canonicalize_path(char *path)
Definition: path.c:337
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
char * pgdata
Definition: pg_upgrade.h:292
#define S_IRWXU
Definition: win32_port.h:288

References canonicalize_path(), check_ok(), fix_path_separator(), fopen_priv, fprintf, MAXPGPATH, new_cluster, OSInfo::num_old_tablespaces, old_cluster, OSInfo::old_tablespaces, os_info, path_is_prefix_of_path(), PATH_QUOTE, 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().

◆ data_type_check_query()

static char * data_type_check_query ( int  checknum)
static

Definition at line 332 of file check.c.

333{
335
336 return psprintf("WITH RECURSIVE oids AS ( "
337 /* start with the type(s) returned by base_query */
338 " %s "
339 " UNION ALL "
340 " SELECT * FROM ( "
341 /* inner WITH because we can only reference the CTE once */
342 " WITH x AS (SELECT oid FROM oids) "
343 /* domains on any type selected so far */
344 " SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typbasetype = x.oid AND typtype = 'd' "
345 " UNION ALL "
346 /* arrays over any type selected so far */
347 " SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typelem = x.oid AND typtype = 'b' "
348 " UNION ALL "
349 /* composite types containing any type selected so far */
350 " SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_class c, pg_catalog.pg_attribute a, x "
351 " WHERE t.typtype = 'c' AND "
352 " t.oid = c.reltype AND "
353 " c.oid = a.attrelid AND "
354 " NOT a.attisdropped AND "
355 " a.atttypid = x.oid "
356 " UNION ALL "
357 /* ranges containing any type selected so far */
358 " SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_range r, x "
359 " WHERE t.typtype = 'r' AND r.rngtypid = t.oid AND r.rngsubtype = x.oid"
360 " ) foo "
361 ") "
362 /* now look for stored columns of any such type */
363 "SELECT n.nspname, c.relname, a.attname "
364 "FROM pg_catalog.pg_class c, "
365 " pg_catalog.pg_namespace n, "
366 " pg_catalog.pg_attribute a "
367 "WHERE c.oid = a.attrelid AND "
368 " NOT a.attisdropped AND "
369 " a.atttypid IN (SELECT oid FROM oids) AND "
370 " c.relkind IN ("
371 CppAsString2(RELKIND_RELATION) ", "
372 CppAsString2(RELKIND_MATVIEW) ", "
373 CppAsString2(RELKIND_INDEX) ") AND "
374 " c.relnamespace = n.oid AND "
375 /* exclude possible orphaned temp tables */
376 " n.nspname !~ '^pg_temp_' AND "
377 " n.nspname !~ '^pg_toast_temp_' AND "
378 /* exclude system catalogs, too */
379 " n.nspname NOT IN ('pg_catalog', 'information_schema')",
380 check->base_query);
381}
#define CppAsString2(x)
Definition: c.h:363
const char * base_query
Definition: check.c:47

References DataTypesUsageChecks::base_query, CppAsString2, data_types_usage_checks, and psprintf().

Referenced by check_for_data_types_usage().

◆ fix_path_separator()

static char * fix_path_separator ( char *  path)
static

Definition at line 549 of file check.c.

550{
551#ifdef WIN32
552
553 char *result;
554 char *c;
555
556 result = pg_strdup(path);
557
558 for (c = result; *c != '\0'; c++)
559 if (*c == '/')
560 *c = '\\';
561
562 return result;
563#else
564
565 return path;
566#endif
567}
char * c

References pg_strdup(), and data_type_check_state::result.

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 783 of file check.c.

784{
785 /*
786 * We unconditionally start/stop the new server because pg_resetwal -o set
787 * wal_level to 'minimum'. If the user is upgrading standby servers using
788 * the rsync instructions, they will need pg_upgrade to write its final
789 * WAL record showing wal_level as 'replica'.
790 */
792
793 /* Reindex hash indexes for old < 10.0 */
796
798
799 stop_postmaster(false);
800}
void report_extension_updates(ClusterInfo *cluster)
Definition: version.c:179

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 570 of file check.c.

571{
573 {
575 "Performing Consistency Checks on Old Live Server\n"
576 "------------------------------------------------");
577 }
578 else
579 {
581 "Performing Consistency Checks\n"
582 "-----------------------------");
583 }
584}

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 804 of file check.c.

805{
806 PQExpBufferData user_specification;
807
808 initPQExpBuffer(&user_specification);
810 {
811 appendPQExpBufferStr(&user_specification, "-U ");
812 appendShellString(&user_specification, os_info.user);
813 appendPQExpBufferChar(&user_specification, ' ');
814 }
815
817 "Some statistics are not transferred by pg_upgrade.\n"
818 "Once you start the new server, consider running these two commands:\n"
819 " %s/vacuumdb %s--all --analyze-in-stages --missing-stats-only\n"
820 " %s/vacuumdb %s--all --analyze-only",
821 new_cluster.bindir, user_specification.data,
822 new_cluster.bindir, user_specification.data);
823
824 if (deletion_script_file_name)
826 "Running this script will delete the old cluster's data files:\n"
827 " %s",
828 deletion_script_file_name);
829 else
831 "Could not create a script to delete the old cluster's data files\n"
832 "because user-defined tablespaces or the new cluster's data directory\n"
833 "exist in the old cluster directory. The old cluster's contents must\n"
834 "be deleted manually.");
835
836 termPQExpBuffer(&user_specification);
837}
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:582
char * bindir
Definition: pg_upgrade.h:295
bool user_specified
Definition: pg_upgrade.h:356

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().

◆ process_data_type_check()

static void process_data_type_check ( DbInfo dbinfo,
PGresult res,
void *  arg 
)
static

Definition at line 389 of file check.c.

390{
392 int ntups = PQntuples(res);
393 char output_path[MAXPGPATH];
394 int i_nspname = PQfnumber(res, "nspname");
395 int i_relname = PQfnumber(res, "relname");
396 int i_attname = PQfnumber(res, "attname");
397 FILE *script = NULL;
398
400
401 if (ntups == 0)
402 return;
403
404 snprintf(output_path, sizeof(output_path), "%s/%s",
406 state->check->report_filename);
407
408 /*
409 * Make sure we have a buffer to save reports to now that we found a first
410 * failing check.
411 */
412 if (*state->report == NULL)
413 *state->report = createPQExpBuffer();
414
415 /*
416 * If this is the first time we see an error for the check in question
417 * then print a status message of the failure.
418 */
419 if (!state->result)
420 {
421 pg_log(PG_REPORT, "failed check: %s", _(state->check->status));
422 appendPQExpBuffer(*state->report, "\n%s\n%s %s\n",
423 _(state->check->report_text),
424 _("A list of the problem columns is in the file:"),
425 output_path);
426 }
427 state->result = true;
428
429 if ((script = fopen_priv(output_path, "a")) == NULL)
430 pg_fatal("could not open file \"%s\": %m", output_path);
431
432 fprintf(script, "In database: %s\n", dbinfo->db_name);
433
434 for (int rowno = 0; rowno < ntups; rowno++)
435 fprintf(script, " %s.%s.%s\n",
436 PQgetvalue(res, rowno, i_nspname),
437 PQgetvalue(res, rowno, i_relname),
438 PQgetvalue(res, rowno, i_attname));
439
440 fclose(script);
441}
#define AssertVariableIsOfType(varname, typename)
Definition: c.h:952
#define _(x)
Definition: elog.c:91
void * arg
void(* UpgradeTaskProcessCB)(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: pg_upgrade.h:511
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:72
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
Definition: regguts.h:323

References _, appendPQExpBuffer(), arg, AssertVariableIsOfType, LogOpts::basedir, createPQExpBuffer(), DbInfo::db_name, fopen_priv, fprintf, log_opts, MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, PQfnumber(), PQgetvalue(), PQntuples(), process_data_type_check(), and snprintf.

Referenced by check_for_data_types_usage(), and process_data_type_check().

◆ process_incompat_polymorphics()

static void process_incompat_polymorphics ( DbInfo dbinfo,
PGresult res,
void *  arg 
)
static

Definition at line 1428 of file check.c.

1429{
1431 int ntups = PQntuples(res);
1432 int i_objkind = PQfnumber(res, "objkind");
1433 int i_objname = PQfnumber(res, "objname");
1434
1437
1438 if (ntups == 0)
1439 return;
1440
1441 if (report->file == NULL &&
1442 (report->file = fopen_priv(report->path, "w")) == NULL)
1443 pg_fatal("could not open file \"%s\": %m", report->path);
1444
1445 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1446
1447 for (int rowno = 0; rowno < ntups; rowno++)
1448 fprintf(report->file, " %s: %s\n",
1449 PQgetvalue(res, rowno, i_objkind),
1450 PQgetvalue(res, rowno, i_objname));
1451}

References arg, AssertVariableIsOfType, DbInfo::db_name, UpgradeTaskReport::file, fopen_priv, fprintf, UpgradeTaskReport::path, pg_fatal, PQfnumber(), PQgetvalue(), PQntuples(), and process_incompat_polymorphics().

Referenced by check_for_incompatible_polymorphics(), and process_incompat_polymorphics().

◆ process_isn_and_int8_passing_mismatch()

static void process_isn_and_int8_passing_mismatch ( DbInfo dbinfo,
PGresult res,
void *  arg 
)
static

Definition at line 1248 of file check.c.

1249{
1250 int ntups = PQntuples(res);
1251 int i_nspname = PQfnumber(res, "nspname");
1252 int i_proname = PQfnumber(res, "proname");
1254
1257
1258 if (ntups == 0)
1259 return;
1260
1261 if (report->file == NULL &&
1262 (report->file = fopen_priv(report->path, "w")) == NULL)
1263 pg_fatal("could not open file \"%s\": %m", report->path);
1264
1265 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1266
1267 for (int rowno = 0; rowno < ntups; rowno++)
1268 fprintf(report->file, " %s.%s\n",
1269 PQgetvalue(res, rowno, i_nspname),
1270 PQgetvalue(res, rowno, i_proname));
1271}

References arg, AssertVariableIsOfType, DbInfo::db_name, UpgradeTaskReport::file, fopen_priv, fprintf, UpgradeTaskReport::path, pg_fatal, PQfnumber(), PQgetvalue(), PQntuples(), and process_isn_and_int8_passing_mismatch().

Referenced by check_for_isn_and_int8_passing_mismatch(), and process_isn_and_int8_passing_mismatch().

◆ process_old_sub_state_check()

static void process_old_sub_state_check ( DbInfo dbinfo,
PGresult res,
void *  arg 
)
static

Definition at line 2141 of file check.c.

2142{
2144 int ntups = PQntuples(res);
2145 int i_srsubstate = PQfnumber(res, "srsubstate");
2146 int i_subname = PQfnumber(res, "subname");
2147 int i_nspname = PQfnumber(res, "nspname");
2148 int i_relname = PQfnumber(res, "relname");
2149
2151
2152 if (ntups == 0)
2153 return;
2154
2155 if (report->file == NULL &&
2156 (report->file = fopen_priv(report->path, "w")) == NULL)
2157 pg_fatal("could not open file \"%s\": %m", report->path);
2158
2159 for (int i = 0; i < ntups; i++)
2160 fprintf(report->file, "The table sync state \"%s\" is not allowed for database:\"%s\" subscription:\"%s\" schema:\"%s\" relation:\"%s\"\n",
2161 PQgetvalue(res, i, i_srsubstate),
2162 dbinfo->db_name,
2163 PQgetvalue(res, i, i_subname),
2164 PQgetvalue(res, i, i_nspname),
2165 PQgetvalue(res, i, i_relname));
2166}

References arg, AssertVariableIsOfType, DbInfo::db_name, UpgradeTaskReport::file, fopen_priv, fprintf, i, UpgradeTaskReport::path, pg_fatal, PQfnumber(), PQgetvalue(), PQntuples(), and process_old_sub_state_check().

Referenced by check_old_cluster_subscription_state(), and process_old_sub_state_check().

◆ process_unicode_update()

static void process_unicode_update ( DbInfo dbinfo,
PGresult res,
void *  arg 
)
static

Definition at line 1774 of file check.c.

1775{
1777 int ntups = PQntuples(res);
1778 int i_reloid = PQfnumber(res, "reloid");
1779 int i_nspname = PQfnumber(res, "nspname");
1780 int i_relname = PQfnumber(res, "relname");
1781
1782 if (ntups == 0)
1783 return;
1784
1785 if (report->file == NULL &&
1786 (report->file = fopen_priv(report->path, "w")) == NULL)
1787 pg_fatal("could not open file \"%s\": %m", report->path);
1788
1789 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1790
1791 for (int rowno = 0; rowno < ntups; rowno++)
1792 fprintf(report->file, " (oid=%s) %s.%s\n",
1793 PQgetvalue(res, rowno, i_reloid),
1794 PQgetvalue(res, rowno, i_nspname),
1795 PQgetvalue(res, rowno, i_relname));
1796}

References arg, DbInfo::db_name, UpgradeTaskReport::file, fopen_priv, fprintf, UpgradeTaskReport::path, pg_fatal, PQfnumber(), PQgetvalue(), and PQntuples().

Referenced by check_for_unicode_update().

◆ process_user_defined_encoding_conversions()

static void process_user_defined_encoding_conversions ( DbInfo dbinfo,
PGresult res,
void *  arg 
)
static

Definition at line 1691 of file check.c.

1692{
1694 int ntups = PQntuples(res);
1695 int i_conoid = PQfnumber(res, "conoid");
1696 int i_conname = PQfnumber(res, "conname");
1697 int i_nspname = PQfnumber(res, "nspname");
1698
1701
1702 if (ntups == 0)
1703 return;
1704
1705 if (report->file == NULL &&
1706 (report->file = fopen_priv(report->path, "w")) == NULL)
1707 pg_fatal("could not open file \"%s\": %m", report->path);
1708
1709 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1710
1711 for (int rowno = 0; rowno < ntups; rowno++)
1712 fprintf(report->file, " (oid=%s) %s.%s\n",
1713 PQgetvalue(res, rowno, i_conoid),
1714 PQgetvalue(res, rowno, i_nspname),
1715 PQgetvalue(res, rowno, i_conname));
1716}

References arg, AssertVariableIsOfType, DbInfo::db_name, UpgradeTaskReport::file, fopen_priv, fprintf, UpgradeTaskReport::path, pg_fatal, PQfnumber(), PQgetvalue(), PQntuples(), and process_user_defined_encoding_conversions().

Referenced by check_for_user_defined_encoding_conversions(), and process_user_defined_encoding_conversions().

◆ process_user_defined_postfix_ops()

static void process_user_defined_postfix_ops ( DbInfo dbinfo,
PGresult res,
void *  arg 
)
static

Definition at line 1334 of file check.c.

1335{
1337 int ntups = PQntuples(res);
1338 int i_oproid = PQfnumber(res, "oproid");
1339 int i_oprnsp = PQfnumber(res, "oprnsp");
1340 int i_oprname = PQfnumber(res, "oprname");
1341 int i_typnsp = PQfnumber(res, "typnsp");
1342 int i_typname = PQfnumber(res, "typname");
1343
1346
1347 if (ntups == 0)
1348 return;
1349
1350 if (report->file == NULL &&
1351 (report->file = fopen_priv(report->path, "w")) == NULL)
1352 pg_fatal("could not open file \"%s\": %m", report->path);
1353
1354 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1355
1356 for (int rowno = 0; rowno < ntups; rowno++)
1357 fprintf(report->file, " (oid=%s) %s.%s (%s.%s, NONE)\n",
1358 PQgetvalue(res, rowno, i_oproid),
1359 PQgetvalue(res, rowno, i_oprnsp),
1360 PQgetvalue(res, rowno, i_oprname),
1361 PQgetvalue(res, rowno, i_typnsp),
1362 PQgetvalue(res, rowno, i_typname));
1363}

References arg, AssertVariableIsOfType, DbInfo::db_name, UpgradeTaskReport::file, fopen_priv, fprintf, UpgradeTaskReport::path, pg_fatal, PQfnumber(), PQgetvalue(), PQntuples(), and process_user_defined_postfix_ops().

Referenced by check_for_user_defined_postfix_ops(), and process_user_defined_postfix_ops().

◆ process_with_oids_check()

static void process_with_oids_check ( DbInfo dbinfo,
PGresult res,
void *  arg 
)
static

Definition at line 1561 of file check.c.

1562{
1564 int ntups = PQntuples(res);
1565 int i_nspname = PQfnumber(res, "nspname");
1566 int i_relname = PQfnumber(res, "relname");
1567
1569
1570 if (ntups == 0)
1571 return;
1572
1573 if (report->file == NULL &&
1574 (report->file = fopen_priv(report->path, "w")) == NULL)
1575 pg_fatal("could not open file \"%s\": %m", report->path);
1576
1577 fprintf(report->file, "In database: %s\n", dbinfo->db_name);
1578
1579 for (int rowno = 0; rowno < ntups; rowno++)
1580 fprintf(report->file, " %s.%s\n",
1581 PQgetvalue(res, rowno, i_nspname),
1582 PQgetvalue(res, rowno, i_relname));
1583}

References arg, AssertVariableIsOfType, DbInfo::db_name, UpgradeTaskReport::file, fopen_priv, fprintf, UpgradeTaskReport::path, pg_fatal, PQfnumber(), PQgetvalue(), PQntuples(), and process_with_oids_check().

Referenced by check_for_tables_with_oids(), and process_with_oids_check().

◆ report_clusters_compatible()

void report_clusters_compatible ( void  )

Definition at line 764 of file check.c.

765{
766 if (user_opts.check)
767 {
768 pg_log(PG_REPORT, "\n*Clusters are compatible*");
769 /* stops new cluster */
770 stop_postmaster(false);
771
773 exit(0);
774 }
775
776 pg_log(PG_REPORT, "\n"
777 "If pg_upgrade fails after this point, you must re-initdb the\n"
778 "new cluster before continuing.");
779}
void cleanup_output_dirs(void)
Definition: util.c:63

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

Referenced by main().

◆ unicode_version_changed()

static bool unicode_version_changed ( ClusterInfo cluster)
static

Definition at line 1803 of file check.c.

1804{
1805 PGconn *conn_template1 = connectToServer(cluster, "template1");
1806 PGresult *res;
1807 char *old_unicode_version;
1808 bool unicode_updated;
1809
1810 res = executeQueryOrDie(conn_template1, "SELECT unicode_version()");
1811 old_unicode_version = PQgetvalue(res, 0, 0);
1812 unicode_updated = (strcmp(old_unicode_version, PG_UNICODE_VERSION) != 0);
1813
1814 PQclear(res);
1815 PQfinish(conn_template1);
1816
1817 return unicode_updated;
1818}
#define PG_UNICODE_VERSION

References cluster(), connectToServer(), executeQueryOrDie(), PG_UNICODE_VERSION, PQclear(), PQfinish(), and PQgetvalue().

Referenced by check_for_unicode_update().

Variable Documentation

◆ data_types_usage_checks

DataTypesUsageChecks data_types_usage_checks[]
static

Definition at line 97 of file check.c.

Referenced by check_for_data_types_usage(), and data_type_check_query().