F.45. pgpro_application_info
pgpro_application_info — это расширение, предназначенное для помощи разработчикам, которые переносят приложения, использующие пакет DBMS_APPLICATION_INFO, из Oracle в Postgres Pro. Администраторы баз данных также могут использовать его в качестве дополнительного источника данных при анализе производительности, а разработчики — для отладки.
Расширение pgpro_application_info создаёт процедуры и функции, которые позволяют приложениям сообщать о своём состоянии, выполняемых действиях и ходе их выполнения. Администратор БД может получить доступ к этой информации через специальные представления.
Типичная последовательность действий клиента, поддерживающего работу с pgpro_application_info, будет выглядеть следующим образом (в данном примере библиотекарь хочет подсчитать все слова «the» в библиотеке):
При подключении к базе данных клиент сообщает, что он —
Librarian, и запускает приложение сканера, которое, в свою очередь, сообщает, что оно — модульBook Scannerи что в данный момент оно пытается выполнить операциюBook Scanning, чтобы найти все вхождения слова «the» в 18042 книгах, при этом на данный момент просканировано 0 книг.Просканировав несколько книг, приложение обновляет информацию, чтобы отразить ход выполнения операции.
Когда сканирование завершено, приложение сообщает об этом и меняет выполняемое действие на
Idle(или NULL).
F.45.1. Установка
Расширение pgpro_application_info включено в состав Postgres Pro Enterprise как стандартное расширение. Чтобы задействовать pgpro_application_info, выполните следующие действия:
Добавьте имя библиотеки в переменную
shared_preload_librariesв файлеpostgresql.conf:shared_preload_libraries = 'pgpro_application_info'
Перезагрузите сервер баз данных, чтобы изменения вступили в силу.
Примечание
Чтобы убедиться, что библиотека установлена правильно, вы можете выполнить следующую команду:
SHOW shared_preload_libraries;
Создайте расширение, выполнив следующий запрос:
CREATE EXTENSION pgpro_application_info;
F.45.2. Использование
pgpro_application_info работает со следующими основными классами данных:
Информация о приложении: имя текущего модуля, выполняемое действие и описание клиента. Администратор БД может получить доступ к информации об активных клиентах и их действиях через представление V_SESSION.
Информация о длительных операциях: текстовые описания и комментарии, отчёт о ходе операции и, при необходимости, ссылка на обрабатываемый объект базы данных. Администратор БД может получить доступ к информации о длительных операциях через представление V_SESSION_LONGOPS, которое помимо данных, отправленных клиентом, содержит временные метки начала и последнего обновления операции, а также ожидаемое оставшееся время выполнения.
Примечание
Обратите внимание, что в Oracle текстовые параметры DBMS_APPLICATION_INFO, передаваемые пользователем, имеют разные ограничения по длине до 64 байт, а в pgpro_application_info для удобства все они имеют одинаковое ограничение — 64 байта. Более длинные значения усекаются.
F.45.2.1. Информация о приложении
Для передачи информации о приложении в pgpro_application_info предусмотрены следующие процедуры:
-
CREATE PROCEDURE DBMS_APPLICATION_INFO.SET_CLIENT_INFO(client_info TEXT) Передаёт информацию о клиенте. Обычно это имя клиента или более сложное описание, но, строго говоря, это может быть любой текст, передаваемый пользователем.
-
CREATE PROCEDURE DBMS_APPLICATION_INFO.SET_ACTION(action_name TEXT) Передаёт имя действия, выполняемого в данный момент в текущем модуле.
-
CREATE PROCEDURE DBMS_APPLICATION_INFO.SET_MODULE(module_name TEXT, action_name TEXT DEFAULT NULL) Передаёт имя выполняемого в данный момент модуля (программы) и действия. По завершении программы рекомендуется вызвать процедуру с именем следующего модуля, если он есть, или с NULL в противном случае.
-
CREATE PROCEDURE DBMS_APPLICATION_INFO.READ_CLIENT_INFO(OUT client_info TEXT) Возвращает информацию о клиенте, переданную ранее процедурой
SET_CLIENT_INFOв текущем сеансе.-
CREATE PROCEDURE DBMS_APPLICATION_INFO.READ_MODULE(OUT module_name TEXT, OUT action_name TEXT) Возвращает информацию о модуле, переданную ранее процедурой
SET_MODULE, и информацию о действии, переданную процедуройSET_MODULEилиSET_ACTIONв текущем сеансе.
F.45.2.1.1. Представление V_SESSION
Представление V_SESSION содержит информацию обо всех активных сеансах, информация о которых была передана процедурами pgpro_application_info, о подключённых клиентах, модулях и выполняемых действиях. Представление содержит одну строку для каждого отдельного сеанса. Когда сеанс впервые сообщает информацию о себе, создаётся соответствующая запись в представлении. Каждая строка существует в течение соответствующего сеанса, поэтому после перезапуска сервера представление пустое. Столбцы представления показаны в Таблице F.30. Для удобства в Postgres Pro также поддерживается эквивалентное представление с названием V$SESSION, привычное для пользователей Oracle и содержащее ту же информацию. Однако обратите внимание, что улучшенная совместимость с Oracle, обеспечиваемая этой альтернативой, является отклонением от стандарта SQL и поэтому делает код менее переносимым.
CREATE FUNCTION DBMS_APPLICATION_INFO.READ_V_SESSION(
OUT SID INTEGER,
OUT DBNAME TEXT,
OUT MODULE TEXT,
OUT ACTION TEXT,
OUT CLIENT_INFO TEXT
)
CREATE VIEW V_SESSION AS SELECT * FROM DBMS_APPLICATION_INFO.READ_V_SESSION();Таблица F.30. Столбцы V_SESSION
| Имя | Описание |
|---|---|
SID | ID сеанса, PID |
DBNAME | Имя базы данных, к которой подключён сеанс. Если вы хотите получить записи только для текущей базы данных, добавьте в запрос следующее условие: WHERE DBNAME=current_database(). |
MODULE | Имя модуля, выполняемого данным сеансом, ранее переданное процедурой SET_MODULE. |
ACTION | Имя действия, выполняемого данным сеансом, ранее переданное процедурой SET_MODULE или SET_ACTION. |
CLIENT_INFO | Информация о связанном с сеансом клиенте, ранее переданная процедурой SET_CLIENT_INFO. |
F.45.2.2. Информация о длительных операциях
CREATE PROCEDURE DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS(
INOUT RINDEX INTEGER,
INOUT SLNO INTEGER,
OP_NAME TEXT DEFAULT NULL,
TARGET OID DEFAULT 0,
CONTEXT INTEGER DEFAULT 0,
SOFAR DOUBLE PRECISION DEFAULT 0,
TOTALWORK DOUBLE PRECISION DEFAULT 0,
TARGET_DESC TEXT DEFAULT 'unknown target',
UNITS TEXT DEFAULT NULL
)Процедура SET_SESSION_LONGOPS создаёт новую строку (или изменяет существующую) в представлении V_SESSION_LONGOPS. Каждая строка содержит информацию об одной длительной операции (как правило, выполняемой более 6 секунд): её описание, с какими объектами она работает и ожидаемое оставшееся время выполнения.
RINDEX: Индекс строки в представленииV_SESSION_LONGOPS. Чтобы создать новую строку, укажите в нём результат функцииDBMS_APPLICATION_INFO.SET_SESSION_LONGOPS_NOHINT(). Когда вы вызываетеSET_SESSION_LONGOPSдля изменения существующей строки, укажите в индексе значение, возвращённое при предыдущем вызове.SLNO: Служебная информация, сохраняемая между вызовами. Чтобы создать новую строку, установите значение NULL. Когда вы вызываетеSET_SESSION_LONGOPSдля изменения существующей строки, установите для данного параметра значение, возвращённое при предыдущем вызове.OP_NAME: Краткое описание выполняемой операции, обычно её имя.TARGET: OID объекта, который обрабатывается в ходе длительной операции.CONTEXT: Произвольное число, задаваемое пользователем.SOFAR: Произвольное число, задаваемое пользователем. Обычно это объём уже выполненной работы.TOTALWORK: Произвольное число, задаваемое пользователем. Обычно это общий ожидаемый объём работы.TARGET_DESC: Описание объекта, который обрабатывается в ходе длительной операции (TARGET).UNITS: Наименование единиц, в которых заданы параметрыSOFARиTOTALWORK.
Значения SOFAR и TOTALWORK используются для расчёта оставшегося времени выполнения в представлении V_SESSION_LONGOPS, но допустимыми значениями являются любые числа, поэтому при несогласованности этих значений (например, если оба значения отрицательные или TOTALWORK=0) оставшееся время выполнения рассчитываться не будет.
F.45.2.2.1. Представление V_SESSION_LONGOPS
Представление V_SESSION_LONGOPS содержит информацию о длительных операциях, переданную ранее процедурой SET_SESSION_LONGOPS. Представление содержит одну строку для каждой отдельной длительной операции. Каждая строка существует до тех пор, пока она не будет перезаписана или не будет остановлен сервер. После перезагрузки сервера представление пустое. Столбцы представления показаны в Таблице F.31. Для удобства в Postgres Pro также поддерживается эквивалентное представление с названием V$SESSION_LONGOPS, привычное для пользователей Oracle и содержащее ту же информацию. Кроме того, в этом представлении столбец P_TIMESTAMP был переименован в TIMESTAMP. Однако обратите внимание, что улучшенная совместимость с Oracle, обеспечиваемая этими альтернативами, является отклонением от стандарта SQL и поэтому делает код менее переносимым.
CREATE FUNCTION DBMS_APPLICATION_INFO.READ_V_SESSION_LONGOPS(
OUT SID INTEGER,
OUT SERIAL_N INTEGER,
OUT DBNAME TEXT,
OUT OPNAME TEXT,
OUT TARGET OID,
OUT TARGET_DESC TEXT,
OUT SOFAR DOUBLE PRECISION,
OUT TOTALWORK DOUBLE PRECISION,
OUT UNITS TEXT,
OUT START_TIME TIMESTAMP,
OUT LAST_UPDATE_TIME TIMESTAMP,
OUT P_TIMESTAMP TIMESTAMP,
OUT TIME_REMAINING INTEGER,
OUT ELAPSED_SECONDS INTEGER,
OUT CONTEXT INTEGER,
OUT MESSAGE TEXT,
OUT USERNAME TEXT
)
CREATE VIEW V_SESSION_LONGOPS AS SELECT * FROM DBMS_APPLICATION_INFO.READ_V_SESSION_LONGOPS();Таблица F.31. Столбцы V_SESSION_LONGOPS
| Имя | Описание |
|---|---|
SID | Идентификатор сеанса, в котором выполняется длительная операция. |
SERIAL_N | Синоним SID. Добавлен для совместимости с Oracle. |
DBNAME | Имя базы данных, к которой подключён сеанс. Если вы хотите получить строки только для текущей базы данных, добавьте в запрос следующее условие: WHERE DBNAME=current_database(). |
OPNAME | Краткое описание выполняемой операции, обычно её имя. |
TARGET | OID объекта, который обрабатывается в ходе длительной операции. |
TARGET_DESC | Описание объекта, который обрабатывается в ходе длительной операции (TARGET). |
SOFAR | Объём уже выполненной работы в единицах, указанных в UNITS. |
TOTALWORK | Общий ожидаемый объём работы в единицах, указанных в UNITS. |
UNITS | Наименование единиц, в которых заданы параметры SOFAR и TOTALWORK. |
START_TIME | Время начала выполнения операции (фактически — время создания данной строки) |
LAST_UPDATE_TIME | Время последнего изменения записи об операции. |
P_TIMESTAMP | Синоним для LAST_UPDATE_TIME. Добавлен для совместимости с Oracle. Для удобства можно использовать другое имя параметра, добавив псевдоним. Например, чтобы создать псевдоним TIMESTAMP, добавьте SELECT P_TIMESTAMP AS TIMESTAMP в определение представления. |
TIME_REMAINING | Ожидаемое оставшееся время выполнения операции (в секундах). Рассчитывается на основе значений SOFAR и TOTALWORK. Оставшееся время выполнения не будет рассчитываться, если эти значения несогласованны, SOFAR=0 или LAST_UPDATE_TIME совпадает с START_TIME. |
ELAPSED_SECONDS | Количество секунд, прошедших с начала выполнения операции (создания строки). |
CONTEXT | Число, заданное пользователем в качестве контекста. |
MESSAGE | Сообщение с краткой статистикой о ходе выполнения операции. |
USERNAME | Имя пользователя, выполняющего операцию. |
F.45.3. Пример
В нашем простом примере приложение будет действовать от имени ленивого мальчика, считающего ворон:
DO $$
DECLARE
rindex integer := DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS_NOHINT();
slno integer := NULL;
total_crows integer := 146;
BEGIN
CALL DBMS_APPLICATION_INFO.SET_CLIENT_INFO('Lazy boy');
CALL DBMS_APPLICATION_INFO.SET_MODULE('Crow counter', 'Prepare');
PERFORM pg_sleep(2);
CALL DBMS_APPLICATION_INFO.SET_ACTION('Count');
FOR i IN 1..total_crows LOOP
CALL DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS(
RINDEX=>rindex,
SLNO=>slno,
OP_NAME=>'Counting birds',
CONTEXT=>42,
SOFAR=>i,
TOTALWORK=>total_crows,
UNITS=>'birds'
);
PERFORM pg_sleep(0.4);
END LOOP;
CALL DBMS_APPLICATION_INFO.SET_ACTION(NULL);
END$$;Если запустить этот код в psql и обращаться к V_SESSION и V_SESSION_LONGOPS в другом сеансе, можно получить такие результаты:
postgres=# select * from v_session_longops; sid | serial_n | dbname | opname | target | target_desc | sofar | totalwork | units | start_time | last_update_time | p_timestamp | time_remaining | elapsed_seconds | context | message | username -----+----------+--------+--------+--------+-------------+-------+-----------+-------+------------+------------------+-------------+----------------+-----------------+---------+---------+---------- (0 rows) postgres=# select * from v_session; sid | dbname | module | action | client_info -----+--------+--------+--------+------------- (0 rows) postgres=# select * from v_session; sid | dbname | module | action | client_info ------+----------+--------------+---------+------------- 3721 | postgres | Crow counter | Prepare | Lazy boy (1 row) postgres=# select * from v_session; sid | dbname | module | action | client_info ------+----------+--------------+--------+------------- 3721 | postgres | Crow counter | Count | Lazy boy (1 row) postgres=# select * from v_session_longops; sid | serial_n | dbname | opname | target | target_desc | sofar | totalwork | units | start_time | last_update_time | p_timestamp | time_remaining | elapsed_seconds | context | message | username ------+----------+----------+----------------+--------+----------------+-------+-----------+-------+----------------------------+----------------------------+----------------------------+----------------+-----------------+---------+--------------------------------------+---------- 3721 | 3721 | postgres | Counting birds | 0 | unknown target | 52 | 146 | birds | 2023-05-12 14:24:19.013571 | 2023-05-12 14:24:39.458126 | 2023-05-12 14:24:39.458126 | 36 | 20 | 42 | Counting birds: 52 of 146 birds done | postgres (1 row) postgres=# select * from v_session_longops; sid | serial_n | dbname | opname | target | target_desc | sofar | totalwork | units | start_time | last_update_time | p_timestamp | time_remaining | elapsed_seconds | context | message | username ------+----------+----------+----------------+--------+----------------+-------+-----------+-------+----------------------------+---------------------------+---------------------------+----------------+-----------------+---------+--------------------------------------+---------- 3721 | 3721 | postgres | Counting birds | 0 | unknown target | 89 | 146 | birds | 2023-05-12 14:24:19.013571 | 2023-05-12 14:24:54.29141 | 2023-05-12 14:24:54.29141 | 22 | 35 | 42 | Counting birds: 89 of 146 birds done | postgres (1 row) postgres=# select * from v_session; sid | dbname | module | action | client_info ------+----------+--------------+--------+------------- 3721 | postgres | Crow counter | Count | Lazy boy (1 row) postgres=# select * from v_session_longops; sid | serial_n | dbname | opname | target | target_desc | sofar | totalwork | units | start_time | last_update_time | p_timestamp | time_remaining | elapsed_seconds | context | message | username ------+----------+----------+----------------+--------+----------------+-------+-----------+-------+----------------------------+----------------------------+----------------------------+----------------+-----------------+---------+---------------------------------------+---------- 3721 | 3721 | postgres | Counting birds | 0 | unknown target | 140 | 146 | birds | 2023-05-12 14:24:19.013571 | 2023-05-12 14:25:14.736656 | 2023-05-12 14:25:14.736656 | 2 | 55 | 42 | Counting birds: 140 of 146 birds done | postgres (1 row) postgres=# select * from v_session_longops; sid | serial_n | dbname | opname | target | target_desc | sofar | totalwork | units | start_time | last_update_time | p_timestamp | time_remaining | elapsed_seconds | context | message | username ------+----------+----------+----------------+--------+----------------+-------+-----------+-------+----------------------------+----------------------------+----------------------------+----------------+-----------------+---------+---------------------------------------+---------- 3721 | 3721 | postgres | Counting birds | 0 | unknown target | 146 | 146 | birds | 2023-05-12 14:24:19.013571 | 2023-05-12 14:25:17.140533 | 2023-05-12 14:25:17.140533 | 0 | 58 | 42 | Counting birds: 146 of 146 birds done | postgres (1 row) postgres=# select * from v_session; sid | dbname | module | action | client_info ------+----------+--------------+--------+------------- 3721 | postgres | Crow counter | | Lazy boy (1 row)
F.45. pgpro_application_info
pgpro_application_info is an extension designed to help developers who port applications using the DBMS_APPLICATION_INFO package from Oracle to Postgres Pro. It can also be used by database administrators as an additional source of data when analyzing performance and by developers when debugging.
pgpro_application_info creates procedures and functions that an application can use to report its status, performed actions, and action progress. The database administrator can access this information through specific views.
The typical sequence of client actions reporting to pgpro_application_info will look like this (in the example, a librarian wants to count all the words “the” in the library):
Once the client makes a connection to the database, it registers itself as the
Librarianand runs the scanner application, which, in its turn, registers itself as theBook Scannermodule and indicates that it is currently attempting to performBook Scanningto find all occurrences of the word “the” in 18042 books, having completed 0 scans as of now.Having scanned a few books, the application updates the information to reflect its progress.
When the scanning is completed, the application registers this fact and sets its current action as
Idle(or NULL).
F.45.1. Installation
The pgpro_application_info extension is a built-in extension included into Postgres Pro Enterprise. To enable pgpro_application_info, do the following:
Add the library name to the
shared_preload_librariesvariable in thepostgresql.conffile:shared_preload_libraries = 'pgpro_application_info'
Reload the database server for the changes to take effect.
Note
To verify that the library was installed correctly, you can run the following command:
SHOW shared_preload_libraries;
Create the extension using the following query:
CREATE EXTENSION pgpro_application_info;
F.45.2. Usage
pgpro_application_info handles the following main data classes:
Application Data: current module name, performed action, and client description. The database administrator can access the information about active clients and their actions via the V_SESSION view.
Information about Long Operations: textual descriptions and comments, operation progress report and optionally the link to the database object in question. The database administrator can access the information about long operations via the V_SESSION_LONGOPS view, which in addition to the data sent by the client contains operation start and latest update timestamps, as well as the estimated time remaining.
Note
Note that in Oracle's DBMS_APPLICATION_INFO textual parameters supplied by the user have various maximum length up to 64 bytes, but for convenience in pgpro_application_info all of them have the same maximum length of 64 bytes. Exceeding information is truncated.
F.45.2.1. Application Data
To set application information, pgpro_application_info provides the following procedures:
-
CREATE PROCEDURE DBMS_APPLICATION_INFO.SET_CLIENT_INFO(client_info TEXT) Sets the client information. This is typically the client name or a more complex description, but strictly speaking, it can be any text provided by the user.
-
CREATE PROCEDURE DBMS_APPLICATION_INFO.SET_ACTION(action_name TEXT) Sets the name of the executed action in the current module.
-
CREATE PROCEDURE DBMS_APPLICATION_INFO.SET_MODULE(module_name TEXT, action_name TEXT DEFAULT NULL) Sets the name of the current module (program) and action. When the program terminates, call this procedure with the name of the next module if there is one, or NULL otherwise.
-
CREATE PROCEDURE DBMS_APPLICATION_INFO.READ_CLIENT_INFO(OUT client_info TEXT) Returns the client information previously set by
SET_CLIENT_INFOin the current session.-
CREATE PROCEDURE DBMS_APPLICATION_INFO.READ_MODULE(OUT module_name TEXT, OUT action_name TEXT) Returns the module information previously set by
SET_MODULEand action information set bySET_MODULEorSET_ACTIONin the current session.
F.45.2.1.1. The V_SESSION View
The V_SESSION view provides the information about all the active sessions reported via pgpro_application_info procedures, the connected clients, modules, and current actions. The view contains one row for each distinct session. When a session reports its information for the first time, the corresponding view entry is created. Each row exists during the corresponding session lifetime so the view is empty after server restart. The columns of the view are shown in Table F.30. For ease of use, Postgres Pro also provides an equivalent view called V$SESSION, familiar to Oracle users, which contains the same information. Note, however, that better compatibility with Oracle provided by this alternative is a deviation from the SQL standard and, consequently, makes the code less portable.
CREATE FUNCTION DBMS_APPLICATION_INFO.READ_V_SESSION(
OUT SID INTEGER,
OUT DBNAME TEXT,
OUT MODULE TEXT,
OUT ACTION TEXT,
OUT CLIENT_INFO TEXT
)
CREATE VIEW V_SESSION AS SELECT * FROM DBMS_APPLICATION_INFO.READ_V_SESSION();
Table F.30. V_SESSION Columns
| Name | Description |
|---|---|
SID | Session ID, PID |
DBNAME | Name of the database the session is connected to. If you want to view the entries only for the current database, add the following condition to the query: WHERE DBNAME=current_database(). |
MODULE | Name of the module executed by the session that was previously set by SET_MODULE. |
ACTION | Name of the action executed by the session that was previously set by SET_MODULE or SET_ACTION. |
CLIENT_INFO | Information about the client associated with the session that was previously set by SET_CLIENT_INFO. |
F.45.2.2. Information about Long Operations
CREATE PROCEDURE DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS(
INOUT RINDEX INTEGER,
INOUT SLNO INTEGER,
OP_NAME TEXT DEFAULT NULL,
TARGET OID DEFAULT 0,
CONTEXT INTEGER DEFAULT 0,
SOFAR DOUBLE PRECISION DEFAULT 0,
TOTALWORK DOUBLE PRECISION DEFAULT 0,
TARGET_DESC TEXT DEFAULT 'unknown target',
UNITS TEXT DEFAULT NULL
)
The SET_SESSION_LONGOPS procedure creates a new row (or updates the existing one) in the V_SESSION_LONGOPS view. Each row contains information about a single long operation (typically longer than 6 seconds): its description, the accessed objects, and the estimated time remaining.
RINDEX: A token which represents the row in theV_SESSION_LONGOPSview. To start a new row, set this to the result of theDBMS_APPLICATION_INFO.SET_SESSION_LONGOPS_NOHINT()function. When you callSET_SESSION_LONGOPSto update the existing row, set this to the returned value from the prior call.SLNO: Internal information saved between calls. To start a new row, set this to NULL. When you callSET_SESSION_LONGOPSto update the existing row, set this to the returned value from the prior call.OP_NAME: Short description of the performed operation, usually its name.TARGET: OID of the object that is being worked on during the long-running operation.CONTEXT: Any number the user wants to store.SOFAR: Any number the user wants to store. This is typically the amount of work which has been done so far.TOTALWORK: Any number the user wants to store. This is typically the amount of work to be done.TARGET_DESC: The description of the object that is being worked on during the long-running operation (TARGET).UNITS: The units in whichSOFARandTOTALWORKare represented.
SOFAR and TOTALWORK values are used to calculate the estimated time remaining in the V_SESSION_LONGOPS view, but valid values are any numbers so if they are inconsistent (for example, both values are negative, or TOTALWORK=0), the estimated time remaining will not be calculated.
F.45.2.2.1. The V_SESSION_LONGOPS View
The V_SESSION_LONGOPS view provides the information about long operations previously passed by SET_SESSION_LONGOPS. The view contains one row for each distinct long operation. Each row exists until it is rewritten or the server is shut down. The view is empty after server restart. The columns of the view are shown in Table F.31. For ease of use, Postgres Pro also provides an equivalent view called V$SESSION_LONGOPS, familiar to Oracle users, which contains the same information. Also, the P_TIMESTAMP column was renamed TIMESTAMP in this view. Note, however, that better compatibility with Oracle provided by these alternatives is a deviation from the SQL standard and, consequently, makes the code less portable.
CREATE FUNCTION DBMS_APPLICATION_INFO.READ_V_SESSION_LONGOPS(
OUT SID INTEGER,
OUT SERIAL_N INTEGER,
OUT DBNAME TEXT,
OUT OPNAME TEXT,
OUT TARGET OID,
OUT TARGET_DESC TEXT,
OUT SOFAR DOUBLE PRECISION,
OUT TOTALWORK DOUBLE PRECISION,
OUT UNITS TEXT,
OUT START_TIME TIMESTAMP,
OUT LAST_UPDATE_TIME TIMESTAMP,
OUT P_TIMESTAMP TIMESTAMP,
OUT TIME_REMAINING INTEGER,
OUT ELAPSED_SECONDS INTEGER,
OUT CONTEXT INTEGER,
OUT MESSAGE TEXT,
OUT USERNAME TEXT
)
CREATE VIEW V_SESSION_LONGOPS AS SELECT * FROM DBMS_APPLICATION_INFO.READ_V_SESSION_LONGOPS();
Table F.31. V_SESSION_LONGOPS Columns
| Name | Description |
|---|---|
SID | ID of the session processing the long-running operation. |
SERIAL_N | Synonym for SID. Added for Oracle-compatibility reasons. |
DBNAME | Name of the database the session is connected to. If you want to view the rows only for the current database, add the following condition to the query: WHERE DBNAME=current_database(). |
OPNAME | Short description of the performed operation, usually its name. |
TARGET | OID of the object that is being worked on during the long-running operation. |
TARGET_DESC | The description of the object that is being worked on during the long-running operation (TARGET). |
SOFAR | The amount of work which has been done so far in units specified in UNITS. |
TOTALWORK | The amount of work to be done in units specified in UNITS. |
UNITS | The units in which SOFAR and TOTALWORK are represented. |
START_TIME | Operation start time (or the time the row was created). |
LAST_UPDATE_TIME | Last row update time. |
P_TIMESTAMP | Synonym for LAST_UPDATE_TIME. Added for Oracle-compatibility reasons. For convenience, you can use another parameter name by adding an alias. For example, to create a TIMESTAMP alias, add SELECT P_TIMESTAMP AS TIMESTAMP to the view definition. |
TIME_REMAINING | Estimate of time remaining for the operation to complete (in seconds). Calculated based on SOFAR and TOTALWORK values. The estimated time remaining will not be calculated, if these values are inconsistent, SOFAR=0, or LAST_UPDATE_TIME is the same as START_TIME. |
ELAPSED_SECONDS | Number of elapsed seconds from the operation start (row creation). |
CONTEXT | The number set by the user as the context. |
MESSAGE | Statistics summary message about the operation progress. |
USERNAME | Name of the user performing the operation. |
F.45.3. Example
In our simple example, the application represents a lazy boy counting crows:
DO $$
DECLARE
rindex integer := DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS_NOHINT();
slno integer := NULL;
total_crows integer := 146;
BEGIN
CALL DBMS_APPLICATION_INFO.SET_CLIENT_INFO('Lazy boy');
CALL DBMS_APPLICATION_INFO.SET_MODULE('Crow counter', 'Prepare');
PERFORM pg_sleep(2);
CALL DBMS_APPLICATION_INFO.SET_ACTION('Count');
FOR i IN 1..total_crows LOOP
CALL DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS(
RINDEX=>rindex,
SLNO=>slno,
OP_NAME=>'Counting birds',
CONTEXT=>42,
SOFAR=>i,
TOTALWORK=>total_crows,
UNITS=>'birds'
);
PERFORM pg_sleep(0.4);
END LOOP;
CALL DBMS_APPLICATION_INFO.SET_ACTION(NULL);
END$$;
If you run this code in psql and access V_SESSION and V_SESSION_LONGOPS in another session, you can get the following output:
postgres=# select * from v_session_longops; sid | serial_n | dbname | opname | target | target_desc | sofar | totalwork | units | start_time | last_update_time | p_timestamp | time_remaining | elapsed_seconds | context | message | username -----+----------+--------+--------+--------+-------------+-------+-----------+-------+------------+------------------+-------------+----------------+-----------------+---------+---------+---------- (0 rows) postgres=# select * from v_session; sid | dbname | module | action | client_info -----+--------+--------+--------+------------- (0 rows) postgres=# select * from v_session; sid | dbname | module | action | client_info ------+----------+--------------+---------+------------- 3721 | postgres | Crow counter | Prepare | Lazy boy (1 row) postgres=# select * from v_session; sid | dbname | module | action | client_info ------+----------+--------------+--------+------------- 3721 | postgres | Crow counter | Count | Lazy boy (1 row) postgres=# select * from v_session_longops; sid | serial_n | dbname | opname | target | target_desc | sofar | totalwork | units | start_time | last_update_time | p_timestamp | time_remaining | elapsed_seconds | context | message | username ------+----------+----------+----------------+--------+----------------+-------+-----------+-------+----------------------------+----------------------------+----------------------------+----------------+-----------------+---------+--------------------------------------+---------- 3721 | 3721 | postgres | Counting birds | 0 | unknown target | 52 | 146 | birds | 2023-05-12 14:24:19.013571 | 2023-05-12 14:24:39.458126 | 2023-05-12 14:24:39.458126 | 36 | 20 | 42 | Counting birds: 52 of 146 birds done | postgres (1 row) postgres=# select * from v_session_longops; sid | serial_n | dbname | opname | target | target_desc | sofar | totalwork | units | start_time | last_update_time | p_timestamp | time_remaining | elapsed_seconds | context | message | username ------+----------+----------+----------------+--------+----------------+-------+-----------+-------+----------------------------+---------------------------+---------------------------+----------------+-----------------+---------+--------------------------------------+---------- 3721 | 3721 | postgres | Counting birds | 0 | unknown target | 89 | 146 | birds | 2023-05-12 14:24:19.013571 | 2023-05-12 14:24:54.29141 | 2023-05-12 14:24:54.29141 | 22 | 35 | 42 | Counting birds: 89 of 146 birds done | postgres (1 row) postgres=# select * from v_session; sid | dbname | module | action | client_info ------+----------+--------------+--------+------------- 3721 | postgres | Crow counter | Count | Lazy boy (1 row) postgres=# select * from v_session_longops; sid | serial_n | dbname | opname | target | target_desc | sofar | totalwork | units | start_time | last_update_time | p_timestamp | time_remaining | elapsed_seconds | context | message | username ------+----------+----------+----------------+--------+----------------+-------+-----------+-------+----------------------------+----------------------------+----------------------------+----------------+-----------------+---------+---------------------------------------+---------- 3721 | 3721 | postgres | Counting birds | 0 | unknown target | 140 | 146 | birds | 2023-05-12 14:24:19.013571 | 2023-05-12 14:25:14.736656 | 2023-05-12 14:25:14.736656 | 2 | 55 | 42 | Counting birds: 140 of 146 birds done | postgres (1 row) postgres=# select * from v_session_longops; sid | serial_n | dbname | opname | target | target_desc | sofar | totalwork | units | start_time | last_update_time | p_timestamp | time_remaining | elapsed_seconds | context | message | username ------+----------+----------+----------------+--------+----------------+-------+-----------+-------+----------------------------+----------------------------+----------------------------+----------------+-----------------+---------+---------------------------------------+---------- 3721 | 3721 | postgres | Counting birds | 0 | unknown target | 146 | 146 | birds | 2023-05-12 14:24:19.013571 | 2023-05-12 14:25:17.140533 | 2023-05-12 14:25:17.140533 | 0 | 58 | 42 | Counting birds: 146 of 146 birds done | postgres (1 row) postgres=# select * from v_session; sid | dbname | module | action | client_info ------+----------+--------------+--------+------------- 3721 | postgres | Crow counter | | Lazy boy (1 row)