sql >> Databáze >  >> RDS >> Database

Najděte ve své aplikaci netěsnosti připojení k databázi

Autor hosta :Michael J Swart (@MJSwart)

Nedávno nás překvapila řada výjimek, které naše aplikace vyvolala. Naše aplikace selhala při pokusu o otevření SqlConnection. Výjimky vypadaly takto:

Chyba System.InvalidOperationException:

Vypršel časový limit. Časový limit uplynul před získáním připojení z fondu. K tomu mohlo dojít, protože všechna sdružená připojení byla používána a bylo dosaženo maximální velikosti fondu.

Soubory připojení

Pamatujte, že .Net používá fondy připojení, aby se zabránilo režii navazování připojení na každý dotaz. Fondy připojení jsou udržovány pro každý řetězec připojení a ve výchozím nastavení je počet připojení ve fondu omezen na sto. Obvykle stačí sto spojení. Nikdy předtím jsme s touto výjimkou neměli problém a naše servery nebyly o nic vytíženější než obvykle, takže jsme váhali, zda zvýšit hodnotu MaxPoolSize. Začali jsme mít podezření na úniky připojení k databázi.
 

Netěsnosti připojení k databázi

Stejně jako k nevracení paměti může dojít k nevracení připojení k databázi, pokud včas nezlikvidujete připojení k databázi. SqlConnections jsou IDisposable, takže je osvědčeným postupem použít příkaz using:

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

Jakmile skončíte s připojením SqlConnection, bude zlikvidováno a skutečné připojení se okamžitě vrátí do fondu připojení, aby jej mohl použít někdo jiný. V opačném případě zůstane připojení používáno, dokud proces neskončí nebo dokud jej garbage collection nevyčistí.

Hledání netěsností připojení

Pokud tedy vaše aplikace zaznamená časové limity připojení kvůli nevracení připojení k databázi, trasování zásobníku vám nemusí pomoci. Stejně jako výjimka z nedostatku paměti kvůli úniku paměti má trasování zásobníku informace o oběti, ale ne hlavní příčinu. Kde tedy můžete najít únik?
 
I když úniky databázových připojení představují problém klienta, můžete najít pomoc na databázovém serveru. Na databázovém serveru se podívejte na připojení na proces a databázi, abyste získali hrubý odhad velikosti každého fondu:

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;

Název programu, název hostitele, ID procesu a název databáze jsou obvykle dostačující k identifikaci připojení přicházejících ze stejného fondu připojení.

To mě vede k tomu, abych se zeptal na několik dalších otázek o fondech s mnoha připojeními. Vzhledem k fondu existují relace, které nějakou dobu spí, a pokud ano, jak dlouho spí a jaký byl poslední příkaz SQL, který provedli?

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;

Text lze nyní použít k prohledání základny kódu vaší aplikace a zjistit, kde může dojít k úniku databázového připojení.

Tyto dotazy jsou užitečné pro odstraňování problémů s únikem databázového připojení a lze je také použít k vytvoření monitoru nebo kontroly stavu.

Zlikvidujte své jednorázové věci, použijte tato použití, utěsněte tyto úniky!

O autorovi

Michael J Swart je vášnivý databázový profesionál a blogger, který se zaměřuje na vývoj databází a softwarovou architekturu. Rád mluví o čemkoli, co souvisí s daty, přispívá do komunitních projektů. Michael bloguje jako „Database Whisperer“ na michaeljswart.com.
  1. Zobrazuje se Došlo k pokusu o načtení programu s chybou nesprávného formátu v projektu replikace SQL Server

  2. Laravel 5 PDOException nemůže najít ovladač

  3. Import databáze MySQL do MS SQL Serveru

  4. Náhodný záznam z databázové tabulky (T-SQL)