Tiempo agotado. El tiempo de espera transcurrido antes de la finalización de la operación o el servidor no responde. La instrucción se ha terminado

296

Tengo muchos usuarios en mi sitio web (20000-60000 por día), que es un sitio de descarga de archivos móviles. Tengo acceso remoto a mi servidor (Windows Server 2008-R2).
He recibido errores de "El servidor no está disponible" antes, pero ahora veo un error de tiempo de espera de conexión.
No estoy familiarizado con esto: ¿por qué ocurre y cómo puedo solucionarlo?

El error completo está abajo:

Error del servidor en la aplicación '/'. Tiempo agotado. El tiempo de espera transcurrido antes de la finalización de la operación o el servidor no responde. La instrucción se ha terminado. Descripción: se produjo una excepción no controlada durante la ejecución de la solicitud web actual. Revise el seguimiento de la pila para obtener más información sobre el error y dónde se originó en el código.

Detalles de la excepción: System.Data.SqlClient.SqlException: Tiempo de espera expirado. El tiempo de espera transcurrido antes de la finalización de la operación o el servidor no responde. La instrucción se ha terminado.

Error de fuente:

Se generó una excepción no controlada durante la ejecución de la solicitud web actual. La información sobre el origen y la ubicación de la excepción se puede identificar utilizando el seguimiento de la pila de excepciones a continuación.

Seguimiento de pila:

[SqlException (0x80131904): Tiempo de espera expirado. El período de tiempo de espera transcurrido antes de la finalización de la operación o el servidor no responde. La declaración ha finalizado.]
System.Data.SqlClient.SqlConnection.OnError (excepción SqlException, boolean breakConnection) +404
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning () +412
System.Data.SqlClient.TdsParser.RunBehader. , SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +1363
System.Data.SqlClient.SqlCommand.FinishExecuteReader (SqlDataReder,
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds (CommandBehavior cmdBehavior, runBehavior runBehavior, Boolean returnStream, async Boolean) 6389442
System.Data.SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, runBehavior runBehavior, Boolean returnStream, método de cadena, resultado DbAsyncResult) + 538
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery (DbAsyncResult result, String methodName, Boolean sendToPipe) +689
System.Data.SqlClient.SqlCommand.ExecuteNonQuery () +327
NovinMedia.Data.DbProcea.rec. , Int32 & rowsAffected) +209
DataLayer.OnlineUsers.Update_SessionEnd_And_Online (Object Session_End, Boolean Online) +440
NiceFileExplorer.Global.Application_Start (remitente de objetos, EventArgs e) +163

[HttpException (0x80004005): Tiempo de espera expirado. El período de tiempo de espera transcurrido antes de la finalización de la operación o el servidor no responde. La declaración ha sido terminada.]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode (HttpContext context, HttpApplication app) +4052053
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS (IntPtrp.Contexto
. Http . InitSpecial (estado HttpApplicationState, manejadores MethodInfo [], IntPtr appContext, contexto HttpContext) +352
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance (IntPtr appContext, HttpContext context) +407
System.Web.HittingApp.

[HttpException (0x80004005): Tiempo de espera expirado. El período de tiempo de espera transcurrido antes de la finalización de la operación o el servidor no responde. La declaración ha sido terminada.]
System.Web.HttpRuntime.FirstRequestInit (contexto HttpContext) +11686928 System.Web.HttpRuntime.EnsureFirstRequestInit (HttpContext context) +141 System.Web.HttpRuntime.ProcessRequestNotificationPrivate (I36)


Edición después RESPUESTAS:
mi Application_Starten Global.asaxes como a continuación:

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

    OnlineUsers.Update_SessionEnd_And_Online(
        DateTime.Now,
        false);

    AddTask("DoStuff", 10);
}

El procedimiento almacenado que se llama es:

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

Tengo dos métodos para obtener usuarios en línea:

  1. utilizando Application["OnlineUsers"] = 0;
  2. el otro usando la base de datos

Entonces, para el método # 2 reinicio todos los usuarios en línea en Application_Start. Hay más de 482,751 registros en esa tabla.

