IBAnalyst: что вы можете увидеть в представлении Summary View
Дмитрий Кузменко, последнее обновление 31-03-2014
Аннотация
Этот документ посвящён объяснению информации на странице «Сводный просмотр» (Summary view) в IBAnalyst, а также тому, как интерпретировать эту информацию для статистики вашей базы данных. Кроме того, мы добавили несколько примеров статистики в установочный пакет, чтобы облегчить вам изучение всех тонкостей статистики InterBase. Они находятся в каталоге Examples установки IBAnalyst.
Если вы не знаете, что такое старейшая транзакция (Oldest transaction), старейший снимок (Oldest snapshot), активная (active) и следующая (Next), пожалуйста, сначала прочитайте статью Крейга Стунца «Понимание времени жизни транзакций»:
http://blogs.teamb.com/craigstuntz/articles/UnderstandingTransactionLifetimes.aspx
Номера транзакций
Если вы прочитали статью «Понимание времени жизни транзакций», возможно, у вас всё ещё остались вопросы о числах OIT/OST/OAT. Вот краткое описание:
| Номер | Удерживается, … | Движется вперёд, … |
| Старейшая транзакция | когда транзакция с этим номером была откачена и в ней было много изменений данных, или когда соединение с клиентом было потеряно | когда автоматическая или ручная уборка (sweep) завершается успешно. |
| Старейший снимок | когда снимок (или чтение с подтверждением записи до IB 7.1) активен в течение длительного времени (он запоминает старейший активный снимок как свой локальный OST) | когда начинается новая транзакция, если транзакция, удерживающая OST, завершена |
| Старейшая активная | когда транзакция с этим номером активна в течение длительного времени | когда начинается новая транзакция, если транзакция, удерживающая OAT, завершена |
| Следующая | никогда | когда начинается новая транзакция |
примечание: старейшая транзакция здесь - это то же самое, что старейшая интересная транзакция (OIT), упоминаемая во многих других статьях.
Хорошая статистика со стандартными настройками
Давайте запустим IBAnalyst и откроем (через меню Statistics/Load statistics from file) файл !allok.txt.

IBAnalyst сообщает не только дату создания базы данных, но также распознаёт текущую дату и время на сервере, если статистика была получена через Services API, или дату файла, если это загруженный файл статистики.
Вот почему мы рекомендуем не изменять файлы статистики, потому что в этом случае IBAnalyst будет неправильно вычислять среднее количество транзакций в день. Строка «Транзакций в день» здесь показывает около ~12500 транзакций в день, и база данных «живёт» с момента её создания или восстановления в течение 8 дней.
Старейшая, старейший снимок, старейшая активная и следующая транзакции здесь в идеальном состоянии; желаем, чтобы ваша статистика всегда выглядела так.
Много активных транзакций
Далее откройте файл !lotofactive.txt (вы можете в любой момент вернуться к картинке !allok, чтобы сравнить следующие примеры с ней).

