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:1586
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1630
static void check_for_data_types_usage(ClusterInfo *cluster)
Definition: check.c:463
static void check_old_cluster_subscription_state(void)
Definition: check.c:2173
static void check_for_unicode_update(ClusterInfo *cluster)
Definition: check.c:1825
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:1066
static void check_for_connection_status(ClusterInfo *cluster)
Definition: check.c:1124
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:1278
static void check_old_cluster_for_valid_slots(void)
Definition: check.c:2065
static void check_for_user_defined_postfix_ops(ClusterInfo *cluster)
Definition: check.c:1366
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:1212
static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
Definition: check.c:1719
static void check_for_incompatible_polymorphics(ClusterInfo *cluster)
Definition: check.c:1457
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 893 of file check.c.

894{
895 /* get/check pg_control data of servers */
899
901 pg_fatal("When checking a live server, "
902 "the old and new port numbers must be different.");
903}
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 838 of file check.c.

839{
840 prep_status("Checking cluster versions");
841
842 /* cluster versions should already have been obtained */
845
846 /*
847 * We allow upgrades from/to the same major version for alpha/beta
848 * upgrades
849 */
850
852 pg_fatal("This utility can only upgrade from PostgreSQL version %s and later.",
853 "9.2");
854
855 /* Only current PG version is supported as a target */
857 pg_fatal("This utility can only upgrade to PostgreSQL version %s.",
858 PG_MAJORVERSION);
859
860 /*
861 * We can't allow downgrading because we use the target pg_dump, and
862 * pg_dump cannot operate on newer database versions, only current and
863 * older versions.
864 */
866 pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.");
867
868 /* Ensure binaries match the designated data directories */
871 pg_fatal("Old cluster data and binary directories are from different major versions.");
874 pg_fatal("New cluster data and binary directories are from different major versions.");
875
876 /*
877 * Since from version 18, newly created database clusters always have
878 * 'signed' default char-signedness, it makes less sense to use
879 * --set-char-signedness option for upgrading from version 18 or later.
880 * Users who want to change the default char signedness of the new
881 * cluster, they can use pg_resetwal manually before the upgrade.
882 */
885 pg_fatal("%s option cannot be used to upgrade from PostgreSQL %s and later.",
886 "--set-char-signedness", "18");
887
888 check_ok();
889}
Assert(PointerIsAligned(start, uint64))
static void check_ok(void)
Definition: initdb.c:2117
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 1124 of file check.c.

1125{
1126 int dbnum;
1127 PGconn *conn_template1;
1128 PGresult *dbres;
1129 int ntups;
1130 int i_datname;
1131 int i_datallowconn;
1132 int i_datconnlimit;
1133 FILE *script = NULL;
1134 char output_path[MAXPGPATH];
1135
1136 prep_status("Checking database connection settings");
1137
1138 snprintf(output_path, sizeof(output_path), "%s/%s",
1140 "databases_cannot_connect_to.txt");
1141
1142 conn_template1 = connectToServer(cluster, "template1");
1143
1144 /* get database names */
1145 dbres = executeQueryOrDie(conn_template1,
1146 "SELECT datname, datallowconn, datconnlimit "
1147 "FROM pg_catalog.pg_database");
1148
1149 i_datname = PQfnumber(dbres, "datname");
1150 i_datallowconn = PQfnumber(dbres, "datallowconn");
1151 i_datconnlimit = PQfnumber(dbres, "datconnlimit");
1152
1153 ntups = PQntuples(dbres);
1154 for (dbnum = 0; dbnum < ntups; dbnum++)
1155 {
1156 char *datname = PQgetvalue(dbres, dbnum, i_datname);
1157 char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
1158 char *datconnlimit = PQgetvalue(dbres, dbnum, i_datconnlimit);
1159
1160 if (strcmp(datname, "template0") == 0)
1161 {
1162 /* avoid restore failure when pg_dumpall tries to create template0 */
1163 if (strcmp(datallowconn, "t") == 0)
1164 pg_fatal("template0 must not allow connections, "
1165 "i.e. its pg_database.datallowconn must be false");
1166 }
1167 else
1168 {
1169 /*
1170 * Avoid datallowconn == false databases from being skipped on
1171 * restore, and ensure that no databases are marked invalid with
1172 * datconnlimit == -2.
1173 */
1174 if ((strcmp(datallowconn, "f") == 0) || strcmp(datconnlimit, "-2") == 0)
1175 {
1176 if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1177 pg_fatal("could not open file \"%s\": %m", output_path);
1178
1179 fprintf(script, "%s\n", datname);
1180 }
1181 }
1182 }
1183
1184 PQclear(dbres);
1185
1186 PQfinish(conn_template1);
1187
1188 if (script)
1189 {
1190 fclose(script);
1191 pg_log(PG_REPORT, "fatal");
1192 pg_fatal("All non-template0 databases must allow connections, i.e. their\n"
1193 "pg_database.datallowconn must be true and pg_database.datconnlimit\n"
1194 "must not be -2. Your installation contains non-template0 databases\n"
1195 "which cannot be connected to. Consider allowing connection for all\n"
1196 "non-template0 databases or drop the databases which do not allow\n"
1197 "connections. A list of databases with the problem is in the file:\n"
1198 " %s", output_path);
1199 }
1200 else
1201 check_ok();
1202}
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:5290
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 1457 of file check.c.

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

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

