Взаимоблокировка — это неразрешимый конфликт блокировок, возникающий при работе двух или более сессий клиентских приложений к СУБД.
Взаимоблокировки и таймауты — это достаточно неприятные ошибки, которые часто возникают только в продуктивных системах, но не воссоздаются в процессе нагрузочного тестирования.
Я попытаюсь кратко описать те инструменты, которые можно использовать для облегчения поиска и устранения подобных ошибок применительно к связке 1С+DB2. Как известно, «Центр управления производительностью» (инструмент из «Корпоративного инструментального пакета» фирмы 1С) на данный момент не умеет извлекать информацию о взаимоблокировках и таймаутах из DB2. Скорее всего, в ближайшем будущем эта возможность появится.
Первым делом нам необходимо подготовить базу DB2 для сохранения событий взаимоблокировок и таймаутов в отдельной таблице. Лучше всего войти на сервер под учетной записью db2admin, тогда не будет проблем с правами доступа при выполнении каких-либо операций.
Открываем консоль администратора DB2 и выполняем последовательно следующие операции:
подключение к базе данных
db2 «CONNECT TO <Имя базы>»
создание отдельного табличного пространства для монитора событий
db2 «CREATE TABLESPACE TBSPACE_LOCKING»
создание самого монитора событий
db2 «CREATE EVENT MONITOR EVMON_LOCKING FOR LOCKING WRITE TO UNFORMATTED EVENT TABLE (TABLE EMDATA.TAB_LOCKING IN TBSPACE_LOCKING)»
запуск монитора событий
db2 «UPDATE DB CFG USING MON_DEADLOCK HISTORY IMMEDIATE»
db2 «SET EVENT MONITOR EVMON_LOCKING STATE 1»
отключение от базы
db2 CONNECT RESET
Далее нам необходимо дождаться появления некоторого количества событий, которые в последствии мы будем анализировать. Если это продуктивная база, то просто ждем, если тестовая, то запускаем нагрузочный тест. Для проведения нагрузочного теста очень удобно использовать Тест-центр (еще одна составная часть «Корпоративного инструментального пакета»).
Следует учесть, что при большой интенсивности взаимоблокировок и таймаутов, монитор событий может записать значительный объем информации, поэтому желательно отслеживать динамику роста базы и своевременно отключать монитор, либо чистить таблицу с логами.
Чтобы проверить наличие зафиксированных событий можно воспользоваться следующим запросом:
SELECT Count(*) FROM TABLE ( EVMON_FORMAT_UE_TO_XML( 'LOG_TO_FILE',FOR EACH ROW OF ( SELECT * FROM emdata.tab_locking)))
Для очистки истории событий необходимо выполнить вот этот запрос:
DELETE FROM EMDATA.«TAB_LOCKING»
Для отключения монитора событий:
db2 «CONNECT TO <Имя базы>»
db2 «SET EVENT MONITOR EVMON_LOCKING STATE 0»
db2 CONNECT RESET
После сбора некоторого объема событий приступаем к извлечению этой информации.
Перед этим необходимо выполнить подготовку инструмента, который позволит преобразовать имеющиеся события в читабельный формат. Для этого:
1) просто для удобства создайте отдельный каталог, например, c:\deadlock
2) скопируйте в него 2 файла из основного каталога IBM DB2. Если DB2 устанавливали по-умолчанию, то эти файлы здесь:
«C:\Program Files\IBM\SQLLIB\samples\java\jdbc\db2evmonfmt.java»
«C:\Program Files\IBM\SQLLIB\samples\java\jdbc\DB2EvmonLocking.xsl»
3) открываем командную строку, заходим в каталог c:\deadlock\ и указываем системе путь к java:
set PATH=C:\Program Files\IBM\SQLLIB\java\jdk\bin;%PATH%
4) компилируем утилиту
javac db2evmonfmt.java
Инструмент готов, теперь непосредственно выполняем извлечение событий в XML-формат:
java db2evmonfmt -d <Имя базы> -ue emdata.tab_locking -type deadlock -fxml -u db2admin -p Password >deadlock.txt
где,
-type deadlock — фильтр на тип выгружаемых событий, можно не указывать, тогда система выгрузит и таймауты, и взаимоблокировки
-u db2admin -p Password — параметры авторизации, если работаете уже под db2admin, то можно не указывать.
deadlock.txt — путь к результирующему файлу
Об этих и остальных параметрах можно почитать в справке, просто вызвав java db2evmonfmt
После вызова указанной команды система сформирует файл deadlock.txt, в который будут помещены события в формате XML. Браузером сразу открывать не пытайтесь, т.к. в этом файле скомпонованы тексты XML cо служебными вставками, поэтому для полноценного просмотра этот файл нужно еще нарезать. А можно и так просматривать с помощью вот этой классной бесплатной программы — Notepad++.
Структура полученных XML-файлов достаточно простая.
Для таймаутов указывается по 1 запросу из участвующих сессий — 1 запрос из сессии, которая захватила и длительное время удерживает ресурс, и 1 запрос из сессии(-й), которая стала жертвой и завершила свое выполнение аварийно.
Для взаимоблокировок указывается похожая информация, но для сессий отображаются ВСЕ выполненные запросы с начала транзакции.
Для удобства можно выполнить замену имен таблиц СУБД на имена метаданных 1С, тогда картина станет более прозрачной для восприятия (программистом 1С эта задача решается легко).
Пример типичной взаимоблокировки:

А вот дальше уже надо включать голову и искать участки кода, которые привели к этим ошибкам. В принципе, параллельно с фиксацией событий средствами DB2, можно включить формирование Технологического журнала 1С, а затем сопоставить каким-то образом эту информацию, но, по утверждению разработчиков ЦУПа, для выполнения этой операции пока недостаточно данных.
Если нужно о чем-то написать подробнее — укажите в комментариях, и я попробую это сделать.
Заранее признателен за замечания по существу.
Использовались материалы из статьи Анализ событий блокировки в DB2 для Linux, UNIX и Windows: Часть 3. Использование монитора событий блокировки для решения проблем параллелизма в DB2 9.7
Взаимоблокировки и таймауты — это достаточно неприятные ошибки, которые часто возникают только в продуктивных системах, но не воссоздаются в процессе нагрузочного тестирования.
Я попытаюсь кратко описать те инструменты, которые можно использовать для облегчения поиска и устранения подобных ошибок применительно к связке 1С+DB2. Как известно, «Центр управления производительностью» (инструмент из «Корпоративного инструментального пакета» фирмы 1С) на данный момент не умеет извлекать информацию о взаимоблокировках и таймаутах из DB2. Скорее всего, в ближайшем будущем эта возможность появится.
Первым делом нам необходимо подготовить базу DB2 для сохранения событий взаимоблокировок и таймаутов в отдельной таблице. Лучше всего войти на сервер под учетной записью db2admin, тогда не будет проблем с правами доступа при выполнении каких-либо операций.
Открываем консоль администратора DB2 и выполняем последовательно следующие операции:
подключение к базе данных
db2 «CONNECT TO <Имя базы>»
создание отдельного табличного пространства для монитора событий
db2 «CREATE TABLESPACE TBSPACE_LOCKING»
создание самого монитора событий
db2 «CREATE EVENT MONITOR EVMON_LOCKING FOR LOCKING WRITE TO UNFORMATTED EVENT TABLE (TABLE EMDATA.TAB_LOCKING IN TBSPACE_LOCKING)»
запуск монитора событий
db2 «UPDATE DB CFG USING MON_DEADLOCK HISTORY IMMEDIATE»
db2 «SET EVENT MONITOR EVMON_LOCKING STATE 1»
отключение от базы
db2 CONNECT RESET
Далее нам необходимо дождаться появления некоторого количества событий, которые в последствии мы будем анализировать. Если это продуктивная база, то просто ждем, если тестовая, то запускаем нагрузочный тест. Для проведения нагрузочного теста очень удобно использовать Тест-центр (еще одна составная часть «Корпоративного инструментального пакета»).
Следует учесть, что при большой интенсивности взаимоблокировок и таймаутов, монитор событий может записать значительный объем информации, поэтому желательно отслеживать динамику роста базы и своевременно отключать монитор, либо чистить таблицу с логами.
Чтобы проверить наличие зафиксированных событий можно воспользоваться следующим запросом:
SELECT Count(*) FROM TABLE ( EVMON_FORMAT_UE_TO_XML( 'LOG_TO_FILE',FOR EACH ROW OF ( SELECT * FROM emdata.tab_locking)))
Для очистки истории событий необходимо выполнить вот этот запрос:
DELETE FROM EMDATA.«TAB_LOCKING»
Для отключения монитора событий:
db2 «CONNECT TO <Имя базы>»
db2 «SET EVENT MONITOR EVMON_LOCKING STATE 0»
db2 CONNECT RESET
После сбора некоторого объема событий приступаем к извлечению этой информации.
Перед этим необходимо выполнить подготовку инструмента, который позволит преобразовать имеющиеся события в читабельный формат. Для этого:
1) просто для удобства создайте отдельный каталог, например, c:\deadlock
2) скопируйте в него 2 файла из основного каталога IBM DB2. Если DB2 устанавливали по-умолчанию, то эти файлы здесь:
«C:\Program Files\IBM\SQLLIB\samples\java\jdbc\db2evmonfmt.java»
«C:\Program Files\IBM\SQLLIB\samples\java\jdbc\DB2EvmonLocking.xsl»
3) открываем командную строку, заходим в каталог c:\deadlock\ и указываем системе путь к java:
set PATH=C:\Program Files\IBM\SQLLIB\java\jdk\bin;%PATH%
4) компилируем утилиту
javac db2evmonfmt.java
Инструмент готов, теперь непосредственно выполняем извлечение событий в XML-формат:
java db2evmonfmt -d <Имя базы> -ue emdata.tab_locking -type deadlock -fxml -u db2admin -p Password >deadlock.txt
где,
-type deadlock — фильтр на тип выгружаемых событий, можно не указывать, тогда система выгрузит и таймауты, и взаимоблокировки
-u db2admin -p Password — параметры авторизации, если работаете уже под db2admin, то можно не указывать.
deadlock.txt — путь к результирующему файлу
Об этих и остальных параметрах можно почитать в справке, просто вызвав java db2evmonfmt
После вызова указанной команды система сформирует файл deadlock.txt, в который будут помещены события в формате XML. Браузером сразу открывать не пытайтесь, т.к. в этом файле скомпонованы тексты XML cо служебными вставками, поэтому для полноценного просмотра этот файл нужно еще нарезать. А можно и так просматривать с помощью вот этой классной бесплатной программы — Notepad++.
Структура полученных XML-файлов достаточно простая.
Для таймаутов указывается по 1 запросу из участвующих сессий — 1 запрос из сессии, которая захватила и длительное время удерживает ресурс, и 1 запрос из сессии(-й), которая стала жертвой и завершила свое выполнение аварийно.
Для взаимоблокировок указывается похожая информация, но для сессий отображаются ВСЕ выполненные запросы с начала транзакции.
Для удобства можно выполнить замену имен таблиц СУБД на имена метаданных 1С, тогда картина станет более прозрачной для восприятия (программистом 1С эта задача решается легко).
Пример типичной взаимоблокировки:

А вот дальше уже надо включать голову и искать участки кода, которые привели к этим ошибкам. В принципе, параллельно с фиксацией событий средствами DB2, можно включить формирование Технологического журнала 1С, а затем сопоставить каким-то образом эту информацию, но, по утверждению разработчиков ЦУПа, для выполнения этой операции пока недостаточно данных.
Если нужно о чем-то написать подробнее — укажите в комментариях, и я попробую это сделать.
Заранее признателен за замечания по существу.
Использовались материалы из статьи Анализ событий блокировки в DB2 для Linux, UNIX и Windows: Часть 3. Использование монитора событий блокировки для решения проблем параллелизма в DB2 9.7