Журналирование сообщений хранимых процедур DB2 для Linux, UNIX и Windows

Среда для динамического журналирования хранимых процедур на C

В этой статье описана среда журналирования, которую можно использовать с хранимыми процедурами IBM® DB2® для Linux, UNIX и Windows для журналирования информационных сообщений и сообщений об ошибках и отладке непосредственно из самих процедур. В методах среды журналирования для координации и изменения поведения журналирования во время выполнения используются концепции совместно используемой памяти. Журналированием можно управлять как на глобальном уровне для всех процедур, так и на уровне отдельной процедуры. Статья обновлена с учетом выхода девятой версии DB2.

Викрам Хатри, сертифицированный специалист-консультант по информационным технологиям, IBM

Викрам Хатри (Vikram Khatri) работает в отделе продаж и распространения компании IBM в составе группы DB2 Migration, его опыт работы в сфере информационных технологий составляет 18 лет. Викрам занимается администрированием баз данных DB2. В своей работе по технической поддержке продаж DB2 он занимается проектами миграции, а также тестированием систем высокой производительности.



22.11.2007

Мотивация

Записывать в файл журнала информационные сообщения, сообщения об ошибках и отладочные сообщения требуется по различным причинам:

  • Тестирование, анализ и проверка бизнес-логики;
  • Отслеживание и просмотр подробных сообщений об ошибках;
  • Динамическое включение и отключение детального журналирования для исправления ошибок бизнес-логики, обнаруженных в производственной среде;
  • Выявление проблем производительности в хранимых процедурах путем проверки времен выполнения журналируемых операторов.

Данную среду журналирования хранимых процедур можно использовать для решения следующих задач:

  1. Динамическое включение и отключение глобального или выборочного журналирования в производственной среде;
  2. Архивация файлов журналов для сохранения размера текущего файла журнала на управляемом уровне;
  3. Определение журналируемых операторов для каждой хранимой процедуры и для каждого агента DB2;
  4. Разделение и объединение файлов журналов для каждого агента DB2;
  5. Минимизация потребления ресурсов собственно процессом журналирования.

Помимо представленного в данной статье описания среды, советуем изучить углубленные методы трассировки и профилирования процедур SQL PL, рассматриваемые в статьях, перечисленных в разделе Ресурсы.


Общая архитектура и конструкция

В DB2 имеются собственные методы журналирования, создающие дамп сообщений в файле db2diag.log. DB2 также имеет функции журналирования и создания дампа подробных трассировок, что позволяет разработчикам DB2 выявлять и устранять обнаруженные проблемы. Представленная в этой статье среда журналирования позволяет осуществлять журналирование информационных и отладочных сообщений в файл для дальнейшего анализа, что позволяет разработчикам хранимых процедур выявлять и устранять проблемы.

Так как хранимые процедуры DB2 могут выполняться параллельно различными агентами DB2, каждый экземпляр журналируемой хранимой процедуры должен читать и предоставлять другим процедурам всю информацию по управлению процессом журналирования. Для этого применяется совместно используемая память, доступная для всех экземпляров журналируемой процедуры.

Настройка журналирования

Для настройки журналирования хранимых процедур применяется процедура DB2.UPDATE_SP_CONFIG. Эту процедуру можно использовать для запуска, останова и управления журналированием, а также для задания параметров в совместно используемой памяти, что позволяет всем выполняемым процедурам использовать общую информацию об управлении журналированием.

Для включения или отключения журналирования для отдельной хранимой процедуры или одновременно всех хранимых процедур сохраните необходимую информацию в файле конфигурации и загрузите его в совместно используемую память при первом вызове журналирования хранимой процедуры. При изменении параметров конфигурации журналирования информация в совместно используемой памяти обновляется, а также сохраняется в файле конфигурации. (Примечание: данный процесс подобен обновлению параметров конфигурации DB2, когда изменения некоторых параметров вступают в действие немедленно, а других - после перезагрузки экземпляра или базы данных. В среде журналирования любые изменения параметров журналирования хранимых процедур вступают в действие немедленно).

Одно из требований к среде журналирования - невысокое потребление системных ресурсов. Это необходимо для того, чтобы вызовы журналируемых процедур не занимали много ресурсов и не создавали излишней служебной информации. Рассматриваемая нами среда позволяет вести журналирование тысяч хранимых процедур без влияния на производительность системы.

Для каждого вызова журналирования необходимо определить, следует ли передавать сообщение в файл журнала. Для этого используется хэш-таблица со связанным списком, основанным на хэш-ключе имен меток журналирования. Для имен с общими хэш-ключами связанный список сохраняется на уровне того же ключа, что необходимо для просмотра параметров конфигурации для определенного имени метки журналирования. Использование хэш-таблицы со связанным списком обеспечивает максимально быстрый поиск.

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

Инициирование журналирования

