-
Notifications
You must be signed in to change notification settings - Fork 3
Failover plugin causes 'MySqlConnection is already in use' with EF Core / Pomelo MySqlConnector #268
Description
Description
When using the failover plugin with Entity Framework Core (Pomelo.EntityFrameworkCore.MySql 9.0.0) and MySqlConnector, an Aurora writer failover causes the connection to enter a permanently broken state. After the first successful reconnection, all subsequent commands fail with MySqlConnection is already in use.
Environment
- AWS.AdvancedDotnetDataProviderWrapper.EntityFrameworkCore.MySqlConnector 1.0.1
- Pomelo.EntityFrameworkCore.MySql 9.0.0
- MySqlConnector 2.4.0 (transitive via Pomelo)
- .NET 10.0
- Aurora MySQL cluster (eu-west-1, 2 writer-eligible instances)
Steps to Reproduce
- Configure EF Core with the wrapper:
optionsBuilder.UseAwsWrapper(
connectionString + ";Plugins=failover;",
wrappedOptions => wrappedOptions.UseMySql(connectionString, serverVersion));-
Execute write queries continuously via
DbContext.Database.ExecuteSqlRawAsync() -
Trigger Aurora failover:
aws rds failover-db-cluster --db-cluster-identifier <cluster> -
Observe behavior
Observed Behavior
- Queries 1-14: succeed (before failover)
- Query 15: fails with connection error (failover starts) —
DealWithOriginalExceptionAsyncfires - Queries 16-17: connection errors (expected during failover)
- Queries 18-26: succeed (wrapper reconnected to new writer — failover worked!)
- Query 27+: ALL fail permanently with
MySqlConnection is already in use
The wrapper successfully reconnects once, but then the underlying MySqlConnection's ServerSession gets stuck in State.Querying — every subsequent command hits StartQuerying() which throws because the session state was never reset.
Root Cause Analysis
The failover plugin calls SetCurrentConnection() to swap the underlying DbConnection to a new one pointing at the new writer. However:
- EF Core's
RelationalConnectioncaches a reference to the originalDbConnection - When the failover plugin swaps the connection, the old
MySqlConnection'sServerSession.m_stateremainsQuerying - The wrapper's
AwsWrapperConnectionhasActiveWrapperCommandslist — commands from the failed connection may not be properly unregistered - Subsequent commands attempt to execute on the old
MySqlConnectionreference (cached by EF Core), which has a session stuck inQueryingstate
The MySqlConnection is already in use check is in MySqlConnector.Core.ServerSession.StartQuerying():
if (m_state is State.Querying or State.CancelingQuery)
throw new InvalidOperationException("This MySqlConnection is already in use.");Additional Issues Found
During investigation we also found:
-
initialConnectionplugin breaks EF Core migrations — it swaps the connection mid-migration transaction, causing DDL to auto-commit but__EFMigrationsHistoryINSERT to be lost (tables created but not recorded) -
EnableRetryOnFailureconflicts with failover plugin — EF Core's retry strategy tries to reuse the connection duringDealWithOriginalExceptionAsync, causing the same "already in use" error immediately -
Plugins=connection string key rejected by MySqlConnector —MySqlConnectionStringBuilderthrowsArgumentException: Option 'plugins' not supported. The wrapper and EF Core need separate connection strings. -
Allow User Variables=truerequired — the wrapper re-parses SQL throughAwsWrapperCommand, causing MySqlConnector to treat@user variables in stored procedure DDL as parameters
Expected Behavior
After a successful failover reconnection, subsequent commands should execute normally against the new writer without connection state corruption.
Workaround
Currently there is no workaround for the failover plugin with EF Core. Using only the initialConnection plugin (without failover) works for reader load balancing but provides no failover handling.