Как найти протекающий дескриптор пула соединений БД? - PullRequest
16 голосов
/ 25 января 2012

Я вижу страшную ошибку "Время ожидания истекло до получения соединения из пула".

Я искал код для любых незакрытых соединений БД, но не смог найти.

Что я хочу сделать, так это: в следующий раз, когда мы получим эту ошибку, система выдаст список, в котором запросы procs или http содержат все дескрипторы, чтобы я мог выяснить, какой код вызывает проблему. 1005 *

Еще лучше было бы посмотреть, как долго держатся эти ручки, чтобы я мог обнаружить использованные, но незакрытые соединения.

Есть ли способ сделать это?

Ответы [ 3 ]

15 голосов
/ 21 февраля 2013

Если вам повезло, что создание / открытие соединения централизовано, тогда следующий класс должен легко обнаружить утечку соединений.Наслаждайтесь:)

/// <summary>
/// This class can help identify db connection leaks (connections that are not closed after use).
/// Usage:
/// connection = new SqlConnection(..);
/// connection.Open()
/// #if DEBUG
/// new ConnectionLeakWatcher(connection);
/// #endif
/// That's it. Don't store a reference to the watcher. It will make itself available for garbage collection
/// once it has fulfilled its purpose. Watch the visual studio debug output for details on potentially leaked connections.
/// Note that a connection could possibly just be taking its time and may eventually be closed properly despite being flagged by this class.
/// So take the output with a pinch of salt.
/// </summary>
public class ConnectionLeakWatcher : IDisposable
{
    private readonly Timer _timer = null;

    //Store reference to connection so we can unsubscribe from state change events
    private SqlConnection _connection = null;

    private static int _idCounter = 0;
    private readonly int _connectionId = ++_idCounter;

    public ConnectionLeakWatcher(SqlConnection connection)
    {
        _connection = connection;
        StackTrace = Environment.StackTrace;

        connection.StateChange += ConnectionOnStateChange;
        System.Diagnostics.Debug.WriteLine("Connection opened " + _connectionId);

        _timer = new Timer(x =>
        {
            //The timeout expired without the connection being closed. Write to debug output the stack trace of the connection creation to assist in pinpointing the problem
            System.Diagnostics.Debug.WriteLine("Suspected connection leak with origin: {0}{1}{0}Connection id: {2}", Environment.NewLine, StackTrace, _connectionId);
            //That's it - we're done. Clean up by calling Dispose.
            Dispose();
        }, null, 10000, Timeout.Infinite);
    }

    private void ConnectionOnStateChange(object sender, StateChangeEventArgs stateChangeEventArgs)
    {
        //Connection state changed. Was it closed?
        if (stateChangeEventArgs.CurrentState == ConnectionState.Closed)
        {
            //The connection was closed within the timeout
            System.Diagnostics.Debug.WriteLine("Connection closed " + _connectionId);
            //That's it - we're done. Clean up by calling Dispose.
            Dispose();
        }
    }

    public string StackTrace { get; set; }

    #region Dispose
    private bool _isDisposed = false;

    public void Dispose()
    {
        if (_isDisposed) return;

        _timer.Dispose();

        if (_connection != null)
        {
            _connection.StateChange -= ConnectionOnStateChange;
            _connection = null;
        }

        _isDisposed = true;
    }

    ~ConnectionLeakWatcher()
    {
        Dispose();
    }
    #endregion
}
5 голосов
/ 06 февраля 2012

Есть несколько хороших ссылок для мониторинга пулов соединений.Выполните в Google поиск по запросу «мониторинг пула соединений .net».

Одна статья, на которую я ссылался некоторое время назад, была Статья Билла Вона (обратите внимание, что она старая, но все еще содержит полезную информацию).Он содержит некоторую информацию о мониторинге пулов соединений, но также дает отличную информацию о том, где могут происходить утечки.

Для мониторинга он предлагает;

"Мониторинг пула соединений

Хорошо, значит, вы открыли соединение и закрыли его и хотите знать, является ли соединениевсе еще на месте - томится в пуле соединений на надувном матрасе. Ну, есть несколько способов определить, сколько соединений все еще на месте (все еще соединено) и даже что они делают. Я обсуждаю некоторые из них здесь и в моей книге:

· Используйте SQL Profiler с шаблоном SQLProfiler TSQL_Replay для трассировки. Для тех, кто знаком с Profiler, это проще, чем опрос с использованием SP_WHO.

· Запустите SP_WHO или SP_WHO2,которые возвращают информацию из таблицы sysprocesses для всех рабочих процессов, показывая текущее состояние каждого процесса. Как правило, есть один процесс сервера SPID на соединение. Если вы назвали свое соединение, используя аргумент имени приложения в строке соединения, это будет легконайти.

· Использование монитора производительности (PerfMon) для мониторинга пулов и соединений.Я подробно остановлюсь на этом далее.

· Мониторинг счетчиков производительности в коде.Эта опция позволяет вам отображать или просто отслеживать состояние вашего пула соединений и количество установленных соединений.Об этом я расскажу в следующем разделе этой статьи. "

Редактировать:

Как всегда, ознакомьтесь с другими подобными постами здесь в SO

Второе редактирование:

После того, как вы подтвердите, что пул не восстанавливает соединения, вы можете попробовать использовать еще одну вещь:событие StateChange, чтобы подтвердить, когда соединения открываются и закрываются. Если вы обнаружите, что в открытое состояние гораздо больше изменений, чем в закрытое, то это будет означать, что где-то есть утечки. Вы также можете зарегистрировать данные вСобытие stateaged вместе с отметкой времени, и если в вашем приложении есть какие-либо другие входы в систему, вы можете начать анализировать файлы журналов для случаев, когда, как представляется, изменения состояния закрыто для открытия, без соответствующего открытия для закрытия. См. эта ссылка для получения дополнительной информации о том, как обрабатывать StateChangedEvent.

0 голосов
/ 25 января 2012

Я использовал это

http://www.simple -talk.com / SQL / производительность / как на идентификацию-медленно обкатка запросы-с-SQL-профайлера /

Чтобы найти долго выполняющиеся хранимые процедуры, я могу вернуться и найти метод, который вызвал SP.

Не знаю, поможет ли это

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...