FirebirdSQL logo

Пакет RDB$PROFILER

Пакет RDB$PROFILER предназначен для управления сеансами профилирования.

Note
  • Пакет RDB$PROFILER для управления профилировщиком является стандартным, хотя сам профилировщикявляется подключаемым модулем. Используемый профилировщик зависит от настройки DefaultProfilerPluginв файле firebird.conf или databases.conf или от параметра PLUGIN_NAME в функции START_SESSION.

  • Firebird 5.0 поставляется с подключаемым модулем профилировщика под названием Default_Profiler.

  • Пользователям разрешено профилировать свои собственные подключения. Для профилирования подключений других пользователей требуется системная привилегия PROFILE_ANY_ATTACHMENT.

Подробное описание таблиц и представлений плагина профилирования Default_Profiler см. в приложении Таблицы плагинов. Плагин профилирования Default_Profiler.

Функция START_SESSION

Функция RDB$PROFILER.START_SESSION запускает новый сеанс профилировщика, превращает его в текущий сеанс (для заданного ATTACHMENT_ID) и возвращает его идентификатор.

Table 1. Входные параметры процедуры RDB$PROFILER.START_SESSION
Параметр Тип Описание

DESCRIPTION

VARCHAR(255) CHARACTER SET UTF8

Пользовательское описание сеанса профилирования. По умолчанию NULL.

FLUSH_INTERVAL

INTEGER

Интервал автоматического сброса статистики в таблицы снимков. По умолчанию NULL. Измеряется в секундах.

ATTACHMENT_ID

BIGINT

Идентификатор соединения для которого запускается сеанс профилирования. По умолчанию CURRENT_CONNECTION.

PLUGIN_NAME

VARCHAR(255) CHARACTER SET UTF8

Наименование плагина профилирования. По умолчанию NULL, что обозначает что будет использоваться плагин профилирования указанный в параметре конфигурации DefaultProfilerPlugin.

PLUGIN_OPTIONS

VARCHAR(255) CHARACTER SET UTF8

Параметры специфичные для плагина профилирования. По умолчанию NULL.

Тип выходного результата: BIGINT NOT NULL.

Если параметр FLUSH_INTERVAL отличен от NULL, то включается автоматический сброс статистики так же, как при вызове RDB$PROFILER.SET_FLUSH_INTERVAL вручную.

Если параметр PLUGIN_NAME имеет значение NULL (по умолчанию), он использует конфигурацию базы данных из параметра DefaultProfilerPlugin.

Для плагина Default_Profiler допустимыми значениями параметра PLUGIN_OPTIONS является NULL или строка DETAILED_REQUESTS.

Если указана опция DETAILED_REQUESTS, то таблица PLG$PROF_REQUESTS будет хранить подробные данные запросов, то есть одну запись для каждого вызова оператора. Это может привести к созданию большого количества записей, что приведёт к медленной работе RDB$PROFILER.FLUSH.

Когда DETAILED_REQUESTS не используется (по умолчанию), таблица PLG$PROF_REQUESTS сохраняет агрегированную запись для каждого оператора, используя REQUEST_ID = 0.

Процедура CANCEL_SESSION

Процедура RDB$PROFILER.CANCEL_SESSION отменяет текущий сеанс профилировщика (для заданного ATTACHMENT_ID).

Все данные сеанса, присутствующие в плагине профилировщика, отбрасываются и не сбрасываются.

Уже сброшенные данные не удаляются автоматически.

Table 2. Входные параметры процедуры RDB$PROFILER.CANCEL_SESSION
Параметр Тип Описание

ATTACHMENT_ID

BIGINT

Идентификатор соединения для которого отменяется сеанс профилирования. По умолчанию CURRENT_CONNECTION.

Процедура DISCARD

Процедура RDB$PROFILER.DISCARD удаляет все сеансы (для заданного ATTACHMENT_ID) из памяти, не сбрасывая их.

Если есть активная сессия, она отменяется.

Table 3. Входные параметры процедуры RDB$PROFILER.DISCARD
Параметр Тип Описание

ATTACHMENT_ID

BIGINT

