We have a weird behavior showing on a system working with Amazon Aurora 2. The behavior exhibits only under load and only sporadically, so (a) it is hard to reproduce it systematically, thus we resort to reading memory dumps, and (b) we suspect it might be related to some concurrency issue. I have two dumps from two nodes in the cluster having this issue and they both have the same characteristics.
The behavior exhibits as a thread permanently (or at least long enough to produce a cascade effect throughout the system) hung in this call stack:
System.dll!System.Net.Sockets.Socket.Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, out System.Net.Sockets.SocketError errorCode) Line 2096 C#
System.dll!System.Net.Sockets.NetworkStream.Read(byte[] buffer, int offset, int size) Line 432 C#
System.dll!System.Net.FixedSizeReader.ReadPacket(byte[] buffer, int offset, int count) Line 26 C#
System.dll!System.Net.Security._SslStream.StartFrameBody(int readBytes, byte[] buffer, int offset, int count, System.Net.AsyncProtocolRequest asyncRequest) Line 648 C#
System.dll!System.Net.Security._SslStream.StartFrameHeader(byte[] buffer, int offset, int count, System.Net.AsyncProtocolRequest asyncRequest) Line 619 C#
System.dll!System.Net.Security._SslStream.StartReading(byte[] buffer, int offset, int count, System.Net.AsyncProtocolRequest asyncRequest) Line 597 C#
System.dll!System.Net.Security._SslStream.ProcessRead(byte[] buffer, int offset, int count, System.Net.AsyncProtocolRequest asyncRequest) Line 557 C#
System.dll!System.Net.Security.SslStream.Read(byte[] buffer, int offset, int count) Line 739 C#
MySqlConnector.dll!MySqlConnector.Utilities.Utility.Read(System.IO.Stream stream, System.Memory<byte> buffer) Line 534 C#
MySqlConnector.dll!MySqlConnector.Protocol.Serialization.StreamByteHandler.ReadBytesAsync.__DoReadBytesSync|6_0(System.Memory<byte> buffer) Line 33 C#
MySqlConnector.dll!MySqlConnector.Protocol.Serialization.StreamByteHandler.ReadBytesAsync(System.Memory<byte> buffer, MySqlConnector.Protocol.Serialization.IOBehavior ioBehavior) Line 25 C#
MySqlConnector.dll!MySqlConnector.Protocol.Serialization.BufferedByteReader.ReadBytesAsync(MySqlConnector.Protocol.Serialization.IByteHandler byteHandler, System.ArraySegment<byte> buffer, int totalBytesToRead, MySqlConnector.Protocol.Serialization.IOBehavior ioBehavior) Line 36 C#
MySqlConnector.dll!MySqlConnector.Protocol.Serialization.BufferedByteReader.ReadBytesAsync(MySqlConnector.Protocol.Serialization.IByteHandler byteHandler, int count, MySqlConnector.Protocol.Serialization.IOBehavior ioBehavior) Line 29 C#
MySqlConnector.dll!MySqlConnector.Protocol.Serialization.ProtocolUtility.ReadPacketAfterHeader(System.ReadOnlySpan<byte> headerBytes, MySqlConnector.Protocol.Serialization.BufferedByteReader bufferedByteReader, MySqlConnector.Protocol.Serialization.IByteHandler byteHandler, System.Func<int> getNextSequenceNumber, MySqlConnector.Protocol.Serialization.ProtocolErrorBehavior protocolErrorBehavior, MySqlConnector.Protocol.Serialization.IOBehavior ioBehavior) Line 432 C#
MySqlConnector.dll!MySqlConnector.Protocol.Serialization.ProtocolUtility.ReadPacketAsync(MySqlConnector.Protocol.Serialization.BufferedByteReader bufferedByteReader, MySqlConnector.Protocol.Serialization.IByteHandler byteHandler, System.Func<int> getNextSequenceNumber, MySqlConnector.Protocol.Serialization.ProtocolErrorBehavior protocolErrorBehavior, MySqlConnector.Protocol.Serialization.IOBehavior ioBehavior) Line 409 C#
MySqlConnector.dll!MySqlConnector.Protocol.Serialization.ProtocolUtility.DoReadPayloadAsync(MySqlConnector.Protocol.Serialization.BufferedByteReader bufferedByteReader, MySqlConnector.Protocol.Serialization.IByteHandler byteHandler, System.Func<int> getNextSequenceNumber, MySqlConnector.Protocol.Serialization.ArraySegmentHolder<byte> previousPayloads, MySqlConnector.Protocol.Serialization.ProtocolErrorBehavior protocolErrorBehavior, MySqlConnector.Protocol.Serialization.IOBehavior ioBehavior) Line 466 C#
MySqlConnector.dll!MySqlConnector.Protocol.Serialization.StandardPayloadHandler.ReadPayloadAsync(MySqlConnector.Protocol.Serialization.ArraySegmentHolder<byte> cache, MySqlConnector.Protocol.Serialization.ProtocolErrorBehavior protocolErrorBehavior, MySqlConnector.Protocol.Serialization.IOBehavior ioBehavior) Line 42 C#
MySqlConnector.dll!MySqlConnector.Core.ServerSession.ReceiveReplyAsync(MySqlConnector.Protocol.Serialization.IOBehavior ioBehavior, System.Threading.CancellationToken cancellationToken) Line 849 C#
MySqlConnector.dll!MySqlConnector.Core.ServerSession.TryResetConnectionAsync(MySqlConnector.Core.ConnectionSettings cs, MySqlConnector.MySqlConnection owningConnection, bool returnToPool, MySqlConnector.Protocol.Serialization.IOBehavior ioBehavior, System.Threading.CancellationToken cancellationToken) Line 552 C#
MySqlConnector.dll!MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnector.MySqlConnection connection, int startTickCount, MySqlConnector.Protocol.Serialization.IOBehavior ioBehavior, System.Threading.CancellationToken cancellationToken) Line 71 C#
MySqlConnector.dll!MySqlConnector.MySqlConnection.CreateSessionAsync(MySqlConnector.Core.ConnectionPool pool, int startTickCount, MySqlConnector.Protocol.Serialization.IOBehavior? ioBehavior, System.Threading.CancellationToken cancellationToken) Line 873 C#
MySqlConnector.dll!MySqlConnector.MySqlConnection.OpenAsync(MySqlConnector.Protocol.Serialization.IOBehavior? ioBehavior, System.Threading.CancellationToken cancellationToken) Line 414 C#
MySqlConnector.dll!MySqlConnector.MySqlConnection.Open() Line 380 C#
Our guess is that while talking to Aurora something happens to the packet order, the connector gets the wrong byte count and tries to read a lot of data that doesn't arrive - thus, gets stuck in Socket.Receive.
We have a weird behavior showing on a system working with Amazon Aurora 2. The behavior exhibits only under load and only sporadically, so (a) it is hard to reproduce it systematically, thus we resort to reading memory dumps, and (b) we suspect it might be related to some concurrency issue. I have two dumps from two nodes in the cluster having this issue and they both have the same characteristics.
We using version 1.3.14 of
MySqlConnectorand we cannot currently upgrade to 2.x due to conflicting dependencies.The behavior exhibits as a thread permanently (or at least long enough to produce a cascade effect throughout the system) hung in this call stack:
As we unroll the stack and examine the state, we observe the following:
BufferedByteReader.ReadBytesAsynctotalBytesToReadis 197399 (which, I suppose, is way too much)ProtocolUtility.ReadPacketAfterHeaderpayloadLengthis set to the same 197399, and we have alsopacketOutOfOrderExceptionset toMySqlProtocolExceptionwith a message of "Packet received out-of-order. Expected 1; got 30."Our guess is that while talking to Aurora something happens to the packet order, the connector gets the wrong byte count and tries to read a lot of data that doesn't arrive - thus, gets stuck in
Socket.Receive.The question is, why we wait in
Socket.Receive? Shouldn't there be a timeout for this operation? My knowledge to the lower-level networking is very limited, and I couldn't find anywhere in the code where we'd set the timeout on theSocket/TcpClient/SslStream/NetworkStream. Am I missing something?