Skip to content
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

Merged
merged 1 commit into from
Oct 31, 2023

Conversation

crystall-bitquill
Copy link
Collaborator

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

@@ -607,4 +618,16 @@ public void test_PreparedStatementHashCodes() throws SQLException, IOException {
conn.close();
}

@RepeatedTest(100)
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

Comment on lines 113 to 126
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;
}
Copy link
Contributor

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;
Copy link
Contributor

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 ?

Copy link
Contributor

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.

IConnectionPlugin nextPlugin,
Log logger,
IConnectionProvider connectionProvider) {
if (logger == null) {
Copy link
Contributor

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?

Comment on lines 112 to 120
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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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);

Comment on lines 145 to 146
rs.next();
return rs.getString(1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
rs.next();
return rs.getString(1);
if (rs.next()) {
return rs.getString(1);
}
return null;
}

@karenc-bq karenc-bq merged commit 7591def into awslabs:main Oct 31, 2023
1 check passed
@karenc-bq karenc-bq deleted the 461 branch October 31, 2023 23:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants