Тайм-аут истек. Время ожидания истекло до завершения операции, или сервер не отвечает. Заявление было прекращено

296

У меня много пользователей на моем веб-сайте (20000-60000 в день), который является сайтом загрузки для мобильных файлов. У меня есть удаленный доступ к моему серверу (Windows Server 2008-R2).
Ранее я получал сообщения об ошибке «Сервер недоступен» , но теперь я вижу ошибку тайм-аута соединения.
Я не знаком с этим - почему это происходит и как я могу это исправить?

Полная ошибка ниже:

Ошибка сервера в приложении '/' Тайм-аут истек. Время ожидания истекло до завершения операции, или сервер не отвечает. Заявление было прекращено. Описание: во время выполнения текущего веб-запроса произошло необработанное исключение. Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.

Сведения об исключении: System.Data.SqlClient.SqlException: истекло время ожидания. Время ожидания истекло до завершения операции, или сервер не отвечает. Заявление было прекращено.

Ошибка источника:

Во время выполнения текущего веб-запроса было сгенерировано необработанное исключение. Информация о происхождении и местонахождении исключения может быть идентифицирована с помощью приведенной ниже трассировки стека исключений.

Трассировки стека:

[SqlException (0x80131904): истекло время ожидания. Время ожидания истекло до завершения операции, или сервер не отвечает. Оператор был прерван.]
System.Data.SqlClient.SqlConnection.OnError (исключение SqlException, логическое breakConnection) +404
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning () +412
System.Data.SqlClient.TiorB () , SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +1363
System.Data.SqlClient.SqlCommand.FinishExecuteReader (SqlDataReegeSigning)
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds (CommandBehavior cmdBehavior, RunBehavior runBehavior, булева returnStream, булева асинхронный) +6389442
System.Data.SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, булева returnStream, метод String, результат DbAsyncResult) + 538
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery (результат DbAsyncResult, строковое имя-метода, логическое значение sendToPipe) +689
System.Data.SqlClient.SqlCommand.ExecuteNonQuery () +327
параметров- объекта- объекта- объекта- объекта- объекта- объекта- объекта- хранилища () , Int32 & rowActed) +209
DataLayer.OnlineUsers.Update_SessionEnd_And_Online (Object Session_End, Boolean Online) +440
NiceFileExplorer.Global.Application_Start (Отправитель объекта, EventArgs e) +163

[HttpException (0x80004005): истекло время ожидания. Время ожидания истекло до завершения операции, или сервер не отвечает. Заявление было прекращено.]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode (HttpContext контекст, HttpApplication приложение) +4052053
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS (IntPtr контекст приложения, HttpContext контекст, MethodInfo [] обработчики) +191
System.Web.HttpApplication. InitSpecial (состояние HttpApplicationState, обработчики MethodInfo [], appContext IntPtr, контекст HttpContext) +352
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance ( контекст appPter IntPt, контекст HttpContext) +407
Int.P.Intemp.Time

[HttpException (0x80004005): истекло время ожидания. Время ожидания истекло до завершения операции, или сервер не отвечает. Оператор был прерван.]
System.Web.HttpRuntime.FirstRequestInit (контекст HttpContext) +11686928 System.Web.HttpRuntime.EnsureFirstRequestInit (контекст HttpContext) +141 System.Web.HttpRuntime.ProcessRequestWisWestWestWestWestWestWestWestWestWestWestWestWestWestWestWestWestWestWestWestWestWisWeb) WISE


EDIT ПОСЛЕ ОТВЕТЫ:
мой Application_Startв Global.asaxэто , как показано ниже:

protected void Application_Start(object sender, EventArgs e)
{
    Application["OnlineUsers"] = 0;

    OnlineUsers.Update_SessionEnd_And_Online(
        DateTime.Now,
        false);

    AddTask("DoStuff", 10);
}

Вызываемая хранимая процедура:

ALTER Procedure [dbo].[sp_OnlineUsers_Update_SessionEnd_And_Online]
    @Session_End datetime,
    @Online bit
As
Begin
    Update OnlineUsers
    SET
        [Session_End] = @Session_End,
        [Online] = @Online

End

У меня есть два способа получить пользователей онлайн:

  1. с помощью Application["OnlineUsers"] = 0;
  2. другой использует базу данных

Итак, для метода № 2 я сбросил все OnlineUsers в Application_Start. В этой таблице более 482 751 записей.

