diff --git a/examples/src/main/java/com/yugabyte/examples/UniformLoadBalanceExample.java b/examples/src/main/java/com/yugabyte/examples/UniformLoadBalanceExample.java index 8a5ea283c..0b4f3749d 100644 --- a/examples/src/main/java/com/yugabyte/examples/UniformLoadBalanceExample.java +++ b/examples/src/main/java/com/yugabyte/examples/UniformLoadBalanceExample.java @@ -51,7 +51,7 @@ public static void main(String[] args) { System.out.println("Setting up the connection pool having 6 connections......."); - testUsingHikariPool("uniform_load_balance", "true", "simple", // Change this 'simple' + testUsingHikariPool("uniform_load_balance", "true", "ignored", controlHost, controlPort, numConnections, verbose, interactive); } diff --git a/gradle.properties b/gradle.properties index a00b0fd74..2c93e3129 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ kotlin.parallel.tasks.in.project=true # This is version for PgJdbc itself # Note: it should not include "-SNAPSHOT" as it is automatically added by build.gradle.kts # Release version can be generated by using -Prelease or -Prc= arguments -pgjdbc.version=42.3.5-yb-7-SNAPSHOT +pgjdbc.version=42.3.5-yb-7 # The options below configures the use of local clone (e.g. testing development versions) # You can pass un-comment it, or pass option -PlocalReleasePlugins, or -PlocalReleasePlugins= diff --git a/pgjdbc/src/main/java/com/yugabyte/ysql/ClusterAwareLoadBalancer.java b/pgjdbc/src/main/java/com/yugabyte/ysql/ClusterAwareLoadBalancer.java index 637bda74f..b407d8461 100644 --- a/pgjdbc/src/main/java/com/yugabyte/ysql/ClusterAwareLoadBalancer.java +++ b/pgjdbc/src/main/java/com/yugabyte/ysql/ClusterAwareLoadBalancer.java @@ -13,17 +13,16 @@ package com.yugabyte.ysql; +import com.yugabyte.ysql.LoadBalanceService.LoadBalance; + import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ThreadLocalRandom; import java.util.logging.Logger; -import com.yugabyte.ysql.LoadBalanceService.LoadBalance; - public class ClusterAwareLoadBalancer implements LoadBalancer { - protected static final Logger LOGGER = - Logger.getLogger("org.postgresql." + ClusterAwareLoadBalancer.class.getName()); + protected static final Logger LOGGER = Logger.getLogger("org.postgresql." + ClusterAwareLoadBalancer.class.getName()); private static volatile ClusterAwareLoadBalancer instance; private List attempted = new ArrayList<>(); @@ -51,7 +50,8 @@ public static ClusterAwareLoadBalancer getInstance(LoadBalanceService.LoadBalanc instance.refreshListSeconds = refreshListSeconds >= 0 && refreshListSeconds <= LoadBalanceProperties.MAX_REFRESH_INTERVAL ? refreshListSeconds : LoadBalanceProperties.DEFAULT_REFRESH_INTERVAL; - LOGGER.fine("Created a new cluster-aware LB instance with loadbalance = " + instance.loadBalance + " and refresh interval " + instance.refreshListSeconds + " seconds"); + LOGGER.fine("Created a new cluster-aware LB instance with loadbalance = " + + instance.loadBalance + " and refresh interval " + instance.refreshListSeconds + " seconds"); } } } @@ -65,38 +65,8 @@ public String toString() { @Override public boolean isHostEligible(Map.Entry e, Byte requestFlags) { - return !attempted.contains(e.getKey()) && !e.getValue().isDown() && isRightNodeType(e.getValue().getNodeType(), requestFlags); - } - - private boolean isRightNodeType(String nodeType, byte requestFlags) { - switch (loadBalance) { - case ANY: - LOGGER.fine("case ANY"); - return true; - case ONLY_PRIMARY: - LOGGER.fine("case ONLY_PRIMARY, nodeType " + nodeType); - return nodeType.equalsIgnoreCase("primary"); - case ONLY_RR: - LOGGER.fine("case ONLY_RR, nodeType " + nodeType); - return nodeType.equalsIgnoreCase("read_replica"); - case PREFER_PRIMARY: - LOGGER.fine("case PREFER_PRIMARY, nodeType " + nodeType + " requestFlag " + requestFlags); - if (requestFlags == LoadBalanceService.STRICT_PREFERENCE) { - return nodeType.equalsIgnoreCase("primary"); - } else { - return nodeType.equalsIgnoreCase("primary") || nodeType.equalsIgnoreCase("read_replica"); - } - case PREFER_RR: - LOGGER.fine("case PREFER_RR, nodeType " + nodeType + " requestFlag " + requestFlags); - if (requestFlags == LoadBalanceService.STRICT_PREFERENCE) { - return nodeType.equalsIgnoreCase("read_replica"); - } else { - return nodeType.equalsIgnoreCase("primary") || nodeType.equalsIgnoreCase("read_replica"); - } - default: - LOGGER.fine("case default"); - return false; - } + return !attempted.contains(e.getKey()) && !e.getValue().isDown() + && LoadBalanceService.isRightNodeType(loadBalance, e.getValue().getNodeType(), requestFlags); } public synchronized String getLeastLoadedServer(boolean newRequest, List failedHosts, @@ -148,7 +118,7 @@ public synchronized String getLeastLoadedServer(boolean newRequest, List if (chosenHost == null && (loadBalance == LoadBalance.ONLY_PRIMARY || loadBalance == LoadBalance.ONLY_RR)) { throw new IllegalStateException("No node available in " + (loadBalance == LoadBalance.ONLY_PRIMARY ? "primary" : "read-replica") - + " cluster to connect to"); + + " cluster to connect to."); } return chosenHost; } diff --git a/pgjdbc/src/main/java/com/yugabyte/ysql/LoadBalanceProperties.java b/pgjdbc/src/main/java/com/yugabyte/ysql/LoadBalanceProperties.java index a2a54d67d..8feec17a4 100644 --- a/pgjdbc/src/main/java/com/yugabyte/ysql/LoadBalanceProperties.java +++ b/pgjdbc/src/main/java/com/yugabyte/ysql/LoadBalanceProperties.java @@ -21,7 +21,6 @@ import java.util.logging.Logger; public class LoadBalanceProperties { - private static final String SIMPLE_LB = "simple"; public static final String LOAD_BALANCE_PROPERTY_KEY = "load-balance"; public static final String TOPOLOGY_AWARE_PROPERTY_KEY = "topology-keys"; public static final String REFRESH_INTERVAL_KEY = "yb-servers-refresh-interval"; @@ -227,7 +226,7 @@ private void setLoadBalanceValue(String value) { default: LOGGER.warning("Invalid value for load-balance: " + value + ", ignoring it."); } - LOGGER.info("loadbalance value set to " + this.loadBalance); + LOGGER.fine("loadbalance value set to " + this.loadBalance); } private int parseAndGetValue(String propValue, int defaultValue, int maxValue) { @@ -283,7 +282,7 @@ public LoadBalancer getAppropriateLoadBalancer() { // return base class conn manager. ld = CONNECTION_MANAGER_MAP.get(this.loadBalance.name()); if (ld == null) { - LOGGER.fine(">>>>>>>>>>>>>>>>>>>>>>>>>>> No LB found for " + this.loadBalance + ", creating one ..."); + LOGGER.fine("No LB found for " + this.loadBalance + ", creating one ..."); synchronized (CONNECTION_MANAGER_MAP) { ld = CONNECTION_MANAGER_MAP.get(this.loadBalance.name()); if (ld == null) { @@ -292,13 +291,13 @@ public LoadBalancer getAppropriateLoadBalancer() { } } } else { - LOGGER.fine(">>>>>>>>>>>>>>>>>>>>>>>>>>> LB found for " + this.loadBalance + ": " + ld); + LOGGER.fine("LB found for " + this.loadBalance + ": " + ld); } } else { String key = this.loadBalance.name() + "&" + placements + "&" + String.valueOf(explicitFallbackOnly).toLowerCase(Locale.ROOT); ld = CONNECTION_MANAGER_MAP.get(key); if (ld == null) { - LOGGER.fine(">>>>>>>>>>>>>>>>>>>>>>>>>>> No LB found for " + this.loadBalance + " and placements " + placements + " and fallback? " + explicitFallbackOnly + ", creating one ..."); + LOGGER.fine("No LB found for " + this.loadBalance + " and placements " + placements + " and fallback? " + explicitFallbackOnly + ", creating one ..."); synchronized (CONNECTION_MANAGER_MAP) { ld = CONNECTION_MANAGER_MAP.get(key); if (ld == null) { @@ -307,7 +306,7 @@ public LoadBalancer getAppropriateLoadBalancer() { } } } else { - LOGGER.fine(">>>>>>>>>>>>>>>>>>>>>>>>>>> LB found for " + this.loadBalance + " and placements " + placements + ": " + ld); + LOGGER.fine("LB found for " + this.loadBalance + " and placements " + placements + ": " + ld); } } return ld; diff --git a/pgjdbc/src/main/java/com/yugabyte/ysql/LoadBalanceService.java b/pgjdbc/src/main/java/com/yugabyte/ysql/LoadBalanceService.java index 2fbf06512..029fcc732 100644 --- a/pgjdbc/src/main/java/com/yugabyte/ysql/LoadBalanceService.java +++ b/pgjdbc/src/main/java/com/yugabyte/ysql/LoadBalanceService.java @@ -4,7 +4,6 @@ import static com.yugabyte.ysql.LoadBalanceProperties.FAILED_HOST_RECONNECT_DELAY_SECS_KEY; import static org.postgresql.Driver.hostSpecs; -import org.postgresql.PGProperty; import org.postgresql.jdbc.PgConnection; import org.postgresql.util.GT; import org.postgresql.util.HostSpec; @@ -28,13 +27,11 @@ public class LoadBalanceService { - private static final ConcurrentHashMap clusterInfoMap = - new ConcurrentHashMap<>(); + private static final ConcurrentHashMap clusterInfoMap = new ConcurrentHashMap<>(); static final byte STRICT_PREFERENCE = 0b00000001; private static Connection controlConnection = null; protected static final String GET_SERVERS_QUERY = "select * from yb_servers()"; - protected static final Logger LOGGER = - Logger.getLogger("org.postgresql." + LoadBalanceService.class.getName()); + protected static final Logger LOGGER = Logger.getLogger("org.postgresql." + LoadBalanceService.class.getName()); private static long lastRefreshTime; private static boolean forceRefreshOnce = false; private static Boolean useHostColumn = null; @@ -102,8 +99,7 @@ private static synchronized boolean refresh(Connection conn, long refreshInterva String region = rs.getString("region"); String zone = rs.getString("zone"); String nodeType = rs.getString("node_type"); - NodeInfo nodeInfo = clusterInfoMap.containsKey(host) ? clusterInfoMap.get(host) : - new NodeInfo(); + NodeInfo nodeInfo = clusterInfoMap.containsKey(host) ? clusterInfoMap.get(host) : new NodeInfo(); synchronized (nodeInfo) { nodeInfo.host = host; nodeInfo.publicIP = publicHost; @@ -114,20 +110,16 @@ private static synchronized boolean refresh(Connection conn, long refreshInterva try { nodeInfo.port = Integer.valueOf(port); } catch (NumberFormatException nfe) { - LOGGER.warning("Could not parse port " + port + " for host " + host + ", using 5433 " + - "instead."); + LOGGER.warning("Could not parse port " + port + " for host " + host + ", using 5433 instead."); nodeInfo.port = 5433; } - long failedHostTTL = Long.getLong(FAILED_HOST_RECONNECT_DELAY_SECS_KEY, - DEFAULT_FAILED_HOST_TTL_SECONDS); + long failedHostTTL = Long.getLong(FAILED_HOST_RECONNECT_DELAY_SECS_KEY, DEFAULT_FAILED_HOST_TTL_SECONDS); if (nodeInfo.isDown) { if (System.currentTimeMillis() - nodeInfo.isDownSince > (failedHostTTL * 1000)) { - LOGGER.fine("Marking " + nodeInfo.host + " as UP since failed-host-reconnect-delay" + - "-secs (" + failedHostTTL + "s) has elapsed"); + LOGGER.fine("Marking " + nodeInfo.host + " as UP since failed-host-reconnect-delay-secs (" + failedHostTTL + "s) has elapsed"); nodeInfo.isDown = false; } else { - LOGGER.fine("Keeping " + nodeInfo.host + " as DOWN since failed-host-reconnect-delay" + - "-secs (" + failedHostTTL + "s) has not elapsed"); + LOGGER.fine("Keeping " + nodeInfo.host + " as DOWN since failed-host-reconnect-delay-secs (" + failedHostTTL + "s) has not elapsed"); } } } @@ -355,8 +347,7 @@ private static synchronized boolean checkAndRefresh(LoadBalanceProperties loadBa } catch (SQLException ex) { if (refreshFailed) { LOGGER.fine("Exception while refreshing: " + ex + ", " + ex.getSQLState()); - String failed = - ((PgConnection) controlConnection).getQueryExecutor().getHostSpec().getHost(); + String failed = ((PgConnection) controlConnection).getQueryExecutor().getHostSpec().getHost(); markAsFailed(failed); } else { String msg = hspec.length > 1 ? " and others" : ""; @@ -410,32 +401,27 @@ private static InetAddress getConnectedInetAddress(Connection conn) throws SQLEx } static boolean isRightNodeType(LoadBalance loadBalance, String nodeType, byte requestFlags) { + LOGGER.fine("loadBalance " + loadBalance + ", nodeType: " + nodeType + ", requestFlags: " + requestFlags); switch (loadBalance) { case ANY: - LOGGER.fine("case ANY"); return true; case ONLY_PRIMARY: - LOGGER.fine("case ONLY_PRIMARY, nodeType " + nodeType); return nodeType.equalsIgnoreCase("primary"); case ONLY_RR: - LOGGER.fine("case ONLY_RR, nodeType " + nodeType); return nodeType.equalsIgnoreCase("read_replica"); case PREFER_PRIMARY: - LOGGER.fine("case PREFER_PRIMARY, nodeType " + nodeType + " requestFlag " + requestFlags); if (requestFlags == LoadBalanceService.STRICT_PREFERENCE) { return nodeType.equalsIgnoreCase("primary"); } else { return nodeType.equalsIgnoreCase("primary") || nodeType.equalsIgnoreCase("read_replica"); } case PREFER_RR: - LOGGER.fine("case PREFER_RR, nodeType " + nodeType + " requestFlag " + requestFlags); if (requestFlags == LoadBalanceService.STRICT_PREFERENCE) { return nodeType.equalsIgnoreCase("read_replica"); } else { return nodeType.equalsIgnoreCase("primary") || nodeType.equalsIgnoreCase("read_replica"); } default: - LOGGER.fine("case default"); return false; } } diff --git a/pgjdbc/src/main/java/com/yugabyte/ysql/LoadBalancer.java b/pgjdbc/src/main/java/com/yugabyte/ysql/LoadBalancer.java index 458f22d4d..3a7e902eb 100644 --- a/pgjdbc/src/main/java/com/yugabyte/ysql/LoadBalancer.java +++ b/pgjdbc/src/main/java/com/yugabyte/ysql/LoadBalancer.java @@ -27,8 +27,7 @@ public interface LoadBalancer { * @param timedOutHosts list of host names where connections were attempted but timed out * @return the name of a host with the least number of connections, as per the driver's stats */ - String getLeastLoadedServer(boolean newRequest, List failedHosts, - ArrayList timedOutHosts); + String getLeastLoadedServer(boolean newRequest, List failedHosts, ArrayList timedOutHosts); /** * @return the value of the property "yb-servers-refresh-interval" specified either in the url or diff --git a/pgjdbc/src/main/java/com/yugabyte/ysql/TopologyAwareLoadBalancer.java b/pgjdbc/src/main/java/com/yugabyte/ysql/TopologyAwareLoadBalancer.java index 76620b368..a3c5d637e 100644 --- a/pgjdbc/src/main/java/com/yugabyte/ysql/TopologyAwareLoadBalancer.java +++ b/pgjdbc/src/main/java/com/yugabyte/ysql/TopologyAwareLoadBalancer.java @@ -20,6 +20,8 @@ import static com.yugabyte.ysql.LoadBalanceProperties.REFRESH_INTERVAL_KEY; import static com.yugabyte.ysql.LoadBalanceProperties.TOPOLOGY_AWARE_PROPERTY_KEY; +import com.yugabyte.ysql.LoadBalanceService.LoadBalance; + import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -29,11 +31,8 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.logging.Logger; -import com.yugabyte.ysql.LoadBalanceService.LoadBalance; - public class TopologyAwareLoadBalancer implements LoadBalancer { - protected static final Logger LOGGER = - Logger.getLogger("org.postgresql." + TopologyAwareLoadBalancer.class.getName()); + protected static final Logger LOGGER = Logger.getLogger("org.postgresql." + TopologyAwareLoadBalancer.class.getName()); /** * Holds the value of topology-keys specified. */ @@ -44,8 +43,7 @@ public class TopologyAwareLoadBalancer implements LoadBalancer { /** * Derived from the placements value above. */ - private final Map> allowedPlacements = - new HashMap<>(); + private final Map> allowedPlacements = new HashMap<>(); private final int PRIMARY_PLACEMENTS_INDEX = 1; private final int REST_OF_CLUSTER_INDEX = -1; /** @@ -101,8 +99,7 @@ private void parseGeoLocations() { } else { int pref = Integer.parseInt(v[1]); if (pref > 0 && pref <= MAX_PREFERENCE_VALUE) { - Set cpSet = allowedPlacements.computeIfAbsent(pref, - k -> new HashSet<>()); + Set cpSet = allowedPlacements.computeIfAbsent(pref, k -> new HashSet<>()); populatePlacementSet(v[0], cpSet); } else { throw new IllegalArgumentException("Invalid preference value for property " + TOPOLOGY_AWARE_PROPERTY_KEY + ": " + value); @@ -139,8 +136,7 @@ public boolean isHostEligible(Map.Entry e, && isRightNode; } - public synchronized String getLeastLoadedServer(boolean newRequest, List failedHosts, - ArrayList timedOutHosts) { + public synchronized String getLeastLoadedServer(boolean newRequest, List failedHosts, ArrayList timedOutHosts) { LOGGER.fine("newRequest: " + newRequest + ", failedHosts: " + failedHosts); // Reset currentPlacementIndex if it's a new request AND refresh() happened after the // last request was processed diff --git a/pgjdbc/src/main/java/org/postgresql/Driver.java b/pgjdbc/src/main/java/org/postgresql/Driver.java index dded85a66..194904530 100644 --- a/pgjdbc/src/main/java/org/postgresql/Driver.java +++ b/pgjdbc/src/main/java/org/postgresql/Driver.java @@ -37,8 +37,8 @@ import org.postgresql.util.SharedTimer; import org.postgresql.util.URLCoder; -import com.yugabyte.ysql.LoadBalanceService; import com.yugabyte.ysql.LoadBalanceProperties; +import com.yugabyte.ysql.LoadBalanceService; import org.checkerframework.checker.nullness.qual.Nullable; import java.io.IOException;