pldebugger. Средство отладки plpgsql
Версия: 1.1.
В исходном дистрибутиве установлено по умолчанию: нет.
Связанные компоненты: plpgsql.
Схема размещения:
ext
.
pldebugger
предоставляет API для выполнения функций с возможностью остановки в заданной точке, пошаговым выполнением, просмотром значений переменных.
Расширение интегрировано с инструментами pg_admin
и dbeaver
, которые предлагают графический интерфейс для разработки и отладки с использованием возможностей расширения. Функции API доступны напрямую из psql
, так как реализованы в виде стандартных SQL-функций.
Доработка
Не производилась.
Ограничения
Для корректной работы pldebugger
необходимо наличие plpgsql
- расширения по работе с plpgsql
.
Так как расширение позволяет перехватывать выполнение кода функций и процедур для отладки, а также видеть значения переменных и управлять процессами управления, его использование доступно только суперпользователю и не рекомендуется в промышленной среде.
Установка
- SberLinux, РЕД ОС, CentOS
- Red Hat Enterprise Linux
- Astra Linux
- Альт СП
sudo dnf install pangolin-pldebugger-{version_component}-{OS}.x86_64.rpm
sudo yum install pangolin-pldebugger-{version_component}-{OS}.x86_64.rpm
sudo apt install pangolin-pldebugger-{version_component}_amd64.deb
sudo apt-get install pangolin-pldebugger-{version_component}-{OS}.x86_64.rpm
Пример заполненной команды:
cd distributive
sudo apt-get -y install pangolin-pldebugger-1.1-sberlinux8.x86_64.rpm
Расширение использует общую разделяемую память сервера, поэтому должно быть добавлено в shared_preload_libraries
:
shared_preload_libraries = 'plugin_debugger'
Для использования расширения на развернутой СУБД необходимо установить его в целевую БД:
CREATE EXTENSION pldebugger SCHEMA ext;
С помощью ключевого слова SCHEMA
можно задать целевую схему для расширения, если этого аргумента нет — расширение будет установлено в первую найденную схему из search_path
.
Настройка
В случае, если расширение используется совместно с расширением plpgsql_check, библиотека расширения должна быть указана первой при перечислении в shared_preload_libraries
:
shared_preload_libraries = 'plugin_debugger,plpgsql_check'
::: admonition Примечание :class: note
Поскольку расширение реализует API для отладки функций и процедур, для работы с ним нужно использовать внешние графические инструменты. В настоящее время работа с данным расширением реализована в pgAdmin4
и DBeaver
(в редакции Enterprise). При необходимости возможно использование функций расширения непосредственно в сеансе psql
.
:::
Архитектура отладчика PL/pgSQL
Отладчик PL/pgSQL реализован в виде трех взаимодействующих компонентов:
- Клиент — среда, в которой вызываются функции API. Обычно представляет собой графический интерфейс пользователя, который отображает исходный код, текущий стек вызовов, переменные и другие элементы, а также позволяет устанавливать точки останова и выполнять код пошагово. Клиент может работать на удаленной машине, отличной от той, где размещен сервер базы данных, например
PgAdmin
. - Целевой сервер — серверная часть, которая запускает отлаживаемый код. Для обеспечения возможности отладки в него должна быть загружена библиотека
plugin_debugger.so
. - Отладочный прокси — дополнительный серверный процесс, к которому подключает клиент. На нем выполняются функции API, методы
pl_dbg*
, а также библиотекиpldbgapi.so
.
Клиент устанавливает обычное соединение через драйвер (libpq
или jdbc
) с отладочным прокси, как если бы подключался к обычной базе данных. После установки соединения, прокси вызывает функции API библиотеки plugin_debugger.so
, которая в свою очередь подключается к целевому серверу на уровне ядра, прозрачным для клиента образом. Протокол между прокси и целевым сервером не видим для других пользователей. Методы pldbg_*
из библиотек API предоставляют доступный интерфейс к средствам отладки.
Доступ к данным методам осуществляется при помощи SQL-функций, предоставляемых расширением. Доступ к этим функциям не ограничивается какими-либо дополнительными механизмами контроля — любой пользователь, имеющий право аутентификации и вызова соответствующих SQL-функций, может перехватить выполнение функции в любом сеансе при наличии информации об ее OID
.
Ниже представлена схема взаимодействия компонентов отладчика:
debugger client *------ libpq --------* Proxy backend
(pgAdmin) *
|
pldebugger socket connection
|
*
application client *----- libpq -------* Target backend
Функции расширения
Функции pldebugger
Имя функции | Аргументы | Тип возвращаемого значения | Описание |
pldbg_abort_target | session integer | boolean | Останавливает выполнение/отладку кода в сессии с переданным в аргументе PID . Возвращает true или false в зависимости от успешности остановки |
pldbg_attach_to_port | portnumber integer | integer | Функция подключается к целевому объекту отладки, прослушивающему заданный порт. Клиент отладчика вызывает эту функцию в ответ на уведомление PLDBGBREAK (уведомление содержит номер порта, к которому необходимо подключиться). Функция возвращает дескриптор сеанса, который идентифицирует конкретный сеанс отладки. При вызове любой из функций с префиксом pldbg_* , нужно указать дескриптор сеанса, возвращаемый функцией pldbg_attach_to_port() . Клиент отладчика может поддерживать несколько одновременных сеансов благодаря многократному вызову pldbg_attach_to_port() (с разными номерами портов) и отслеживанию возвращаемых дескрипторов сеанса |
pldbg_continue | session integer | breakpoint | Функция отправляет команду continue целевому объекту отладчика, а затем ожидает, пока он достигнет следующего исполняемого оператора. На выходе возвращается запись типа breakpoint , характеризующая точку останова и содержащая идентификатор функции, а также номер строки, в которой целевой объект в данный момент остановлен |
pldbg_create_listener | Отсутствуют | integer | Функция создает сеанс отладки. Возвращает id сессии сеанса отладки |
pldbg_deposit_value | session integer varname text linenumber integer value text | boolean | Функция перезаписывает значение заданной переменной (идентифицируемой по имени и номеру строки). Аргумент value определяется как выражение, результатом которого должно быть значение с типом, аналогичным типу заданной переменной (или приводимым к нему типом) |
pldbg_drop_breakpoint | session integer func oid linenumber integer | boolean | Функция удаляет локальную точку останова в целевом процессе |
pldbg_get_breakpoints | session integer | setof breakpoint | Функция возвращает набор точек останова. Каждая запись в результирующем наборе идентифицирует точку останова |
pldbg_get_proxy_info | Отсутствуют | proxyinfo | Функция извлекает небольшую коллекцию параметров с сервера, которые связаны с версией сервера и версией протокола API , реализованного расширением для взаимодействия с ним внешних графических инструментов (например, pgAdmin ). Функция может быть вызвана (из клиентского процесса отладчика), чтобы узнать, с какой версией прокси-API происходит взаимодействие — если этой функции не существует, можно предположить, что обмен данными осуществляется с прокси-API версии 1 |
pldbg_get_source | session integer func oid | text | Функция возвращает исходный код для заданной функции. Клиент отладчика всегда должен извлекать исходный код, вызывая данную функцию, вместо чтения pg_proc . Если вместо этого производится чтение pg_proc , то считываемый исходный код может не совпадать с исходным кодом, фактически выполняемым целевым объектом (поскольку исходный код мог быть изменен в другой транзакции). pldbg_get_source() всегда извлекает исходный код из целевого объекта и гарантирует, что получаемый на выходе исходный код является исходным кодом, выполняемым целевым объектом |
pldbg_get_stack | session integer | setof frame | Функция возвращает набор записей, каждая из которых описывает один фрейм в стеке вызовов. В каждой записи содержится информация о соответствующем фреймворке, включая строковое представление, пригодное для отображения имени и значения каждого аргумента конкретного вызова. |
pldbg_get_target_info | signature text targettype char | targetinfo | Устаревшая функция, которая возвращает информацию о целевой отлаживаемой функции. Используется для обратной совместимости со старыми версиями pgAdmin . Для новых приложений получение информации из каталога происходит напрямую |
pldbg_get_variables | session integer | setof var | Функция возвращает набор записей var . Записи в результирующем наборе содержат информацию об одной рассматриваемой локальной переменной (или параметре) во фреймворке стека. Каждая запись содержит имя переменной, номер строки, в которой была объявлена переменная, а также флаг, сообщающий, является ли имя уникальным в пределах области действия функции. Если имя не является уникальным, клиент отладчика может использовать номер строки для различия переменных с одинаковыми именами. Также каждая запись содержит флаг, используемый для определения, является ли переменная константной; флаг, определяющий, является ли переменная нулевой, а также тип данных переменной (OID соответствующего pg_type ) с ее значением. Чтобы просмотреть переменные, определенные в другом фреймворке стека, необходимо вызвать pldbg_select_frame() для переключения внимания отладчика на конкретный фреймворк |
pldbg_oid_debug | functionoid oid | integer | Функция получает информацию о функции с переданным OID из pg_proc и в случае, если функция найдена, информация о ней получена, а пользователь, запустивший ее является суперпользователем, устанавливается локальная точка останова в начале данной функции. В случае успеха возвращается 0, в противном случае - код ошибки |
pldbg_select_frame | session integer frame integer | breakpoint | Функция изменяет цель отладчика на указанный кадр (в стеке вызовов). При остановке отладчик переключается на наиболее глубоко вложенную функцию в стеке вызовов (так как это функция, которая выполняется в данный момент времени). Цель отладчика можно изменить на другие фреймворки стека с целью получения исходного кода для этого фреймворка, значения переменных в этом фреймворке и точек останова в целевом объекте. Отладчик остается на выбранном кадре до тех пор, пока он не будет изменен пользователем или пока целевой объект не остановится на другой точке останова. Функция возвращает запись типа breakpoint , содержащую идентификатор функции и номер строки, на которой целевой объект в данный момент остановлен |
pldbg_set_breakpoint | session integer func oid linenumber integer | boolean | Функция регистрирует локальную точку останова в целевом процессе |
pldbg_set_global_breakpoint | session integer func oid linenumber integer targetpid integer | boolean | Функция регистрирует точку останова в глобальной структуре с точками останова. На вход принимает id сессии, в которой запущен отладчик, OID функции, которую планируется отлаживать, номер строки функции, на которую устанавливается точка останова, а также PID целевого процесса, в котором будет выполняться отлаживаемая функция |
pldbg_step_into | session integer | breakpoint | Функция отправляет команду step/into целевому объекту отладчика, а затем ожидает, пока целевой объект достигнет следующего исполняемого оператора, и возвращает запись типа breakpoint |
pldbg_step_over | session integer | breakpoint | Функция отправляет команду step/over целевому объекту отладчика, а затем ожидает, пока целевой объект достигнет следующего исполняемого оператора в текущей функции. Если целевой объект столкнется с точкой останова (например, в дочернем вызове) до перехода к следующей исполняемой строке, он остановится на точке останова. Функция возвращает запись типа breakpoint |
pldbg_wait_for_breakpoint | session integer | breakpoint | Функция ожидает, пока целевой объект отладки достигнет точки останова. Необходимо вызвать функцию сразу после того, как pldbg_attach_to_port() вернет идентификатор сеанса. Функция pldbg_wait_for_breakpoint() почти идентична функциям pldbg_step_into() , pldbg_step_over() и pldbg_continue() (все они ожидают целевого объекта), но эта функция не отправляет команду целевому объекту первой. |
pldbg_wait_for_target | session integer | integer | Функция объявляет прокси-процесс активным отладчиком, ожидающим глобальных точек останова и возвращает дескриптор сеанса, который идентифицирует конкретный сеанс отладки. Когда вызывается любая из других функций pldbg , необходимо указать соответствующий дескриптор сеанса. Данный клиент отладчика может поддерживать несколько одновременных сеансов, вызывая pldbg_attach_to_port() много раз (с разными номерами портов) и отслеживая возвращаемые дескрипторы сеанса |
plpgsql_oid_debug | functionoid oid | integer | Оболочка функции pldbg_oid_debug (functionoid oid) создана для обратной совместимости со старыми версиями pgAdmin |
Типы данных расширения
Типы, добавляемые расширением:
breakpoint
frame
proxyinfo
targetinfo
var
Управление
Решение не оказывает влияния на кластерную архитектуру СУБД Pangolin, включая потоковую и логическую репликацию, процессы резервного копирования, интеграцию с СРК, а также сохраняет полную обратную совместимость с текущей версией СУБД Pangolin.
Поскольку решение предоставляет возможность перехвата исполнения функций и доступа к полному стеку выполнения plpgsql
кода, необходимо обеспечить аудит вызовов функций из задействованных расширений.
Использование модуля
Отладка кода с помощью pgAdmin
-
Запустите
pgAdmin
, подключитесь к БД. -
В
pgAdmin
найдите в дереве объектов БД функциюget_count(text, int)
, в опциях, доступных через выпадающее менюDebugging
, установите режимSet breakpoint
.Результат — открылось окно отладчика, в другой сессии ожидается запуск целевой функции.
-
Откройте новую сессию
psql
и подключитесь к демонстрационной БД. -
В
psql
вызовите функцию:select * from get_count('pg_class', 2);.
Результат — сессия
psql
зависла на выполнении функции. -
Перейдите в окно отладки
pgAdmin
.Результат — в окне отладчика появился код функции, выделена строка, на которой в данный момент остановлено выполнение функции.
-
В отладчике осуществите
step into
.Результат — в окне отладчика выделена следующая строка, на которой остановилось выполнение функции.
-
Проверьте вкладки с отладочной информацией.
Результат — во вкладках с отладочной информацией отображается актуальная информация, включающая номер текущей строки, значения аргументов функции, значения локальных переменных функции и др.
-
В отладчике выберите строку с номером 10 и установите точку останова, нажав на область рядом с номером строки левой кнопкой мыши.
Результат — на выбранной строке появился символ точки останова рядом с номером строки.
-
В отладчике нажмите кнопку
continue
.Результат — выполнение функции продолжилось до точки останова.
-
В отладчике осуществите
step into
.Результат — в отладчике появился код вложенной функции и ее стек, курсор установлен на первой строке функции.
-
В отладчике нажмите кнопку
continue
.Результат — выполнился код вложенной функции, в отладчике появился код родительской функции, выполнение остановилось на следующей после вызова вложенной функции строке.
-
В отладчике осуществите
step over
.Результат — выполнился код вложенной функции без перехода в нее, выполнение остановилось на следующей строке.
-
В отладчике нажмите кнопку
stop
.Результат — выполнение функции прервалось, в консоли
psql
появилось сообщение о том, что выполнение функции остановлено администратором. -
Закройте вкладку отладчика, закройте
pgAdmin
, закройтеpsql
.
Отключение функциональности
Для отключения данной функциональности необходимо:
- Удалить расширение командой:
DROP EXTENSION pldebugger;
- Убрать библиотеку расширения
plugin_debugger
изshared_preload_libraries
. - Перезагрузить сервер СУБД:
pg_ctl restart
Ссылки на документацию разработчика
pldebugger: https://github.com/EnterpriseDB/pldebugger.