Pull to refresh

Обзор Greenmask — утилиты для логического дампа PgSQL с трансформацией данных на лету

Level of difficultyEasy
Reading time7 min
Views1.9K
Архитектура Greenmask
Архитектура Greenmask

Greenmask — это кроссплатформенный инструмент, разработанный на Go специально для безопасной работы с данными PostgreSQL: он помогает делать логические бэкапы, восстанавливать таблицы и при необходимости — анонимизировать чувствительную информацию. Главное преимущество Greenmask — полная совместимость с pg_dump и pg_restore. То есть, если вы уже работаете с этими инструментами, интеграция Greenmask не потребует пересмотра всей инфраструктуры.

Один из ключевых сценариев использования утилиты - подготовка баз данных для тестового стенда. Greenmask позволяет упростить процесс дампа продуктивных баз, обработки их для анонимизации тех же персональных данных, снижения размера баз (в тестовой среде зачастую не нужны терабайты данных с прода), восстановления дампов в тестовый контур.

Ниже в статье я опишу базовый функционал, примеры конфигураций для начала работы с Greenmask, а так же рассмотрим примеры трансформации данных при дампе таблиц.


Архитектура: кто за что отвечает

В PostgreSQL логическое резервное копирование делится на три условные части:

  • Pre-data — структура таблиц (без FK и PK);

  • Data — сами строки таблиц, а также значения последовательностей (sequences) и бинарные объекты (Large Objects);

  • Post-data — всё остальное: PK, FK, триггеры и т. д.

Greenmask фокусируется в основном на части Data — той самой серединой, где находятся строки таблиц. Всё, что касается структуры — на входе и выходе — доверяется стандартным инструментам PostgreSQL (pg_dump, pg_restore), так что Greenmask можно встроить в уже существующие CI/CD пайплайны, процессы резервного копирования и т.д.

В основе Greenmask лежит формат резервной копии directory, который умеет разбивать бэкап на множество файлов и позволяет выполнять операции в несколько потоков.

Greenmask так же добавляет абстракцию хранилища. Есть два варианта:

  • directory — просто папка на диске;

  • s3 — любые совместимые с S3 хранилища, включая AWS, MinIO, Yandex Cloud и т.д.

Так что можно заливать дампы сразу в S3 без промежуточных прослоек, так же эффективно проводить восстановление в несколько потоков.

Трансформация и проверка данных

Трансформация данных — отдельная важная часть Greenmask. Программа умеет:

  • читать строки напрямую в формате COPY;

  • использовать метаинформацию о таблицах для правильной трансформации;

  • применять трансформеры - например: hash, random и много других;

  • валидировать изменения — команда validate покажет, как изменятся данные, и предупредит, если что-то пойдёт не так.

Таким образом, можно необходимые вам чувствительные к утечкам поля с данными (например, email, ФИО, номера телефонов) трансформировать в случайные данные при этом те остаются «похожими на настоящие».

Ниже мы разберем примеры конфигураций.

Базовые примеры файла конфигураций

root@d6142f095c79:~# cat dump.yaml
dump:
  pg_dump_options:
    dbname: "host=/run/postgresql user=postgres dbname=demo"
    jobs: 10
    table: "users"
    load-via-partition-root: true

storage:
  type: "directory"
  directory:
    path: "/tmp/backup"

Секция dump описывает параметры подключения, какие данные берем.

Секция storage - про то куда сохраняем, как выше было замечено, поддерживаются как локальные директории так и S3.

Далее запускаем утилиту greenmask --config dump.yaml --log-level info dump.

На выходе получаем директорию с дампом данных описанных в конфиге

root@d6142f095c79:~# ls -la /tmp/backup/
total 12
drwxr-xr-x 3 root root 4096 May  8 09:50 .
drwxrwxrwt 1 root root 4096 May  8 09:50 ..
drwxr-x--- 2 root root 4096 May  8 09:50 1746697821870

Как видно конфигурационный файл достаточно простой, после небольшой адаптации под ваше окружение вы уже можете начать использовать утилиту для бекапов, для подготовки баз тестового стенда, переливать нужные данные с прода в тестовое окружение и т.д.

Трансформация данных

Но наверное ключевой функционал - это трансформация данных. Greenmask позволяет вам описать в конфигурационном файле какие таблицы и данные в них каким образом вы хотите модифицировать в дампе перед тем как сохранить его (данные в таблице источнике не меняются). Данные могут быть как чувствительные к утечкам (например, персональные данные) так и нет, все зависит от вашей задачи.

Greenmask поддерживает на текущий момент два типа трансформации - random и hash. При этом по умолчанию доступно 47 базовых видов трансформаций, полный список можно посмотреть в документации. Почти все базовые виды трансформаций используют тип трансформации random, то есть после завершения работы трансформации на выходе вы получаете в дампе случайный набор аналогичных данных, при этом если вам нужны детерминированные данные, то вы можете использовать тип трансформации hash, тогда при одних и тех же входящих записях вы будете получать один и тот же набор трансформированных данных.

Greenmask использует SHA-3 как алгоритм хеширования, да он медленный и не гарантирует отсутствие коллизий на большом объеме данных. У разработчиков greenmask есть планы реализации более продвинутых алгоритмов.

Давайте разберемся, для примера, с одним видом трансформации - RandomEmail. Для этого доработаем наш конфиг и потом при помощи validate посмотрим как конкретно будут обработаны данные из таблицы.

Добавим в конфиг секцию transformation следующего вида:

dump:
  pg_dump_options:
    dbname: "host=/run/postgresql user=postgres dbname=demo"
    jobs: 10
    table: "users"
    load-via-partition-root: true

  transformation:
    - schema: "public"
      name: "users"
      transformers:
        - name: "RandomEmail"
          params:
            column: "email"
            max_random_length: 10

storage:
  type: "directory"
  directory:
    path: "/tmp/backup"

Далее, мы можем при помощи параметра validate посмотреть как greenmask планирует менять данные перед тем как сохранить дамп в локальную папку или на S3:

greenmask --config dump.yaml --log-level info validate \
  --warnings \
  --data \
  --diff \
  --schema \
  --format=text \
  --table-format=vertical \
  --transformed-only \
  --rows-limit=10

В выводе видим следующее:

root@d6142f095c79:~# greenmask --config dump.yaml --log-level info validate \
  --warnings \
  --data \
  --diff \
  --schema \
  --format=text \
  --table-format=vertical \
  --transformed-only \
  --rows-limit=10

        "public"."users"
+-----------+--------+----------------------------+-----------------------------------+
| %LineNum% | Column | OriginalValue              | TransformedValue                  |
+-----------+--------+----------------------------+-----------------------------------+
| 0         | id     | 1                          | 1                                 |
+           +--------+----------------------------+-----------------------------------+
|           | email  | john.doe@example.com       | 7582dd23522f90232810@yahoo.com    |
+-----------+--------+----------------------------+-----------------------------------+
| 1         | id     | 2                          | 2                                 |
+           +--------+----------------------------+-----------------------------------+
|           | email  | jane.smith@example.com     | 16396162316dd0096256@gmx.com      |
+-----------+--------+----------------------------+-----------------------------------+
| 2         | id     | 3                          | 3                                 |
+           +--------+----------------------------+-----------------------------------+
|           | email  | bob.johnson@example.com    | 5328930b54ffe127330d@fastmail.com |
+-----------+--------+----------------------------+-----------------------------------+
| 3         | id     | 4                          | 4                                 |
+           +--------+----------------------------+-----------------------------------+
|           | email  | alice.williams@example.com | 94bdc6195b6960e600d4@yandex.com   |
+-----------+--------+----------------------------+-----------------------------------+
| 4         | id     | 5                          | 5                                 |
+           +--------+----------------------------+-----------------------------------+
|           | email  | charlie.brown@example.com  | 80654a75212e176354a7@gmail.com    |
+-----------+--------+----------------------------+-----------------------------------+
| 5         | id     | 6                          | 6                                 |
+           +--------+----------------------------+-----------------------------------+
|           | email  | emma.davis@example.com     | 186443b43fb0e7317dd3@yandex.com   |
+-----------+--------+----------------------------+-----------------------------------+
| 6         | id     | 7                          | 7                                 |
+           +--------+----------------------------+-----------------------------------+
|           | email  | michael.wilson@example.com | fb185fb854d4897f0fa0@zoho.com     |
+-----------+--------+----------------------------+-----------------------------------+
| 7         | id     | 8                          | 8                                 |
+           +--------+----------------------------+-----------------------------------+
|           | email  | sarah.miller@example.com   | a3f141f64a5c9eb6be6c@hotmail.com  |
+-----------+--------+----------------------------+-----------------------------------+
| 8         | id     | 9                          | 9                                 |
+           +--------+----------------------------+-----------------------------------+
|           | email  | david.taylor@example.com   | a72bf01319a47272596b@zoho.com     |
+-----------+--------+----------------------------+-----------------------------------+
| 9         | id     | 10                         | 10                                |
+           +--------+----------------------------+-----------------------------------+
|           | email  | lisa.anderson@example.com  | 5bc13b03057f91190136@hotmail.com  |
+-----------+--------+----------------------------+-----------------------------------+

Как видно из вывода ID записей в таблице не меняются, меняются только email адреса. В OriginalValue указаны те данные которые сейчас хранятся в таблице, в TransformedValue указано во что планирует переписать greenmask значения при сохранении дампа. Данные в оригинальной таблице не меняются, меняются только данные в дампе перед сохранением.

При этом типовой вид трансформации позволяет достаточно гибко настроить, какие домены будут использоваться для создания случайных email адресов, какой длины будет запись. Если вам нужны детерминированные данные - можно указать использовать тип трансформации hash и на выходе вы всегда будете получать один и тот же набор хешированных email адресов, что достаточно упрощает работу с ними при этом без раскрытия оригинальных данных.

Восстановление данных

Greenmask так же достаточно просто позволяет восстановить данные из созданного дампа, команда для этого:

greenmask --config dump.yaml --log-level info restore -d demo latest

Далее остается дождаться полного восстановления ваших данных.

Заключение

В статье постарался обзорно описать функционал утилиты, основные сценарии использования и типовые конфигурационные файлы.

Что планирую раскрыть в следующих статьях:

  • продвинутые трансформеры

  • подмножества (database substets) - возможность использовать фильтры для дампа только небольшого количества данных, актуально для очень больших баз

  • более глубокое погружение в архитектуру утилиты

  • детальное описание сценариев использования утилиты, с примерами, конфигами и т.д.

Для тех кто хочет самостоятельно разобраться в утилите - есть набор Docker образов Greenmask Playground, который позволяет развернуть demo базу postgresql, S3, последнюю версию greenmask в полноценный демо стенд.

Разработчик проекта достаточно активно отвечает в Telegram канале, если будут возникать какие-то вопросы - смело подключайтесь. Так же видно что его усилий не хватает для динамичного развития проекта, если вы хотите принять участие в разработке opensource проекта на Go - будет супер!

Tags:
Hubs:
+7
Comments0

Articles