Skip to content

Commit e7ea2df

Browse files
committed
[#31357] YSQL: Conn Mgr - Update SIGHUP LCV on AP Control Backends on SIGHUP
Summary: Setup: Connection Manager enabled in Auth Passthrough mode. `enable_ysql_conn_mgr=true` & `ysql_conn_mgr_use_auth_backend=false`. Issue: GUC vars updated via SIGHUPs are not visible on newly authenticated clients (authenticated after GUC change is effected). These are PGC_BACKEND GUCs that require postmaster to process a SIGHUP and re-read the PG config. The root cause is that control backends don't update their "Logical Client Version" when handling a SIGHUP. The LCV which indicates the latest "version" of GUC changes that *should* be visible to a client. Thus, clients aren't assigned to transactional backends having the correct LCV (thus, not having the correct/expected GUC values). Solution: Control backend LCVs are updated same as postmaster LCVs, but separately (not set directly from the postmaster LCV). This involves setting the increment_LCV flag in guc.c for control backends (in addition for the postmaster proc) and incrementing the SIGHUP_LCV for the control backend in the SIGHUP handler section of the main postgres.c backend loop. Test Plan: Jenkins: all tests Manually run with Auth Passthrough enabled `./yb_build.sh --enable-ysql-conn-mgr-test --java-test 'org.yb.ysqlconnmgr.TestSessionParameters#testUpdatingRuntimeFlagPGCBackend'` `./yb_build.sh --enable-ysql-conn-mgr-test --java-test 'org.yb.pgsql.TestPgRegressThirdPartyExtensionsPgHintPlan#schedule'` `./yb_build.sh --enable-ysql-conn-mgr-test --java-test 'org.yb.ysqlconnmgr.TestAuthPassthrough'` Reviewers: skumar, arpit.saxena, mkumar Reviewed By: arpit.saxena Subscribers: yql Differential Revision: https://phorge.dev.yugabyte.com/D52580
1 parent 1f718f1 commit e7ea2df

5 files changed

Lines changed: 87 additions & 46 deletions

File tree

java/yb-ysql-conn-mgr/src/test/java/org/yb/ysqlconnmgr/TestSessionParameters.java

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -866,16 +866,7 @@ public void testUpdatingRuntimeFlagPGCSession() throws Exception {
866866
}
867867
}
868868

869-
@Test
870-
public void testUpdatingRuntimeFlagPGCBackend() throws Exception {
871-
Map<String, String> tserverFlags = new HashMap<>();
872-
tserverFlags.put("allowed_preview_flags_csv", "ysql_conn_mgr_alter_guc_adoption_strategy,"
873-
+ "ysql_conn_mgr_alter_guc_stale_backend_ttl_ms");
874-
tserverFlags.put("ysql_conn_mgr_alter_guc_adoption_strategy", "connection_static");
875-
tserverFlags.put("ysql_conn_mgr_alter_guc_stale_backend_ttl_ms", Integer.toString(-1));
876-
tserverFlags.put("ysql_conn_mgr_max_conns_per_db", "6");
877-
restartClusterWithAdditionalFlags(java.util.Collections.emptyMap(), tserverFlags);
878-
869+
private void updateRuntimeFlagPGCBackend() throws Exception {
879870
try (
880871
Connection conn =
881872
getConnectionBuilder().withConnectionEndpoint(ConnectionEndpoint.YSQL_CONN_MGR)
@@ -918,4 +909,32 @@ public void testUpdatingRuntimeFlagPGCBackend() throws Exception {
918909
}
919910
}
920911
}
912+
913+
@Test
914+
public void testUpdatingRuntimeFlagPGCBackendAuthBackend() throws Exception {
915+
Map<String, String> tserverFlags = new HashMap<>();
916+
tserverFlags.put("allowed_preview_flags_csv", "ysql_conn_mgr_alter_guc_adoption_strategy,"
917+
+ "ysql_conn_mgr_alter_guc_stale_backend_ttl_ms");
918+
tserverFlags.put("ysql_conn_mgr_alter_guc_adoption_strategy", "connection_static");
919+
tserverFlags.put("ysql_conn_mgr_alter_guc_stale_backend_ttl_ms", Integer.toString(-1));
920+
tserverFlags.put("ysql_conn_mgr_max_conns_per_db", "6");
921+
tserverFlags.put("ysql_conn_mgr_use_auth_backend", "true");
922+
restartClusterWithAdditionalFlags(java.util.Collections.emptyMap(), tserverFlags);
923+
924+
updateRuntimeFlagPGCBackend();
925+
}
926+
927+
@Test
928+
public void testUpdatingRuntimeFlagPGCBackendAuthPassthrough() throws Exception {
929+
Map<String, String> tserverFlags = new HashMap<>();
930+
tserverFlags.put("allowed_preview_flags_csv", "ysql_conn_mgr_alter_guc_adoption_strategy,"
931+
+ "ysql_conn_mgr_alter_guc_stale_backend_ttl_ms");
932+
tserverFlags.put("ysql_conn_mgr_alter_guc_adoption_strategy", "connection_static");
933+
tserverFlags.put("ysql_conn_mgr_alter_guc_stale_backend_ttl_ms", Integer.toString(-1));
934+
tserverFlags.put("ysql_conn_mgr_max_conns_per_db", "6");
935+
tserverFlags.put("ysql_conn_mgr_use_auth_backend", "false");
936+
restartClusterWithAdditionalFlags(java.util.Collections.emptyMap(), tserverFlags);
937+
938+
updateRuntimeFlagPGCBackend();
939+
}
921940
}

src/postgres/src/backend/tcop/postgres.c

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6830,35 +6830,31 @@ PostgresMain(const char *dbname, const char *username)
68306830
if (ConfigReloadPending)
68316831
{
68326832
ConfigReloadPending = false;
6833+
68336834
/*
6834-
* YB: Reloading postgres config file on a control connection can
6835-
* have some repercussion, therefore adopting most safest option;
6836-
* destroy the control connection which leads to failure of client
6837-
* authentication and let client keep trying agin untill a new
6838-
* control connection is formed for authentication with updated
6839-
* config file.
6840-
* Control connection is identified if a connection receives a
6841-
* Auth Passthrough Request ('A') packet.
6835+
* YB: Check whether this is a Conn Mgr "Control Backend", in case a
6836+
* config reload happens before the first Auth request packet is
6837+
* handled by this backend. See the 'A' packet handler below for
6838+
* more details.
6839+
* Control backends need to update their SIGHUP LCVs in tandem with
6840+
* the postmaster process (for this, they need to be identified as
6841+
* control backends before calling `ProcessConfigFile`).
6842+
* We don't care about the actual GUC setting changed or its value
6843+
* as these will be correctly set on transactional backends with
6844+
* matching Logical Client Version
6845+
* (Final LCV = catalog_table_LCV + SIGHUP_LCV).
68426846
*/
6843-
if (firstchar == 'A') /* Auth Passthrough Request */
6844-
{
6845-
/*
6846-
* Make sure auth pass through packet is sent by connection
6847-
* manager only
6848-
*/
6849-
if (!YbIsClientYsqlConnMgr())
6850-
ereport(FATAL,
6851-
(errcode(ERRCODE_PROTOCOL_VIOLATION),
6852-
errmsg("invalid frontend message type %d", firstchar)));
6847+
if (firstchar == 'A' && YbIsClientYsqlConnMgr())
6848+
yb_conn_mgr_is_auth_passthrough_backend = true;
68536849

6854-
ereport(FATAL,
6855-
(errcode(ERRCODE_PROTOCOL_VIOLATION),
6856-
errmsg("reloading config on control connection is not supported")));
6857-
}
6858-
else
6850+
ProcessConfigFile(PGC_SIGHUP);
6851+
6852+
if (yb_conn_mgr_is_auth_passthrough_backend &&
6853+
yb_conn_mgr_sighup_had_backend_guc_change)
68596854
{
6860-
ProcessConfigFile(PGC_SIGHUP);
6861-
} /* YB */
6855+
yb_conn_mgr_sighup_logical_client_version++;
6856+
yb_conn_mgr_sighup_had_backend_guc_change = false;
6857+
}
68626858
}
68636859

