Skip to content

[WIP] feat: unified read/write splitting plugin family#2016

Open
sergiyvamz wants to merge 18 commits into
mainfrom
feature/unified-read-write-splitting
Open

[WIP] feat: unified read/write splitting plugin family#2016
sergiyvamz wants to merge 18 commits into
mainfrom
feature/unified-read-write-splitting

Conversation

@sergiyvamz

@sergiyvamz sergiyvamz commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Refactors the read/write splitting plugins onto a unified, composition-based plugin so routing signal, switch gate, reader/writer resolution, caching, and initial-connection handling can be mixed, then builds new capabilities on top. Existing plugin codes and behavior are preserved.

What's included

  • Unified base (UnifiedReadWriteSplittingPlugin) with helper families; the existing codes (readWriteSplitting, autoReadWriteSplitting, srw, gdbReadWriteSplitting) are reconstructed as helper assemblies.
  • New plugin codes: autoSimpleReadWriteSplitting, gdbAutoReadWriteSplitting, gdbSimpleReadWriteSplitting, gdbAutoSimpleReadWriteSplitting.
  • Query-level load balancing (queryLevelLoadBalancing, loadBalancingIncludeWriter): select a fresh reader on each read-routing decision instead of reusing a sticky reader; family-wide, not auto-only.
  • Statement recreation on connection switch (allowStatementRecreationOnConnectionSwitch, default on): reused Statement/PreparedStatement/CallableStatement are re-created on the routed connection (replaying recorded settings, bound parameters, and registered OUT parameters). Stream/LOB parameters or a pending batch fall back to the current connection with a one-time warning.

Tests

  • ~135 unit tests across signals, gate, cache, classifiers, resolvers, verifier, connect handlers, update policies, candidate sources, and plugin orchestration.
  • Integration suites for the non-GDB plugins, plus reader-transaction and PreparedStatement-rebind scenarios. Integration tests require a live cluster.

Docs

  • Dedicated pages for the four new plugin codes, wired into the plugin index and cross-reference tables; updated configuration assistant, read/write splitting plugin pages, and README parameter table.

@sergiyvamz sergiyvamz changed the title feat: unified read/write splitting plugin family (new codes, query-level load balancing, statement recreation) feat: unified read/write splitting plugin family Jul 8, 2026
sergiyvamz added 15 commits July 8, 2026 16:26
…ed PerQueryBalancedReaderPolicy

Adds isolated unit tests (happy/exception/failure/timeout paths) for routing signals, switch gate, cache policy, role classifiers, writer/reader resolvers (topology, endpoint, gdb), the endpoint connection verifier, and the topology connect handler. Removes the unused PerQueryBalancedReaderPolicy and its now-dead LoadBalancingPolicy.isPerQuery default.
Covers rebind-to-reader/writer, already-on-target no-op, transaction pin, rebind opt-out, missing rebind handle, rebind-failure fallback, and once-only reuse warning, exercised through AutoReadWriteSplittingPlugin.
Adds queryLevelLoadBalancing and loadBalancingIncludeWriter properties. When enabled, the reader resolver uses PerQueryBalancedReaderPolicy and the plugin rotates reader-to-reader (role-safe) on each read-routing decision within an established read-only phase, instead of reusing a single sticky reader. Wired into readWriteSplitting, autoReadWriteSplitting, gdbReadWriteSplitting, and srw assemblies. Also warns once when a PreparedStatement/CallableStatement is re-executed under query-level LB (cannot rotate readers). Unit-tested; connection-lifecycle interaction with open ResultSets (req 14.9) still needs integration validation.
…dWriteSplitting

Each reuses the existing read/write splitting integration suite (readWriteSplitting / srw) with the sqlParser plugin ordered ahead of the SQL-routed plugin. Base tests that execute un-hinted raw read SQL expecting to stay on the current connection are disabled, since SQL-based routing intentionally reroutes those reads. GDB variants are intentionally excluded (not supported by the integration suite yet).
…g; add endpoint-based GDB codes

Renames the SQL-routed endpoint code and its class/factory/test to the 'Simple' naming. Adds gdbSimpleReadWriteSplitting (setReadOnly-driven) and autoGdbSimpleReadWriteSplitting (SQL-routed): endpoint-based Global Database splitting that applies region rules and Global Write Forwarding to the configured write endpoint (seeded via a new EndpointWriterHostRefresher so the GDB writer resolver can evaluate its region). Registered with weights 1330/1340. Unit-tested; GDB integration tests are out of scope (not supported by the integration suite).
… prefix first)