Здесь строка «Активные транзакции» помечена красным, потому что есть большая разница между старейшей активной и следующей транзакцией. Это означает, что некоторая транзакция на момент снятия статистики всё ещё активна, и после её начала уже запущено 55 000 транзакций (они могут быть в любом состоянии - активные, зафиксированные, откаченные). Поскольку среднее количество транзакций в день составляет ~12500, IBAnalyst показывает вам предупреждение, что некоторая транзакция всё ещё живёт в течение 4,4 дней. Это может произойти, когда:
- некоторое приложение всё ещё работает и имеет хотя бы одну открытую транзакцию - возможно, какой-то пользователь держит приложение запущенным в течение длительного времени;
- приложение работает долго и теряет дескрипторы транзакций - то есть ваш код (или компоненты/библиотеки, которые вы используете) динамически запускает транзакции и при некоторых обстоятельствах «забывает» завершить их откатом или фиксацией;
- ваше приложение не использует явные транзакции (BDE), оставляя управление транзакциями используемым компонентам. В результате время жизни транзакций не контролируется приложением, и вы можете быть уверены, что большинство транзакций Next-OAT действительно активны;
- ваше приложение использует драйвер или компоненты, которые допускают «транзакцию по умолчанию». Если ваш код не управляет этой транзакцией, она может работать очень долго.
К сожалению, статистика не показывает фактическое количество активных транзакций в данный момент. Это можно увидеть только в InterBase 7.x с помощью IBConsole, IB Performance Monitor или через прямой запрос к временной системной таблице tmp$transactions. В Firebird 1.5 вы можете вызвать isc_database_info с параметром isc_info_active_transactions.
Уборка (Sweep)
Теперь откроем файл !needsweep.txt.
Sweep - это процесс обслуживания внутри InterBase. Sweep проходит по всем записям в базе данных и пытается очистить все устаревшие версии, затем пытается продвинуть номер старейшей транзакции вперёд. В новой созданной базе данных интервал sweep по умолчанию равен 20000. Когда разница между транзакциями (см. таблицу ниже) становится больше интервала sweep, sweep запускается автоматически. Таким образом, вы можете наблюдать периодическое снижение производительности вашей базы данных. Например, ваши приложения работают нормально в понедельник и вторник, но в среду пользователи сообщают о проблемах с производительностью в течение нескольких часов, а затем производительность снова становится нормальной.
Если вы видите подобное поведение - это автоматическая уборка.
| Версия сервера | Когда запускается sweep |
| InterBase 7.x | (Старейшая активная - Старейшая) > Интервал sweep |
| InterBase 4.x, 5.x, 6.x, Firebird до 1.5.2, Yaffil | (Старейший снимок - Старейшая) > Интервал sweep |
Таблица 1. Условия запуска автоматической уборки
примечание: IBAnalyst автоматически показывает правильную информацию о разрыве sweep для всех версий. IBAnalyst может определить разницу между реализациями серверов только по идентификатору ODS, например, InterBase 7.x имеет ODS 11.x, другие современные серверы имеют ODS 10.x. Если вы работаете только с базами InterBase 7.x (ODS 11), вы можете переключить соответствующую опцию в диалоговом окне Options.
Когда интервал sweep вашей базы данных <> 0, IBAnalyst в основном помечает эту строку жёлтым цветом (предупреждая вас, что автоматическая уборка может начаться в любой непредсказуемый момент). Как правило, 60% всех приложений имеют проблемы с автоматической уборкой. Самый простой способ избежать этой проблемы - установить интервал sweep равным 0, что приводит к отключению автоматической уборки. Но если какое-то приложение сделает много изменений, а затем откатит их, старейшая транзакция заморозится и не будет двигаться вперёд, пока не будет запущена уборка. Поскольку эффективное состояние транзакций вычисляется от старейшей до следующей транзакции, это расстояние будет расти, и производительность упадёт. Чтобы предотвратить это, вы должны запускать sweep вручную (gfix -sweep). На этой картинке вы можете видеть поведение, когда интервал sweep равен 0 и была откачена большая транзакция:

Здесь значение разрыва sweep показывает, что некоторая большая (сделавшая много изменений) транзакция была откачена около 4,5 дней назад. Мы рекомендуем вам запускать sweep вручную каждый день.
Конечно, для тех упомянутых 60% приложений, возможно, лучше установить интервал sweep больше или меньше 20000, но это зависит от многих факторов (ежедневное количество транзакций - один из этих факторов, например) и может быть понято только экспериментальным путём. Итак, если вы установите интервал sweep равным 0, вы можете быть уверены, что уборка не запустится автоматически в непредсказуемый момент.
Ту же картину вы можете увидеть для файла !rollback.txt.
примечание: Если sweep запускается автоматически, для большой базы данных или базы данных с большим количеством мусорных версий записей снимок, активная и следующая транзакции могут двигаться вперёд, пока работает sweep, и sweep может снова запуститься при ближайшем старте транзакции.
Когда sweep не может выполнить свою работу
Существует много случаев, когда sweep не может продвинуть старейшую транзакцию выше. Конечно, sweep сначала пытается выполнить свою работу, то есть проверить все записи в базе данных и собрать ненужные версии записей. Но он будет запускаться снова и снова без успеха, если

возникла какая-то проблема при запуске sweep: сервер был остановлен во время sweep, или произошла ошибка при очистке мусорных версий записей. Кроме того, вы можете увидеть эту картину, когда:
-
статистика была снята во время работы sweep;
-
sweep запущен и пытается собрать мусор для таблицы, которая постоянно обновляется. Это может продолжаться до тех пор, пока обновления не закончатся.
-
sweep зависает на блокировках страниц, потому что с данными работает много пользователей.
Как правило, sweep не имеет шансов завершиться при высокой нагрузке на базу данных. Обычно, когда производительность деградирует до невозможности продолжать нормальную работу, DBA перезапускает сервер, и sweep запускается при первом подключении пользователя. Поскольку пройдет некоторое время, пока подключатся другие пользователи, sweep успеет завершить свою работу.
Поскольку начиная с InterBase 7.1/7.5 Sweep gap рассчитывается иначе, чем в предыдущих версиях, другая ситуация, когда sweep не может выполнить свою работу, возникает, если какое-то приложение имеет длительную snapshot-транзакцию:

