sql >> Databasteknik >  >> RDS >> Database

Hitta databasanslutningsläckor i din applikation

Gästförfattare:Michael J Swart (@MJSwart)

Vi blev nyligen överraskade av ett antal undantag som vår ansökan gav. Vår applikation misslyckades när vi försökte öppna en SqlConnection. Undantagen såg ut så här:

Fel System.InvalidOperationException:

Timeout har gått ut. Timeoutperioden förflutit innan en anslutning från poolen erhölls. Detta kan ha inträffat på grund av att alla poolade anslutningar användes och maximal poolstorlek nåddes.

Anslutningspooler

Kom ihåg att .Net använder anslutningspooler för att undvika kostnaden för att upprätta en anslutning för varje fråga. Anslutningspooler upprätthålls för varje anslutningssträng och som standard är antalet anslutningar i poolen begränsat till hundra. Hundra anslutningar är vanligtvis tillräckligt. Vi har aldrig haft problem med detta undantag tidigare och våra servrar var inte mer upptagna än vanligt så vi var tveksamma till att öka värdet på MaxPoolSize. Vi började misstänka databasanslutningsläckor.
 

Databasanslutningsläckor

Precis som minnesläckor kan databasanslutningsläckor uppstå om du inte gör dig av med dina databasanslutningar i tid. SqlConnections är IDisposable så det är en bästa praxis att använda användningssatsen:

using (SqlConnection conn = new SqlConnection(connectionString)) 
{
  conn.Open();
  // etc...
}

Så snart du är klar med SqlConnection, kasseras den och den faktiska anslutningen återgår omedelbart till anslutningspoolen så att den kan användas av någon annan. Annars förblir anslutningen i bruk tills processen avslutas eller sopsamlingen städar upp den.

Hitta dina anslutningsläckor

Så om din applikation upplever anslutningstimeout på grund av en databasanslutningsläcka kanske stackspårningarna inte hjälper dig. Precis som ett undantag från minnet på grund av en minnesläcka har stackspåret information om offret, men inte grundorsaken. Så var kan du gå för att hitta läckan?
 
Även om databasanslutningsläckor är ett klientproblem kan du få hjälp från databasservern. På databasservern, titta på anslutningar per process per databas för att få en grov uppskattning av storleken på varje pool:

select count(*) as sessions,
         s.host_name,
         s.host_process_id,
         s.program_name,
         db_name(s.database_id) as database_name
   from sys.dm_exec_sessions s
   where is_user_process = 1
   group by host_name, host_process_id, program_name, database_id
   order by count(*) desc;

Programnamn, värdnamn, process-id och databasnamn är vanligtvis tillräckligt bra för att identifiera anslutningar som kommer från samma anslutningspool.

Detta leder till att jag ställer några fler frågor om pooler med många kopplingar. Med tanke på en pool, finns det sessioner som har sovit ett tag och i så fall hur länge har de sovit och vilken var den senaste SQL-satsen de körde?

declare @host_process_id int = 1508;
  declare @host_name sysname = N'SERV4102';
  declare @database_name sysname = N'My_Database';
 
  select datediff(minute, s.last_request_end_time, getdate()) as minutes_asleep,
         s.session_id,
         db_name(s.database_id) as database_name,
         s.host_name,
         s.host_process_id,
         t.text as last_sql,
         s.program_name
    from sys.dm_exec_connections c
    join sys.dm_exec_sessions s
         on c.session_id = s.session_id
   cross apply sys.dm_exec_sql_text(c.most_recent_sql_handle) t
   where s.is_user_process = 1
         and s.status = 'sleeping'
         and db_name(s.database_id) = @database_name
         and s.host_process_id = @host_process_id
         and s.host_name = @host_name
         and datediff(second, s.last_request_end_time, getdate()) > 60
   order by s.last_request_end_time;

Texten kan nu användas för att söka i din applikations kodbas för att hitta var du kan ha en databasanslutningsläcka.

Dessa frågor är användbara för att felsöka en databasanslutningsläcka och de kan också användas för att skapa en monitor eller hälsokontroll.

Kassera dina engångsartiklar, använd dessa användningsområden, täta de läckorna!

Om författaren

Michael J Swart är en passionerad databasproffs och bloggare som fokuserar på databasutveckling och mjukvaruarkitektur. Han tycker om att prata om allt datarelaterat, att bidra till samhällsprojekt. Michael bloggar som "Database Whisperer" på michaeljswart.com.
  1. Hur får man ut antalet dagars skillnad mellan två datum på MySQL?

  2. Hur kan jag köra ett inbyggt SQL-skript i JPA/Hibernate?

  3. Undvik HA/DR Solution Self-Delusion

  4. Så här använder du Summa, Avg och Count i Select Statement - SQL Server / TSQL Tutorial Del 128