940{
941 int tblnum;
942 char new_tablespace_dir[MAXPGPATH];
943
944 prep_status("Checking for new cluster tablespace directories");
945
946 for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
947 {
948 struct stat statbuf;
949
950 snprintf(new_tablespace_dir, MAXPGPATH, "%s%s",
951 os_info.old_tablespaces[tblnum],
953
954 if (stat(new_tablespace_dir, &statbuf) == 0 || errno != ENOENT)
955 pg_fatal("new cluster tablespace directory already exists: \"%s\"",
956 new_tablespace_dir);
957 }
958
959 check_ok();
960}
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 1630 of file check.c.

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

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

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

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

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

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

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

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

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

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

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

908{
909 int dbnum;
910
911 for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
912 {
913 int relnum;
914 RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
915
916 for (relnum = 0; relnum < rel_arr->nrels;
917 relnum++)
918 {
919 /* pg_largeobject and its index should be skipped */
920 if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
921 pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"",
923 rel_arr->rels[relnum].nspname,
924 rel_arr->rels[relnum].relname);
925 }
926 }
927}
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 1949 of file check.c.

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

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

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

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

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

969{
970 FILE *script = NULL;
971 int tblnum;
972 char old_cluster_pgdata[MAXPGPATH],
973 new_cluster_pgdata[MAXPGPATH];
974 char *old_tblspc_suffix;
975
976 *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
978
979 strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
980 canonicalize_path(old_cluster_pgdata);
981
982 strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
983 canonicalize_path(new_cluster_pgdata);
984
985 /* Some people put the new data directory inside the old one. */
986 if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
987 {
989 "\nWARNING: new data directory should not be inside the old data directory, i.e. %s", old_cluster_pgdata);
990
991 /* Unlink file in case it is left over from a previous run. */
992 unlink(*deletion_script_file_name);
993 pg_free(*deletion_script_file_name);
994 *deletion_script_file_name = NULL;
995 return;
996 }
997
998 /*
999 * Some users (oddly) create tablespaces inside the cluster data
1000 * directory. We can't create a proper old cluster delete script in that
1001 * case.
1002 */
1003 for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
1004 {
1005 char old_tablespace_dir[MAXPGPATH];
1006
1007 strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
1008 canonicalize_path(old_tablespace_dir);
1009 if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
1010 {
1011 /* reproduce warning from CREATE TABLESPACE that is in the log */
1013 "\nWARNING: user-defined tablespace locations should not be inside the data directory, i.e. %s", old_tablespace_dir);
1014
1015 /* Unlink file in case it is left over from a previous run. */
1016 unlink(*deletion_script_file_name);
1017 pg_free(*deletion_script_file_name);
1018 *deletion_script_file_name = NULL;
1019 return;
1020 }
1021 }
1022
1023 prep_status("Creating script to delete old cluster");
1024
1025 if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
1026 pg_fatal("could not open file \"%s\": %m",
1027 *deletion_script_file_name);
1028
1029#ifndef WIN32
1030 /* add shebang header */
1031 fprintf(script, "#!/bin/sh\n\n");
1032#endif
1033
1034 /* delete old cluster's default tablespace */
1035 fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
1037
1038 /* delete old cluster's alternate tablespaces */
1039 old_tblspc_suffix = pg_strdup(old_cluster.tablespace_suffix);
1040 fix_path_separator(old_tblspc_suffix);
1041 for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
1042 fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
1044 old_tblspc_suffix, PATH_QUOTE);
1045 pfree(old_tblspc_suffix);
1046
1047 fclose(script);
1048
1049#ifndef WIN32
1050 if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
1051 pg_fatal("could not add execute permission to file \"%s\": %m",
1052 *deletion_script_file_name);
1053#endif
1054
1055 check_ok();
1056}
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:2150
#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 optimizer statistics may not have been transferred by pg_upgrade.\n"
818 "Once you start the new server, consider running:\n"
819 " %s/vacuumdb %s--all --analyze-in-stages --missing-stats-only", new_cluster.bindir, user_specification.data);
820
821 if (deletion_script_file_name)
823 "Running this script will delete the old cluster's data files:\n"
824 " %s",
825 deletion_script_file_name);
826 else
828 "Could not create a script to delete the old cluster's data files\n"
829 "because user-defined tablespaces or the new cluster's data directory\n"
830 "exist in the old cluster directory. The old cluster's contents must\n"
831 "be deleted manually.");
832
833 termPQExpBuffer(&user_specification);
834}
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 1425 of file check.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1801{
1802 PGconn *conn_template1 = connectToServer(cluster, "template1");
1803 PGresult *res;
1804 char *old_unicode_version;
1805 bool unicode_updated;
1806
1807 res = executeQueryOrDie(conn_template1, "SELECT unicode_version()");
1808 old_unicode_version = PQgetvalue(res, 0, 0);
1809 unicode_updated = (strcmp(old_unicode_version, PG_UNICODE_VERSION) != 0);
1810
1811 PQclear(res);
1812 PQfinish(conn_template1);
1813
1814 return unicode_updated;
1815}
#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().