Здесь два предупреждения - одно (желтое) о длительной snapshot-транзакции, другое (красное) об интервале sweep и Sweep gap.
Длительная snapshot-транзакция
Предыдущая картинка указывает на длительную snapshot-транзакцию в InterBase 7.1/7.5. Если бы Sweep interval был установлен в 0, красных предупреждений не было бы, только желтые. Похожая картинка укажет на длительную snapshot-транзакцию в других версиях InterBase, Firebird и Yaffil:

Как видите, здесь Sweep gap рассчитывается по разнице между Oldest Snapshot и Oldest transaction (для ODS 10, версии до IB7.x). Поэтому предупреждения о sweep нет (кроме стандартного интервала sweep).
Но не только snapshot-транзакции влияют на состояние транзакций таким образом. Все версии InterBase, Firebird и Yaffil, кроме InterBase 7.1/7.5, имеют следующее поведение, которое мы назвали «артефакт read committed».
Снова снапшоты и когда ReadCommitted замораживает Oldest Snapshot
Откройте !snapshot2.txt. :

Обратите внимание, что Oldest transaction больше, чем Oldest snapshot. И Sweep gap имеет отрицательное значение. Это может произойти в двух случаях. Первый случай - когда snapshot-транзакции запускаются и фиксируются одна за другой. То есть эта картина может возникнуть со снапшотами так же, как и предыдущая. Следующий случай происходит только на серверах, отличных от IB 7.1/7.5, с ReadCommitted-транзакциями (или в комбинации ReadCommitted и Snapshot-транзакций). Они могут заблокировать номер Oldest Snapshot так же, как это делают Snapshot-транзакции. Текущее состояние транзакций можно эмулировать следующей последовательностью:
-
запустить транзакцию 1, snapshot или read_committed
-
запустить/зафиксировать несколько read_committed-транзакций
-
запустить транзакцию 2, snapshot или read_committed
-
запустить/зафиксировать несколько read_committed-транзакций
-
зафиксировать транзакцию 1
(конечно, мы говорим здесь о read_committed write-транзакциях, а не read-only).
В этот момент активная транзакция 2 (snapshot или read committed), запущенная после snapshot 1 (пункт 3), будет удерживать номер снапшота как Oldest Snapshot (если вы работаете с IB 7.1/7.5, это может произойти только для параллельных snapshot-транзакций. read_committed или read_committed+snapshot не дадут такого эффекта). Поскольку больших откатов не было, Oldest transaction движется вперед и становится больше, чем Oldest Snapshot.
Теперь, если у вас есть длительная read committed-транзакция, вы увидите примерно такую картину. К сожалению, здесь вы ничего не можете сделать со своими приложениями (кроме добавления параметра «read» для read-only-транзакций). И, конечно, в этом случае sweep не запустится автоматически (если он установлен <> 0).
примечание: это поведение будет исправлено в Firebird 2.0
Абсолютное и относительное представление
По умолчанию IBAnalyst заполняет строки транзакций в процентах от их абсолютного значения. То есть 100% - это от 0 до Next transaction. Иногда, когда база данных работает долгое время, вы можете увидеть информацию о транзакциях так:

Хотя транзакций много, разница между snapshot, active и oldest выглядит очень маленькой (близко к 98%). Чтобы сделать ситуацию более понятной, откройте диалог Options, вкладку Transactions и отметьте опцию «Relative (from oldest) bars %» (вы не можете установить этот флажок, если используете старый вид без графических полос). После нажатия кнопки OK вид транзакций изменится на:

Теперь вы видите разницу транзакций в относительном представлении (100% - это от Oldest (или snapshot) транзакции до Next, а не от 0). Так легче понять текущую ситуацию и увидеть предупреждения (если они есть).
Этот вид сохранится, пока вы не снимете флажок в диалоге Options. Вы можете понять, какой вид видите, по строке Oldest Transaction или Oldest snapshot - в относительном представлении одна из этих строк никогда не заполняется зеленым цветом. В абсолютном представлении она всегда заполнена (частично, конечно).
Остались вопросы? Спросите нас: [email protected]