List:Commits« Previous MessageNext Message »
From:mmatthews Date:October 4 2007 9:50pm
Subject:Connector/J commit: r6615 - in trunk: . connector-j connector-j/src/com/mysql/jdbc
View as plain text  
Modified:
   trunk/
   trunk/connector-j/CHANGES
   trunk/connector-j/src/com/mysql/jdbc/LoadBalancingConnectionProxy.java
Log:
Merged revisions 6608-6614 via svnmerge from 
svn+ssh://mmatthews@stripped/connectors-svnroot/connector-j/branches/branch_5_0

.......
  r6614 | mmatthews | 2007-10-04 14:31:52 -0500 (Thu, 04 Oct 2007) | 9 lines
  
  Fixed BUG#31053 - Connections established using URLs of the form
  
        "jdbc:mysql:loadbalance://" weren't doing failover if they tried to 
  
        connect to a MySQL server that was down. The driver now attempts
  
        connections to the next "best" (depending on the load balance strategy
  
        in use) server, and continues to attempt connecting to the next "best"
  
        server every 250 milliseconds until one is found that is up and running 
  
        or 5 minutes has passed.
  
        
  
        If the driver gives up, it will throw the last-received SQLException.
.......



Property changes on: trunk
___________________________________________________________________
Name: svnmerge-integrated
   - /branches/branch_5_0:1-6607 /branches/branch_5_1:1-6582,6584-6611
   + /branches/branch_5_0:1-6614 /branches/branch_5_1:1-6582,6584-6611

Modified: trunk/connector-j/CHANGES
===================================================================
--- trunk/connector-j/CHANGES	2007-10-04 19:31:52 UTC (rev 6614)
+++ trunk/connector-j/CHANGES	2007-10-04 19:50:37 UTC (rev 6615)
@@ -289,6 +289,16 @@
       This fix also ensures that the precision of UNSIGNED MEDIUMINT
       and UNSIGNED BIGINT is reported correctly via DBMD.getColumns().
 
+    - Fixed BUG#31053 - Connections established using URLs of the form
+      "jdbc:mysql:loadbalance://" weren't doing failover if they tried to 
+      connect to a MySQL server that was down. The driver now attempts
+      connections to the next "best" (depending on the load balance strategy
+      in use) server, and continues to attempt connecting to the next "best"
+      server every 250 milliseconds until one is found that is up and running 
+      or 5 minutes has passed.
+      
+      If the driver gives up, it will throw the last-received SQLException.
+      
 07-19-07 - Version 5.0.7
 
     - Setting the configuration parameter "useCursorFetch" to "true" for

Modified: trunk/connector-j/src/com/mysql/jdbc/LoadBalancingConnectionProxy.java
===================================================================
--- trunk/connector-j/src/com/mysql/jdbc/LoadBalancingConnectionProxy.java	2007-10-04
19:31:52 UTC (rev 6614)
+++ trunk/connector-j/src/com/mysql/jdbc/LoadBalancingConnectionProxy.java	2007-10-04
19:50:37 UTC (rev 6615)
@@ -80,30 +80,73 @@
 
 			int bestHostIndex = 0;
 
