Functionality added or changed:
Added an experimental load-balanced connection designed for use with SQL nodes in a MySQL Cluster/NDB environment (This is not for master-slave replication. For that, we suggest you look at
ReplicationConnection
orlbpool
).If the JDBC URL starts with
jdbc:mysql:loadbalance://host-1,host-2,...host-n
, the driver will create an implementation ofjava.sql.Connection
that load balances requests across a series of MySQL JDBC connections to the given hosts, where the balancing takes place after transaction commit.Therefore, for this to work (at all), you must use transactions, even if only reading data.
Physical connections to the given hosts will not be created until needed.
The driver will invalidate connections that it detects have had communication errors when processing a request. A new connection to the problematic host will be attempted the next time it is selected by the load balancing algorithm.
There are two choices for load balancing algorithms, which may be specified by the
loadBalanceStrategy
JDBC URL configuration property:random
: The driver will pick a random host for each request. This tends to work better than round-robin, as the randomness will somewhat account for spreading loads where requests vary in response time, while round-robin can sometimes lead to overloaded nodes if there are variations in response times across the workload.bestResponseTime
: The driver will route the request to the host that had the best response time for the previous transaction.
bestResponseTime
: The driver will route the request to the host that had the best response time for the previous transaction.Added configuration property
padCharsWithSpace
(defaults tofalse
). If set totrue
, and a result set column has theCHAR
type and the value does not fill the amount of characters specified in the DDL for the column, the driver will pad the remaining characters with space (for ANSI compliance).When
useLocalSessionState
is set totrue
and connected to a MySQL-5.0 or later server, the JDBC driver will now determine whether an actualcommit
orrollback
statement needs to be sent to the database whenConnection.commit()
orConnection.rollback()
is called.This is especially helpful for high-load situations with connection pools that always call
Connection.rollback()
on connection check-in/check-out because it avoids a round-trip to the server.Added configuration property
useDynamicCharsetInfo
. If set tofalse
(the default), the driver will use a per-connection cache of character set information queried from the server when necessary, or when set totrue
, use a built-in static mapping that is more efficient, but isn't aware of custom character sets or character sets implemented after the release of the JDBC driver.NoteThis only affects the
padCharsWithSpace
configuration property and theResultSetMetaData.getColumnDisplayWidth()
method.New configuration property,
enableQueryTimeouts
(defaulttrue
).When enabled, query timeouts set with
Statement.setQueryTimeout()
use a sharedjava.util.Timer
instance for scheduling. Even if the timeout doesn't expire before the query is processed, there will be memory used by theTimerTask
for the given timeout which won't be reclaimed until the time the timeout would have expired if it hadn't been cancelled by the driver. High-load environments might want to consider disabling this functionality. (this configuration property is part of themaxPerformance
configuration bundle).Give better error message when "streaming" result sets, and the connection gets clobbered because of exceeding
net_write_timeout
on the server.random
: The driver will pick a random host for each request. This tends to work better than round-robin, as the randomness will somewhat account for spreading loads where requests vary in response time, while round-robin can sometimes lead to overloaded nodes if there are variations in response times across the workload.com.mysql.jdbc.[NonRegistering]Driver
now understands URLs of the formatjdbc:mysql:replication://
andjdbc:mysql:loadbalance://
which will create a ReplicationConnection (exactly like when using[NonRegistering]ReplicationDriver
) and an experimental load-balanced connection designed for use with SQL nodes in a MySQL Cluster/NDB environment, respectively.In an effort to simplify things, we're working on deprecating multiple drivers, and instead specifying different core behavior based upon JDBC URL prefixes, so watch for
[NonRegistering]ReplicationDriver
to eventually disappear, to be replaced withcom.mysql.jdbc[NonRegistering]Driver
with the new URL prefix.Fixed issue where a failed-over connection would let an application call
setReadOnly(false)
, when that call should be ignored until the connection is reconnected to a writable master unlessfailoverReadOnly
had been set tofalse
.Driver will now use
INSERT INTO ... VALUES (DEFAULT)
form of statement for updatable result sets forResultSet.insertRow()
, rather than pre-populating the insert row with values fromDatabaseMetaData.getColumns()
(which results in aSHOW FULL COLUMNS
on the server for every result set). If an application requires access to the default values beforeinsertRow()
has been called, the JDBC URL should be configured withpopulateInsertRowWithDefaultValues
set totrue
.This fix specifically targets performance issues with ColdFusion and the fact that it seems to ask for updatable result sets no matter what the application does with them.
More intelligent initial packet sizes for the "shared" packets are used (512 bytes, rather than 16K), and initial packets used during handshake are now sized appropriately as to not require reallocation.
Bugs fixed:
More useful error messages are generated when the driver thinks a result set is not updatable. (Thanks to Ashley Martens for the patch). (Bug#28085)
Connection.getTransactionIsolation()
uses "SHOW VARIABLES LIKE
" which is very inefficient on MySQL-5.0+ servers. (Bug#27655)Fixed issue where calling
getGeneratedKeys()
on a prepared statement after callingexecute()
didn't always return the generated keys (executeUpdate()
worked fine however). (Bug#27655)CALL /* ... */
doesn't work. As a side effect of this fix, you can now usesome_proc
()/* */
and#
comments when preparing statements using client-side prepared statement emulation.If the comments happen to contain parameter markers (
?
), they will be treated as belonging to the comment (that is, not recognized) rather than being a parameter of the statement.NoteThe statement when sent to the server will contain the comments as-is, they're not stripped during the process of preparing the
PreparedStatement
orCallableStatement
.ResultSet.get*()
with a column index < 1 returns misleading error message. (Bug#27317)Using
ResultSet.get*()
with a column index less than 1 returns a misleading error message. (Bug#27317)Comments in DDL of stored procedures/functions confuse procedure parser, and thus metadata about them can not be created, leading to inability to retrieve said metadata, or execute procedures that have certain comments in them. (Bug#26959)
Fast date/time parsing doesn't take into account
00:00:00
as a legal value. (Bug#26789)PreparedStatement
is not closed inBlobFromLocator.getBytes()
. (Bug#26592)When the configuration property
useCursorFetch
was set totrue
, sometimes server would return new, more exact metadata during the execution of the server-side prepared statement that enables this functionality, which the driver ignored (using the original metadata returned duringprepare()
), causing corrupt reading of data due to type mismatch when the actual rows were returned. (Bug#26173)CallableStatements
withOUT/INOUT
parameters that are "binary" (BLOB
,BIT
,(VAR)BINARY
,JAVA_OBJECT
) have extra 7 bytes. (Bug#25715)Whitespace surrounding storage/size specifiers in stored procedure parameters declaration causes
NumberFormatException
to be thrown when calling stored procedure on JDK-1.5 or newer, as the Number classes in JDK-1.5+ are whitespace intolerant. (Bug#25624)Client options not sent correctly when using SSL, leading to stored procedures not being able to return results. Thanks to Don Cohen for the bug report, testcase and patch. (Bug#25545)
Statement.setMaxRows()
is not effective on result sets materialized from cursors. (Bug#25517)BIT(> 1)
is returned asjava.lang.String
fromResultSet.getObject()
rather thanbyte[]
. (Bug#25328)