SilverLight
источник
1
Как здесь сказано По умолчанию 15 секунд
V4Vendetta
1
Лучше сделать анализ первопричин, Есть разные причины, чтобы вызвать такую ​​проблему. Основным является сложная структура запроса. Я столкнулся с той же проблемой при получении изображений, которые хранятся в виде шестнадцатеричных значений в таблице.
Виджай Кумбхойе
Помимо причин, приведенных выше, я добавлю еще одну: Время ожидания блокировки: docs.microsoft.com/en-us/sql/t-sql/statements/… Если этот поток ожидает блокировки слишком долго, он будет зависеть от времени ожидания. вышеуказанный документ.
Герберт Ю

Ответы:

345

Похоже, у вас есть запрос, который занимает больше времени, чем нужно. По трассировке стека и коду вы сможете точно определить, что это за запрос.

Этот тип таймаута может иметь три причины;

  1. Где-то тупик
  2. Статистика базы данных и / или кеш плана запросов неверны
  3. Запрос слишком сложный и должен быть настроен

Тупик может быть трудно исправить, но легко определить, так ли это. Подключитесь к своей базе данных с помощью Sql Server Management Studio. На левой панели щелкните правой кнопкой мыши узел сервера и выберите « Монитор активности» . Посмотрите на запущенные процессы. Обычно большинство будет бездействовать или работать. Когда возникает проблема, вы можете идентифицировать любой заблокированный процесс по состоянию процесса. Если вы щелкнете правой кнопкой мыши по процессу и выберете детали, он покажет вам последний запрос, выполненный процессом.

Вторая проблема заставит базу данных использовать неоптимальный план запроса. Это можно решить, очистив статистику:

exec sp_updatestats

Если это не сработает, вы также можете попробовать

dbcc freeproccache

Вы не должны делать это, когда ваш сервер находится под большой нагрузкой, потому что он временно подвергнется значительному снижению производительности, так как все хранимые процессы и запросы перекомпилируются при первом выполнении. Однако, поскольку вы заявляете, что проблема возникает иногда , и трассировка стека указывает, что ваше приложение запускается, я думаю, что вы выполняете запрос, который запускается только изредка. Возможно, вам будет лучше, если вы заставите SQL Server не использовать предыдущий план запроса. Смотрите этот ответ для деталей о том, как это сделать.

Я уже коснулся третьей проблемы, но вы можете легко определить, нуждается ли запрос в настройке, выполнив запрос вручную, например, с помощью Sql Server Management Studio. Если выполнение запроса занимает слишком много времени, даже после сброса статистики вам, вероятно, потребуется настроить его. Чтобы помочь с этим, вы должны опубликовать точный запрос в новом вопросе.

Марникс ван Вален
источник
39
У меня была та же ошибка, но в запросе, который "просто" занял 8 сек ... и ваш совет о решении exec sp_updatestatsмоей проблемы. Большое спасибо!
nrod
2
Решение такой проблемы почти никогда не зависит от настройки времени ожидания или размера пула соединений. Вам нужно погрузиться и выяснить причину. Если вам нужна помощь в устранении этой основной причины, вы можете оставить свой вопрос.
Марникс ван Вален
5
Это конечно не тупик. Это может быть вызвано чрезмерной блокировкой, но взаимные блокировки устраняются за секунду, и они генерируют разные ошибки. Это может быть чрезмерная блокировка, но не тупик.
Майкл Дж Сварт
1
мы уверены, что это тайм-аут команды, а не тайм-аут соединения? «System.Data.SqlClient.SqlConnection.OnError» для меня указывает на проблему подключения.
Майк У
1
@PrashantPimpale Это зависит Если у вас есть серьезная проблема в производстве, когда неправильная статистика приводит к плохим планам выполнения, тогда да, это может быть решением. Если исключить исключительные проблемы (например, сбой оборудования), обновление статистики не повредит вашу базу данных. Это может вызвать медленные запросы на некоторое время. В конце концов, это ваш звонок.
Марникс ван Вален
155

В вашем коде, где вы запускаете хранимую процедуру, у вас должно быть что-то вроде этого:

SqlCommand c = new SqlCommand(...)
//...

Добавьте такую ​​строку кода:

c.CommandTimeout = 0;

Это будет ждать столько времени, сколько необходимо для завершения операции.