SilverLight
fuente
1
Como dice aquí por defecto es de 15 segundos
V4Vendetta
1
Es mejor hacer un análisis de causa raíz. Hay varias razones para causar tal problema. Lo más básico es la estructura compleja de consulta. Enfrenté el mismo problema cuando busqué imágenes que se almacenaron como valores hexadecimales en la tabla.
Vijay Kumbhoje
Además de las causas anteriores, agregaré una más: Tiempo de espera de bloqueo: docs.microsoft.com/en-us/sql/t-sql/statements/… Si este hilo espera demasiado tiempo el bloqueo, se agotará el tiempo en función de documento anterior.
Herbert Yu

Respuestas:

345

Parece que tiene una consulta que tarda más de lo debido. A partir de su seguimiento de pila y su código, debería poder determinar exactamente qué consulta es.

Este tipo de tiempo de espera puede tener tres causas;

  1. Hay un punto muerto en alguna parte
  2. Las estadísticas de la base de datos y / o el caché del plan de consulta son incorrectos
  3. La consulta es demasiado compleja y necesita ser ajustada

Un punto muerto puede ser difícil de solucionar, pero es fácil determinar si ese es el caso. Conéctese a su base de datos con Sql Server Management Studio. En el panel izquierdo, haga clic con el botón derecho en el nodo del servidor y seleccione Monitor de actividad . Echa un vistazo a los procesos en ejecución. Normalmente la mayoría estará inactiva o en ejecución. Cuando se produce el problema, puede identificar cualquier proceso bloqueado por el estado del proceso. Si hace clic derecho en el proceso y selecciona detalles , le mostrará la última consulta ejecutada por el proceso.

El segundo problema hará que la base de datos use un plan de consulta subóptimo. Se puede resolver borrando las estadísticas:

exec sp_updatestats

Si eso no funciona, también puedes intentar

dbcc freeproccache

No debe hacer esto cuando su servidor está bajo una carga pesada porque incurrirá temporalmente en un gran golpe de rendimiento ya que todos los procesos y consultas almacenados se vuelven a compilar cuando se ejecutan por primera vez. Sin embargo, como usted indica que el problema ocurre a veces , y el seguimiento de la pila indica que su aplicación se está iniciando, creo que está ejecutando una consulta que solo se ejecuta ocasionalmente. Es mejor que obligue a SQL Server a no reutilizar un plan de consulta anterior. Consulte esta respuesta para obtener detalles sobre cómo hacerlo.

Ya he tocado el tercer problema, pero puede determinar fácilmente si la consulta necesita ajustes ejecutando la consulta manualmente, por ejemplo, utilizando Sql Server Management Studio. Si la consulta tarda demasiado en completarse, incluso después de restablecer las estadísticas, probablemente deba ajustarla. Para obtener ayuda con eso, debe publicar la consulta exacta en una nueva pregunta.

Marnix van Valen
fuente
39
Estaba teniendo este mismo error, pero en una consulta que 'solo' tomó 8 segundos ... y su sugerencia sobre el exec sp_updatestatsproblema resuelto. ¡Muchas gracias!
nrod
2
Resolver un problema como este casi nunca es cuestión de ajustar los tiempos de espera o el tamaño del grupo de conexiones. Tendrás que sumergirte y descubrir la causa raíz. Si necesita ayuda para resolver esa causa raíz, puede publicar su propia pregunta.
Marnix van Valen
55
Esto ciertamente no es un punto muerto. Puede ser causado por un bloqueo excesivo, pero los puntos muertos se resuelven en un segundo y generan diferentes errores. Esto puede ser un bloqueo excesivo, pero no un punto muerto.
Michael J Swart
1
¿estamos seguros de que este es un tiempo de espera de comando y no un tiempo de espera de conexión? "System.Data.SqlClient.SqlConnection.OnError" para mí indica un problema de conexión.
Mike W
1
@PrashantPimpale Depende Si tiene un problema grave en la producción donde las estadísticas incorrectas resultan en planes de ejecución erróneos, entonces, sí, esta podría ser una solución. Salvo problemas excepcionales (como fallas de hardware), la actualización de estadísticas no dañará su base de datos. Puede causar consultas más lentas por un momento. Al final, es tu decisión.
Marnix van Valen
155

En su código donde ejecuta el procedimiento almacenado, debería tener algo como esto:

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

Agregue dicha línea de código:

c.CommandTimeout = 0;

Esto esperará tanto tiempo como sea necesario para que se complete la operación.