Идентификатор соединения для которого удаляются все сеансы профилирования. По умолчанию CURRENT_CONNECTION.

Процедура FINISH_SESSION

Процедура RDB$PROFILER.FINISH_SESSION завершает текущий сеанс профилировщика (для заданного ATTACHMENT_ID).

Table 4. Входные параметры процедуры RDB$PROFILER.FINISH_SESSION
Параметр Тип Описание

FLUSH

BOOLEAN

Сбрасывать ли текущую статистику профилирования в таблицы моментальных снимков.

ATTACHMENT_ID

BIGINT

Идентификатор соединения для которого завершается сеанс профилирования. По умолчанию CURRENT_CONNECTION.

Если значение параметра FLUSH равно TRUE, то таблицы моментальных снимков обновляются данными завершённого сеанса (и старых завершённых сеансов, ещё не присутствующих в моментальном снимке). В противном случае данные остаются только в памяти для последующего обновления.

Вызов RDB$PROFILER.FINISH_SESSION(TRUE) имеет тот же смысл, что и вызов RDB$PROFILER.FINISH_SESSION(FALSE), за которым следует RDB$PROFILER.FLUSH (с использованием того же ATTACHMENT_ID).

Процедура FLUSH

Процедура RDB$PROFILER.FLUSH обновляет таблицы моментальных снимков данными из сеансов профиля (для заданного ATTACHMENT_ID) в памяти.

Table 5. Входные параметры процедуры RDB$PROFILER.FLUSH
Параметр Тип Описание

ATTACHMENT_ID

BIGINT

Идентификатор соединения для которого обновляются таблицы моментальных снимков из сеансов профилирования. По умолчанию CURRENT_CONNECTION.

После обновления данные сохраняются в таблицах PLG$PROF_SESSIONS, PLG$PROF_STATEMENTS, PLG$PROF_RECORD_SOURCES, PLG$PROF_REQUESTS, PLG$PROF_PSQL_STATS и PLG$PROF_RECORD_SOURCE_STATS и могут быть прочитаны и проанализированы пользователем.

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

После сброса завершённые сеансы удаляются из памяти.

Процедура PAUSE_SESSION

Процедура RDB$PROFILER.PAUSE_SESSION приостанавливает текущий сеанс профилировщика (для заданного ATTACHMENT_ID), после чего статистика для последующих выполненных операторов не собирается.

Table 6. Входные параметры процедуры RDB$PROFILER.PAUSE_SESSION
Параметр Тип Описание

FLUSH

BOOLEAN

Сбрасывать ли текущую статистику профилирования в таблицы моментальных снимков.

ATTACHMENT_ID

BIGINT

Идентификатор соединения для которого приостанавливается сеанс профилирования. По умолчанию CURRENT_CONNECTION.

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

Вызов RDB$PROFILER.PAUSE_SESSION(TRUE) имеет тот же смысл, что и вызов RDB$PROFILER.PAUSE_SESSION(FALSE), за которым следует RDB$PROFILER.FLUSH (с использованием того же ATTACHMENT_ID).

Процедура RESUME_SESSION

Процедура RDB$PROFILER.RESUME_SESSION возобновляет текущий сеанс профилировщика (для заданного ATTACHMENT_ID), если он был приостановлен, после чего вновь собирается статистика последующих выполненных операторов.

Table 7. Входные параметры процедуры RDB$PROFILER.RESUME_SESSION
Параметр Тип Описание

ATTACHMENT_ID

BIGINT

Идентификатор соединения для которого возобновляется сеанс профилирования. По умолчанию CURRENT_CONNECTION.

Процедура SET_FLUSH_INTERVAL

Процедура RDB$PROFILER.SET_FLUSH_INTERVAL включает периодическую автоматическую сброс статистики в таблицы моментальных снимков (когда FLUSH_INTERVAL больше 0) или выключает (когда FLUSH_INTERVAL равно 0).

Table 8. Входные параметры процедуры RDB$PROFILER.SET_FLUSH_INTERVAL
Параметр Тип Описание

FLUSH_INTERVAL

INTEGER

Интервал автоматического сброса статистики. Задаётся в секундах.

ATTACHMENT_ID

BIGINT

