Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sVuJB-00CGFp-U1 for pgsql-hackers@arkaria.postgresql.org; Mon, 22 Jul 2024 14:46:37 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1sVuJA-0030SI-41 for pgsql-hackers@arkaria.postgresql.org; Mon, 22 Jul 2024 14:46:36 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sVuJ9-0030S9-KM for pgsql-hackers@lists.postgresql.org; Mon, 22 Jul 2024 14:46:36 +0000 Received: from mail-il1-x136.google.com ([2607:f8b0:4864:20::136]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sVuJ7-000sKS-3P for pgsql-hackers@lists.postgresql.org; Mon, 22 Jul 2024 14:46:34 +0000 Received: by mail-il1-x136.google.com with SMTP id e9e14a558f8ab-39626aee4easo20073875ab.3 for ; Mon, 22 Jul 2024 07:46:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1721659592; x=1722264392; darn=lists.postgresql.org; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date:from:to :cc:subject:date:message-id:reply-to; bh=Hx6HJNKSK3FT50QGZ9/7a+OTrkEpKilppdD0zc0koDI=; b=Gu5t7XjqFihbzUDxu/UOmStDR92sVvXrTNwArbcHjh6vZGRwk3CbzHLGdOsKwt6E85 Iwpxr2EuS+DQMmwp8ca43MVeNd43ozcz9BIGmxiO/lcmRVpMWfpfrOOD7XjVFBMm4+sT akJ4xNCd1AdEUmjGXKUkD2n/lkYojDZxICLuGLANgr9Z5EMTgLRh344eVmcxrsc+yfsQ xRjJ9Kp9u8pLin+kNEiVSB8R/lCKyer7aF62JoSDu4i2noxS9IRmvIrsrWJI0QsGLSuK T6/PdliHekc1pfqN0GNTiToIfr1gjmt97QdIsECLWn87xY8U3vm8BImutnYiPJikdRfB wU3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1721659592; x=1722264392; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Hx6HJNKSK3FT50QGZ9/7a+OTrkEpKilppdD0zc0koDI=; b=nIQ54fFf4FPOAhW7lM9FbFG7QP0Zo5iSz2WT0F0pdfOp1pjIbDgag4kJkzx0KZdX+U aCpHZpDeHoCv/mgBa8wEp9g210AFp2H68La36AmKSh+QsfJl7eWFjWcoEVZu/AKvlV70 dKFXsAl71owYsdCSgDOPg0ZCBdjuUMJXaXi0zMwzSDrfZoho4AgNZ7HdsVxgY5VZ0NPu 5oEI1pet4Bj+19tT1JcbnTwjG0TQ8txUFZlTxRRm6LkjdX/cxSIMOrghwg2Tl5a7gglM 4FIXPW1aJMnSPw+UnQ9HW9yxp6zNtBolVaGY1u7s3VCj2GmBB/MS5u6Jw1ycYPBLzSsd 091Q== X-Forwarded-Encrypted: i=1; AJvYcCXe1+Ix48h/ufr3x/j0kVxYu1fDwG/NY/sWoL9UbGgQTjOdLUVdE1AUDBYJY/Matnm9UJq7hGd7tmcqyZE0Uzv2znT9GR/n6SjTgJGvRxQJeAZj X-Gm-Message-State: AOJu0YzxnkU8LKxD0iQEF4gwtVVTo2DvQqlkOshbjg+ei+++xkaaqn3E It4qV02G7yMAFuyCOlvnNeh/iHeZqr5dJAcyNlH6wnZzo2vW7ocS X-Google-Smtp-Source: AGHT+IE+HNgJNbkoPBJRgSZaNT2vZLOmD1354eJDxk+KGSBJafhF7p+kli4zsYx0BQFm+F/L+3l8nw== X-Received: by 2002:a92:ca4f:0:b0:377:14a7:fc99 with SMTP id e9e14a558f8ab-398e6e819e6mr119648075ab.24.1721659592101; Mon, 22 Jul 2024 07:46:32 -0700 (PDT) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id e9e14a558f8ab-397f5c2b7aesm25557045ab.40.2024.07.22.07.46.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Jul 2024 07:46:31 -0700 (PDT) Date: Mon, 22 Jul 2024 09:46:29 -0500 From: Nathan Bossart To: Amit Kapila Cc: Michael Paquier , vignesh C , "Hayato Kuroda (Fujitsu)" , Justin Pryzby , Masahiko Sawada , Peter Smith , Julien Rouhaud , "pgsql-hackers@lists.postgresql.org" Subject: Re: pg_upgrade and logical replication Message-ID: References: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="J2K2qp3eYz+vxFHK" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --J2K2qp3eYz+vxFHK Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit On Mon, Jul 22, 2024 at 03:45:19PM +0530, Amit Kapila wrote: > On Mon, Jul 22, 2024 at 7:35 AM Michael Paquier wrote: >> On Sat, Jul 20, 2024 at 09:03:07PM -0500, Nathan Bossart wrote: >> >> This is an extremely expensive way to perform that check, and so I'm >> >> wondering why we don't just do >> >> >> >> SELECT count(*) FROM pg_catalog.pg_subscription; >> >> >> >> once in count_old_cluster_subscriptions(). >> > >> > Like so... > > Isn't it better to directly invoke get_subscription_count() in > check_new_cluster_subscription_configuration() where it is required > rather than in a db-specific general function? IIUC the old cluster won't be running at that point. >> Ah, good catch. That sounds like a good thing to do because we don't >> care about the number of subscriptions for each database in the >> current code. >> >> This is something that qualifies as an open item, IMO, as this code >> is new to PG17. +1 >> A comment in get_db_rel_and_slot_infos() becomes incorrect where >> get_old_cluster_logical_slot_infos() is called; it is still referring >> to the subscription count. I removed this comment since IMHO it doesn't add much. >> Actually, on the same grounds, couldn't we do the logical slot info >> retrieval in get_old_cluster_logical_slot_infos() in a single pass as >> well? pg_replication_slots reports some information about all the >> slots, and the current code has a qual on current_database(). It >> looks to me that this could be replaced by a single query, ordering >> the slots by database names, assigning the slot infos in each >> database's DbInfo at the end. > > Unlike subscriptions, logical slots are database-specific objects. We > have some checks in the code like the one in CreateDecodingContext() > for MyDatabaseId which may or may not create a problem for this case > as we don't consume changes when checking > LogicalReplicationSlotHasPendingWal via > binary_upgrade_logical_slot_has_caught_up() but I think this needs > more analysis than what Nathan has proposed. So, I suggest taking up > this task for PG18 if we want to optimize this code path. I see what you mean. -- nathan --J2K2qp3eYz+vxFHK Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="v2-0001-pg_upgrade-retrieve-subscription-count-more-effic.patch" From b3c3c6533e7f221dc869e613e78802a3054d42b3 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Sat, 20 Jul 2024 21:01:29 -0500 Subject: [PATCH v2 1/1] pg_upgrade: retrieve subscription count more efficiently --- src/bin/pg_upgrade/check.c | 9 +++---- src/bin/pg_upgrade/info.c | 43 +++++++-------------------------- src/bin/pg_upgrade/pg_upgrade.h | 3 +-- 3 files changed, 13 insertions(+), 42 deletions(-) diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 27924159d6..39d14b7b92 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -1797,17 +1797,14 @@ check_new_cluster_subscription_configuration(void) { PGresult *res; PGconn *conn; - int nsubs_on_old; int max_replication_slots; /* Subscriptions and their dependencies can be migrated since PG17. */ if (GET_MAJOR_VERSION(old_cluster.major_version) < 1700) return; - nsubs_on_old = count_old_cluster_subscriptions(); - /* Quick return if there are no subscriptions to be migrated. */ - if (nsubs_on_old == 0) + if (old_cluster.nsubs == 0) return; prep_status("Checking for new cluster configuration for subscriptions"); @@ -1821,10 +1818,10 @@ check_new_cluster_subscription_configuration(void) pg_fatal("could not determine parameter settings on new cluster"); max_replication_slots = atoi(PQgetvalue(res, 0, 0)); - if (nsubs_on_old > max_replication_slots) + if (old_cluster.nsubs > max_replication_slots) pg_fatal("\"max_replication_slots\" (%d) must be greater than or equal to the number of " "subscriptions (%d) on the old cluster", - max_replication_slots, nsubs_on_old); + max_replication_slots, old_cluster.nsubs); PQclear(res); PQfinish(conn); diff --git a/src/bin/pg_upgrade/info.c b/src/bin/pg_upgrade/info.c index 95c22a7200..e43be79aa5 100644 --- a/src/bin/pg_upgrade/info.c +++ b/src/bin/pg_upgrade/info.c @@ -28,7 +28,7 @@ static void print_db_infos(DbInfoArr *db_arr); static void print_rel_infos(RelInfoArr *rel_arr); static void print_slot_infos(LogicalSlotInfoArr *slot_arr); static void get_old_cluster_logical_slot_infos(DbInfo *dbinfo, bool live_check); -static void get_db_subscription_count(DbInfo *dbinfo); +static void get_subscription_count(ClusterInfo *cluster); /* @@ -293,17 +293,13 @@ get_db_rel_and_slot_infos(ClusterInfo *cluster, bool live_check) get_rel_infos(cluster, pDbInfo); - /* - * Retrieve the logical replication slots infos and the subscriptions - * count for the old cluster. - */ if (cluster == &old_cluster) - { get_old_cluster_logical_slot_infos(pDbInfo, live_check); - get_db_subscription_count(pDbInfo); - } } + if (cluster == &old_cluster) + get_subscription_count(cluster); + if (cluster == &old_cluster) pg_log(PG_VERBOSE, "\nsource databases:"); else @@ -750,14 +746,14 @@ count_old_cluster_logical_slots(void) /* * get_db_subscription_count() * - * Gets the number of subscriptions in the database referred to by "dbinfo". + * Gets the number of subscriptions in the cluster. * * Note: This function will not do anything if the old cluster is pre-PG17. * This is because before that the logical slots are not upgraded, so we will * not be able to upgrade the logical replication clusters completely. */ static void -get_db_subscription_count(DbInfo *dbinfo) +get_subscription_count(ClusterInfo *cluster) { PGconn *conn; PGresult *res; @@ -766,36 +762,15 @@ get_db_subscription_count(DbInfo *dbinfo) if (GET_MAJOR_VERSION(old_cluster.major_version) < 1700) return; - conn = connectToServer(&old_cluster, dbinfo->db_name); + conn = connectToServer(&old_cluster, "template1"); res = executeQueryOrDie(conn, "SELECT count(*) " - "FROM pg_catalog.pg_subscription WHERE subdbid = %u", - dbinfo->db_oid); - dbinfo->nsubs = atoi(PQgetvalue(res, 0, 0)); + "FROM pg_catalog.pg_subscription"); + cluster->nsubs = atoi(PQgetvalue(res, 0, 0)); PQclear(res); PQfinish(conn); } -/* - * count_old_cluster_subscriptions() - * - * Returns the number of subscriptions for all databases. - * - * Note: this function always returns 0 if the old_cluster is PG16 and prior - * because we gather subscriptions only for cluster versions greater than or - * equal to PG17. See get_db_subscription_count(). - */ -int -count_old_cluster_subscriptions(void) -{ - int nsubs = 0; - - for (int dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++) - nsubs += old_cluster.dbarr.dbs[dbnum].nsubs; - - return nsubs; -} - static void free_db_and_rel_infos(DbInfoArr *db_arr) { diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h index 8afe240bdf..e6dbbe6a93 100644 --- a/src/bin/pg_upgrade/pg_upgrade.h +++ b/src/bin/pg_upgrade/pg_upgrade.h @@ -197,7 +197,6 @@ typedef struct * path */ RelInfoArr rel_arr; /* array of all user relinfos */ LogicalSlotInfoArr slot_arr; /* array of all LogicalSlotInfo */ - int nsubs; /* number of subscriptions */ } DbInfo; /* @@ -296,6 +295,7 @@ typedef struct char major_version_str[64]; /* string PG_VERSION of cluster */ uint32 bin_version; /* version returned from pg_ctl */ const char *tablespace_suffix; /* directory specification */ + int nsubs; /* number of subscriptions */ } ClusterInfo; @@ -430,7 +430,6 @@ FileNameMap *gen_db_file_maps(DbInfo *old_db, const char *new_pgdata); void get_db_rel_and_slot_infos(ClusterInfo *cluster, bool live_check); int count_old_cluster_logical_slots(void); -int count_old_cluster_subscriptions(void); /* option.c */ -- 2.39.3 (Apple Git-146) --J2K2qp3eYz+vxFHK--