Bug #83329 MySqlException "Unknown command" inserting large blob with UseCompression=true
Submitted: 11 Oct 2016 4:37 Modified: 12 Aug 2022 3:32
Reporter: Bradley Grainger (OCA) Email Updates:
Status: Can't repeat Impact on me:
None 
Category:Connector / NET Severity:S2 (Serious)
Version:8.0.30 OS:Windows (Windows 10 x64)
Assigned to: CPU Architecture:Any

[11 Oct 2016 4:37] Bradley Grainger
Description:
Windows 10 x64
Microsoft .NET Framework 4.6.2
Visual Studio 2015
MySql.Data 6.9.9

When MySqlConnectionStringBuilder.UseCompression = true is set, inserting a large random blob will throw the following exception:

Unhandled Exception: MySql.Data.MySqlClient.MySqlException: Unknown command
   at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
   at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
   at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
   at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
   at MySqlCompressBlob.Program.Main(String[] args) in Program.cs:line 33

I've pasted code to reproduce this at https://gist.github.com/bgrainger/ef06cf4d784a0df414f1a9406c74ccd8

In the example, creating a random blob of length 16519388 doesn't reproduce the problem, but making it one byte larger will.

Setting UseCompression=false will also work around the problem.

How to repeat:
Create a new C# console application with the source code at: https://gist.github.com/bgrainger/ef06cf4d784a0df414f1a9406c74ccd8

I've also reproduced the source below:

using System;
using MySql.Data.MySqlClient;

namespace MySqlCompressBlob
{
	class Program
	{
		static void Main(string[] args)
		{
			var csb = new MySqlConnectionStringBuilder
			{
				Server = "localhost",
				Database = "test",
				UserID = "root",
				Password = /* redacted */
				UseCompression = true,
			};

			using (var connection = new MySqlConnection(csb.ConnectionString))
			{
				connection.Open();

				using (var cmd = new MySqlCommand("drop table if exists test.blobs; create table test.blobs(data longblob)", connection))
					cmd.ExecuteNonQuery();

				var bytes = new byte[16519389]; // no exception with new byte[16519388]
				var random = new Random(1);
				random.NextBytes(bytes);

				using (var cmd = new MySqlCommand("insert into test.blobs(data) values(@data);", connection))
				{
					cmd.Parameters.AddWithValue("data", bytes);
					cmd.ExecuteNonQuery();
				}
			}
		}
	}
}
[11 Oct 2016 4:43] Bradley Grainger
MySQL Server mysqld 5.7.11-log (on Windows 10 x64)
[11 Oct 2016 4:57] Bradley Grainger
Edit: fixed title s/blog/blob/
[12 Oct 2016 9:41] Chiranjeevi Battula
Hello Bradley Grainger,

Thank you for the bug report and test case.
Verified this behavior on Visual Studio 2013 (C#.Net) and Connector/NET 6.9.9 version.

Thanks,
Chiranjeevi.
[12 Oct 2016 9:41] Chiranjeevi Battula
Screenshot

Attachment: 83329.JPG (image/jpeg, text), 200.64 KiB.

[7 Apr 2020 16:13] Daniel Valdez
Posted by developer:
 
This test was done using all the specified versions and the mentioned error
didn't came up,
instead of that, we received the exception:
 
MySql.Data.MySqlClient.MySqlException: 'Packets larger than
max_allowed_packet are not allowed.'
 
Which is properly triggered, only when we modify the value of the variable
max_allowed_packet to be higher than the value to be inserted the test works
fine, the blob value is properly inserted in the database.
 
Regards
[10 Aug 2022 17:26] Daniel Valdez
This test was done using all the specified versions and the mentioned error
didn't came up, instead of that, we received the exception:

MySql.Data.MySqlClient.MySqlException: 'Packets larger than
max_allowed_packet are not allowed.'

Which is properly triggered, only when we modify the value of the variable
max_allowed_packet to be higher than the value to be inserted the test works
fine, the blob value is properly inserted in the database.
[12 Aug 2022 3:32] Bradley Grainger
I tested again with 8.0.30. When I increased the test array size to new byte[16519400], it failed with:

System.IO.IOException: Unable to write data to the transport connection: An established connection was aborted by the software in your host machine..
 ---> System.Net.Sockets.SocketException (10053): An established connection was aborted by the software in your host machine.
   at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.Security.SslStream.WriteSingleChunk[TIOAdapter](TIOAdapter writeAdapter, ReadOnlyMemory`1 buffer)
   at System.Net.Security.SslStream.WriteAsyncChunked[TIOAdapter](TIOAdapter writeAdapter, ReadOnlyMemory`1 buffer)
   at System.Net.Security.SslStream.WriteAsyncInternal[TIOAdapter](TIOAdapter writeAdapter, ReadOnlyMemory`1 buffer)
   at System.Net.Security.SslStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at MySql.Data.MySqlClient.TimedStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at MySql.Data.MySqlClient.CompressedStream.CompressAndSendCache()
   at MySql.Data.MySqlClient.MySqlStream.SendPacket(MySqlPacket packet)
   at MySql.Data.MySqlClient.NativeDriver.ExecutePacket(MySqlPacket packetToExecute)
   at MySql.Data.MySqlClient.NativeDriver.Close(Boolean isOpen)

Inner Exception:

IOException: Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.
   at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.Security.SslStream.WriteSingleChunk[TIOAdapter](TIOAdapter writeAdapter, ReadOnlyMemory`1 buffer)
   at System.Net.Security.SslStream.WriteAsyncChunked[TIOAdapter](TIOAdapter writeAdapter, ReadOnlyMemory`1 buffer)
   at System.Net.Security.SslStream.WriteAsyncInternal[TIOAdapter](TIOAdapter writeAdapter, ReadOnlyMemory`1 buffer)
   at System.Net.Security.SslStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at MySql.Data.MySqlClient.TimedStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at MySql.Data.MySqlClient.CompressedStream.CompressAndSendCache()
   at MySql.Data.MySqlClient.MySqlStream.SendPacket(MySqlPacket packet)
   at MySql.Data.MySqlClient.NativeDriver.ExecutePacket(MySqlPacket packetToExecute)
   at MySql.Data.MySqlClient.NativeDriver.SendQuery(MySqlPacket queryPacket, Int32 paramsPosition)
   at MySql.Data.MySqlClient.Driver.SendQuery(MySqlPacket p, Int32 paramsPosition)
   at MySql.Data.MySqlClient.Statement.ExecuteNext()
   at MySql.Data.MySqlClient.PreparableStatement.Execute()
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)

MySQL is running with --max-allowed-packet=96M, which should be much larger than the packet attempting to be sent.