Elastep
fuente
144
También debe tener en cuenta que el valor 0 no se recomienda : un valor de 0 indica que no hay límite, y debe evitarse en CommandTimeout porque un intento de ejecutar un comando esperará indefinidamente. Es mejor saber cuánto tiempo tarda el comando y aumentar el valor de Tiempo de espera si es necesario.
Otiel
77
Estoy de acuerdo con Otiel y rechacé su respuesta: al establecer el comando Timeout en 0, no le da al servidor web la oportunidad de recuperarse de un servidor de base de datos que no responde. En segundo lugar, cuando alcanza el tiempo de espera predeterminado, debe considerar mirar la causa. En la mayoría de los casos, es mejor corregir la consulta que aumentar el tiempo de espera.
Maarten Kieft
10
No caería en la trampa de no recomendarlo. Ha sido muy útil para mí y para mis tareas diarias programadas: tener un tiempo de espera infinito no impide que un proceso se complete y devuelva un error si algo sale mal. En pocas palabras, solo le permite permitir que finalice una consulta cuando sea necesario, sin tener problemas más adelante, porque no había asignado suficiente tiempo para que el proceso finalice. También puede evitar bloquear su programa mediante subprocesos múltiples.
WonderWorker
2
Sí, para grandes transferencias de datos que no configuran esto no tiene sentido. Si está transfiriendo millones de filas, entonces lo que dicen Otiel y BlackHawkDesign no tiene sentido.
bluerubez
En 20 años de desarrollo centrado en datos, nunca he necesitado hacer esto. Casi siempre hay una solución razonablemente simple que brinda un mejor rendimiento y no crea la oportunidad de que un solo proceso trabaje en una base de datos durante todo el día. La gran mayoría de los problemas de rendimiento de db se pueden ajustar a donde realizan varios órdenes de magnitud más rápido. Es decir, ese proceso que está esperando 3 horas para completar, probablemente podría ajustarse a 3 minutos o incluso 3 segundos.
b_levitt
25

Puede establecer la CommandTimeoutpropiedad del comando SQL para permitir la transacción SQL de larga ejecución.

Es posible que también deba mirar la consulta SQL que está causando el tiempo de espera.

Kev Ritchie
fuente
hola, "o necesita mirar la consulta SQL que está causando el tiempo de espera" -> en sql server 2008 ¿dónde debo verificar ese tiempo de espera?
SilverLight
Es posible que deba probar el procedimiento almacenado que se llama desde DataLayer.OnlineUsers.Update_SessionEnd_And_Online ya que el seguimiento de pila parece apuntar hacia él. Tome una copia de la base de datos en vivo en la prueba y ejecute el Procedimiento almacenado pasando los parámetros requeridos, si tarda más de 30 segundos en completarse, es por eso que está obteniendo un tiempo de espera. Supongo que tiene acceso a SQL Server Management Studio.
Kev Ritchie
Sí, tengo acceso a SQL Server 2008. Debería intentarlo.
SilverLight
Si encuentra el procedimiento almacenado que está causando el problema, puede ejecutar la consulta contenida en el procedimiento almacenado a través del Asesor de ajuste de base de datos que le sugerirá si necesita algún índice, etc. Enlace aquí msdn.microsoft.com/en-us/library /ms174202.aspx
Kev Ritchie
12

Si bien todas las respuestas anteriores abordan el problema, no cubrieron todos los casos.

Microsoft ha reconocido el problema y lo solucionó en 2011 para los sistemas operativos compatibles, por lo que si obtiene el seguimiento de la pila como:

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)

Es posible que deba actualizar sus ensamblados .NET.

Este problema se produce debido a un error en el algoritmo de reintento de conexión para bases de datos duplicadas.

Cuando se utiliza el algoritmo de reintento, el proveedor de datos espera a que finalice la primera llamada de lectura (SniReadSync). La llamada se envía al equipo de back-end que ejecuta SQL Server, y el tiempo de espera se calcula multiplicando el valor de tiempo de espera de conexión por 0.08. Sin embargo, el proveedor de datos establece incorrectamente una conexión a un estado condenado si la respuesta es lenta y si la primera llamada SniReadSync no se completa antes de que expire el tiempo de espera.

Ver KB 2605597 para más detalles.

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

Matcheek
fuente
9

