-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: query timeout kill query directed to incorrect instance #474
Conversation
bc6f795
to
3ab271b
Compare
@@ -607,4 +618,16 @@ public void test_PreparedStatementHashCodes() throws SQLException, IOException { | |||
conn.close(); | |||
} | |||
|
|||
@RepeatedTest(100) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to run it so many times?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the new connection for the query timeout is made, the reader cluster endpoint doesn't always choose a reader different from the original connection so it's hard to reproduce this issue consistently.
final RdsUtils rdsUtils = new RdsUtils(); | ||
if (rdsUtils.isReaderClusterDns(mainHostInfo.getHost())) { | ||
final String connectedHostName = getCurrentlyConnectedInstance(connection); | ||
String instanceEndpoint = | ||
rdsUtils.getRdsInstanceHostPattern(mainHostInfo.getHost()).replace("?", connectedHostName); | ||
if (!StringUtils.isNullOrEmpty(mainHostInfo.getHostProperties().get(PropertyKey.clusterInstanceHostPattern.getKeyName()))) { | ||
instanceEndpoint = mainHostInfo.getHostProperties().get(PropertyKey.clusterInstanceHostPattern.getKeyName()) | ||
.replace("?", connectedHostName); | ||
} | ||
final HostInfo instanceHostInfo = ConnectionUtils.createInstanceHostWithProperties(instanceEndpoint, mainHostInfo); | ||
final JdbcConnection hostConnection = this.connectionProvider.connect(instanceHostInfo); | ||
connection.close(); | ||
connection = hostConnection; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest to relocate this logic into a new plugin. In this way, it'd be easier for users to use it when it's needed, or skip it. That gives more flexibility for users who don't experience any issue with query timeout.
* http://www.gnu.org/licenses/gpl-2.0.html. | ||
*/ | ||
|
||
package com.mysql.cj.jdbc.ha; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
com.mysql.cj.jdbc.ha.util ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And similar suggestion's for the ConnectionUtils class above.
09c684b
to
b846c4b
Compare
b846c4b
to
07aced7
Compare
IConnectionPlugin nextPlugin, | ||
Log logger, | ||
IConnectionProvider connectionProvider) { | ||
if (logger == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think logger is used in this file. Do we need to store it?
String instanceEndpoint = | ||
rdsUtils.getRdsInstanceHostPattern(mainHostInfo.getHost()).replace("?", connectedHostName); | ||
if (!StringUtils.isNullOrEmpty( | ||
mainHostInfo.getHostProperties().get(PropertyKey.clusterInstanceHostPattern.getKeyName()))) { | ||
instanceEndpoint = mainHostInfo.getHostProperties().get(PropertyKey.clusterInstanceHostPattern.getKeyName()) | ||
.replace("?", connectedHostName); | ||
} | ||
final HostInfo instanceHostInfo = | ||
ConnectionUtils.createInstanceHostWithProperties(instanceEndpoint, mainHostInfo); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
String instanceEndpoint = | |
rdsUtils.getRdsInstanceHostPattern(mainHostInfo.getHost()).replace("?", connectedHostName); | |
if (!StringUtils.isNullOrEmpty( | |
mainHostInfo.getHostProperties().get(PropertyKey.clusterInstanceHostPattern.getKeyName()))) { | |
instanceEndpoint = mainHostInfo.getHostProperties().get(PropertyKey.clusterInstanceHostPattern.getKeyName()) | |
.replace("?", connectedHostName); | |
} | |
final HostInfo instanceHostInfo = | |
ConnectionUtils.createInstanceHostWithProperties(instanceEndpoint, mainHostInfo); | |
final String pattern = mainHostInfo.getHostProperties().get(PropertyKey.clusterInstanceHostPattern.getKeyName()); | |
final String instanceEndpoint = !StringUtils.isNullOrEmpty(pattern) ? pattern : rdsUtils.getRdsInstanceHostPattern(mainHostInfo.getHost()); | |
final HostInfo instanceHostInfo = | |
ConnectionUtils.createInstanceHostWithProperties( | |
instanceEndpoint.replace("?", connectedHostName), | |
mainHostInfo); |
rs.next(); | ||
return rs.getString(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rs.next(); | |
return rs.getString(1); | |
if (rs.next()) { | |
return rs.getString(1); | |
} | |
return null; | |
} |
07aced7
to
15403f8
Compare
Summary
fix: query timeout kill query directed to incorrect instance
Description
When a query timeout is set and the timeout value has passed, the driver sends a kill query to stop the process through a new connection that was created using the same host as the original connection. When using the reader cluster url, connections are randomly sent to one of the available reader instances. This will occasionally cause errors when the kill query is sent to a different instance where the statement was not executed, resulting in an "Unknown process id" message.
This PR adds a check in the default connection plugin for connections using the reader cluster url. Once the connection is made using the reader cluster url, a new connection is made to a reader instance that is obtained by querying for the current instance name. The original connection using the reader cluster is replaced with the connection to the instance.
Addresses #461
Additional Reviewers