autoGdbReadWriteSplitting -> gdbAutoReadWriteSplitting; autoGdbSimpleReadWriteSplitting -> gdbAutoSimpleReadWriteSplitting. Renames the codes, plugin classes, and factories consistently and re-registers them; behavior unchanged.
…tement

PreparedStatement/CallableStatement can now be rerouted to a different connection on re-execution for query-level load balancing. A recording InvocationHandler captures parameter setters, out-parameter registrations, and statement settings so they can be replayed onto a statement re-prepared on the routed connection; the wrapper's target is swapped via a stable proxy. A statement becomes non-rebindable if a one-shot stream/reader parameter is bound or a batch is pending, in which case the plugin warns once instead. Recording is gated on queryLevelLoadBalancing + rebindStatementOnRouting, so there is no overhead by default. Writes are never rotated. Also records all StatementWrapper settings for replay. Unit-tested; real behavior still needs integration validation.
… tests

Add test_transactionOnReaderStaysOnReader to verify a transaction on a reader connection stays pinned to the reader (transactions pin the connection but do not force the writer). Add test_reExecutedPreparedStatementRotatesAcrossReaders to verify PreparedStatement rebind-on-execute rotates reader-to-reader when queryLevelLoadBalancing is enabled. Add public AuroraTestUtility.getInstanceIdSql() accessor returning the raw (un-hinted) instance-id SELECT.
…codes

Add dedicated pages for the four new plugin codes (autoSimpleReadWriteSplitting, gdbAutoReadWriteSplitting, gdbSimpleReadWriteSplitting, gdbAutoSimpleReadWriteSplitting) and wire them into the plugin index, host selection strategies, and accessible-regions references. Document queryLevelLoadBalancing, loadBalancingIncludeWriter, and rebindStatementOnRouting across the configuration assistant and the read/write splitting plugin pages, and update mutual-exclusion warnings to cover the full family.
…OnConnectionSwitch

Rename the read/write splitting property (and its AwsWrapperProperty constant/field) to a clearer, jargon-free name that frames it as a permission for re-creating already-created statements when a routing decision switches the underlying connection. Update the property description, the reused-bound-statement message, tests, the configuration assistant, the plugin docs, and the CHANGELOG. Pure rename; behavior is unchanged.
@sergiyvamz sergiyvamz force-pushed the feature/unified-read-write-splitting branch from 44391fa to 0461a61 Compare July 8, 2026 23:29
…ites to *Tests

Merge AutoReadWriteSplittingTest (base-suite subclass) into AutoReadWriteSplittingTests, and rename SimpleReadWriteSplittingTest -> SimpleReadWriteSplittingTests and AutoSimpleReadWriteSplittingTest -> AutoSimpleReadWriteSplittingTests for a consistent *Tests suite naming convention. Remove the stale AutoReadWriteSplittingPluginTest unit test (from the rebase of PR #2009) that targets the pre-unified auto-plugin API, along with its now-unused switchedToBalancedReader message key; query-level load balancing is covered by the unified tests.
@sergiyvamz sergiyvamz changed the title feat: unified read/write splitting plugin family [WIP] feat: unified read/write splitting plugin family Jul 9, 2026
…write splitting

When no reader can be selected or reached (e.g. the only reader is unavailable and the host-selection strategy reports no matching host), UnifiedReadWriteSplittingPlugin.performSwitch now falls back to the writer connection instead of remaining on the current (possibly broken) reader connection. This matches the legacy read/write splitting behavior and fixes reader-down/reader-failover integration tests that surfaced a misleading 'does not support host selection strategy: random' error followed by a CommunicationsException. The current connection is kept only if the writer is also unreachable.
…o/simple configs

Disable test_setReadOnlyTrue_oneReaderDown_fallsBackToWriter for SimpleReadWriteSplittingTests (srw connects to fixed endpoints, so a single-instance outage does not make the read endpoint fail). Disable test_setReadOnlyFalseInTransaction_setAutocommitFalse for the auto configs and test_autoCommitStatePreserved_acrossConnectionSwitches for auto-simple, because with autocommit disabled the connection is pinned to preserve the transaction, so setReadOnly does not switch -- matching the already-disabled sibling transaction tests.
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.

1 participant