Database
 sql >> база данни >  >> RDS >> Database

Намерете течове на връзка с база данни във вашето приложение

Автор на гост:Michael J Swart (@MJSwart)

Наскоро бяхме изненадани от редица изключения, които нашето приложение хвърли. Приложението ни се провали при опит за отваряне на SqlConnection. Изключенията изглеждаха така:

Грешка System.InvalidOperationException:

Времето за изчакване е изтекло. Периодът на изчакване е изтекъл преди получаването на връзка от пула. Това може да се е случило, защото всички обединени връзки са били използвани и е достигнат максималният размер на пула.

Пулове за връзки

Не забравяйте, че .Net използва пулове за връзки, за да избегне излишните разходи за установяване на връзка при всяка заявка. Пуловите за връзки се поддържат за всеки низ за свързване и по подразбиране броят на връзките в пула е ограничен до сто. Обикновено са достатъчни сто връзки. Никога преди не сме имали проблем с това изключение и нашите сървъри не бяха по-натоварени от обикновено, така че се колебаехме да увеличим стойността на MaxPoolSize. Започнахме да подозираме течове на връзка с базата данни.
 

Течове на връзка с база данни

Точно като изтичане на памет, течове на връзка към базата данни могат да възникнат, ако не изхвърлите връзките си към базата данни навреме. SqlConnections са IDisposable, така че е най-добрата практика да използвате израза using:

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

Веднага след като приключите с SqlConnection, тя се изхвърля и действителната връзка незабавно се връща в пула за връзки, за да може да се използва от някой друг. В противен случай връзката остава в употреба, докато процесът приключи или събирането на боклука не я почисти.

Намиране на течове във връзка

Така че, ако вашето приложение изпитва изчакване на връзката поради изтичане на връзка с база данни, проследяването на стека може да не ви помогне. Точно като изключение за липса на памет поради изтичане на памет, проследяването на стека има информация за жертвата, но не и за основната причина. И така, къде можете да отидете, за да намерите теча?
 
Въпреки че течовете на връзката към базата данни са клиентски проблем, можете да намерите помощ от сървъра на базата данни. На сървъра на база данни погледнете връзките на процес за база данни, за да получите приблизителна оценка на размера на всеки пул:

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;

Името на програмата, името на хоста, идентификатора на процеса и името на базата данни обикновено са достатъчно добри, за да идентифицират връзките, идващи от същия пул за връзки.

Това ме кара да задам още няколко въпроса за пулове с много връзки. Като се има предвид пул, има ли сесии, които са спяли от известно време и, ако да, колко време са спят и кой е последният SQL оператор, който са изпълнили?

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;

Текстът вече може да се използва за търсене в кодовата база на приложението ви, за да намерите къде може да имате изтичане на връзка с базата данни.

Тези заявки са полезни за отстраняване на неизправности при изтичане на връзка с база данни и могат да се използват и за създаване на монитор или проверка на състоянието.

Изхвърлете вашите материали за еднократна употреба, използвайте тези употреби, запечатайте тези течове!

За автора

Майкъл Джей Суорт е страстен професионалист по бази данни и блогър, който се фокусира върху разработването на бази данни и софтуерната архитектура. Той обича да говори за всичко, свързано с данни, като допринася за обществени проекти. Майкъл пише в блогове като „Шептач на база данни“ в michaeljswart.com.
  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Проектиране на модел на данни за система за резервиране на хотелски стаи

  2. Част 1 – Как да инсталирате SuiteCRM и обратно инженерство на неговата база данни

  3. Как да изтриете ред в SQL

  4. Синтетично генериране на данни

  5. Урок за SQL транзакции