Elastep
источник
144
Вы также должны знать, что значение 0 не рекомендуется : значение 0 указывает на отсутствие ограничений, и его следует избегать в CommandTimeout, потому что попытка выполнить команду будет ждать бесконечно долго. Лучше узнать, сколько времени занимает команда, и при необходимости увеличить значение Timeout.
Отиэль
7
Я согласен с Otiel и отклонил ваш ответ: устанавливая commandTimeout в 0, вы не даете веб-серверу шанс восстановиться с сервера базы данных, который не отвечает. Во-вторых, когда вы устанавливаете таймаут по умолчанию, вы должны рассмотреть причину. В большинстве случаев лучше исправить запрос, чем увеличивать время ожидания.
Мартен Кифт
10
Я бы не попал в ловушку не рекомендовать его. Это было очень полезно для меня и моих ежедневных запланированных задач: бесконечный тайм-аут не останавливает завершение процесса и возвращает ошибку, если что-то идет не так. Проще говоря, это просто позволяет вам разрешить выполнение запроса в любое время, не вызывая при этом проблем, потому что вы не выделили достаточно времени для завершения процесса. Вы также можете избежать блокировки вашей программы многопоточностью.
WonderWorker
2
Да, для больших передач данных, не устанавливая это не имеет смысла. Если вы переносите миллионы строк, то, что говорят Otiel и BlackHawkDesign, не имеет смысла.
Bluerubez
За 20 лет разработки, ориентированной на данные, мне никогда не нужно было этого делать. Почти всегда есть достаточно простое решение, которое дает лучшую производительность и не создает возможности для одного процесса в течение всего дня. Подавляющее большинство проблем с производительностью дБ можно настроить так, чтобы они выполнялись на несколько порядков быстрее. То есть процесс, который вы ожидаете 3 часа, может быть настроен на 3 минуты или даже 3 секунды.
b_levitt
25

Вы можете установить CommandTimeoutсвойство команды SQL, чтобы разрешить длительную транзакцию SQL.

Вам также может понадобиться посмотреть на SQL-запрос, который вызывает тайм-аут.

Кев Ричи
источник
Привет, "или вам нужно посмотреть на SQL-запрос, который вызывает тайм-аут" -> в SQL Server 2008, где я должен проверить этот тайм-аут?
SilverLight
Вам может потребоваться проверить хранимую процедуру, которая вызывается из DataLayer.OnlineUsers.Update_SessionEnd_And_Online, поскольку трассировка стека, кажется, указывает на нее. Возьмите копию действующей базы данных в тест и запустите хранимую процедуру, передав необходимые параметры, если для ее завершения требуется более 30 секунд, поэтому вы получаете тайм-аут. Я предполагаю, что у вас есть доступ к SQL Server Management Studio.
Кев Ричи
Да, у меня есть доступ к SQL Server 2008. Я должен попробовать свой путь.
SilverLight
Если вы найдете хранимую процедуру, которая вызывает проблему, вы можете запустить запрос, содержащийся в хранимой процедуре, с помощью помощника
Кев Ричи
12

Хотя все предыдущие ответы касались этой проблемы, они не охватывали все случаи.

Microsoft признала проблему и исправила ее в 2011 году для поддерживаемых операционных систем, поэтому, если вы получите трассировку стека, например:

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)

вам может понадобиться обновить ваши сборки .NET.

Эта проблема возникает из-за ошибки в алгоритме повторных подключений для зеркальных баз данных.

При использовании алгоритма повтора поставщик данных ожидает завершения первого вызова чтения (SniReadSync). Вызов отправляется на внутренний компьютер, на котором выполняется SQL Server, и время ожидания рассчитывается путем умножения значения времени ожидания соединения на 0,08. Однако поставщик данных неправильно устанавливает соединение в обреченное состояние, если ответ медленный и если первый вызов SniReadSync не завершен до истечения времени ожидания.

См. KB 2605597 для подробной информации.

https://support.microsoft.com/kb/2605597

matcheek
источник
9

Может быть, это будет кому-то полезно. Я столкнулся с той же проблемой, и в моем случае причина была в том, что SqlConnection был открыт и не размещен в методе, который я вызывал в цикле с примерно 2500 итерациями. Пул соединений исчерпан. Правильная утилизация решила проблему.

вечность
источник
этот! именно это. Моя проблема заключалась в том, что я запускал методы в другом потоке, не дожидаясь их (потому что пользователю не нужен результат этого метода, фоновый скрипт). Без избавления (используя usingблоки) у меня есть эта проблема тайм-аута. Это, казалось, решило это.
CularBytes
Вы получили ошибку тайм-аута при достижении максимального пула соединений или истечении тайм-аута. Время ожидания истекло до завершения операции, или сервер не отвечает. Так как, если вы получаете максимальный достигнутый пул, имеет смысл проверить утечку соединения. но я получаю сервер не отвечает ошибка.
Джива Суббурай
8