Для инициирования журналирования из хранимой процедуры DB2 необходимо вызвать DB2.OPEN_LOG с двумя параметрами. Первый параметр представляет собой имя метки журналирования, второй - дескриптор. Для простоты в качестве имени метки журналирования можно использовать имя хранимой процедуры. Для отдельных бизнес-функций также можно применять общую метку журналирования для группы хранимых процедур. Например, если имеется вложенная процедура, вызывающая шесть других хранимых процедур DB2 для функции Get Best Rate Quote, для всех семи хранимых процедур DB2 можно использовать имя метки GBQR. Вторым параметром в DB2.OPEN_LOG является дескриптор CHAR(48). Этот дескриптор состоит из двух структур C. Одна из них содержит адрес совместно используемой памяти метки и соответствующих действий по журналированию, другая структура содержит метку времени вызова DB2.OPEN_LOG.

Журналирование сообщений

Для сообщений журналирования в нашей среде журналирования предусмотрены две хранимые процедуры: DB2.LOGINFO и DB2.LOGGER. Для каждой из них требуется два параметра. Первый представляет собой дескриптор журналирования, полученный из DB2.OPEN_LOG, второй - журналируемое сообщение. DB2.LOGINFO записывает информационное сообщение в журнал, если в совместно используемой памяти имеется метка журналирования. DB2.LOGGER журналирует отладочное сообщение, если параметру отладки задано значение Y и в совместно используемой памяти имеется метка журналирования.

Как правило, LOGINFO используется для протоколирования подробных сообщений об ошибках и других информационных сообщений. Для журналирования отладочных сообщений в файл журнала используется процедура LOGGER. Если отладочные сообщения не требуется вносить в файл журнала, отключите журналирование, задав параметру отладки для метки журналирования значение N. Задать этот параметр можно при помощи хранимой процедуры DB2.UPDATE_SP_CONFIG, применяемой для администрирования журналирования. Для полного отключения сообщений LOGINFO удалите метку журналирования из совместно используемой памяти. Задайте отладочному параметру значение R для удаления метки.

Закрытие журналирования

В конце хранимой процедуры можно закрыть журналирование при помощи вызова процедуры DB2.CLOSE_LOG. Для процедуры CLOSE_LOG необходимо в качестве входного параметра указать дескриптор журналирования. Процедура CLOSE_LOG записывает последнее сообщение с интервалом времени от начала до завершения журналирования. Вызов CLOSE_LOG применяется для определения полного времени выполнения.


Справочник по среде журналирования

Пример меток журналирования

При первом вызове DB2.OPEN_LOG на основе меток журналирования, хранящихся в совместно используемой памяти, создается хэш-таблица со связанным списком, как это показано на рисунке 1. Для каждой метки журналирования, считываемой из совместно используемой или файла конфигурации, процедура OPEN_LOG при первом вызове создает хэш-ключ на основе имени метки и размера хэш-таблицы. Для хэш-таблицы с размером 10 метки get_quote, find_zip_code, verify_zip и put_culls используют один хэш-ключ 3. Хэш-таблица со связанным списком содержит информацию об указателях меток журналирования в совместно используемой. Этот адрес разделяемой памяти хранится в дескрипторе, передаваемом из процедуры OPEN_LOG в последующие вызовы процедур LOGGER и LOGINFO.

Рисунок 1. Хэш-таблица со связанным списком
Хэш-таблица со связанным списком

Методы журналирования можно вызывать из хранимых процедур SQL-PL (см. пример) или из любых внешних хранимых процедур (COBOL, Java™ и т. д.). Если используются внешние хранимые процедуры, написанные на C, можно использовать журналирование хранимых процедур или непосредственно вызовы журналирования без упаковщиков хранимых процедур (см. пример).

Наша среда журналирования хранимых процедур состоит из двух частей. Первая часть представляет собой администрирование журналирования и предназначена для настройки параметров конфигурации. Вторая часть - журналирование хранимых процедур, которые используются из тела SQL-PL или из других хранимых процедур.

Администрирование журналирования

Имеются три хранимыех процедуры администрирования журналирования. Хранимая процедура DB2.UPDATE_SP_CONFIG задает и хранит параметры конфигурации журналирования. Хранимая процедура DB2.GET_SP_CONFIG создает список параметров журналирования и их значений. Третья хранимая процедура DB2.GET_SP_LOG предназначена для вывода содержимого в файл журнала.

Обновление конфигурации хранимых процедур

Хранимая процедура администрирования журналирования DB2.UPDATE_SP_CONFIG предназначается для задания имени метки в файле конфигурации и в совместно используемой памяти. Как правило, эта хранимая процедура вызывается из командной строки при помощи CLP или командного редактора DB2 с целью обновления параметров журналирования.

CALL DB2.UPDATE_SP_CONFIG(log_token_name, value);

Параметр log_token_name представляет собой имя метки журналирования. В среде используется два типа меток журналирования: глобальные и частные, относящиеся к отдельной хранимой процедуре или к группе хранимых процедур.

Глобальные метки - В среде применяются две глобальные метки.

  1. GLOBAL_LOGGING - По умолчанию задается значение Y. Если этому параметру задать значение N, останавливаются все операции журналирования, используемые процедурами LOGINFO и LOGGER. При помощи этого параметра можно отключить журналирование для всех хранимых процедур во время выполнения;
  2. LOG_SPLIT - По умолчанию задается значение N. Если LOG_SPLIT задано значение N, среда журналирования записывает сообщения всех предложений в файл журнала sp.log. Если хранимая процедура выполняется одновременно различными агентами DB2, все предложения журналирования собираются в одном файле журнала, однако их можно различить по уникальному идентификационному номеру приложения каждого агента DB2. Если все операторы записаны в один файл, их можно отфильтровать при помощи программы grep и просмотреть только операторы, журналированные отдельным агентом DB2. Если этому параметру задать значение Y, для каждого агента DB2 заводится отдельный файл журнала; имя каждого файла начинается с идентификатора приложения агента DB2.

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

Изменение меток журналирования при помощи хранимой процедуры DB2.UPDATE_SP_CONFIG:

  • Отключение глобального журналирования:
    call DB2.UPDATE_SP_CONFIG('GLOBAL_LOGGING','N');
  • Включение глобального журналирования:
    call DB2.UPDATE_SP_CONFIG('GLOBAL_LOGGING','Y');
  • Включение совместного использования файла журнала:
    call DB2.UPDATE_SP_CONFIG('LOG_SPLIT','Y');

    Примечание: Если включено совместное использование файла журнала, имя файла журнала представляет собой последнюю часть идентификатора приложения, полученного при помощи команды db2 list applications. Например, типовой вывод данной команды выглядит следующим образом:

Листинг 1. Пример вывода команды db2 list applications
Auth Id  Application    Appl.      Application Id                 DB       # of
Name           Handle                                    Name    Agents
-------- -------------- ---------- ------------------------------ -------- -----
DB2INST1 db2jcc_applica 864        GA0A0A34.A905.051223231443     FALCON   1    
DB2INST1 db2jcc_applica 867        GA0A0A34.A904.051223231442     FALCON   1    
DB2INST1 db2jcc_applica 866        GA0A0A34.A906.051223231441     FALCON   1    
DB2INST1 db2jcc_applica 862        GA0A0A34.A907.051223231440     FALCON   1

Если все вышеперечисленные агенты DB2 выполняют одну и ту же хранимую процедуру, создается четыре файла журналов с именами:
051223231443.log
051223231442.log
051223231441.log
051223231440.log

  • Отключение совместного использования файла журнала:
    call DB2.UPDATE_SP_CONFIG('LOG_SPLIT','N');
  • Создание метки журналирования TESTSP с атрибутом Debug, которому задано значение Y:
    call DB2.UPDATE_SP_CONFIG('TESTSP','Y');
  • Обновление метки журналирования TESTSP при помощи атрибута Debug со значением N:
    call DB2.UPDATE_SP_CONFIG('TESTSP','N');
  • Удаление метки журналирования TESTSP из совместно используемой памяти и файла конфигурации:
    call DB2.UPDATE_SP_CONFIG('TESTSP','R');

Хранимая процедура DB2.UPDATE_SP_CONFIG обновляет совместно используемую память и записывает в файл конфигурации все метки журналирования. Папке журналов назначается имя splog, эту папку необходимо создать в папке ~/sqllib. Это можно сделать двумя способами:

  • Если защищенный пользователь DB2 отличается от пользователя экземпляра:
    • Создайте папку splog в папке sqllib и измените права доступа к файлу на 777;
    • В папке splog создайте папку с именем, соответствующим имени базы данных;
    • Создайте в этой папке папку archive.
  • Если защищенный пользователь DB2 идентичен пользователю экземпляра:
    • Среда создает необходимые файлы и папки, поскольку имеет все необходимые права доступа;
    • Если требуется сохранить папку splog отдельно от папки sqllib, можно для splog создать отдельную точку монтирования и символьную ссылку ~/sqllib/splog, указывающую на эту точку.

Хранимая процедура администрирования журналирования DB2.UPDATE_SP_CONFIG создает или изменяет файл конфигурации .splogrc в папке журнала. Например, если база данных имеет имя "sample", и защищенный пользователь DB2 не совпадает с пользователем экземпляра, создайте папку sqllib/splog, а затем папку sqllib/splog/sample и папку sqllib/splog/sample/archive. Если защищенный пользователь совпадает с пользователем экземпляра, среда создает эти папки автоматически.

