pgsync
Синхронизация одной Postgres базы данных в другую.
pgsync декларирует следующие преимущества
- скорость - таблицы передаются параллельно
- безопасность - встроенные методы, чтобы исключить утечку чувствительных данных
- гибкость - изящная обработка различий в схемах данных, например отсутствующих колонок
- удобство - синхронизация части таблиц, групп таблиц, и относящихся записей
Проверено в бою на Instcart.
Установка
gem install pgsync
в директории проекта
pgsync --init
будет создан файл .pgsync.yml
, файл для настройки. Рекомендуется добавить файл под контроль версий. Сам файл не содержит чувствительной информации и может распространяться через контроль версий.
Использование
Синхронизировать все таблицы
pgsync
Синхронизировать конкретные таблицы
pgsync table1, table2
Синхронизировать конкретные строки
pgsync articles "where active = 1"
синхронизация строк с сохранением существующих
pgsync articles "where active = 1" --preserve
или очистка/удаление
pgsync articles "where active = 1" --truncate
Исключение таблиц
pgsync --exclude users
Для исключения таблиц на постоянной основе используем конфигурацию
exclude:
- payments
- users
Для Rails правильным будет добавить в исключения
exclude:
- schema_migrations
- ar_internal_metadata
Определение групп
groups:
news:
- articles
- tags
- comments
- links
Синхронизация группы
pgsync news
Детальные настройки для каждой таблицы в группе и указание параметра при синхронизации
groups:
news:
artciles: "where id = {1}"
comments: "where acrticle_id = {1} order by created_at desc limit 10"
links: "where id in (select link_id from articles where id = {1})"
запуск
pgsync news:123
Схема данных
pgsync
создан для работы с данными, для синхронизации, обновления схемы надо использовать миграции.
предварительная синхронизация схемы
pgsync --schema-first
Внимание! Это удалит все существующие данные.
Для конкретных таблиц
pgsync table1,table2 --schema-first
и только схема
pgsync --schema-only
pgsync даже не пытается синхронизировать расширения Postgres
Исключения данных
Чтобы исключить утечку данных с сервера, например пароли, email адреса
data_rules:
email: unique_email
last_name: random_letter
birthday: random_date
user.auth_token:
value: secret
visit_counts:
statement: "(RANDOM() * 10)::int"
encrypted_*: null
last_name
затронет все колонки называемые last_name
, users.last_name
затронет только данные в таблице users
. Поддерживается "шаблоны поиска" (wildcards), первое найденное правило будет применено
Опции
- unique_email
- unique_phone
- unique_secret
- random_letter
- random_int
- random_date
- random_time
- random_ip
- value
- statement
- null
- untouched
Правила начинающиеся с unique_
требуют, чтобы в таблице был первичный ключ. unique_phone
также требует чтобы первичный ключ был числом.
Внешние ключи
Внешние ключи затрудняют синхронизацию данных. Три возможных варианта:
- определение порядка таблиц вручную
- использование отложенных констант
- отключение триггеров внешних ключей, которое "молча", без выдачи ошибок нарушит ссылочную целостность данных
Определяем порядок синхронизации вручную, и используем ключ --jobs 1
, чтобы синхронизировалась одна таблица за раз.
pgsync table1,table2,table3 --jobs 1
если таблицы имеют deferrable constariants, используем
pgsync --deferrable-constraints
для отключения триггеров внешних ключей и потенциального разрушения целостности ссылок (связей данных), используем
pgsync --disable-integrity
Отключение триггеров
pgsync --disable-user-triggers
Добавление данных
Для супер-больших таблиц, или только добавления данных в таблицы, синхронизируем пакетами (sync batches)
pgsync large_table --in-batches
Защита
Всегда подключаться через SSH или VPN. Или использовать sslmode=verify-full
.
Безопасность
Чтобы исключить случайное уничтожение или перезапись данных в production
, точка назначения ограничена на localhost
или 127.0.0.1
по умолчанию. Чтобы использовать другой хост, добавить to_safe: true
в .pgsync.yml
Несколько баз данных
pgsync --init db2
что создаст .pgsync-db2.yml
, и запуск с этой конфигурацией
pgsync --db db2