Я столкнулся с той же проблемой, работал над этим около 3 дней. Я заметил, что наше количество записей невелико, наш старший разработчик хранит в базе данных 2 изображения и отпечаток пальца. Когда я пытаюсь получить эти шестнадцатеричные значения, которые занимают много времени, я вычисляю среднее время выполнения моей процедуры примерно 38 секунд. Время ожидания команды по умолчанию составляет 30 секунд, поэтому оно меньше среднего времени, необходимого для запуска моей хранимой процедуры. Я установил свой тайм-аут команды, как показано ниже

cmd.CommandTimeout = 50

и он работает нормально, но иногда, если ваш запрос занимает более 50 секунд, он выдаст ту же ошибку.

Виджай Кумбхойе
источник
8

Вы должны установить атрибут CommandTimeout. Вы можете установить атрибут CommandTimeout в дочернем классе DbContext.

public partial class StudentDatabaseEntities : DbContext
{
    public StudentDatabaseEntities()
        : base("name=StudentDatabaseEntities")
    {
        this.Database.CommandTimeout = 180;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<StudentDbTable> StudentDbTables { get; set; }
}
Сиддарт Кантед
источник
4

Я недавно столкнулся с этой ошибкой и после небольшого исследования обнаружил, что причина в том, что у нас заканчивается свободное место на диске с базой данных (менее 1 ГБ).

Как только я переместил файлы базы данных (.mdf и .ldf) на другой диск на том же сервере (с большим количеством места), на ту же страницу (с запросом), которая была загружена по тайм-ауту в течение трех секунд.

Еще одна вещь, которую необходимо исследовать при попытке устранить эту ошибку, - это размер файлов журнала базы данных. Ваши файлы журнала просто могут быть сокращены.

Хафиз Адевуи
источник
3

У меня проблема с большими вычислениями в sp_foo, которые занимают много времени, поэтому я исправил
этот маленький бит код

public partial class FooEntities : DbContext
{
   public FooEntities()
         : base("name=FooEntities")
    {
        this.Configuration.LazyLoadingEnabled = false;

        // Get the ObjectContext related to this DbContext
        var objectContext = (this as IObjectContextAdapter).ObjectContext;

        // Sets the command timeout for all the commands
        objectContext.CommandTimeout = 380;
    }
Набиль Икбал
источник
3

Время ожидания по умолчанию составляет 15 секунд, чтобы изменить его, 0 не ограничено, любое другое число - это количество секунд.

В коде

using (SqlCommand sqlCmd = new SqlCommand(sqlQueryString, sqlConnection))
   {
      sqlCmd.CommandTimeout = 0; // 0 = give it as much time as it needs to complete
      ...
    }

В вашем Web.Config "Тайм-аут команды = 0;" не превышать время ожидания или менее 1 часа (3600 секунд)

  <add name="ConnectionString" connectionString="Data Source=ServerName;User ID=UserName;Password=Password;Command Timeout=3600;" providerName="System.Data.SqlClient" />
Дэвид С Фукс
источник
2
Это два разных таймаута. Ваше первое предложение касается вопроса. Ваш второй будет работать только в том случае, если провайдер соединения его поддерживает, а SqlClient - нет. В любом случае, тайм-аут 0 никогда не является хорошей идеей в производстве. 30 секунд - обычное значение по умолчанию.
Suncat2000
2

@SilverLight .. Это явно проблема с объектом базы данных. Это может быть плохо написанный запрос или отсутствующие индексы. Но на данный момент я не буду предлагать вам увеличивать время ожидания, не исследуя проблему с вашими объектами базы данных.

NovinMedia.Data.DbObject.RunProcedure(String storedProcName, IDataParameter[] parameters, Int32& rowsAffected) +209

Поместите точку останова в эту строку кода, чтобы узнать имя процедуры, а затем оптимизируйте процедуру, посмотрев на ее план выполнения.

Я не могу помочь вам больше, пока вы не опубликуете подробности о хранимой процедуре.

Амит Рай Шарма
источник
Хранимая процедура не делает ничего особенного. Однако кажется, что таблица OnlineUsers блокируется во время выполнения процедуры. Попробуйте профилировщик SQL, чтобы увидеть, что происходит на Application_Start
Амит Рай Шарма
2

пытаться

EXEC SP_CONFIGURE 'remote query timeout', 1800
reconfigure
EXEC sp_configure

EXEC SP_CONFIGURE 'show advanced options', 1
reconfigure
EXEC sp_configure

EXEC SP_CONFIGURE 'remote query timeout', 1800
reconfigure
EXEC sp_configure

затем перестройте свой индекс

Максуд
источник
8
Можете ли вы объяснить свое решение?
Hp93
0

Время ожидания истекло, поскольку запрос sql занимает больше времени, чем указано в свойстве sqlCommand.CommandTimeout.

Очевидно, что вы можете увеличить CommandTimeout для решения этой проблемы, но перед этим вы должны оптимизировать свой запрос, добавив индекс. Если вы выполняете запрос в Sql Server Management Studio, включая фактический план выполнения, то Sql Server Management Studio предложит вам соответствующий индекс. В большинстве случаев вы избавитесь от проблемы тайм-аута, если сможете оптимизировать свой запрос.

Хабир
источник
0

TLDR :