Листинг 2. Файл конфигурации
db2inst1@p595 /home/db2inst1/sqllib/splog/sample=>ls -al
drwxrwsrwx   3 db2inst1 db2grp1         512 Dec 22 13:53 .
drwxrwsrwx   3 db2inst1 db2grp1         512 Dec 21 23:45 ..
-rw-r--r--   1 db2inst1 db2grp1        6811 Dec 22 15:46 .splogrc
-rw-r--r--   1 db2inst1 db2grp1        5192 Dec 22 13:50 051222034739.log
-rw-r--r--   1 db2inst1 db2grp1        3904 Dec 22 15:45 051222195007.log
drwx--S---   2 db2inst1 db2grp1         512 Feb 09 1971  archive
-rw-r--r--   1 db2inst1 db2grp1      768700 Dec 22 15:46 sp.log

Хранимая процедура DB2.UPDATE_SP_CONFIG создает или обновляет файл .splogrc в папке ~/sqllib/splog/имя_базы_данных.

Листинг 3. Файл конфигурации
$ cat .splogrc
# *************************************************************************
# ** (C) COPYRIGHT International Business Machines Corp. 2000 - 2005
# ** Все права защищены.
# **
# ** Викрам Хатри, vikram.khatri(at)us.ibm.com
# ** Вы используете этот файл под свою ответственность.
 Гарантии и поддержка не предоставляются
# *************************************************************************
global_logging=Y
log_split=N
testsp=No

Редактировать файл конфигурации непосредственно не требуется. Даже если непосредственно отредактировать этот файл, увидеть влияние изменения параметров сразу же не удастся, поскольку хранимая процедура DB2.UPDATE_SP_CONFIG также обновляет совместно используемую память, которая представляет собой основное место хранения параметров журналирования для DB2.LOGINFO и DB2.LOGGER.

После создания метки журналирования (например, TESTSP) ее можно использовать при вызове DB2.OPEN_LOG для запуска журналирования. Вызов DB2.LOGINFO после OPEN_LOG только проверяет наличие метки TESTSP в совместно используемой памяти. Если этой метки нет, сообщения LOGINFO журналируются. Процедура DB2.LOGGER при помощи метки TESTSP проверяет параметр DEBUG. Если ему задано значение Y, в журнал записываются отладочные сообщения.

Получение конфигурации хранимых процедур

Поскольку доступ к файлу конфигурации .splogrc не обязателен, просмотреть настройки меток журналирования можно при помощи хранимой процедуры DB2.GET_SP_CONFIG.

Листинг 4. Получение параметров журналирования хранимых процедур
db2inst1@p595 /home/db2inst1/sqllib/splog/sample=>db2 "call db2.get_sp_config()" 
Result set 1
--------------
        
SP_NAME              DEBUG_MODE
-------------------- ----------
TESTSP               No

Получение файла журнала хранимых процедур

Файлы журналов хранимых процедур находятся в папке ~/sqllib/splog/YourDBName . При LOG_SPLIT=Y для каждого агента DB2 создаются отдельные файлы журналов. Если нет учетной записи с доступом к серверу DB2, извлечь содержимое файла журнала можно при помощи хранимой процедуры DB2.GET_SP_LOG. Для этой процедуры в качестве входного параметра требуется имя файла журнала. Если для LOG_SPLIT задано значение N, в качестве имени журнала используется sp.log. В противном случае можно определить при помощи команды db2 list applications идентификатор приложения, а затем использовать последнюю часть этого идентификатора в качестве имени файла журнала.

Листинг 5. Получение содержимого файла журнала хранимых процедур
db2inst1@p595 /home/db2inst1/sqllib/splog/sample=>db2 "call db2.get_sp_log('sp.log')" 
Result set 1
--------------
12-25-2005 22:29:39.839:[testsp:051226021028] Begin Stored Procedure *** [681574408]
12-25-2005 22:29:39.839:[testsp:051226021028] The database name from dbInfo is SAMPLE
12-25-2005 22:29:39.839:[testsp:051226021028] The HOME variable is /home/db2inst1
12-25-2005 22:29:39.839:[testsp:051226021028] 
The Application ID is *LOCAL.db2inst1.051226021028
12-25-2005 22:29:39.839:[testsp:051226021028] End   Stored Procedure *** Elapsed 0.000
12-25-2005 22:36:04.048:[testsp:051226021028] Begin Stored Procedure *** [681574408]
12-25-2005 22:36:04.048:[testsp:051226021028] The database name from dbInfo is SAMPLE
12-25-2005 22:36:04.048:[testsp:051226021028] The HOME variable is /home/db2inst1
12-25-2005 22:36:04.048:[testsp:051226021028] 
The Application ID is *LOCAL.db2inst1.051226021028
12-25-2005 22:36:04.048:[testsp:051226021028] End   Stored Procedure *** Elapsed 0.000

Хранимые процедуры среды журналирования

Имеется четыре хранимые процедуры журналирования, которые можно использовать в хранимых процедурах SQL-PL для журналирования сообщений. Подробно они представлены в таблице 1.

