Skip to content

Conversation

@sophia-bq
Copy link
Contributor

Summary

introduces the Simple Read/Write Splitting Plugin (srw)

Description

an alternative to the existing Read/Write Splitting Plugin that connects directly to specified read and write endpoints

Additional Reviewers

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

| Plugin codes / Plugin codes | [limitless](./using-plugins/UsingTheLimitlessConnectionPlugin.md) | [bg](./using-plugins/UsingTheBlueGreenPlugin.md) |
|--------------------------------------------------|-------------------------------------------------------------------|--------------------------------------------------|
| [bg](./using-plugins/UsingTheBlueGreenPlugin.md) | <span style="color:red;font-size:20px">&cross;</span> | |
| Plugin codes / Plugin codes | [limitless](./using-plugins/UsingTheLimitlessConnectionPlugin.md) | [bg](./using-plugins/UsingTheBlueGreenPlugin.md) |
Copy link
Contributor

Choose a reason for hiding this comment

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

srw is not compatible with readWriteSplitting plugin.

Copy link
Contributor

Choose a reason for hiding this comment

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

and not with auroraStaleDns


## Loading the Simple Read/Write Splitting Plugin

The simple read/write splitting plugin is not loaded by default. To load the plugin, include it in the `wrapperPlugins` connection parameter. If you would like to load the simple read/write splitting plugin alongside the failover and host monitoring plugins, the simple read/write splitting plugin must be listed before these plugins in the plugin chain. If it is not, failover exceptions will not be properly processed by the plugin. See the example below to properly load the read/write splitting plugin with these plugins.
Copy link
Contributor

Choose a reason for hiding this comment

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

the simple read/write splitting plugin must be listed before these plugins in the plugin chain

That's a bit outdated statement. The driver sort plugins automatically so plugin order isn't so important. However, if user opt out with auto sorting then certainly srw should go before failover and efm.

properties.setProperty("srwReadEndpoint", "test-db.cluster-ro-XYZ.us-east-2.rds.amazonaws.com");
```

## Federated Authentication Plugin Parameters
Copy link
Contributor

Choose a reason for hiding this comment

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

Federated? Should it be SRW Plugin Parameters?


The property `verifyNewSrwConnections` is enabled by default. This means that when new connections are made with the simple read/write splitting plugin, a query is sent to the new connection to verify its role. If a write connection connects to a reader, an error is thrown. If a read connection connects to the writer, a warning is logged and the connection is not stored for reuse.

#### Non-Aurora clusters
Copy link
Contributor

Choose a reason for hiding this comment

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

Non-Aurora and non RDS Cluster?

The verification step uses an Aurora specific query to determine the role of the connection, if the endpoint is not to an Aurora database, disable `verifyNewSrwConnections` by setting it to `false` in the properties.

#### Autocommit
If `verifyNewSrwConnections` is enabled and autocommit is set to false when the simple read/write splitting plugin makes a new connection, unexpected errors such as `Cannot change transaction read-only property in the middle of a transaction.` will occur. As part of verification, the plugin executes a query against a new connection, which when autocommit is set to false will open a transaction.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we rephrase it? It's hard to understand when the occurs and what to do to fix it.


## Supplying the connection string

When using the simple read/write splitting plugin against Aurora clusters, you do not have to supply multiple instance URLs in the connection string. Instead, supply just the URL for the initial instance to which you're connecting. You must also include either the failover plugin or the Aurora host list plugin in your plugin chain so that the driver knows to query Aurora for its topology. See the section on [loading the simple read/write splitting plugin](#loading-the-simple-readwrite-splitting-plugin) for more info.
Copy link
Contributor

Choose a reason for hiding this comment

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

Aurora and RDS clusters?

Copy link
Contributor

Choose a reason for hiding this comment

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

What is Aurora host list plugin ?


To take full advantage of the benefits of RDS Proxy it is recommended to only connect through RDS Proxy endpoints. See [Using the AWS JDBC Driver with RDS Proxy](./../../../README.md#rds-proxy) for limitations.

## Using the Simple Read/Write Splitting Plugin against non-Aurora clusters
Copy link
Contributor

Choose a reason for hiding this comment

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

non-Aurora and non-RDS Clusters?


## Using the Simple Read/Write Splitting Plugin against non-Aurora clusters

The simple read/write splitting plugin can be used to switch between any two endpoints. If the endpoints do not direct to an Aurora database, ensure the property `verifyNewSrwConnections` is set to `false`. See [Limitations of verifyNewSrwConnections](UsingTheSimpleReadWriteSplittingPlugin.md#non-aurora-clusters) for details.
Copy link
Contributor

Choose a reason for hiding this comment

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

the same, Aurora or RDS Cluster

@@ -0,0 +1,78 @@
# Simple Read/Write Splitting Plugin

The simple read/write splitting plugin adds functionality to switch between endpoints via calls to the `Connection#setReadOnly` method. Based off the values provided in the properties, upon calling `setReadOnly(true)`, the plugin will connect to the given endpoint for read operations. When `setReadOnly(false)` is called, the plugin will connect to the given endpoint for write operations. Future calls to `setReadOnly` will switch between the established writer and reader connections according to the boolean argument you supply to the `setReadOnly` method.
Copy link
Contributor

Choose a reason for hiding this comment

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

We need to mention that this plugin doesn't rely on cluster topology but just on provided endpoints and their DNS resolution.

final Properties props = new Properties();

// Enable srw, failover, and efm2 plugins and set properties
props.setProperty(PropertyDefinition.PLUGINS.name, "srw,failover,efm2");
Copy link
Contributor

Choose a reason for hiding this comment

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

Lets use failover2 to promote it.

final JdbcCallable<Void, SQLException> initHostProviderFunc) throws SQLException {

this.hostListProviderService = hostListProviderService;
if (hostListProviderService.isStaticHostListProvider()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

why?

this.pluginService = pluginService;
this.properties = properties;
this.writeEndpoint = writeEndpoint;
this.readEndpoint = SRW_READ_ENDPOINT.getString(properties);
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it mean that SRW_READ_ENDPOINT is optional parameter?

}

private boolean isWriteEndpoint(final @NonNull HostSpec hostSpec) {
return Objects.equals(hostSpec.getHost(), this.writeEndpoint);
Copy link
Contributor

Choose a reason for hiding this comment

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

We need to use getHostAndPort() and verify equalsIgnoreCase()

final Connection conn = this.pluginService.connect(this.writeEndpointHostSpec, this.properties, this);

if (this.verifyNewConnections && this.pluginService.getHostRole(conn) != HostRole.WRITER) {
logAndThrowException(
Copy link
Contributor

Choose a reason for hiding this comment

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

Need retry logic as discussed

switchCurrentConnectionTo(this.writerConnection, writeEndpointHostSpec);
}

private void getNewReaderConnection() throws SQLException {
Copy link
Contributor

Choose a reason for hiding this comment

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

Need retry logic as discussed


public class SimpleReadWriteSplittingTest extends ReadWriteSplittingTests {
String pluginCode = "srw";
String pluginCodesWithFailover = "failover,efm2,srw,initialConnection";
Copy link
Contributor

Choose a reason for hiding this comment

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

failover2

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.

2 participants