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-onlypgsync даже не пытается синхронизировать расширения 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