Таблица 1. Хранимые процедуры для журналирования
Имя хранимой процедурыСинтаксисАргументы
DB2.OPEN_LOGCALL DB2.OPEN_LOG (log_token_name, handle)

log_token_name - Имя метки журналирования. Если это имя имеется в совместно используемой памяти, заданной DB2.UPDATE_SP_CONFIG, выполняются действия по записи в журнал, в противном случае журналирование не выполняется.

handle -- Имя переменной, объявленной в коде SQL-PL. Переменную необходимо объявить как CHAR(160) FOR BIT DATA.

DB2 LOGINFOCALL DB2.LOGINFO (handle, message)

handle - Дескриптор, заданный вызовом DB2.OPEN_LOG.

message - Информационное сообщение, которое требуется журналировать.

DB2.LOGGERCALL DB2.LOGGER (handle, message)

handle - Дескриптор, заданный вызовом DB2.OPEN_LOG.

message - Информационное сообщение, которое требуется журналировать.

DB2.CLOSE_LOGCALL DB2.CLOSE_LOG (handle)

handle - Дескриптор, заданный вызовом DB2.OPEN_LOG.


Настройка

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

Действия администратора баз данных

  1. Создайте папку splog в папке ~/sqllib. Для просмотра файлов журналов администратор баз данных может создать символьную ссылку ~/sqllib/splog, указывающую на другое местоположение, к которому вы имеете доступ;

  2. Задайте права доступа к папке ~/sqllib/splog, чтобы предоставить полный доступ защищенному пользователю DB2;

  3. Создайте папку с именем базы данных в папке ~/sqllib/splog;

  4. Создайте папку archive в папке ~/sqllib/splog/имя_базы_данных;

  5. Создайте временное пользовательское табличное пространство для глобальной временной таблицы. Хранимые процедуры администрирования журналирования DB2.GET_SP_CONFIG и DB2.GET_SP_LOG для возврата клиенту набора результатов используют глобальную временную таблицу. Далее в сценарии показан пример, который можно изменить для создания временного пользовательского табличного пространства в собственной среде.

    Листинг 6. Создание временного пользовательского табличного пространства
    CREATE USER TEMPORARY TABLESPACE dgtt IN 
    DATABASE PARTITION GROUP PG0 
    PAGESIZE 4096 
    MANAGED BY SYSTEM 
    USING ('/stagefs/dbins17a/dgtt/dgtttbsp.tablespace') 
    ON DBPARTITIONNUMS (0)
    EXTENTSIZE 32 
    PREFETCHSIZE AUTOMATIC 
    BUFFERPOOL IBMDEFAULTBP 
    DROPPED TABLE RECOVERY OFF;

Действия разработчика

Данная среда журналирования протестирована на платформах AIX® 5.3.1 (64-разрядной) и Linux™ (64-разрядной) с использованием ОС Suse 9 и RHEL 3. Для вашей конкретной (32/64-разрядной) платформы UNIX® используйте программы bldrtn и embprep из папки ~/sqllib/samples/c вместо файлов, предоставленных с данной средой. Программы bldrtn и embprep, привязанные к конкретной платформе, задают правильный компилятор и параметры связывания..

Таблица 2. Источник журналирования
Имя файлаНазначение
splogger.sqcВстроенные подпрограммы на C и упаковщики встроенных процедур для методов журналирования.
splogger.expИмя методов для экспорта в общую библиотеку.
spcatСценарии каталога DB2 для журналирования внешних подпрограмм с общей библиотекой в качестве хранимой процедуры DB2 в схеме DB2.
spalterСценарии каталога DB2 для изменения хранимых процедур с учетом другого имени общей библиотеки, чтобы DB2 могла загрузить в память новую библиотеку, если для DB2 KEEPFENCED задано значение YES.
makefileСоздание файла для компилирования исходного кода.
bldrtnСценарий, вызываемый makefile для компиляции исходного кода C. Используйте файл bldrtn, соответствующий вашей установке UNIX (из папки ~/sqllib/samples/c), вместо предоставленного файла.
embprepСценарий, используемый программой bldrtn для предварительной обработки файла sqc с помощью DB2 PREP и его привязки к базе данных с помощью BIND. Используйте файл embprep, соответствующий вашей установке UNIX (из папки ~/sqllib/samples/c), вместо предоставленного файла.

Компиляция исходного кода

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

  1. Распакуйте файл SQLPLLogging.zip в какую-либо папку;
  2. Скопируйте программы embprep и bldrtn из папки ~/sqllib/samples/c в вышеупомянутую папку;
  3. Запустите команду make для создания общей библиотеки.

Команда makefile использует сценарии embprep и bldrtn для компиляции исходного кода и копирует общую библиотеку в папку ~/sqllib/function. Команда makefile также заносит в каталог хранимые процедуры в DB2.


Работа со средой журналирования через хранимые процедуры SQL-PL