Идентификатор соединения для которого обновляются таблицы моментальных снимков из сеансов профилирования. По умолчанию CURRENT_CONNECTION.

Как работает профилирования SQL и PSQL кода

Профилировщик позволяет пользователям измерять стоимость производительности кода SQL и PSQL.

Это реализовано с помощью системного пакета в движке, передающего данные плагину профилировщика.

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

Пакет RDB$PROFILER позволяет профилировать выполнение кода PSQL, собирая статистику о том, сколько раз выполнялась каждая строка, а также её минимальное, максимальное и накопленное время выполнения (с точностью до наносекунд), а также открывать и извлекать статистику неявных и явных SQL-курсоров.

Note

К сожалению профилировщик не может работать с базами данных 1 SQL-диалекта.

Это происходит из-за того, что таблицы моментальных снимков содержат поля с типом BIGINT, которые нельзя создать в 1-диалекте.

Для сбора данных профиля пользователь должен сначала запустить сеанс профиля с помощью RDB$PROFILER.START_SESSION. Эта функция возвращает идентификатор сеанса профиля, который позже сохраняется в таблицах моментальных снимков профилировщика для запроса и анализа пользователем. Сеанс профилировщика может быть локальным (то же соединение) или удалённым (другое соединение).

Удалённое профилирование просто перенаправляет команды на удалённое соединение. Это позволяет клиенту одновременно профилировать несколько сеансов.Кроме того, локально или удалённо запущенный сеанс профилировщика может получать команды, выданные в другом соединении.

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

Если удалённое соединение исходит от другого пользователя, вызывающий пользователь должен иметь системную привилегию PROFILE_ANY_ATTACHMENT.

После запуска сеанса в памяти начинает собираться статистика PSQL и SQL операторов. Обратите внимание, что сеанс профилировщика собирает данные только об операторах, выполненных только в том соединении, которое связанно с сеансом профилировщика.

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

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

Новый сеанс профилировщика может быть запущен, когда уже есть активный сеанс. В этом случае текущий сеанс завершается как будто была вызвана процедураRDB$PROFILER.FINISH_SESSION(FALSE), поэтому таблицы моментальных снимков не обновляются в этот момент.

Чтобы проанализировать собранные данные, пользователь должен сбросить данные в таблицы моментальных снимков,что можно сделать, завершив или приостановив сеанс (с параметром FLUSH, установленным в TRUE) или вызвав RDB$PROFILER.FLUSH.Данные сбрасываются с помощью автономной транзакции (транзакция, запущенная и завершенная для конкретной цели обновления данных профилировщика).

Пример

Ниже приведён пример сеанса профилировщика и запросов для анализа данных.

  1. Подготовка — создание таблицы и процедур, которые будут анализироваться.

    create table tab (
        id integer not null,
        val integer not null
    );
    
    set term !;
    
    create or alter function mult(p1 integer, p2 integer) returns integer
    as
    begin
        return p1 * p2;
    end!
    
    create or alter procedure ins
    as
        declare n integer = 1;
    begin
        while (n <= 1000)
        do
        begin
            if (mod(n, 2) = 1) then
                insert into tab values (:n, mult(:n, 2));
            n = n + 1;
        end
    end!
    
    set term ;!
  2. Запуск профилирования.

    select rdb$profiler.start_session('Profile Session 1') from rdb$database;
    
    set term !;
    
    execute block
    as
    begin
        execute procedure ins;
        delete from tab;
    end!
    
    set term ;!
    
    execute procedure rdb$profiler.finish_session(true);
    
    execute procedure ins;
    
    select rdb$profiler.start_session('Profile Session 2') from rdb$database;
    
    select mod(id, 5),
           sum(val)
      from tab
      where id <= 50
      group by mod(id, 5)
      order by sum(val);
    
    execute procedure rdb$profiler.finish_session(true);
  3. Анализ результатов профилирования.

    set transaction read committed;
    
    select * from plg$prof_sessions;
    
    select * from plg$prof_psql_stats_view;
    
    select * from plg$prof_record_source_stats_view;
    
    select preq.*
      from plg$prof_requests preq
      join plg$prof_sessions pses
        on pses.profile_id = preq.profile_id and
           pses.description = 'Profile Session 1';
    
    select pstat.*
      from plg$prof_psql_stats pstat
      join plg$prof_sessions pses
        on pses.profile_id = pstat.profile_id and
           pses.description = 'Profile Session 1'
      order by pstat.profile_id,
               pstat.request_id,
               pstat.line_num,
               pstat.column_num;
    
    select pstat.*
      from plg$prof_record_source_stats pstat
      join plg$prof_sessions pses
        on pses.profile_id = pstat.profile_id and
           pses.description = 'Profile Session 2'
      order by pstat.profile_id,
               pstat.request_id,
               pstat.cursor_id,
               pstat.record_source_id;

