Set aurora_replica_read_consistency to "session" before DML commands .Net6.0 + EFCore6 + Pomelo6 + AWS Aurora (MySQL 5.7)
See original GitHub issueThe issue
I am using AWS Aurora MySQL. Following below article, I have created a secondary readonly cluster and enabled write-forwarding on it so that all write queries sent to secondary readonly cluster are forwarded to primary cluster.
As mentioned in above post, it also requires to set parameter aurora_replica_read_consistency at session level. And I’ve set this in the init_connect like this:
set @@aurora_replica_read_consistency=SESSION
… so that it gets executed automatically when new client connects.
When testing write-queries in MySQL Workbench, it works perfectly and no additional change is required. The same behavior was expected in our .net6.0 application. However, when issuing a write-query in .net6.0 application using Pomelo 6.0.1, it throws an error as if aurora_replica_read_consistency is set to blank.
Exception message:
Stack trace: Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details.
---> MySqlConnector.MySqlException (0x80004005): The MySQL server is running with the --read-only option so it cannot execute this statement
at MySqlConnector.Core.ServerSession.ReceiveReplyAsyncAwaited(ValueTask`1 task) in /_/src/MySqlConnector/Core/ServerSession.cs:line 954
at MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior ioBehavior) in /_/src/MySqlConnector/Core/ResultSet.cs:line 44
at MySqlConnector.MySqlDataReader.ActivateResultSet(CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 127
at MySqlConnector.MySqlDataReader.CreateAsync(CommandListPosition commandListPosition, ICommandPayloadCreator payloadCreator, IDictionary`2 cachedProcedures, IMySqlCommand command, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 456
at MySqlConnector.Core.CommandExecutor.ExecuteReaderAsync(IReadOnlyList`1 commands, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/CommandExecutor.cs:line 56
at MySqlConnector.MySqlCommand.ExecuteReaderAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlCommand.cs:line 330
at MySqlConnector.MySqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlCommand.cs:line 323
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(StateManager stateManager, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.<>c__DisplayClass33_0`2.<<ExecuteAsync>b__0>d.MoveNext()
Do we need additional changes when using write-forward on AWS Aurora MySQL with Pomelo?
Further technical details
MySQL version: 5.7.12-log Operating system: AWS RDS Aurora Pomelo.EntityFrameworkCore.MySql version: 6.0.1 Microsoft.AspNetCore.App version:
Other details about my project setup: TargetFramework: .net6.0 WebAPI Project
Issue Analytics
- State:
- Created a year ago
- Comments:33
Note that you will need to disable SSL with
SslMode=None;
for the packet capture to be useful. If that’s not possible (e.g., can’t be disabled on Aurora) then all the packets will be encrypted and I won’t be able to read them to see what’s going on.My guess would be connection pooling.
MySqlConnection.Open
doesn’t always result in a new connection being established to the database server (for performance). Most of the time, an existing connection is reused. Moreover, that connection is reset (to clear session variables, temp tables, etc.). My guess would be that in Aurora, this also clears theaurora_replica_read_consistency
setting.You could test this theory by adding
Connection Reset = false;
to your connection string.