Tal vez sea útil para alguien. Me enfrenté al mismo problema y en mi caso, la razón fue que SqlConnection se abrió y no se eliminó en el método que llamé en bucle con aproximadamente 2500 iteraciones. El grupo de conexiones estaba agotado. La disposición adecuada resolvió el problema.

eternidad
fuente
¡esta! exactamente esto Mi problema era que estaba activando métodos en un hilo diferente sin esperarlos (porque el usuario no necesita un resultado de ese método, script de fondo). Sin eliminar (haciendo uso de usingbloques) tengo este problema de tiempo de espera. Esto pareció resolverlo.
CularBytes
¿Recibió el error de tiempo de espera con el grupo de conexiones máximo alcanzado o expiró el tiempo de espera? El período de tiempo de espera transcurrió antes de la finalización de la operación o el servidor no responde. Debido a que si recibe el grupo máximo alcanzado, tiene sentido buscar una conexión filtrada. pero recibo un error del servidor que no responde.
Jeeva Subburaj
8

Me enfrenté al mismo problema, trabajé alrededor de 3 días. Me di cuenta de que nuestro número de registros no es mucho, nuestro desarrollador senior mantiene 2 imágenes y huellas digitales en la base de datos. Cuando trato de obtener estos valores hexadecimales que toman mucho tiempo, calculo que el tiempo promedio para ejecutar mi procedimiento es de aproximadamente 38 segundos. El tiempo de espera predeterminado del comando es de 30 segundos, por lo que es menos del tiempo promedio requerido para ejecutar mi procedimiento almacenado. Configuré mi tiempo de espera de comando como a continuación

cmd.CommandTimeout = 50

y funciona bien, pero a veces si su consulta demora más de 50 segundos, generará el mismo error.

Vijay Kumbhoje
fuente
8

Tienes que establecer el atributo CommandTimeout. Puede establecer el atributo CommandTimeout en la clase secundaria 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; }
}
Siddarth Kanted
fuente
4

Encontré este error recientemente y después de una breve investigación, descubrí que la causa era que nos estábamos quedando sin espacio en el disco que contenía la base de datos (menos de 1 GB).

Tan pronto como moví los archivos de la base de datos (.mdf y .ldf) a otro disco en el mismo servidor (con mucho más espacio), la misma página (ejecutando la consulta) que se había agotado se cargó en tres segundos.

Otra cosa a investigar, al intentar resolver este error, es el tamaño de los archivos de registro de la base de datos. Es posible que sea necesario reducir los archivos de registro.

Hafiz Adewuyi
fuente
3

Tengo un problema con el cálculo grande en sp_foo que toma mucho tiempo, así que lo solucioné
con este pequeño código de bit

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;
    }
Nabeel Iqbal
fuente
3

El tiempo de espera predeterminado es de 15 segundos, para cambiar eso, 0 es ilimitado, cualquier otro número es el número de segundos.

En codigo

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

En su Web.Config, "Tiempo de espera de comando = 0;" no exceda el tiempo de espera, o por debajo de 1 hora (3600 segundos)

  <add name="ConnectionString" connectionString="Data Source=ServerName;User ID=UserName;Password=Password;Command Timeout=3600;" providerName="System.Data.SqlClient" />
David C Fuchs
fuente
2
Esos son dos tiempos de espera diferentes. Su primera sugerencia aborda la pregunta. Su segundo solo funcionaría si el proveedor de conexión lo admitiera, lo que no hace SqlClient. En cualquier caso, un tiempo de espera de 0 nunca es una buena idea en la producción. 30 segundos es el valor predeterminado habitual.
Suncat2000
2

@SilverLight .. Esto es claramente un problema con un objeto de base de datos. Puede ser una consulta mal escrita o índices faltantes. Pero a partir de ahora no le sugeriré que aumente el tiempo de espera sin investigar el problema con los objetos de su base de datos

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

Coloque un punto de interrupción en esta línea de código para averiguar el nombre del procedimiento y luego optimice el procedimiento mirando su plan de ejecución.

No puedo ayudarlo más hasta el momento en que publique detalles sobre el procedimiento almacenado.

Amit Rai Sharma
fuente
El procedimiento almacenado no hace nada sofisticado. Sin embargo, parece que la tabla OnlineUsers se está bloqueando mientras se ejecuta el procedimiento. Pruebe el generador de perfiles SQL para ver lo que está sucediendo en Application_Start
Amit Rai Sharma
2