Пакет RDB$TIME_ZONE_UTIL

Пакет RDB$TIME_ZONE_UTIL содержит процедуры и функции для работы с часовыми поясами.

docnext count = 2

Функция RDB$TIME_ZONE_UTIL.DATABASE_VERSION()

Функция RDB$TIME_ZONE_UTIL.DATABASE_VERSION возвращает версию базы данных часовых поясов (из библиотеки icu).

Тип возвращаемого результата

VARCHAR(10) CHARACTER SET ASCII

Example 1. Использование функции RDB$TIME_ZONE_UTIL.DATABASE_VERSION
SELECT rdb$time_zone_util.database_version()
FROM rdb$database;
DATABASE_VERSION
================
2021a

Процедура RDB$TIME_ZONE_UTIL.TRANSITIONS()

Процедура RDB$TIME_ZONE_UTIL.TRANSITIONS возвращает набор правил для часового пояса между начальной и конечной временной меткой.

Table 1. Входные параметры процедуры RDB$TIME_ZONE_UTIL.TRANSITIONS
Параметр Тип Описание

RDB$TIME_ZONE_NAME

CHAR(63)

Наименование часового пояса

RDB$FROM_TIMESTAMP

TIMESTAMP WITH TIME ZONE

Начало интервала дат

RDB$TO_TIMESTAMP

TIMESTAMP WITH TIME ZONE

Окончание интервала дат

Table 2. Выходные параметры процедуры RDB$TIME_ZONE_UTIL.TRANSITIONS
Параметр Тип Описание

RDB$START_TIMESTAMP

TIMESTAMP WITH TIME ZONE

Дата начала действия правила

RDB$END_TIMESTAMP

TIMESTAMP WITH TIME ZONE

Дата окончания действия правила

RDB$ZONE_OFFSET

SMALLINT

Смещение времени в минутах для заданного часового пояса

RDB$DST_OFFSET

SMALLINT

Летнее смещение времени в минутах для заданного часового пояса

RDB$EFFECTIVE_OFFSET

SMALLINT

Эффективное смещение, вычисляется как RDB$ZONE_OFFSET + RDB$DST_OFFSET

Example 1. Использование процедуры RDB$TIME_ZONE_UTIL.TRANSITIONS
SELECT
  RDB$START_TIMESTAMP,
  RDB$END_TIMESTAMP,
  RDB$ZONE_OFFSET AS ZONE_OFF,
  RDB$DST_OFFSET AS DST_OFF,
  RDB$EFFECTIVE_OFFSET AS OFF
FROM rdb$time_zone_util.transitions(
    'America/Sao_Paulo',
    timestamp '2017-01-01',
    timestamp '2019-01-01');
         RDB$START_TIMESTAMP            RDB$END_TIMESTAMP ZONE_OFF DST_OFF  OFF
============================ ============================ ======== ======= ====
2016-10-16 03:00:00.0000 GMT 2017-02-19 01:59:59.9999 GMT     -180      60 -120
2017-02-19 02:00:00.0000 GMT 2017-10-15 02:59:59.9999 GMT     -180       0 -180
2017-10-15 03:00:00.0000 GMT 2018-02-18 01:59:59.9999 GMT     -180      60 -120
2018-02-18 02:00:00.0000 GMT 2018-10-21 02:59:59.9999 GMT     -180       0 -180
2018-10-21 03:00:00.0000 GMT 2019-02-17 01:59:59.9999 GMT     -180      60 -120