2011-12-22 27 views
210

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

El error completo es el siguiente:

Server Error in '/' Application. Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated.]
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +404
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +412
System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +1363
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +6387741
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +6389442
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +538
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) +689
System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +327
NovinMedia.Data.DbObject.RunProcedure(String storedProcName, IDataParameter[] parameters, Int32& rowsAffected) +209
DataLayer.OnlineUsers.Update_SessionEnd_And_Online(Object Session_End, Boolean Online) +440
NiceFileExplorer.Global.Application_Start(Object sender, EventArgs e) +163

[HttpException (0x80004005): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated.]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app) +4052053
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +191
System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +352
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +407
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +375

[HttpException (0x80004005): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated.]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +11686928 System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +141 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +4863749


Edición después RESPUESTAS:
mi Application_Start en Global.asax es como abajo:

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 

que tienen dos métodos para hacer que los usuarios en línea:

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

Por lo tanto, para el método # 2 se restablece todas OnlineUsers en Application_Start. Hay más de 482,751 registros en esa tabla.

+0

Como se dice aquí [predeterminado es de 15 segundos] (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectiontimeout.aspx) – V4Vendetta

+0

mejor hacer la raíz análisis de causa, hay varias razones para causar tal problema. Lo más básico es una estructura compleja de consulta. Me enfrenté al mismo problema cuando busco imágenes que almacenan como valores hexadecimales en la tabla. –

+0

Además de las causas anteriores, agregaré una más: Tiempo de espera de bloqueo: https://docs.microsoft.com/en-us/sql/t-sql/statements/set-lock-timeout-transact-sql Si esto el hilo que espera demasiado tiempo para el bloqueo expirará en función del documento anterior. –

Respuesta

249

Parece que tiene una consulta que tarda más de lo debido. Desde tu rastro de pila y tu código deberías poder determinar exactamente qué consulta es esa.

Este tipo de tiempo de espera puede tener tres causas;

  1. Hay un punto muerto en algún lugar
  2. estadísticas y/o plan de consulta caché de la base de datos son incorrectos
  3. La consulta es demasiado compleja y necesita ser sintonizado

Un interbloqueo puede ser difícil de arreglar , 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. Eche un vistazo a los procesos en ejecución. Normalmente, la mayoría estará inactiva o funcionando. Cuando se produce el problema, puede identificar cualquier proceso bloqueado por el estado del proceso. Si hace clic con el botón 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 utilice un plan de consulta subóptimo. Puede ser resuelto por la limpieza de las estadísticas:

exec sp_updatestats 

Si eso no funciona, también se podría tratar

dbcc freeproccache 

que no debe hacer esto cuando el servidor está bajo carga pesada porque va a incurrir temporalmente un gran golpe de rendimiento ya que todos los procesos almacenados y las consultas se vuelven a compilar cuando se ejecutan por primera vez. Sin embargo, como usted dice 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. Puede ser mejor forzando a SQL Server a no reutilizar un plan de consulta previo. Consulte this answer para obtener detalles sobre cómo hacerlo.

Ya he mencionado el tercer problema, pero puede determinar fácilmente si la consulta necesita ajuste 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, es probable que deba ajustarla. Para obtener ayuda con eso, debe publicar la consulta exacta en una nueva pregunta.

+27

Estaba teniendo el mismo error pero en una consulta que 'solo' tomó 8 segundos ... y su consejo sobre el 'exec sp_updatestats' resolvió mi problema. ¡Muchas gracias! – nrod

+1

Resolver un problema como este casi nunca es una cuestión de afinar los tiempos de espera o el tamaño del grupo de conexiones. Tendrá que sumergirse y descubrir la causa raíz. Si necesita ayuda para resolver esa causa raíz, puede publicar su propia pregunta. –

+3

Esto ciertamente no es un punto muerto. Puede ser causado por un bloqueo excesivo, pero los bloqueos se resuelven en un segundo y generan diferentes errores. Esto puede ser un bloqueo excesivo, pero no un punto muerto. –

17

Puede establecer la propiedad CommandTimeout del Comando SQL para permitir la transacción larga de SQL.

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

+0

hola, "o necesita ver la consulta SQL que está causando el tiempo de espera excedido" -> en el servidor sql 2008, ¿dónde debería verificar ese tiempo de espera? – MoonLight

+0

Es posible que deba probar el Procedimiento almacenado que se llama desde DataLayer.OnlineUsers.Update_SessionEnd_And_Online, ya que el Stack Trace parece apuntar hacia él. Tome una copia de la base de datos en vivo para probar y ejecutar el Procedimiento almacenado pasando los parámetros requeridos, si le toma más de 30 segundos completarlo, es por eso que tiene un tiempo de espera. Supongo que tiene acceso a SQL Server Management Studio. –

+0

sí, tengo acceso al servidor sql 2008. debería intentarlo. – MoonLight

2

@SilverLight .. Esto es claramente un problema con un objeto de base de datos. Puede ser una consulta mal escrita o faltan índices. Pero a partir de ahora no voy a sugerir a aumentar el tiempo de espera sin investigar el asunto con su base de datos de objetos

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

Ponga un punto de interrupción en esta línea de código findout el nombre del procedimiento y luego optimizar el procedimiento examinado su plan de ejecución.

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

+0

El procedimiento almacenado no hace ninguna cosa elegante. Sin embargo, parece que la tabla OnlineUsers se está bloqueando mientras se está ejecutando el procedimiento. Pruebe el Analizador de SQL para ver qué ocurre en Application_Start –

102

En su código en el que ejecutar el procedimiento almacenado debe tener algo como esto:

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

añadir una línea como de código:

c.CommandTimeout = 0; 

Esto hará esperar tanto tiempo como sea necesario para la operación para completar.

+105

También debe tener en cuenta que el valor de 0 no es [recomendado] (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand. commandtimeout% 28v = VS.100% 29.aspx): * Un valor de 0 indicaciones sin 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

+3

Estoy de acuerdo con Otiel y rechacé su respuesta: al establecer el comando TimeTimeout en 0, no le da al servidor web la posibilidad de recuperarse de un servidor de base de datos que no responde. En segundo lugar, al llegar al tiempo de espera predeterminado, debería considerar buscar la causa. En la mayoría de los casos, es mejor corregir la consulta que aumentar el tiempo de espera. –

+8

No me 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 devuelve un error si algo sale mal. En pocas palabras, solo permite que una consulta termine siempre que lo necesite, sin darse más problemas más adelante, porque no ha asignado suficiente tiempo para que el proceso finalice. También puede evitar bloquear su programa mediante multi-threading. –

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 

continuación reconstruir su índice de

4

me encontré con este error recientemente y después de un breve investigación, encontró que la causa es que nos estábamos quedando sin espacio en el disco de la celebración de la base de datos (menos de 1GB).

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 había agotado se cargó dentro de tres segundos.

Otra cosa para investigar, al tratar de resolver este error, es el tamaño de los archivos de registro de la base de datos. Sus archivos de registro pueden necesitar ser reducidos.

8

Quizás sea útil para alguien. Me enfrenté con el 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 eliminación adecuada resolvió el problema.

+0

esto! exactamente esto Mi problema era que estaba disparando métodos en un hilo diferente sin esperarlos (porque el usuario no necesita un resultado de ese método, script de fondo). Sin deshacerme (haciendo uso de bloques 'using') Tengo este problema de tiempo de espera. Esto pareció resolverlo. – CularBytes

+0

¿Recibió el error de tiempo de espera con el máximo del grupo de conexiones alcanzado o el 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. Porque, si recibe el grupo máximo alcanzado, tiene sentido buscar una conexión filtrada. pero recibo un error del servidor que no responde. –

9

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

Microsoft ha reconocido el problema y lo arreglaron en el año 2011 para los sistemas operativos compatibles, por lo que si se 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 tenga que actualizar los ensamblados .NET.

This issue occurs because of an error in the connection-retry algorithm for mirrored databases.

When the retry-algorithm is used, the data provider waits for the first read (SniReadSync) call to finish. The call is sent to the back-end computer that is running SQL Server, and the waiting time is calculated by multiplying the connection time-out value by 0.08. However, the data provider incorrectly sets a connection to a doomed state if a response is slow and if the first SniReadSync call is not completed before the waiting time expires.

Ver KB 2605597 para obtener detalles

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

5

que enfrenté mismo problema trabajado en él alrededor de 3 días. Noté que como nuestra cantidad de registros no es mucha, nuestro desarrollador senior guarda 2 imágenes y huellas dactilares en la base de datos. Cuando trato de recuperar estos valores hexadecimales tarda mucho tiempo, calculo el tiempo promedio para ejecutar mi procedimiento es de alrededor de 38 segundos. El tiempo de comando predeterminado es de 30 segundos, por lo que es menor que el tiempo promedio requerido para ejecutar mi procedimiento almacenado. Me puse mi CommandTimeout, como a continuación

cmd.CommandTimeout = 50 

y su bien, pero a veces si su consulta tarda más de 50 segundos, se le pedirá mismo error de trabajo.

1

tengo problema con gran cálculo en sp_foo que tienen gran tiempo así me fijo
con este pequeño código de bits

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

Hay que establecer el atributo de 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; } 
} 
Cuestiones relacionadas