Подтвердить что ты не робот

Как отслеживать код вызова в трассировке SQL Server?

Я хотел бы использовать трассировки SQL Server для отслеживания большего количества контекстов о том, какой код использует базу данных. Я собирался использовать свойство "Имя приложения" в строке подключения. Это выглядит примерно так:

object CallingObject; //set elsewhere
SqlConnectionStringBuilder connectionString = GetConnectionString();
connectionString.ApplicationName = CallingObject.GetType().ToString();
using (SqlConnection connection = new SqlConnection(connectionString.ToString()))
{
    // do your thing
}

За исключением того, что большое разнообразие результирующих строк соединения будет означать, что .net Connection Pooling больше не эффективен.

Как я могу отслеживать код вызова в SQL Trace, не теряя при этом преимущества пула соединений?

4b9b3361

Ответ 1

Пока вы используете SQL Server и до тех пор, пока у вас есть (или может быть) централизованная логика создания соединения, вы можете использовать функцию CONTEXT_INFO: http://msdn.microsoft.com/en-us/library/ms187768.aspx

Мы делаем что-то подобное для отслеживания соединений DB в многопользовательском серверном приложении. Каждый раз, когда создается новое соединение с БД (повторно используется из пула соединений, действительно, но "создано" в коде ADODB/ADO.Net):

DECLARE @ContextInfoBinary binary(128); 
SET @ContextInfoBinary = Convert(Binary(128), 'XX' + Replicate(Char(0), 36) + 'Up to 90 characters of connection info - username, page, action, etc') 
SET CONTEXT_INFO @ContextInfoBinary

Позже, когда вы хотите "отслеживать" соединения, вы можете преобразовать указанный диапазон контекстной информации обратно в контент VarChar:

SELECT RTRIM(hostname) AS hostname
    , hostprocess
    , RTRIM(program_name) AS program_name
    , CASE 
        WHEN SubString(Context_Info, 1, 2) = 0x5858
            THEN Replace(Convert(VarChar(90), SubString(Context_Info, 39, 90)), CHAR(0), '')
        ELSE 'UNKNOWN' 
        END AS ExtendedConnectionDescription
    --More stuff here, depending on what you're looking for
FROM master.sys.sysprocesses 

Некоторые соображения:

  • Мы перешли к этой концепции специально из-за проблем с объединением соединений с функцией имени приложения. Нам важно иметь возможность отслеживать причины блокировки для конкретных пользователей и процессов в любой момент времени.
  • Это добавляет команду БД для выполнения для каждого созданного соединения - это может или не может представлять значительные накладные расходы, в зависимости от дизайна вашего приложения.
  • В этом примере используется VarChar (до 90 символов); если вам нужно отслеживать данные NVarChar (расширенный символ), ваше пространство падает до 45 символов.
  • В этом примере мы оставляем 36 байт, которые могут быть использованы для какой-либо другой цели, например, для предотвращения запуска триггеров для некоторых соединений.
  • Вы можете вывести значение в трассировку явно с помощью sp_trace_generateevent, как описано в этом связанном вопросе: Как вы получаете доступ к переменной Context_Info() в профиле Profiler SQL2005?

UPDATE:

Только после повторного чтения вашего вопроса я понял, что вы, похоже, явно хотите добавлять информацию только на трассировку, а не столько для ad-hoc-анализа ваших текущих подключений (что более того, что я связал с использованием "Название приложения", извините); единственным полезным подходом, который я видел, является вызов sp_trace_generateevent. Если вы собираетесь это сделать, я бы посоветовал вам также добавить connection_info, так как он вам больше не будет стоить (у вас уже есть db round-trip для sp_trace_generateevent) и определенно поможет вам с другими типами анализа позже.

Ответ 3

Почему у вас нет вывода трассировки в таблице базы данных (желательно на другом компьютере/экземпляре, чем работает трассировка)? Таким образом, вы можете запросить таблицу трассировки исходя из ваших параметров, посмотрите, какие операции впитывают весь процессор%, см. Текст команды для нее и т.д.