| Bug #39784 | Make loadbalancing proxy exception handling global blacklist-aware | ||
|---|---|---|---|
| Submitted: | 1 Oct 2008 16:40 | Modified: | 16 Oct 2008 14:24 |
| Reporter: | Todd Farmer (OCA) | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | Connector / J | Severity: | S3 (Non-critical) |
| Version: | 5.1.7 | OS: | Any |
| Assigned to: | Todd Farmer | CPU Architecture: | Any |
[15 Oct 2008 21:29]
Todd Farmer
Fixed and pushed.
[16 Oct 2008 14:24]
Tony Bedford
An entry was added to the 5.1.7 changelog: When the LoadBalancingConnectionProxy handles a SQLException with SQL state starting with “08”, it calls invalidateCurrentConnection, which in turn removes that Connection from liveConnections and the connectionsToHostsMap, but it did not add the host to the new global blacklist, if the global blacklist was enabled. There was also the possibility of a NullPointerException when trying to update stats, where connectionsToHostsMap.get(this.currentConn) was called: int hostIndex = ((Integer) this.hostsToListIndexMap.get(this.connectionsToHostsMap.get(this.currentConn))).intValue(); This could happen if a client tried to issue a rollback after catching a SQLException caused by a connection failure.

Description: When the LoadBalancingConnectionProxy handles a SQLException with SQL state starting with "08", it calls invalidateCurrentConnection(), which in turn removes that Connection from liveConnections and the connectionsToHostsMap, but it does not currently add the host to the new global blacklist (if enabled). There is also the possibility of a NPE when trying to update stats where connectionsToHostsMap.get(this.currentConn) is called: int hostIndex = ((Integer) this.hostsToListIndexMap .get(this.connectionsToHostsMap.get(this.currentConn))) .intValue(); This can happen if a client tries to issue a rollback after catching a SQLException caused by a connection failure. How to repeat: import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Date; public class BasicConnectionLBTest { public static void main(String[] args) { try { Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager .getConnection( "jdbc:mysql:loadbalance://localhost:3307,localhost:3306/test?retriesAllDown=30&loadBalanceBlacklistTimeout=500&connectTimeout=100", "root", null); conn.setAutoCommit(false); while ( true ) { // kill one of the mysqld instances sometime here. try { Statement stmt = conn.createStatement(); ResultSet rs = stmt.execute("SELECT SLEEP(1)"); conn.commit(); } catch (SQLException e) { try{ conn.rollback(); } catch (Exception se) { se.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } } }