Al fin luego de mucho trabajar ya dimos con la respuesta de este dilema que algunos lectores de nuestro espacio han tenido. Si quieres aportar algo no dudes en compartir tu conocimiento.
Solución:
El número máximo de conexiones entre las versiones y ediciones de SQL Server es 32 767.
Puede determinar cuántas conexiones tiene actualmente SQL Server observando:
SELECT ConnectionStatus = CASE WHEN dec.most_recent_sql_handle = 0x0
THEN 'Unused'
ELSE 'Used'
END
, CASE WHEN des.status = 'Sleeping'
THEN 'sleeping'
ELSE 'Not Sleeping'
END
, ConnectionCount = COUNT(1)
FROM sys.dm_exec_connections dec
INNER JOIN sys.dm_exec_sessions des ON dec.session_id = des.session_id
GROUP BY CASE WHEN des.status = 'Sleeping'
THEN 'sleeping'
ELSE 'Not Sleeping'
END
, CASE WHEN dec.most_recent_sql_handle = 0x0
THEN 'Unused'
ELSE 'Used'
END;
Si la relación entre conexiones usadas y no usadas de la consulta anterior es preocupante, es probable que grupo de conexionesing está habilitado por aplicaciones cliente conectadas al servidor, y esas conexiones no se están utilizando de manera eficiente. Es posible que desee que los desarrolladores modifiquen la conexión. string para que estas aplicaciones limiten el tamaño del conjunto de conexiones y se aseguren de que están desechando las conexiones correctamente. Si las conexiones no se eliminan correctamente, permanecerán abiertas mientras se ejecute la aplicación cliente.
Si te sientes particularmente rabioso y necesitas deshacerte de todas las conexiones que no han hecho nada recientemente (independientemente de si realmente están actualmente realizando trabajo), puede ejecutar el siguiente código, que generará una lista de sesiones que se pueden eliminar. Deberá copiar y pegar los comandos generados en una nueva ventana de SSMS para ejecutar los comandos. También te recomiendo tener tu currículum actualizado por si acaso.
DECLARE @cmd NVARCHAR(MAX); SET @cmd = ''; SELECT @cmd = @cmd + CASE WHEN @cmd = '' THEN '' ELSE CHAR(13) + CHAR(10) END + 'KILL ' + CONVERT(VARCHAR(MAX), dec.session_id) + ';' FROM sys.dm_exec_connections dec WHERE dec.most_recent_sql_handle = 0x0;
PRINT @cmd;
Es posible escalar linealmente el número de conexiones más allá de 32 767 fragmentando los datos en varios nodos de SQL Server. Sin embargo, en mi opinión, usar sharding como una forma de eludir el límite en el número de conexiones es similar a usar una bomba atómica para matar una araña. Eso será mata a la araña, pero tú solo podría tener problemas más grandes al final del día. Sin mencionar que es bastante difícil construir una bomba atómica, sin mencionar que implementa la fragmentación correctamente.
Me he encontrado con un comportamiento extraño con la agrupación de conexiones en el pasado, y su escenario se alinea bien con una de esas situaciones. Si su aplicación está utilizando la agrupación de conexiones (y eso sigue siendo una especulación, en este punto, hasta que lo confirme o lo niegue), entonces tendrá muchas conexiones abiertas. Esto es por diseño.
La agrupación de conexiones tiene como objetivo reducir la sobrecarga de crear una conexión de base de datos. Tomemos, por ejemplo, un grupo de conexiones de 3. Por lo que puedo decir, el ciclo de vida es algo así (comenzando desde un caché de grupo de conexiones en frío):
- El usuario de la aplicación A solicita una conexión a la base de datos
- El grupo de conexiones inicia el subproceso de conexión 1 a la base de datos
- El usuario de la aplicación B solicita una conexión a la base de datos
- El grupo de conexiones inicia el subproceso de conexión 2 a la base de datos
- El usuario de la aplicación A cierra su conexión… al grupo de conexiones
- El usuario de la aplicación C solicita una conexión a la base de datos
- Problemas con el grupo de conexiones
sp_reset_connection
en el hilo 1 - El grupo de conexiones asigna el subproceso 1 al usuario de la aplicación C
Esta es una simplificación excesiva, pero los puntos destacados incluyen:
- La conexión permanecerá abierta entre el grupo de conexiones grupo de subprocesos y la base de datos hasta que la base de datos o el grupo de conexiones cierren la conexión a la fuerza
- La conexión permanece abierta con el contexto de ejecución de las últimas sesiones hasta que otro usuario reutiliza ese subproceso, momento en el cual
sp_reset_connection
se llama.
Aquí está el material de referencia que usé para llegar a estas conclusiones.
Agrupación de conexiones para SQL Server DBA
El caso de la transacción huérfana
Puedes añadir valor a nuestra información contribuyendo tu veteranía en las explicaciones.