Postgres Dump Selected Rows - PullRequest
       72

Postgres Dump Selected Rows

1 голос
/ 22 октября 2019

У меня есть база данных, в которой есть центральный объект, от которого зависит большая часть данных;много справочных таблиц, одно-много объединений и много-много объединений. Мне нужно создать резервную копию всех строк на основе свойства в центральной таблице и иметь возможность восстановить эти строки.

Для целей резервного копирования. Я добавил ON DELETE CASCADE в соответствующие зависимые таблицы. Поэтому я могу стереть все строки, просто

DELETE FROM main_table WHERE attr=1

Но мне нужно иметь возможность восстановить все строки и ссылки, связанные с ними, в более ранний момент времени. Очки:

  • pg_dump не позволяет создавать дампы на основе операторов SQL
  • COPY не генерирует SQL

Поэтому это решение, которое я предлагаюи я ненавижу этоДля каждой таблицы значение атрибута:

CREATE TABLE tmp_main_table AS SELECT * FROM main_table WHERE attr=val;
CREATE TABLE tmp_table_1 AS SELECT * FROM table_1 WHERE main_table_id IN (SELECT id FROM main_Table WHERE attr=val);
...

Тогда pg_dump -t tmp_main_table -t tmp_table_1 ...

Восстановление затем потребует повторной вставки строк в эти таблицы. У меня есть полный контроль над базой данных, поэтому я могу быть уверен, что идентификаторы ссылочных таблиц остаются прежними, но все это кажется очень хрупким. Есть ли лучший способ?

РЕДАКТИРОВАТЬ: Подробнее

Мы запустили несколько коммерческих сайтов, где клиенты обновляют свои ресурсы через API. Однако часто случается, что вызовы API клиентов ошибочны, и они не замечают этого в течение нескольких дней. В этом случае они позвонят нам и попросят восстановить свой инвентарь до прежнего состояния. Мы должны иметь возможность делать периодические снимки данных клиентом для быстрого восстановления. Вот простой пример БД для иллюстрации: в приведенном ниже примере мне нужно выполнить резервное копирование только строк в product на customer_id для последующего восстановления, а при восстановлении я хочу, чтобы остальные строки остались одни и только строкипринадлежащий этому конкретному customer_id восстановлен:

CREATE TABLE customer (
    id SERIAL PRIMARY KEY,
    name TEXT
);

CREATE TABLE color (
    id SERIAL PRIMARY KEY,
    name TEXT
);

CREATE TABLE flag (
    id SERIAL PRIMARY KEY,
    name TEXT
);

CREATE TABLE product (
    id SERIAL PRIMARY KEY,
    name TEXT,
    color_id INTEGER, -- foreign key to color(id)
    customer_id INTEGER -- foreign key to customer(id)
);

CREATE TABLE product_flag_join (
   id SERIAL PRIMARY KEY,
   product_id INTEGER, -- foreign key to product(id)
   flag_id -- foreign key to flag(id)
);

1 Ответ

1 голос
/ 22 октября 2019

Использование разбиение таблицы кажется хорошим решением. Это требует довольно большой подготовительной работы, но дает большой комфорт при резервном копировании и восстановлении данных. Каждый клиент должен иметь свои собственные разделы во всех таблицах, которые содержат данные, специфичные для клиента, поэтому вы можете создать резервную копию всей базы данных с помощью одной команды (предпочтительно в двоичном формате) и восстановить только выбранные таблицы. Вы также можете рассмотреть возможность создания клиентских разделов в отдельных схемах и при необходимости восстановить всю схему.

Если по какой-либо причине вышеприведенное невозможно, я бы подумал о следующей схеме:

  • установить спасательный сервер Postgres на локальном компьютере
  • выполнять ежедневное двоичное резервное копирование всей базы данных
  • восстанавливать резервную копию с требуемого дня на сервере спасения при необходимости
  • генерироватьДамп SQL путем запроса к серверу спасения
  • восстановление дампа SQL на главном сервере
...