tratar

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

luego reconstruya su índice

maksoud
fuente
8
¿Puedes explicar tu solución?
Hp93
0

El tiempo de espera expiró porque la consulta sql está tardando más tiempo del establecido en la propiedad sqlCommand.CommandTimeout.

Obviamente, puede aumentar CommandTimeout para resolver este problema, pero antes de hacerlo debe optimizar su consulta agregando índice. Si ejecuta su consulta en Sql Server Management Studio, incluido el plan de ejecución real , Sql Server Management Studio le sugerirá un índice adecuado. La mayoría de las veces se librará del problema del tiempo de espera si puede optimizar su consulta.

Khabir
fuente
0

TLDR :

  1. Reiniciar los servidores de aplicaciones y de bases de datos es la solución más rápida donde el volumen de datos, la configuración de red y el código no han cambiado. Siempre lo hacemos por regla general
  2. Puede ser un indicador de falla del disco duro que necesita reemplazo - verifique las notificaciones del sistema

A menudo he encontrado este error por varias razones y he tenido varias soluciones, que incluyen:

  1. refactorizando mi código para usar SqlBulkCopy
  2. aumentar los valores de tiempo de espera, como se indica en varias respuestas o verificar las causas subyacentes ( puede no estar relacionado con los datos )
  3. Tiempo de espera de conexión (predeterminado 15 s): cuánto tiempo se tarda en establecer una conexión con el servidor SQL antes de finalizar, relacionado con TCP / PORT, puede pasar por una lista de verificación de resolución de problemas (artículo muy útil de MSDN)
  4. Tiempo de espera de comando (predeterminado 30 s): cuánto tiempo se tarda en esperar la ejecución de una consulta: ejecución de consultas / tráfico de red relacionado: también tiene un proceso de solución de problemas (otro artículo muy útil de MSDN)
  5. Reinicio de los servidores, tanto de la aplicación como del servidor de base de datos (si están separados), donde el código y los datos no han cambiado, el entorno debe haber cambiado: lo primero que debe hacer. Normalmente causado por parches (sistema operativo, .Net Framework o parches o actualizaciones de SQL Server). Particularmente si la excepción de tiempo de espera aparece como a continuación (incluso si no usamos Azure):
    • System.Data.Entity.Core.EntityException: se ha producido una excepción que probablemente se deba a un error transitorio. Si se está conectando a una base de datos SQL Azure, considere usar SqlAzureExecutionStrategy. ---> System.Data.Entity.Core.EntityCommandExecutionException: se produjo un error al ejecutar la definición del comando. Vea la excepción interna para más detalles. ---> System.Data.SqlClient.SqlException: se ha producido un error de nivel de transporte al recibir resultados del servidor. (proveedor: Proveedor TCP, error: 0 - El período de tiempo de espera del semáforo ha expirado) ---> System.ComponentModel.Win32Exception: El período de tiempo de espera del semáforo ha expirado
usuario919426
fuente
0

También asegúrese de no tener una transacción pendiente. :)

Estaba haciendo algunas pruebas y comencé una transacción para estar seguro, pero nunca la cerré. Desearía que el error hubiera sido más explícito, ¡pero bueno!

jeromej
fuente
0

Hemos tenido tiempos difíciles Timeout expired/max pool reached Sqlexception. Como solución alternativa y para evitar reiniciar el servidor o el servicio, modificamos la MAX SERVER MEMORYvariable en SQL Server (ya sea a través de SQL Managment Studio o T-SQL):

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

Esto soluciona temporalmente el problema hasta que vuelva a suceder. En nuestro caso, sospechamos que tiene que ver con fugas de conexión a nivel de aplicación.

Santiago abandona SO
fuente
0

Recientemente actualizamos a la versión NuGet de SqlClient( Microsoft.Data.SqlClient) que contiene un error . Este error se introdujo durante la vida útil del ciclo 1.x y ya se ha solucionado. La solución estará disponible en la versión 2.0.0 que no está disponible en el momento de escribir este artículo. Una vista previa está disponible.

Puede inspeccionar los detalles aquí: https://github.com/dotnet/SqlClient/issues/262

Noel Widmer
fuente