Механизм сбора информации о движении данных (Data Lineage)
Описание
Функциональность доступна только для редакций Enterprise и Enterprise для ERP-систем.
Функциональность предназначена для сбора информации о движении данных внутри БД, реализована в виде расширения, загружаемого на старте сервера.
Потоком данных между объектами базы является выполнение запроса в БД, когда источником и приемником данных является объект базы. Это выполнение DML-запросов INSERT / UPDATE / MERGE / COPY FROM, а также DDL-запросы, когда при определении объекта базы сразу происходит его наполнение: CREATE TABLE ... AS, SELECT INTO, CREATE MATERIALIZED VIEW.
Статистика по запросам, содержащим потоки данных, является консолидированной по всем запускам. При первом исполнении запроса определяются потоки данных, и по каждому из них добавляется одна запись, при последующих запусках этого запроса обновляется лишь статистическая информация запроса.
На диаграмме ниже изображена последовательность выполнения процессов. Красным отмечены процессы, которые реализованы в продукте СУБД Pangolin, а синим — процессы, для которых необходимо предоставление прав, доступов, данных и настроек.

Сброс статистики (неконсистентный)
Для удаления всей статистики без учета консистентности сохранения данных, реализованы методы psql_data_lineage_reset и psql_data_lineage_clean. При их вызове будет удалена информация о статистике для всех БД и файлы с содержимым будут так же удалены с диска. Ниже в таблицах подробная информация о данных функциях.
Консистентное удаление данных
Для обеспечения консистентного удаления данных без потери записей от момента SELECT до RESET реализована функция freeze.
При сборе статистики по Data Lineage с помощью функций psql_data_lineage_objects, psql_data_lineage_attributes и другими может потребоваться последующая очистка данных. Но обычный сброс через psql_data_lineage_reset может быть неконсистентным, если состояние изменилось между последним SELECT и сбросом.
Чтобы избежать этого, используется функциональность freeze, в которую входят следующие функции:
psql_data_lineage_freeze_data«замораживает» все собранные на момент выполнения функции данные Data Lineage. Снимок данных сохраняется в файлdl_freezed_stat.statв директории DL, что позволяет выполнять консистентный сброс в рамках разрываемого подключения. После заморозки можно безопасно собирать и анализировать статистику.psql_data_lineage_reset_freezedочищает новые данные в shared memory, не затрагивая зафиксированные. Такая очистка работает консистентно, поскольку учитывает новое и старое состояния счетчиков и записей.psql_data_lineage_restore_freezedудаляет созданный файлdl_freezed_stat.stat, если сбор данных отменен. После этого все запросы снова будут идти в shared memory для получения данных.
Таким образом, функциональность freeze обеспечивает консистентную очистку и работу с данными без потери информации.
После очистки с использованием функциональности freeze записи в Data Lineage не удаляются полностью — их счетчики обнуляются, и они перестают отображаться в запросах. Такие записи (zero-records) служат кешем для ускорения последующего разбора дерева запросов.
При заполнении общей памяти на 75% в первую очередь очищаются zero-records, что может увеличить время разбора ранее выполненных запросов.
На текущий момент нет механизма поддержки параллельного использования функциональности freeze. Обеспечение осуществления вызовов данных функций только в одном процессе остается за пользователем.
Принцип работы
Процесс включения мониторинга DL:

При загрузке расширения на старте СУБД выделяется общая память (shared memory) для обеспечения его работоспособности независимо от того, включена ли функциональность параметром psql_data_lineage.enable.
После активации функциональности статистика собирается по всем БД системы (если иное не указано в параметрах). При заполнении общей памяти более чем на 75% в лог СУБД выводится предупреждение уровня WARNING с рекомендацией очистить память (в первую очередь очищаются zero-records).
Функции и представления, обеспечивающие выгрузку данных, создаются при создании расширения и доступны в той БД, где создано расширение, но предоставляют статистику по всем базам данных.
Параметр psql_data_lineage.max_records задает максимальное количество записей о статистике уникальных запросов DL. При превышении этого лимита выполнение запросов с потоками данных будет приводить к ошибке.
Более подробно конфигурационные параметры функциональности описаны в подразделе «Параметры конфигурирования расширения» раздела «psql_data_lineage. Сбор информации о движении данных» документа «Описание расширений продукта СУБД Pangolin».
Ограничение функциональности
В одной транзакции можно использовать не более 255 уникальных ID-запросов для DDL-запросов, которые имеют одинаковый инициализирующий запрос. Далее ID-запросы могут повторяться.
Настройка
Установка и настройка используемого в рамках функционального решения расширения описана в разделе «psql_data_lineage. Сбор информации о движении данных» документа «Описание расширений продукта СУБД Pangolin».
Сценарии использования
Ограничение максимального количества записей
-
Сбросить данные о ранее собранной статистике:
SELECT psql_data_lineage_reset(); -
Установите максимальное количество записей уникальных запросов:
ALTER SYSTEM SET psql_data_lineage.max_records=100; -
Перезагрузите СУБД:
pg_ctl restart -
Создайте и наполните таблицы:
SQL-запрос
DROP DATABASE IF EXISTS dl_1;
CREATE DATABASE dl_1;
DROP TABLE IF EXISTS test_dl_1;
CREATE TABLE test_dl_1(i int);
INSERT INTO test_dl_1 VALUES (1);
INSERT INTO test_dl_1 VALUES (2), (3);
DO $$
BEGIN
FOR i IN 1..98 LOOP
EXECUTE 'CREATE TABLE test_mm (a int); INSERT INTO test_mm VALUES (1); DROP TABLE test_mm;';
END LOOP;
END $$;Результат: При достижении определенного количества записей (3/4 от установленного параметром числа) в логе будет писаться
WARNING:WARNING: Data Lineage fill more than 3/4. Please clean -
Выведите информацию о количестве записей в БД:
SELECT count(*) FROM psql_dl_stats_with_meta \gxРезультат:
-[ RECORD 1 ]
count | 100 -
Выполните еще один запрос, создающий новую запись в Data Lineage:
INSERT INTO test_dl_1 VALUES (2), (3), (4);Результат: При достижении полного заполнения в логе будут писаться
WARNINGсначала про удаление самого старого объекта, затем напоминание о необходимости очистки:WARNING: Data Lineage reached it's limit 100 -> oldest record removed
WARNING: Data Lineage fill more than 3/4. Please clean
Консистентная очистка данных (freeze функциональность)
-
Создайте БД
dl_1, таблицуtest_dl_1и сделайте 2 вставки:DROP DATABASE IF EXISTS dl_1;
CREATE DATABASE dl_1;
DROP TABLE IF EXISTS test_dl_1;
CREATE TABLE test_dl_1(i int);
INSERT INTO test_dl_1 VALUES (1);
INSERT INTO test_dl_1 VALUES (2); -
Выведите статистику:
SELECT * FROM psql_dl_stats_with_meta \gxПримерный результат:
-[ RECORD 1 ]-----+----------------------------------
qualified_name | -1027113734904351403/1
process_id | -1027113734904351403
parent_process_id | -1027113734904351403
query_id | -404261266763271458
input | CONST
output | dl_1.public.test_dl_1
first_time | 2024-10-14 17:44:53.024427+03
last_time | 2024-10-14 17:44:53.026825+03
query_plan | Insert on test_dl_1 +
| -> Result +
|
query_text | INSERT INTO test_dl_1 VALUES ($1)
exec_duration | 0.021154000000000003
exec_count | 2
count_row | 2 -
Заморозьте сбор статистики:
SELECT psql_data_lineage_freeze_data();Результат: Данные о статистике заморожены:
psql_data_lineage_freeze_data
-------------------------------
1
(1 row) -
Вставьте данные (в другом процессе). Запросить статистику. От пользователя postgres:
INSERT INTO test_dl_1 VALUES (3);
INSERT INTO test_dl_1 VALUES (4), (5);
SELECT * FROM psql_dl_stats_with_meta \gxРезультат: Вставленные данные не влияют на результаты выдаваемых значений:
-[ RECORD 1 ]-----+----------------------------------
qualified_name | -1027113734904351403/1
process_id | -1027113734904351403
parent_process_id | -1027113734904351403
query_id | -404261266763271458
input | CONST
output | dl_1.public.test_dl_1
first_time | 2024-10-14 17:44:53.024427+03
last_time | 2024-10-14 17:44:53.026825+03
query_plan | Insert on test_dl_1 +
| -> Result +
|
query_text | INSERT INTO test_dl_1 VALUES ($1)
exec_duration | 0.021154000000000003
exec_count | 2
count_row | 2 -
Удалите замороженные данные (при этом обновляется shared memory). Запросите данные, не прерывая изначальный процесс. От пользователя postgres:
SELECT psql_data_lineage_reset_freezed();
SELECT * FROM psql_dl_stats_with_meta \gxРезультат: При выполнении
freezeвсе данные в процессе были перемещены в файлdl_freezed_stat.statи запрашиваются из него. Новые данные, которые были записаны в параллельном процессе, записываются в shared memory и после reset freezed находятся в актуальном состоянии.