В следующем примере хранимой процедуры SQL-PL TESTSP показано использование хранимых процедур журналирования.

Листинг 7. Работа со средой журналирования в SQL-PL
$ db2 CONNECT TO SAMPLE
$ db2 "call DB2.UPDATE_SP_CONFIG('TESTSP','Y')"
$ db2 CONNECT RESET
        
$ db2 -tf testsp.sql
        
File testsp.sql
-----------------		
--#SET TERMINATOR @
        
CONNECT TO SAMPLE
@
SET CURRENT SCHEMA = 'TEST'
@
DROP PROCEDURE TESTSP
@
CREATE PROCEDURE TESTSP()
LANGUAGE SQL
BEGIN
  DECLARE h  CHAR(160) FOR BIT DATA;
  DECLARE count INTEGER DEFAULT 0;
  CALL DB2.OPEN_LOG('TESTSP',h);
  SET count = count + 1;
  CALL DB2.LOGINFO(h,'this is a test loginfo '||CHAR(COALESCE(count,0))||'
         message');
  SET count = count + 1;
  CALL DB2.LOGGER(h,'this is a test logger '||CHAR(COALESCE(count,0))||'
          message');CALL DB2.CLOSE_LOG(h);
END
@
CONNECT RESET
@
        
Call TESTSP Stored Procedure
----------------------------
        
$ db2 "call test.testsp()"
Рисунок 2. Вывод файла журнала
Вывод файла журнала

Использование среды журналирования при помощи хранимых процедур C

Подпрограммы среды журналирования написаны на C, поэтому их можно использовать непосредственно из хранимых процедур C без необходимости вызова хранимых процедур журналирования. В представленном ниже примере хранимой процедуры на C используется API журналирования. Для применения методов журналирования включите в проект общую библиотеку splogger.

Включите в хранимую процедуру C файл logger.h, определяющий прототипы методов журналирования.

Листинг 8. API среды журналирования - файл заголовка logging.h
#define BYTEHANDLESIZE 160 		
void openLog(char *name, char *handle);
void closeLog(char *handle);
void setDBName(struct sqludf_dbinfo *dbInfo);
void logger(char *handle, char *fmt, ... );
void logginfo(char *handle, char *fmt, ... );
Листинг 9. Пример хранимой процедуры на C с API методов журналирования
SQL_API_RC SQL_API_FN Snow
(
   char outMessage[100],
   sqlint16 *outMessageNullInd,
   char sqlstate[6],
   char qualName[28],
   char specName[19],
   char diagMsg[71],
   struct sqludf_dbinfo *dbInfo
)
{
   char byteHandle[BYTEHANDLESIZE];  
   char dbName[128] = "";
       
   setDBName(dbInfo);		  
   openLog("TESTSP", byteHandle);
   strncpy(outMessage, (char *)(dbInfo->dbname), dbInfo->dbnamelen);
   outMessage[dbInfo->dbnamelen] = '\0';
   logger(byteHandle, "The database name from dbInfo is %s", outMessage);
   strcat(outMessage, "::");  
   logger(byteHandle, "The HOME variable is %s", getenv("HOME"));
   strcat(outMessage, getenv("HOME"));
   strcat(outMessage, "::");
   strcat(outMessage, (char *)(dbInfo->appl_id));
   logger(byteHandle, "The Application ID is %s", (char *)(dbInfo->appl_id));
   *outMessageNullInd = 0;
   closeLog(byteHandle);
   return 0;  
}

Обратите внимание на использование setDBName в дополнение к вызовам API журналирования. Программе на C необходимо вызывать этот метод, поскольку он получает из структуры dbInfo DB2 имя базы данных, необходимое для задания имени файла журнала.

Для регистрации примера хранимой процедуры используйте следующий код SQL.

Листинг 10. Регистрация примера хранимой процедуры
CREATE PROCEDURE DB.SNOW
(
   OUT   MSG       VARCHAR(100)
)
DYNAMIC RESULT SETS 0
DETERMINISTIC
LANGUAGE C
PARAMETER STYLE SQL
DBINFO
FENCED NOT THREADSAFE
NO SQL
PROGRAM TYPE SUB
EXTERNAL NAME 'splogger!Snow';

Вопросы и ответы

Вопрос: При попытке компиляции с применением makefile выводится сообщение об ошибке "bldrtn not found."

Ответ: В зависимости от способа копирования файлов в систему могли измениться права доступа к bldrtn. Попробуйте изменить права доступа к файлам bldrtn, embprep и spcat при помощи команды chmod. Примеры:
$ chmod +x embprep bldrtn spcat bld spalter

Вопрос: При создании папки splogger при выполнении spcat выводится сообщение об ошибке "database connection does not exist". В spcat нет никаких предложений connect. Где искать ошибку?

Ответ: В spcat нет предложений connect, поскольку предполагается неявное подключение к базе данных.

Листинг 11. Использование неявного подключения
$ db2set DB2DBDFT=<your database name>
$ db2stop force
$ db2start						
$ db2 activate db <your database name>

Вопрос: У меня нет доступа к экземпляру DB2. Как скомпилировать исходный код и создать папку splogger?

Ответ: Отредактируйте makefile и задайте значения параметров ALIAS, UID и PWD. Вставьте предложение CONNECT в spcat и spalter.

Вопрос: Для чего предназначен сценарий bld?

Ответ: Сценарий bld позволяет скомпилировать splogger как автономную программу, а не общую библиотеку. Это требуется в целях тестирования. Сценарий создает двоичный файл splog, который можно использовать для выполнения основной программы в splogger.sqc.

Вопрос: При запуске команды make выводится сообщение об ошибке "make: 1254-004 The error code from the last command is 4."

Ответ: Это нормальный результат выполнения сценария spcat. Он применяет команду DROP PROCEDURE к журналируемым хранимым процедурам DB2. Если в базе данных еще нет хранимых процедур, то выводится представленное выше сообщение. При следующем запуске spcat сообщение об ошибке выводиться не будет.

Вопрос: Как использовать эту процедуру журналирования при изменениях в среде и как ее использовать из хранимых процедур SQL-PL? Я не могу задать KEEPFENCED значение NO из соображений производительности, так как имеются другие внешние хранимые процедуры на C, выполняющиеся в системе.

Ответ: Задайте параметру уровня экземпляра DB2 значение KEEPFENCED=YES при помощи команды CLP UPDATE DBM CFG USING KEEPFENCED YES. После перезапуска экземпляра DB2 загрузит библиотеку внешних хранимых процедур в память при первом вызове хранимой процедуры. Такие общие библиотеки остаются в памяти до перезапуска экземпляра. При изменении внешней библиотеки и ее копировании в папку ~/sqllib/function DB2 не использует эту библиотеку, поскольку она уже загружена в память. Это не ограничение DB2, а скорее способ работы операционной системы (например, на мэйнфрейме общую библиотеку можно загружать и выгружать).

Очевидно, что в производственной системе требуется задать параметру KEEPFENCED значение YES. Если необходимо выполнить изменения во внешних хранимых процедурах (включая splogger), имеется способ, позволяющий заставить DB2 загрузить новую библиотеку. Такой подход применяется в сценарии spalter. Этот сценарий переименовывает общую библиотеку и изменяет хранимые процедуры с учетом нового имени библиотеки. DB2 загружает новую библиотеку, но старая при этом остается в памяти до перезапуска экземпляра.

Листинг 12. Изменение общей библиотеки при параметре KEEPFENCED=YES
#! /bin/ksh
TOK=$(date +"%y%m%d%H%M%S")
SHLIBNAME=splogger$TOK
rm -f ~/sqllib/function/splogger*
cp -f splogger ~/sqllib/function/$SHLIBNAME
db2 -tv << !EOF
ALTER PROCEDURE DB2.UPDATE_SP_CONFIG EXTERNAL NAME '${SHLIBNAME}!UpdateSPConfig';
ALTER PROCEDURE DB2.GET_SP_CONFIG    EXTERNAL NAME '${SHLIBNAME}!GetSPConfig';
ALTER PROCEDURE DB2.GET_SP_LOG       EXTERNAL NAME '${SHLIBNAME}!GetSPLog';
ALTER PROCEDURE DB2.OPEN_LOG         EXTERNAL NAME '${SHLIBNAME}!OpenLog';
ALTER PROCEDURE DB2.CLOSE_LOG        EXTERNAL NAME '${SHLIBNAME}!CloseLog';
ALTER PROCEDURE DB2.LOGGER           EXTERNAL NAME '${SHLIBNAME}!Logger';
ALTER PROCEDURE DB2.LOGINFO          EXTERNAL NAME '${SHLIBNAME}!Loginfo';
!EOF

Вопрос: В файле журнала в строке "Begin Stored Procedure *** [681574408]" приведено число. Что оно означает?

Ответ: Это адрес совместно используемой памяти, используемый библиотекой splogger. При остановке DB2 совместно используемая память, используемая DB2, освобождается. Для общей библиотеки splogger невозможно определить время освобождения совместно используемой памяти. Это число можно использовать для освобождения совместно используемой памяти, используемой библиотекой. Для освобождения памяти введите команду ipcrm -m 681574408.

Вопрос: Я использую среду журналирования, но файлов журналов нет. Где их найти?

Ответ: Это наиболее типичная проблема. Ищите файл журнала в папке /tmp. Данная проблема связана с идентификатором защищенного пользователя и разрешениями на доступ к файлам в папке ~/sqllib/splog. Попросите администратора баз данных создать папку splog в папке ~/sqllib и предоставить полный доступ к этой папке splog для защищенного пользователя. Также можно создать папку splog в каталоге home защищенного пользователя, а затем создать в ~/sqllib/splog гибкую ссылку, указывающую на эту папку splog. Хранимые процедуры журналирования предназначены для запуска в качестве ЗАЩИЩЕННОГО процесса и выполняются под учетной записью защищенного пользователя DB2.

Вопрос: Что представляет собой метод hardw в рассматриваемой среде и для чего он предназначен?

Ответ: Среда журналирования предназначена для отладки хранимых процедур, метод hardw применяется для отладки подпрограмм журналирования.

Вопрос: Журналирование в файл остановилось. В файл журнала больше не добавляются сообщения. Что происходит?

Ответ: Убедитесь, что в файловой системе с папкой splog достаточно свободного места.

Вопрос: Какие другие параметры DB2 необходимо настроить при работе с данной средой?

Ответ: Никаких.

Вопрос: Вывод DB2.GET_SP_LOG слишком запутан. Что сделано неправильно?

Ответ: Хранимая процедура DB2.GET_SP_LOG за раз считывает четыре тысячи байт из файла журнала. Перенаправьте вывод в файл.

Вопрос: При попытке откомпилировать эту среду на платформе Windows® выводится множество сообщений об ошибке компилятора. Что нужно сделать?

Ответ: Данная среда протестирована только на платформах AIX и Linux. В данный момент выполняется преобразование этой среды для платформы Windows с использованием языка C#.

Вопрос: При компиляции среды на платформе Solaris выводятся сообщения об ошибках компилятора. Что делать?

Ответ: Данная среда не тестировалась на платформе Solaris. Сообщите, пожалуйста, дополнительные данные об ошибках, я попытаюсь их устранить.

Вопрос: При компиляции на платформе Linux выводятся сообщения об ошибках. Что нужно сделать?

Ответ: Скопируйте файлы bldrtn и embprep из папки ~/sqllib/samples/c в свою папку и выполните компиляцию еще раз.

Вопрос: Планируется ли включить эту среду в комплект поставки DB2?

Ответ: В данный момент нет.

Вопрос: Можно ли изменить эту среду для использования в моих собственных продуктах?

Ответ: Да. Рассматриваемая среда журналирования хранимых процедур поставляется с открытым исходным кодом. Необходимо сохранить информацию об авторских правах IBM в каждом исходном файле.

Вопрос: При попытке освободить совместно используемую память с помощью команды ipcrm выводится сообщение об ошибке с запретом очистки совместно используемой памяти. Как устранить такую ошибку?

Ответ: Процесс журналирования хранимых процедур выполняется под учетной записью защищенного пользователя DB2. Войдите в систему как защищенный пользователь DB2 и попробуйте очистить память еще раз. Если защищенным пользователем DB2 является nobody, попросите системного администратора освободить совместно используемую память при помощи команды ipcrm.

Вопрос: Используется данная среда, хранимые процедуры полностью отлажены. Вызовы журналирования мне больше не нужны. В целях повышения производительности хочется сэкономить даже эти несколько миллисекунд. Как лучше всего отключить журналирование?

Ответ: Отключить глобальное журналирование можно при помощи задания параметру global_logging значения N. Если требуется экономить каждую миллисекунду времени выполнения хранимых процедур, закомментируйте все предложения CALL DB2. после того, как SQL-PL или внешние хранимые процедуры будут полностью готовы к использованию. Для размещения и снятия знаков комментария я применяю простой сценарий sed.

Листинг 13. Глобальное отключение журналирования
db2 "call db2.update_sp_config('global_logging','y')"
Листинг 14. Комментирование предложений CALL DB2. в хранимых процедурах SQL-PL
#!/bin/ksh
# Comment Logger Calls		
cat actsp.sql | sed 's/CALL DB2./--CALL DB2./' > sp.sql
db2 -td@ -f sp.sql 
       
#!/bin/ksh
# Uncomment Logger Calls		
cat sp.sql | sed 's/--CALL DB2./CALL DB2./' > actsp.sql
db2 -td@ -f actsp.sql

Вопрос: Я хотел бы расширить функциональность данной среды. Как это можно сделать?

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


Заключение

Рассматриваемую в данной статье среду журналирования можно использовать для журналирования информационных и отладочных сообщений в файл журнала и для измерения производительности. Среду также можно использовать в производственной системе для включения или отключения "на лету" журналирования хранимых процедур; это помогает понять работу хранимых процедур и упрощает управление ими.


Благодарности

Особая благодарность Берту Виалпандо (Burt VialPando) и Норе Соколоф (Nora Sokolof) за технический анализ данной статьи.


Загрузка

ОписаниеИмяРазмер
Исходный код среды журналированияSQLPLLogging.zip13 KB

Ресурсы

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Information Management
ArticleID=270799
ArticleTitle=Журналирование сообщений хранимых процедур DB2 для Linux, UNIX и Windows
publish-date=11222007