68646860
/*
@@ -7512,10 +7508,20 @@ PostgresMain(const char *dbname, const char *username)
75127508
*/
75137509
if (YbIsClientYsqlConnMgr())
75147510
{
7511+
/*
7512+
* YB: Only "Control Backends" are supposed to receive 'A'
7513+
* authentication request packets (in the Auth Passthrough mode
7514+
* of Conn Mgr). Conversely, 'A' packets are supposed to be
7515+
* handled by control backends only. So, the receipt of this
7516+
* packet with Conn Mgr enabled can be taken as confirmation
7517+
* that this is a control backend. This information is required
7518+
* to correctly process SIGHUPs involving PGC_BACKEND GUC
7519+
* updates.
7520+
*/
7521+
yb_conn_mgr_is_auth_passthrough_backend = true;
75157522
MyProcPort->yb_is_auth_passthrough_req = true;
75167523
MyProcPort->yb_has_auth_passthrough_failed = false;
75177524

7518-
75197525
if (!YBCIsSysTablePrefetchingStarted() &&
75207526
YbUseTserverResponseCacheForAuth(YbGetSharedCatalogVersion()))
75217527
{

src/postgres/src/backend/utils/misc/guc.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11175,6 +11175,22 @@ set_config_option_ext(const char *name, const char *value,
1117511175
case PGC_BACKEND:
1117611176
if (context == PGC_SIGHUP)
1117711177
{
11178+
/*
11179+
* YB: We need to increment local LCV for ConnMgr here since
11180+
* this change will only take effect in new backends.
11181+
* This will fire even if the variable value in config is not
11182+
* changed, which is acceptable since config reloads are rare.
11183+
*
11184+
* Record PGC_BACKEND change for LCV increment.
11185+
* Fires for the postmaster (!IsUnderPostmaster) and for
11186+
* CM control backends. Must precede the early return below so
11187+
* control backends set the flag before skipping the GUC apply.
11188+
*/
11189+
if (YbIsYsqlConnMgrEnabled() &&
11190+
(!IsUnderPostmaster || yb_conn_mgr_is_auth_passthrough_backend) &&
11191+
changeVal && !is_reload)
11192+
yb_conn_mgr_sighup_had_backend_guc_change = true;
11193+
1117811194
/*
1117911195
* If a PGC_BACKEND or PGC_SU_BACKEND parameter is changed in
1118011196
* the config file, we want to accept the new value in the
@@ -11199,16 +11215,6 @@ set_config_option_ext(const char *name, const char *value,
1119911215
*/
1120011216
if (IsUnderPostmaster && changeVal && !is_reload)
1120111217
return -1;
11202-
11203-
/*
11204-
* YB: We need to increment local LCV for ConnMgr here since
11205-
* this change will only take effect in new backends
11206-
* This will fire even if the variable value in config is not
11207-
* changed, which is acceptable since config reloads are rare
11208-
*/
11209-
if (YbIsYsqlConnMgrEnabled() && !IsUnderPostmaster && changeVal &&
11210-
!is_reload)
11211-
yb_conn_mgr_sighup_had_backend_guc_change = true;
1121211218
}
1121311219
else if (context != PGC_POSTMASTER &&
1121411220
context != PGC_BACKEND &&

src/postgres/src/backend/utils/misc/yb_ysql_conn_mgr_helper.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ YbIsClientYsqlConnMgr()
8585
return IsYugaByteEnabled() && yb_is_client_ysqlconnmgr;
8686
}
8787

88+
bool yb_conn_mgr_is_auth_passthrough_backend = false;
89+
8890
bool
8991
YbIsAuthPassthroughInProgress(struct Port *port)
9092
{

src/postgres/src/include/yb_ysql_conn_mgr_helper.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ extern uint64_t yb_conn_mgr_sighup_logical_client_version;
8484
*/
8585
extern bool yb_conn_mgr_sighup_had_backend_guc_change;
8686

87+
/*
88+
* Set to true when this PG backend receives its first Auth Passthrough ("AP")
89+
* Request packet (header type 'A'), identifying it as a CM control backend for
90+
* the auth-passthrough flow. Backend type cannot be changed to or from control
91+
* backend. Thus this flag is never unset, once set.
92+
*/
93+
extern bool yb_conn_mgr_is_auth_passthrough_backend;
94+
8795
/*
8896
* Check whether the connection is made from Ysql Connection Manager.
8997
*/

0 commit comments

Comments
 (0)