Расширение позволяет устанавливать динамические пробы на функции PostgreSQL в user space и детально исследовать внутреннюю работу СУБД.
Проб | Имя | Описание |
---|---|---|
TIME | Время выполнения функции | Данный тип проб позволяет отслеживать среднее время выполнения функции и количество вызовов функции. |
HIST | Гистограмма времени выполнения функции | Собирается информация о времени выполнения функции в виде гистограммы. Это позволяет более детально изучить как работает функция при разных обстоятельствах. |
MEM | Информация о том как изменялась память при вызове функции | Собирается информация о том как меняется память до входа в функцию и после выхода из неё. |
Чтобы проверить, находится ли необходимая вам функция в ELF файле, можно воспользоваться следующими командами:
objdump:
objdump -T /opt/pgpro/ent-15/bin/postgres
objdump -T /opt/pgpro/ent-15/bin/postgres | awk '{ print $7 }'
readelf:
readelf -s -W /opt/pgpro/ent-15/bin/postgres
readelf -s -W /opt/pgpro/ent-15/bin/postgres | awk '{ print $8 }'
nm:
nm -D --demangle /opt/pgpro/ent-15/bin/postgres
nm -D --demangle /opt/pgpro/ent-15/bin/postgres | awk '{ print $NF }'
Где /opt/pgpro/ent-15/bin/postgres - путь до установленных бинарников PostgreSQL.
Чтобы установить пробу, необходимо воспользоваться следующей sql
функцией:
set_uprobe(IN func text, IN uprobe_type text, IN is_shared boolean);
Аргумент | Описание |
---|---|
func | Название функции из исполняемого файла или подгружаемой библиотеки |
uprobe_type | Тип пробы
|
is_shared | Признак установки пробы на текущий сеанс или на все новые сеансы
|
При корректном завершении set_uprobe
возвращает имя func.
Чтобы посмотреть все установленные пробы, необходимо воспользоваться следующим запросом:
select list_uprobes();
Запрос возвращает набор строк, в каждой строке содержится запись, которая соответствует одному установленному пробу.
Запись имеет вид:
(func, uprobe_type, is_shared)
Аргумент | Описание |
---|---|
func | Название функции из исполняемого файла или подгружаемой библиотеки |
uprobe_type | см. типы проб |
is_shared | Признак установки пробы на текущий сеанс или на все новые сеансы
|
Чтобы получить информации о пробе, установленной на текущем сеансе, необходимо воспользоваться следующей sql
функцией:
stat_time_uprobe(IN func text)
Аргумент | Описание |
---|---|
func | Название функции из исполняемого файла или подгружаемой библиотеки |
При корректном завершении возвращает строку вида:
"calls: {количество вызовов функции} avg time: {среднее время выполнения функции} ns"
.
Чтобы получить гистограмму времени выполнения функции, необходимо воспользоваться следующей sql
функцией:
stat_hist_uprobe( IN func text, IN start double precision, IN stop double precision, IN step double precision)
Аргумент | Описание |
---|---|
func | Название функции из исполняемого файла или подгружаемой библиотеки |
start | Значение в микросекундах, с которого нужно начать строить гистограмму. Если функция выполнялась меньше указанного значения, то эти времена не попадут в итоговую гистограмму |
stop | Значение в микросекундах, на котором нужно закончить строить гистограмму. Если функция выполнялась больше указанного значения, то эти времена не попадут в итоговую гистограмму |
step | Значение в микросекундах, шаг гистограммы |
Если параметры start, stop, step для прошлой функции не известны заранее, то можно воспользоваться функцией, которая подберет их автоматически:
stat_hist_uprobe( IN func text)
Аргумент | Описание |
---|---|
func | Название функции из исполняемого файла или подгружаемой библиотеки |
При корректном завершении возвращает набор строк, который в psql
будет выглядеть как гистограмма, аналогичная выводу bpftrace
.
- time_range - Интервал времени
- hist_entry - Строка для красоты забитая '@', один символ за 2% из percent
- percent - Процент измерений, который попал в данный интервал
Примечание: Чтобы гистограмма была выравненной, нужно получать данные из функции, а не вызывать её напрямую. Правильный вариант:
select * from stat_hist_uprobe('PortalStart');
Основное отличие от профилирования собственного процесса заключается в том, что результат профилирования будет доступен на файловой системе, а не сразу в виде результата функций.
Чтобы получить результаты профилирования для всех сеансов, необходимо воспользоваться следующей функцией:
dump_uprobe_stat(IN func text, IN should_empty_stat boolean)
Аргумент | Описание |
---|---|
func | Название функции из исполняемого файла или подгружаемой библиотеки |
should_empty_stat | Признак сброса собранной информации.
|
При корректном завершении в каталоге pg_uprobe.data_dir создается файл с собранной информацией. Для каждого типа проб свой формат:
Тип пробы | Описание файла |
---|---|
TIME | Имя файла: TIME_{func}.txt В файле строка вида: num calls: {количество вызовов функции} avg time: {среднее время выполнения функции} nanosec |
HIST | Имя файла: HIST_{func}.txt В файле строки вида: time,count
|
MEM | Имя файла: MEM_{func}.txt В файле строки вида: memory,count
|
Чтобы удалить пробу, необходимо воспользоваться следующей функцией:
delete_uprobe(IN func text, IN should_write_stat boolean)
Аргумент | Описание |
---|---|
func | Название функции из исполняемого файла или подгружаемой библиотеки |
should_write_stat | Только когда профилируем множество сеансов. Если true, то перед удалением пробы собирается результаты профилирования для всех сеансов аналогично функции |
Важно отметить, что сам проб удаляется только на текущем сеансе. С остальных сеансов проб не будет удален, но на новых уже появляться не будет.