auto_dump. Сбор и воспроизведение проблемных запросов
В исходном дистрибутиве установлено по умолчанию: нет.
Связанные компоненты: отсутствуют.
Схема размещения: не используется.
Данное расширение реализует процесс получения воспроизведения медленного выполнения запроса без использования платформы 1С:Предприятие. Расширение:
- Формирует выгрузку таблиц, которые используются в запросе. Можно включать в выгрузку, как временные таблицы, так и постоянные таблицы;
- Создает SQL-запрос для переноса и подготовки данных для воспроизведения проблемного запроса;
- Создает файл проблемного SQL-запроса для его воспроизведения и получает его план выполнения (с помощью команды
EXPLAIN).
Доработка
Доработка не проводилась.
Установка
Для начала использования расширения выполните следующие действия:
-
Пропишите в конфигурационном файле (
postgresql.conf/postgres.yml) СУБД Pangolin название расширения в настроечный параметрshared_preload_libraries:shared_preload_libraries = 'auto_dump' -
Включите расширение путем заполнения основного конфигурационного параметра:
auto_dump.enable = on -
Настройте расширение, для этого выполните конфигурирование дополнительных параметров.
-
Выполните перезапуск сервера:
systemctl restart postgresql -
Далее расширение нужно установить в целевую БД командой:
CREATE EXTENSION auto_dump;
Настройка
Конфигурационные параметры
Основные параметры
Параметр | Тип данных | Значение по умолчанию | Описание |
|---|---|---|---|
|
|
| Признак включения расширения |
|
| – | Путь директории, в которую будут сохраняться файлы с дампами таблиц. Параметр обязателен для настройки. У пользователя, под которым запущена служба СУБД, должны быть права на доступ к этой директории |
Параметры, определяющие объем данных в дампе
Параметр | Тип данных | Значение по умолчанию | Описание |
|---|---|---|---|
|
|
| При включении параметра в дамп будут добавлены временные таблицы сессии, участвующие в текущем запросе |
|
|
| При включении параметра в дамп будут добавлены все постоянные таблицы, участвующие в текущем запросе |
|
|
| При включении параметра в дамп будут добавлены все временные таблицы сессии, в том числе и участвующие в текущем запросе |
|
|
| При включении параметра в дамп будет записано содержимое таблиц, для которых снимается дамп. Если параметр выключен, то в SQL-запросе будет описано только создание таблиц, без их заполнения |
|
|
| При включении параметра в дамп будет записано создание индексов для таблиц, которые участвуют в дампе |
|
|
| Определяет метод выгрузки данных таблиц Если параметр включен, данные таблиц выгружаются с помощью команды |
|
|
| При включении параметра будет сформирован файл с SQL-запросом, для которого сформирован дамп |
|
|
| При включении параметра будет сформирован файл с SQL-командами создания таблиц, для которых снимается дамп |
|
|
| При включении параметра будет сформирован файл с планом выполнения текущего SQL-запроса |
Параметры, включающие критерии срабатывания
Параметр | Тип данных | Значение по умолчанию | Описание |
|---|---|---|---|
|
| – | Фрагмент SQL-запроса, при появлении которого в запросе будет осуществлено срабатывание получения дампа |
|
|
| При включении параметра будет осуществляться дамп запросов отмененных со стороны СУБД (например, командой |
|
|
| При включении параметра будет анализироваться ожидаемое и фактическое количество строк для всех запросов. Чтобы сработало автоматическое формирование дампа по запросу, должны одновременно выполниться два критерия |
|
|
| Критерий срабатывания автоматического дампа по абсолютной разнице между ожидаемым и фактическим количеством строк. Анализируются все узлы плана. Если ожидаемое количество строк отличается от фактического количества строк более чем на заданное в параметре число, то критерий считается выполнен. Если значение равно |
|
|
| Критерий срабатывания автоматического дампа по разнице в процентах между ожидаемым и фактическим количеством строк В качестве параметра устанавливается число от 0 до 100. Анализируются все узлы плана. По каждому узлу проверяется отношение суммы ожидаемого количества строк и фактического количества строк к ожидаемому количеству строк. Если это отношение превышает установленный параметр, то критерий считается выполненным. Если значение равно |
|
|
| Сохранить выгрузку запроса, если время его выполнения превышает значение |
|
|
| Задает значение тайм-аута для |
Ограничения
Не рекомендуется настраивать auto_dump таким образом, чтобы оно выгружало каждый запрос. Расширение предназначено для отладки и не может использоваться для непрерывного мониторинга.
Ограничения:
- Расширение
auto_dumpнесовместимо с командойPREPARE TRANSACTIONпри работе с временными таблицами. - Если включен параметр
auto_dump.dump_all_temp_tables, расширениеauto_dumpне может обратиться к временным пространствам имен из автономных транзакций.
Использование модуля
Пример использования
-
С помощью технологического журнала был получен текст SQL-запроса:
SELECTT3._Q_001_F_000RRef,T3._Q_001_F_001,T1._Q_001_F_002,T1._Q_001_F_001RRef,T2._Fld23FROM pg_temp.tt3 T1LEFT OUTER JOIN _Reference7X1 T2ON (T1._Q_001_F_001RRef = T2._IDRRef)INNER JOIN pg_temp.tt2 T3ON (T1._Q_001_F_000RRef = T3._Q_001_F_000RRef) -
В конфигурационном файле
postgresql.conf/postgres.ymlбыли добавлены строки:shared_preload_libraries = ‘auto_dump’auto_dump.enable = onauto_dump.output_directory = ‘/tmp/auto_d’auto_dump.dump_on_query_string = ‘LEFT OUTER JOIN _Reference7X1’ -
Перезапуск службы СУБД:
user@server: sudo systemctl restart postgresql@16-main.service -
Добавление расширения в базу данных
auto_d:user@server: psql -h localhost -U postgres -d auto_dauto_d=# create extension auto_dump;CREATE EXTENSION -
Пользователь в 1С выполнил действие, которое использует проблемный запрос. После этого в каталоге
/tmp/auto_dпоявился новый каталог, который имеет следующий форматPIDПроцесса-ГГГГ-ММ-ДД-ЧЧ-ММ-СС-ПорядковыйНомер.user@server:/tmp/auto_d/71491-2025_06_11_12_42_36_00$ ls -l-rw------- 1 postgres postgres 3241 июн 11 12:42 create.sql-rw------- 1 postgres postgres 6743 июн 11 12:42 createwithdata.sqlФайл
create.sqlсодержит текст:CREATE TEMPORARY TABLE tt3 (_q_001_f_000rref bytea,_q_001_f_001rref bytea,_q_001_f_002 numeric(22,2));CREATE INDEX tmpind_1 ON pg_temp.tt3 USING btree (_q_001_f_000rref);ANALYZE tt3;CREATE TEMPORARY TABLE tt2 (_q_001_f_000rref bytea,_q_001_f_001 numeric(16,2));CREATE INDEX tmpind_0 ON pg_temp.tt2 USING btree (_q_001_f_000rref);ANALYZE tt2;/*SELECTT3._Q_001_F_000RRef,T3._Q_001_F_001,T1._Q_001_F_002,T1._Q_001_F_001RRef,T2._Fld23FROM pg_temp.tt3 T1LEFT OUTER JOIN _Reference7X1 T2ON (T1._Q_001_F_001RRef = T2._IDRRef)INNER JOIN pg_temp.tt2 T3ON (T1._Q_001_F_000RRef = T3._Q_001_F_000RRef);*//*Query Text: SELECTT3._Q_001_F_000RRef,T3._Q_001_F_001,T1._Q_001_F_002,T1._Q_001_F_001RRef,T2._Fld23FROM pg_temp.tt3 T1LEFT OUTER JOIN _Reference7X1 T2ON (T1._Q_001_F_001RRef = T2._IDRRef)INNER JOIN pg_temp.tt2 T3ON (T1._Q_001_F_000RRef = T3._Q_001_F_000RRef)Hash Join (cost=8.01..9.51 rows=22 width=79)Hash Cond: (t1._q_001_f_000rref = t3._q_001_f_000rref)-> Hash Left Join (cost=6.76..8.01 rows=22 width=72)Hash Cond: (t1._q_001_f_001rref = t2._idrref)-> Seq Scan on tt3 t1 (cost=0.00..1.22 rows=22 width=40)-> Hash (cost=6.36..6.36 rows=36 width=64)-> Seq Scan on _reference7x1 t2 (cost=0.00..6.36 rows=36 width=64)-> Hash (cost=1.12..1.12 rows=12 width=24)-> Seq Scan on tt2 t3 (cost=0.00..1.12 rows=12 width=24)*//*Query Text: SELECTT3._Q_001_F_000RRef,T3._Q_001_F_001,T1._Q_001_F_002,T1._Q_001_F_001RRef,T2._Fld23FROM pg_temp.tt3 T1LEFT OUTER JOIN _Reference7X1 T2ON (T1._Q_001_F_001RRef = T2._IDRRef)INNER JOIN pg_temp.tt2 T3ON (T1._Q_001_F_000RRef = T3._Q_001_F_000RRef)Hash Join (cost=8.01..9.51 rows=22 width=79) (actual time=0.027..0.037 rows=22 loops=1)Output: t3._q_001_f_000rref, t3._q_001_f_001, t1._q_001_f_002, t1._q_001_f_001rref, t2._fld23Hash Cond: (t1._q_001_f_000rref = t3._q_001_f_000rref)Buffers: shared hit=6, local hit=2-> Hash Left Join (cost=6.76..8.01 rows=22 width=72) (actual time=0.020..0.025 rows=22 loops=1)Output: t1._q_001_f_002, t1._q_001_f_001rref, t1._q_001_f_000rref, t2._fld23Inner Unique: trueHash Cond: (t1._q_001_f_001rref = t2._idrref)Buffers: shared hit=6, local hit=1-> Seq Scan on pg_temp.tt3 t1 (cost=0.00..1.22 rows=22 width=40) (actual time=0.001..0.002 rows=22 loops=1)Output: t1._q_001_f_000rref, t1._q_001_f_001rref, t1._q_001_f_002Buffers: local hit=1-> Hash (cost=6.36..6.36 rows=36 width=64) (actual time=0.016..0.016 rows=36 loops=1)Output: t2._fld23, t2._idrrefBuckets: 1024 Batches: 1 Memory Usage: 11kBBuffers: shared hit=6-> Seq Scan on public._reference7x1 t2 (cost=0.00..6.36 rows=36 width=64) (actual time=0.003..0.011 rows=36 loops=1)Output: t2._fld23, t2._idrrefBuffers: shared hit=6-> Hash (cost=1.12..1.12 rows=12 width=24) (actual time=0.005..0.005 rows=12 loops=1)Output: t3._q_001_f_000rref, t3._q_001_f_001Buckets: 1024 Batches: 1 Memory Usage: 9kBBuffers: local hit=1-> Seq Scan on pg_temp.tt2 t3 (cost=0.00..1.12 rows=12 width=24) (actual time=0.002..0.002 rows=12 loops=1)Output: t3._q_001_f_000rref, t3._q_001_f_001Buffers: local hit=1Settings: enable_mergejoin = 'off', cpu_operator_cost = '0.001'*/Файл
createwithdata.sqlсодержит текст:CREATE TEMPORARY TABLE tt3 (_q_001_f_000rref bytea,_q_001_f_001rref bytea,_q_001_f_002 numeric(22,2));CREATE INDEX tmpind_1 ON pg_temp.tt3 USING btree (_q_001_f_000rref);INSERT INTO tt3 (_q_001_f_000rref, _q_001_f_001rref, _q_001_f_002) VALUES(E'\\x8ca0000d8843cd1b11dc8d043d710079',E'\\x8ca1000d8843cd1b11dc8ea92d97a749',36960.00),(E'\\x8ca1000d8843cd1b11dc8ea92d97a74a',E'\\x8ca1000d8843cd1b11dc8ea92d97a749',123750.00);ANALYZE tt3;CREATE TEMPORARY TABLE tt2 (_q_001_f_000rref bytea,_q_001_f_001 numeric(16,2));CREATE INDEX tmpind_0 ON pg_temp.tt2 USING btree (_q_001_f_000rref);INSERT INTO tt2 (_q_001_f_000rref, _q_001_f_001) VALUES(E'\\x8ca0000d8843cd1b11dc8d043d71007d',59500.00),(E'\\x8ca0000d8843cd1b11dc8d043d710076',153176.73);ANALYZE tt2;/*SELECTT3._Q_001_F_000RRef,T3._Q_001_F_001,T1._Q_001_F_002,T1._Q_001_F_001RRef,T2._Fld23FROM pg_temp.tt3 T1LEFT OUTER JOIN _Reference7X1 T2ON (T1._Q_001_F_001RRef = T2._IDRRef)INNER JOIN pg_temp.tt2 T3ON (T1._Q_001_F_000RRef = T3._Q_001_F_000RRef);*//*Query Text: SELECTT3._Q_001_F_000RRef,T3._Q_001_F_001,T1._Q_001_F_002,T1._Q_001_F_001RRef,T2._Fld23FROM pg_temp.tt3 T1LEFT OUTER JOIN _Reference7X1 T2ON (T1._Q_001_F_001RRef = T2._IDRRef)INNER JOIN pg_temp.tt2 T3ON (T1._Q_001_F_000RRef = T3._Q_001_F_000RRef)Hash Join (cost=8.01..9.51 rows=22 width=79)Hash Cond: (t1._q_001_f_000rref = t3._q_001_f_000rref)-> Hash Left Join (cost=6.76..8.01 rows=22 width=72)Hash Cond: (t1._q_001_f_001rref = t2._idrref)-> Seq Scan on tt3 t1 (cost=0.00..1.22 rows=22 width=40)-> Hash (cost=6.36..6.36 rows=36 width=64)-> Seq Scan on _reference7x1 t2 (cost=0.00..6.36 rows=36 width=64)-> Hash (cost=1.12..1.12 rows=12 width=24)-> Seq Scan on tt2 t3 (cost=0.00..1.12 rows=12 width=24)*//*Query Text: SELECTT3._Q_001_F_000RRef,T3._Q_001_F_001,T1._Q_001_F_002,T1._Q_001_F_001RRef,T2._Fld23FROM pg_temp.tt3 T1LEFT OUTER JOIN _Reference7X1 T2ON (T1._Q_001_F_001RRef = T2._IDRRef)INNER JOIN pg_temp.tt2 T3ON (T1._Q_001_F_000RRef = T3._Q_001_F_000RRef)Hash Join (cost=8.01..9.51 rows=22 width=79) (actual time=0.027..0.037 rows=22 loops=1)Output: t3._q_001_f_000rref, t3._q_001_f_001, t1._q_001_f_002, t1._q_001_f_001rref, t2._fld23Hash Cond: (t1._q_001_f_000rref = t3._q_001_f_000rref)Buffers: shared hit=6, local hit=2-> Hash Left Join (cost=6.76..8.01 rows=22 width=72) (actual time=0.020..0.025 rows=22 loops=1)Output: t1._q_001_f_002, t1._q_001_f_001rref, t1._q_001_f_000rref, t2._fld23Inner Unique: trueHash Cond: (t1._q_001_f_001rref = t2._idrref)Buffers: shared hit=6, local hit=1-> Seq Scan on pg_temp.tt3 t1 (cost=0.00..1.22 rows=22 width=40) (actual time=0.001..0.002 rows=22 loops=1)Output: t1._q_001_f_000rref, t1._q_001_f_001rref, t1._q_001_f_002Buffers: local hit=1-> Hash (cost=6.36..6.36 rows=36 width=64) (actual time=0.016..0.016 rows=36 loops=1)Output: t2._fld23, t2._idrrefBuckets: 1024 Batches: 1 Memory Usage: 11kBBuffers: shared hit=6-> Seq Scan on public._reference7x1 t2 (cost=0.00..6.36 rows=36 width=64) (actual time=0.003..0.011 rows=36 loops=1)Output: t2._fld23, t2._idrrefBuffers: shared hit=6-> Hash (cost=1.12..1.12 rows=12 width=24) (actual time=0.005..0.005 rows=12 loops=1)Output: t3._q_001_f_000rref, t3._q_001_f_001Buckets: 1024 Batches: 1 Memory Usage: 9kBBuffers: local hit=1-> Seq Scan on pg_temp.tt2 t3 (cost=0.00..1.12 rows=12 width=24) (actual time=0.002..0.002 rows=12 loops=1)Output: t3._q_001_f_000rref, t3._q_001_f_001Buffers: local hit=1Settings: enable_mergejoin = 'off', cpu_operator_cost = '0.001'*/
Ссылки на документацию разработчика
Дополнительно поставляемый модуль auto_dump.