Я создал специальную службу Windows, которая распределяет новые задания (процессы, а не потоки) на основе очереди в таблице MySQL. «Задания» - это приложения, работающие с базами данных, а также сервис (с этого момента я буду называть его «менеджер»).
В периоды большого объема (инициируется много «заданий») эта ошибка начинает возникать, довольно часто (затрагивается примерно ~ 1 из 20 заданий). «Интересно» то, что 9 раз из 10, когда возникает эта ошибка, это самая первая команда SQL нового задания. Я не думаю, что видел это в менеджере. Редкий случай, когда эта ошибка возникает в середине задания (десятки команд SQL выполняются за одно задание).
MySql.Data.MySqlClient.MySqlException (0x80004005): Authentication to host '***' for user '***' using method 'mysql_native_password' failed with message: Reading from the stream has failed. ---> MySql.Data.MySqlClient.MySqlException (0x80004005): Reading from the stream has failed. ---> System.IO.EndOfStreamException: Attempted to read past the end of the stream.
at MySql.Data.MySqlClient.MySqlStream.ReadFully(Stream stream, Byte[] buffer, Int32 offset, Int32 count)
at MySql.Data.MySqlClient.MySqlStream.LoadPacket()
at MySql.Data.MySqlClient.MySqlStream.LoadPacket()
at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
at MySql.Data.MySqlClient.Authentication.MySqlAuthenticationPlugin.ReadPacket()
at MySql.Data.MySqlClient.Authentication.MySqlAuthenticationPlugin.AuthenticationFailed(Exception ex)
at MySql.Data.MySqlClient.Authentication.MySqlAuthenticationPlugin.ReadPacket()
at MySql.Data.MySqlClient.Authentication.MySqlAuthenticationPlugin.Authenticate(Boolean reset)
at MySql.Data.MySqlClient.NativeDriver.Authenticate(String authMethod, Boolean reset)
at MySql.Data.MySqlClient.NativeDriver.Open()
at MySql.Data.MySqlClient.Driver.Open()
at MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings)
at MySql.Data.MySqlClient.MySqlPool.CreateNewPooledConnection()
at MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()
at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver()
at MySql.Data.MySqlClient.MySqlPool.GetConnection()
at MySql.Data.MySqlClient.MySqlConnection.Open()
at MySql.Data.MySqlClient.MySqlHelper.ExecuteReader(String connectionString, String commandText, MySqlParameter[] commandParameters)
Фон на моем стеке:
- Windows Server 2016 (это то, на чем работают менеджер и задания)
- MySql.Data 6.10.8 (пакет nuget для интеграции .NET SQL)
Настройки строки соединения SQL (без аутентификации):
- шифровать = ложь;
- AllowZeroDatetime = истина;
- CheckParameters = ложь;
Вещи, которые я пробовал:
SSL: большинство поисковиков Google для этой проблемы предлагают точно такой же пост, предлагающий изменить настройки SSL. Я просто добавлю ссылку: http://www.voidcn.com/article/p-phfoefri-bpr.html (ни одно из предложенных решений не помогло мне)
Конфигурация пула соединений: я успешно отключил пул соединений (например, добавив "Pooling = false;" в строку соединения), но я боюсь, что это не очень хорошее решение в долгосрочной перспективе. Я хочу иметь возможность использовать и понимать пул соединений из-за его преимуществ производительности. Конечно, отключение пула соединений не может быть единственным способом исправить это. Существуют и другие параметры, относящиеся к пулу соединений, такие как «сброс соединения», но у меня нет достаточного понимания, чтобы их использовать, и я нахожу документацию sql по каждому параметру слишком короткой, чтобы действительно понять это. Я попытался увеличить настройку MaxPool, но это не имело никакого эффекта. Существует также параметр «ConnectionTimeout», который задает количество времени, в течение которого соединение будет ожидать ответа сервера, прежде чем прервать его. У меня есть вопрос по этому поводу, когда sql cmd ожидает открытия соединения в пуле, делает ли это только ждать секунд "CommandTimeout"?
Все мои команды sql выполняются с использованием класса MySqlHelper следующим образом (некоторые из моих команд просто используют ExecuteNonQuery очень похожим образом):
using (MySqlDataReader sqlRdr = MySqlHelper.ExecuteReader(connString, cmdText, sqlParams.ToArray()))
{
while (sqlRdr.Read())
{
ret.Add(getFromRdr(sqlRdr));
}
}
У меня проблемы с "устранением" этой ошибки. Большинство исследований, которые я проводил в поисках этого исключения, просто возвращаются к тому же посту об изменении настроек SSL. Не похоже, что моя проблема связана с SSL, тем более что отключение пула соединений, похоже, решает эту проблему.
Заранее спасибо за любую помощь.