Bug #52231 Standardize Exception checks for load-balancer
Submitted: 19 Mar 2010 18:32 Modified: 24 Mar 2010 11:21
Reporter: Todd Farmer (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S2 (Serious)
Version:5.1.12 OS:Any
Assigned to: Todd Farmer CPU Architecture:Any

[19 Mar 2010 18:32] Todd Farmer
Description:
There is independent logic in LoadBalancingConnectionProxy and implementations of LoadBalanceStrategy as to which SQLExceptions trigger failover to a new host.  The former looks at just the first two characters of the SQLState:

if (sqlState.startsWith("08"))
...

while the latter use a different test:

 if (sqlEx instanceof CommunicationsException
  || "08S01".equals(sqlEx.getSQLState())) {
...

This should be standardized, as it is currently possible for a new Connection object to throw an Exception when the first selected host is unavailable.  Because MySqlIO.createNewIO() can throw SQLException with SQLState of "08001", which does not trigger the "try another host" logic in the LoadBalanceStrategy implementations, an Exception is thrown having only attempted a connection to a single host.

How to repeat:
See source.

Suggested fix:
Standardize SQLException inspection in a new LoadBalancingConnectionProxy method, and let implementations of LoadBalanceStrategy invoke that.

This also would allow potential runtime configuration of which exceptions should trigger failover.  For example, one could define certain NDB Exceptions as cause for failover, beyond simple connection problems.
[19 Mar 2010 20:46] Todd Farmer
Pushed in r916.
[24 Mar 2010 11:21] Tony Bedford
An entry has been added to the 5.1.13:

Logic in implementations of LoadBalancingConnectionProxy and LoadBalanceStrategy behaved differently as to which SQLExceptions trigger failover to a new host. The former looked at the first two characters of the SQLState:

if (sqlState.startsWith("08"))
...

The latter used a different test:

if (sqlEx instanceof CommunicationsException
  || "08S01".equals(sqlEx.getSQLState())) {
...

This meant it was possible for a new Connection object to throw an Exception when the first selected host was unavailable. This happened because MySqlIO.createNewIO() could throw an SQLException with a SQLState of “08001”, which did not trigger the “try another host” logic in the LoadBalanceStrategy implementations, so an Exception was thrown after having only attempted connecting to a single host.