Skip to content

Commit 230aa28

Browse files
authored
docs: update known limitation section for blue/green deployment (#1490)
1 parent c9333e7 commit 230aa28

File tree

3 files changed

+23
-59
lines changed

3 files changed

+23
-59
lines changed

README.md

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -118,26 +118,23 @@ To find all the documentation and concrete examples on how to use the AWS JDBC D
118118

119119
#### Amazon RDS Blue/Green Deployments
120120

121-
Although the AWS Advanced JDBC Wrapper is not compatible with [AWS Blue/Green Deployments](https://docs.aws.amazon.com/whitepapers/latest/overview-deployment-options/bluegreen-deployments.html) and does not officially support them, the combination of the AWS Advanced JDBC Wrapper and the Failover Plugin has been validated for use with clusters that employ Blue/Green Deployments. While general basic connectivity to both Blue and Green clusters is always in place, some failover cases are not fully supported.
121+
The AWS Advanced JDBC Wrapper **versions 2.6.0 and above** now include enhanced full support for Blue/Green Deployments. This support requires a minimum database version that includes a specific metadata table. This constraint **does not** apply to RDS MySQL.
122122

123-
The current limitations are:
123+
**No action is required** if your database does not include the new metadata table -- the driver will continue to operate as before with no special blue/green functionality. If you have questions or encounter issues, please open an issue in this repository.
124+
125+
Supported RDS PostgreSQL Versions: `rds_tools v1.7 (17.1, 16.5, 15.9, 14.14, 13.17, 12.21)` and above.<br>
126+
Supported Aurora PostgreSQL Versions: Engine Release `17.5, 16.9, 15.13, 14.18, 13.21` and above.<br>
127+
Supported Aurora MySQL Versions: Engine Release `3.07` and above.
128+
129+
If your database version does **not** support this table, the driver will automatically detect its absence and fallback to its previous behaviour in wrapper versions <2.6.0. In this fallback mode, Blue/Green handling is subject to the same limitations listed below.
130+
131+
AWS Advanced JDBC Wrapper **versions earlier than 2.6.0** are not compatible with [AWS Blue/Green Deployments](https://docs.aws.amazon.com/whitepapers/latest/overview-deployment-options/bluegreen-deployments.html) and do not officially support them. However, the combination of the AWS Advanced JDBC Wrapper and the Failover Plugin has been validated for use with clusters that employ Blue/Green Deployments for these versions. While general basic connectivity to both Blue and Green clusters is always in place, some failover cases are not fully supported.
132+
133+
The limitations for versions earlier than 2.6.0 are:
124134
- After a Blue/Green switchover, the wrapper may not be able to properly detect the new topology and handle failover, as there are discrepancies between the metadata and the available endpoints.
125135
- The specific version requirements for Aurora MySQL versus Aurora PostgreSQL may vary, as the internal systems used by the wrapper can differ[^1].
126136

127-
The development team is aware of these limitations and is working to improve the wrapper's awareness and handling of Blue/Green switchovers. In the meantime, users can consider utilizing the `enableGreenNodeReplacement` configuration parameter, which allows the driver to override incorrect topology metadata and try to connect to available new Blue endpoints.
128-
129-
> [!WARNING]\
130-
> **Blue/Green Support Behaviour and Version Compatibility**
131-
>
132-
> The AWS Advanced JDBC Wrapper now includes enhanced full support for Blue/Green Deployments. This support requires a minimum database version that includes a specific metadata table. This constraint **does not** apply to RDS MySQL.
133-
>
134-
> If your database version does **not** support this table, the driver will automatically detect its absence and fallback to its previous behaviour. In this fallback mode, Blue/Green handling is subject to the same limitations listed above.
135-
>
136-
> **No action is required** if your database does not include the new metadata table -- the driver will continue to operate as before. If you have questions or encounter issues, please open an issue in this repository.
137-
>
138-
> Supported RDS PostgreSQL Versions: `rds_tools v1.7 (17.1, 16.5, 15.9, 14.14, 13.17, 12.21)` and above.<br>
139-
> Supported Aurora PostgreSQL Versions: Engine Release `17.5, 16.9, 15.13, 14.18, 13.21` and above.<br>
140-
> Supported Aurora MySQL Versions: Engine Release `3.07` and above.
137+
For these earlier versions, users can consider utilizing the `enableGreenNodeReplacement` configuration parameter, which allows the driver to override incorrect topology metadata and try to connect to available new Blue endpoints.
141138

142139
[^1]: Aurora MySQL requires v3.07 or later.
143140

wrapper/src/main/java/software/amazon/jdbc/dialect/RdsMultiAzDbClusterPgDialect.java

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,19 @@ public class RdsMultiAzDbClusterPgDialect extends PgDialect {
3939
private static final String TOPOLOGY_QUERY =
4040
"SELECT id, endpoint, port FROM rds_tools.show_topology('aws_jdbc_driver-" + DriverInfo.DRIVER_VERSION + "')";
4141

42-
private static final String WRITER_NODE_FUNC_EXIST_QUERY =
43-
"SELECT 1 AS tmp FROM information_schema.routines"
44-
+ " WHERE routine_schema='rds_tools' AND routine_name='multi_az_db_cluster_source_dbi_resource_id'";
45-
4642
// For reader nodes, the query should return a writer node ID. For a writer node, the query should return no data.
4743
private static final String FETCH_WRITER_NODE_QUERY =
4844
"SELECT multi_az_db_cluster_source_dbi_resource_id FROM rds_tools.multi_az_db_cluster_source_dbi_resource_id()"
4945
+ " WHERE multi_az_db_cluster_source_dbi_resource_id !="
5046
+ " (SELECT dbi_resource_id FROM rds_tools.dbi_resource_id())";
5147

48+
private static final String IS_RDS_CLUSTER_QUERY =
49+
"SELECT multi_az_db_cluster_source_dbi_resource_id FROM rds_tools.multi_az_db_cluster_source_dbi_resource_id()";
50+
5251
private static final String FETCH_WRITER_NODE_QUERY_COLUMN_NAME = "multi_az_db_cluster_source_dbi_resource_id";
5352

5453
private static final String NODE_ID_QUERY = "SELECT dbi_resource_id FROM rds_tools.dbi_resource_id()";
5554

56-
private static final String NODE_ID_FUNC_EXIST_QUERY =
57-
"SELECT 1 AS tmp FROM information_schema.routines"
58-
+ " WHERE routine_schema='rds_tools' AND routine_name='dbi_resource_id'";
59-
6055
private static final String IS_READER_QUERY = "SELECT pg_is_in_recovery()";
6156

6257
@Override
@@ -69,39 +64,11 @@ public ExceptionHandler getExceptionHandler() {
6964

7065
@Override
7166
public boolean isDialect(final Connection connection) {
72-
Statement stmt = null;
73-
ResultSet rs = null;
74-
try {
75-
stmt = connection.createStatement();
76-
rs = stmt.executeQuery(WRITER_NODE_FUNC_EXIST_QUERY);
77-
78-
if (rs.next()) {
79-
rs.close();
80-
stmt.close();
81-
82-
stmt = connection.createStatement();
83-
rs = stmt.executeQuery(NODE_ID_FUNC_EXIST_QUERY);
84-
85-
return rs.next();
86-
}
87-
return false;
67+
try (Statement stmt = connection.createStatement();
68+
ResultSet rs = stmt.executeQuery(IS_RDS_CLUSTER_QUERY)) {
69+
return rs.next() && rs.getString(1) != null;
8870
} catch (final SQLException ex) {
8971
// ignore
90-
} finally {
91-
if (stmt != null) {
92-
try {
93-
stmt.close();
94-
} catch (SQLException ex) {
95-
// ignore
96-
}
97-
}
98-
if (rs != null) {
99-
try {
100-
rs.close();
101-
} catch (SQLException ex) {
102-
// ignore
103-
}
104-
}
10572
}
10673
return false;
10774
}

wrapper/src/test/java/software/amazon/jdbc/DialectTests.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ void testRdsPgIsDialectIsAurora() throws SQLException {
252252
void testRdsTazPgIsDialectSuccess() throws SQLException {
253253
when(mockStatement.executeQuery(any())).thenReturn(successResultSet);
254254
when(successResultSet.next()).thenReturn(true);
255+
when(successResultSet.getString(1)).thenReturn("id");
255256
assertTrue(rdsTazPgDialect.isDialect(mockConnection));
256257
}
257258

@@ -269,11 +270,10 @@ void testRdsTazPgIsDialectQueryReturnedEmptyResultSet() throws SQLException {
269270
}
270271

271272
@Test
272-
void testRdsTazPgIsDialectWriterNodeQueryFailed() throws SQLException {
273-
when(mockStatement.executeQuery(any())).thenReturn(successResultSet, failResultSet);
274-
when(successResultSet.next()).thenReturn(true);
273+
void testRdsTazPgIsDialectIsRdsClusterQueryFailed() throws SQLException {
274+
when(mockStatement.executeQuery(any())).thenReturn(failResultSet);
275+
when(successResultSet.next()).thenReturn(false);
275276
assertFalse(rdsTazPgDialect.isDialect(mockConnection));
276-
verify(successResultSet, times(1)).next();
277277
verify(failResultSet, times(1)).next();
278278
}
279279

0 commit comments

Comments
 (0)