Skip to content

fix: query timeout kill query directed to incorrect instance#474

Merged
karenc-bq merged 1 commit intoawslabs:mainfrom
Bit-Quill:461
Oct 31, 2023
Merged

fix: query timeout kill query directed to incorrect instance#474
karenc-bq merged 1 commit intoawslabs:mainfrom
Bit-Quill:461

Conversation

@crystall-bitquill
Copy link
Copy Markdown
Contributor

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

conn.close();
}

@RepeatedTest(100)
Copy link
Copy Markdown
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
Copy Markdown
Contributor 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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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.

@crystall-bitquill crystall-bitquill force-pushed the 461 branch 3 times, most recently from 09c684b to b846c4b Compare October 18, 2023 23:43
IConnectionPlugin nextPlugin,
Log logger,
IConnectionProvider connectionProvider) {
if (logger == null) {
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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;
}

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.

3 participants