sql >> Database >  >> RDS >> Database

Vind lekken in de databaseverbinding in uw toepassing

Gastauteur:Michael J Swart (@MJSwart)

Onlangs werden we verrast door een aantal uitzonderingen die onze applicatie veroorzaakte. Onze toepassing mislukte bij het openen van een SqlConnection. De uitzonderingen zagen er als volgt uit:

Fout System.InvalidOperationException:

Time-out verlopen. De time-outperiode is verstreken voordat verbinding werd gemaakt met de pool. Dit kan zijn gebeurd omdat alle gepoolde verbindingen in gebruik waren en de maximale poolgrootte werd bereikt.

Verbindingspools

Onthoud dat .Net verbindingspools gebruikt om de overhead van het tot stand brengen van een verbinding bij elke query te helpen voorkomen. Verbindingspools worden onderhouden voor elke verbindingsreeks en standaard is het aantal verbindingen in de pool beperkt tot honderd. Honderd aansluitingen zijn meestal voldoende. We hebben nog nooit eerder een probleem gehad met deze uitzondering en onze servers waren niet drukker dan normaal, dus we aarzelden om de waarde van MaxPoolSize te verhogen. We begonnen lekken in de databaseverbinding te vermoeden.
 

Databaseverbindingslekken

Net als geheugenlekken kunnen databaseverbindingslekken optreden als u uw databaseverbindingen niet op tijd weggooit. SqlConnections zijn IDisposable, dus het is een goede gewoonte om de instructie using te gebruiken:

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

Zodra u klaar bent met de SqlConnection, wordt deze verwijderd en keert de daadwerkelijke verbinding onmiddellijk terug naar de verbindingspool, zodat deze door iemand anders kan worden gebruikt. Anders blijft de verbinding in gebruik totdat het proces eindigt of de garbagecollection het opruimt.

Uw verbindingslekken vinden

Dus als uw toepassing verbindingstime-outs ervaart vanwege een lek in de databaseverbinding, kunnen de stacktraces u mogelijk niet helpen. Net als een uitzondering in het geheugen als gevolg van een geheugenlek, bevat de stacktracering informatie over het slachtoffer, maar niet over de hoofdoorzaak. Dus waar kun je het lek vinden?
 
Ook al zijn lekken in de databaseverbinding een clientprobleem, je kunt hulp krijgen van de databaseserver. Kijk op de databaseserver naar verbindingen per proces per database om een ​​ruwe schatting te krijgen van de grootte van elke 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;

Programmanaam, hostnaam, proces-ID en databasenaam zijn meestal goed genoeg om verbindingen te identificeren die uit dezelfde verbindingspool komen.

Dit brengt me ertoe nog een paar vragen te stellen over pools met veel verbindingen. Zijn er, gegeven een pool, sessies die een tijdje hebben geslapen en, zo ja, hoe lang hebben ze geslapen en wat was de laatste SQL-instructie die ze hebben uitgevoerd?

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;

De tekst kan nu worden gebruikt om in de codebasis van uw toepassing te zoeken waar u mogelijk een lek in de databaseverbinding heeft.

Deze query's zijn handig voor het oplossen van problemen met een databaseverbindingslek en ze kunnen ook worden gebruikt om een ​​monitor of statuscontrole te maken.

Gooi uw disposables weg, gebruik die gebruiken, dicht die lekken!

Over de auteur

Michael J Swart is een gepassioneerde databaseprofessional en blogger die zich richt op database-ontwikkeling en software-architectuur. Hij praat graag over alles wat met data te maken heeft en draagt ​​bij aan gemeenschapsprojecten. Michael blogt als "Database Whisperer" op michaeljswart.com.
  1. Gegevensreplicatie in IRI Workbench

  2. Verschil tussen left join en right join in SQL Server

  3. Foutafhandeling op afgestudeerd niveau

  4. MySQL - ORDER BY-waarden binnen IN()