-			for (int i = 0; i < responseTimes.length; i++) {
-				long candidateResponseTime = responseTimes[i];
-
-				if (candidateResponseTime < minResponseTime) {
-					if (candidateResponseTime == 0) {
+			long[] localResponseTimes = new long[responseTimes.length];
+			
+			synchronized (responseTimes) {
+				System.arraycopy(responseTimes, 0, localResponseTimes, 0, responseTimes.length);
+			}
+			
+			SQLException ex = null;
+			
+			for (int attempts = 0; attempts < 1200 /* 5 minutes */; attempts++) {
+				for (int i = 0; i < localResponseTimes.length; i++) {
+					long candidateResponseTime = localResponseTimes[i];
+	
+					if (candidateResponseTime < minResponseTime) {
+						if (candidateResponseTime == 0) {
+							bestHostIndex = i;
+	
+							break;
+						}
+	
 						bestHostIndex = i;
-
-						break;
+						minResponseTime = candidateResponseTime;
 					}
-
-					bestHostIndex = i;
-					minResponseTime = candidateResponseTime;
 				}
+	
+				if (bestHostIndex == localResponseTimes.length - 1) {
+					// try again, assuming that the previous list was mostly
+					// correct as far as distribution of response times went
+					
+					synchronized (responseTimes) {
+						System.arraycopy(responseTimes, 0, localResponseTimes, 0, responseTimes.length);
+					}
+					
+					continue;
+				}
+				String bestHost = (String) hostList.get(bestHostIndex);
+	
+				Connection conn = (Connection) liveConnections.get(bestHost);
+	
+				if (conn == null) {
+					try {
+						conn = createConnectionForHost(bestHost);
+					} catch (SQLException sqlEx) {
+						ex = sqlEx;
+						
+						if (sqlEx instanceof CommunicationsException ||
"08S01".equals(sqlEx.getSQLState())) {
+							localResponseTimes[bestHostIndex] = Long.MAX_VALUE;
+							
+							try {
+								Thread.sleep(250);
+							} catch (InterruptedException e) {
+							}
+							
+							continue;
+						} else {
+							throw sqlEx;
+						}
+					}
+				}
+	
+				return conn;
 			}
-
-			String bestHost = (String) hostList.get(bestHostIndex);
-
-			Connection conn = (Connection) liveConnections.get(bestHost);
-
-			if (conn == null) {
-				conn = createConnectionForHost(bestHost);
+			
+			if (ex != null) {
+				throw ex;
 			}
-
-			return conn;
+			
+			return null; // we won't get here, compiler can't tell
 		}
 	}
 
@@ -146,14 +189,41 @@
 
 			String hostPortSpec = (String) hostList.get(random);
 
-			Connection conn = (Connection) liveConnections.get(hostPortSpec);
-
-			if (conn == null) {
-				conn = createConnectionForHost(hostPortSpec);
+			SQLException ex = null;
+			
+			for (int attempts = 0; attempts < 1200 /* 5 minutes */; attempts++) {
+				Connection conn = (Connection) liveConnections.get(hostPortSpec);
+				
+				if (conn == null) {
+					try {
+						conn = createConnectionForHost(hostPortSpec);
+					} catch (SQLException sqlEx) {
+						ex = sqlEx;
+						
+						if (sqlEx instanceof CommunicationsException ||
"08S01".equals(sqlEx.getSQLState())) {
+							
+							try {
+								Thread.sleep(250);
+							} catch (InterruptedException e) {
+							}
+							
+							continue;
+						} else {
+							throw sqlEx;
+						}
+					}
+				}
+	
+				return conn;
 			}
+			
+			if (ex != null) {
+				throw ex;
+			}
+			
+			return null; // we won't get here, compiler can't tell
+		}
 
-			return conn;
-		}
 	}
 
 	private Connection currentConn;
@@ -247,7 +317,7 @@
 		connProps.setProperty(NonRegisteringDriver.PORT_PROPERTY_KEY,
 				hostPortPair[1]);
 
-		Connection conn = new ConnectionImpl(hostPortSpec, Integer
+		Connection conn = ConnectionImpl.getInstance(hostPortSpec, Integer
 				.parseInt(hostPortPair[1]), connProps, connProps
 				.getProperty(NonRegisteringDriver.DBNAME_PROPERTY_KEY),
 				"jdbc:mysql://" + hostPortPair[0] + ":" + hostPortPair[1] + "/");
@@ -370,8 +440,10 @@
 						.get(this.connectionsToHostsMap.get(this.currentConn)))
 						.intValue();
 
-				this.responseTimes[hostIndex] = getLocalTimeBestResolution()
-						- this.transactionStartTime;
+				synchronized (this.responseTimes) {
+					this.responseTimes[hostIndex] = getLocalTimeBestResolution()
+							- this.transactionStartTime;
+				}
 
 				pickNewConnection();
 			}

Thread
Connector/J commit: r6615 - in trunk: . connector-j connector-j/src/com/mysql/jdbcmmatthews4 Oct