  1. Перезагрузка серверов приложений и БД - самое быстрое решение, когда объем данных, настройки сети и код не изменились. Мы всегда делаем это как правило
  2. Может быть индикатор сбоя жесткого диска, который требует замены - проверьте системные уведомления

Я часто сталкивался с этой ошибкой по разным причинам и имел различные решения, в том числе:

  1. рефакторинг моего кода для использования SqlBulkCopy
  2. увеличение значений тайм-аута, как указано в различных ответах или проверка основных причин ( может быть не связана с данными )
  3. Тайм-аут соединения (по умолчанию 15 с) - Время ожидания установления соединения с сервером SQL перед завершением - связано с TCP / PORT - может пройти контрольный список для устранения неполадок (очень удобная статья MSDN)
  4. Тайм-аут команды (по умолчанию 30 с) - Сколько времени занимает ожидание выполнения запроса - Выполнение запроса / сетевой трафик - также имеет процесс устранения неполадок (еще одна очень удобная статья MSDN)
  5. Перезагрузка сервера (ов) - как приложения, так и сервера БД (если они отдельно) - там, где код и данные не изменились, среда должна была измениться - первое, что вы должны сделать. Обычно вызвано исправлениями (исправления или обновления операционной системы, .Net Framework или SQL Server). В частности, если исключение тайм-аута выглядит так, как показано ниже (даже если мы не используем Azure):
    • System.Data.Entity.Core.EntityException: Возникло исключение, которое, вероятно, связано с временным сбоем. Если вы подключаетесь к базе данных SQL Azure, рассмотрите возможность использования SqlAzureExecutionStrategy. ---> System.Data.Entity.Core.EntityCommandExecutionException: произошла ошибка при выполнении определения команды. Смотрите внутреннее исключение для деталей. ---> System.Data.SqlClient.SqlException: ошибка транспортного уровня произошла при получении результатов от сервера. (поставщик: поставщик TCP, ошибка: 0 - истекло время ожидания семафора.) ---> System.ComponentModel.Win32Exception: истекло время ожидания семафора
user919426
источник
0

Также убедитесь, что у вас просто нет ожидающей транзакции. :)

Я делал несколько тестов и начал транзакцию, чтобы быть безопасным, но никогда не закрывал ее. Хотелось бы, чтобы ошибка была более явной, ну да ладно!

jeromej
источник
0

У нас были трудные времена Timeout expired/max pool reached Sqlexception. В качестве обходного пути и для предотвращения перезапуска сервера или службы мы MAX SERVER MEMORYизменяем переменную в SQL Server (через SQL Managment Studio или T-SQL):

DECLARE @maxMem INT = 3000 --Max. memory for SQL Server instance in MB
EXEC sp_configure 'show advanced options', 1
RECONFIGURE

Это временно устраняет проблему до тех пор, пока это не произойдет снова. В нашем случае мы подозреваем, что это связано с утечками соединения на уровне приложения.

Сантьяго выходит так
источник
0

Недавно мы обновились до версии NuGet SqlClient( Microsoft.Data.SqlClient), которая содержит ошибку . Эта ошибка была введена во время жизненного цикла 1.x и уже исправлена. Исправление будет доступно в версии 2.0.0, которая недоступна на момент написания этой статьи. Предварительный просмотр доступен.

Вы можете проверить детали здесь: https://github.com/dotnet/SqlClient/issues/262

Ноэль Видмер
источник