Инкрементальный архив и восстановление частичных таблиц Postgresql - PullRequest
0 голосов
/ 23 мая 2018

Мне интересно, каковы лучшие практики для:

  1. Периодически (ежемесячно) архивировать часть таблицы Postgresql в .sql файл

  2. Затем можно восстановить эту часть в исходной таблице, если необходимо.

Например, скажем, у меня есть transactions_table, который выглядит следующим образом:

+----+------------+-------------+
| Id |    Date    | Transaction |
+----+------------+-------------+
|  1 | 2017-06-01 |         123 |
|  2 | 2017-06-02 |         120 |
|  3 | 2017-07-01 |          45 |
|  4 | 2017-08-01 |         420 |
+----+------------+-------------+

Как мне поступить с архивированием данных за июнь 2017 года, чтобы все данные за июнь 2017 года были удалены из transactions_table, и я создаю файл June2017.sql, который содержит команды вставки и всю другую информацию, чтобы ее можно было легко повторно ввести вtransactions_table?Это возможно с pg_dump или есть лучшая альтернатива?

Postgresql db v9.6 и поддерживается AWS.Я планирую хранить June2017.sql и тому подобное либо в корзине S3, либо в долговременном хранилище, таком как AWS Glacier.Я могу понять эту часть.Просто нужно знать, как правильно архивировать данные.

Извините за широкий вопрос.Любая помощь приветствуется.

1 Ответ

0 голосов
/ 24 мая 2018
  1. pg_dump не поддерживает WHERE из коробки.Но здесь кто-то предоставил патч, который вводит эту функцию.Вы можете попробовать, если это работает для вас.

  2. Альтернативой может быть написание функции, которая создает новую таблицу, скажем archive_transactions_table и pg_dump этой таблицы.

    CREATE FUNCTION create_archive_transactions_table
                    (_year integer,
                     _month integer)
                    RETURNS void
    AS
    $$
    BEGIN
      DROP TABLE IF EXISTS archive_transactions_table;
      CREATE TABLE archive_transactions_table
                   AS SELECT *
                             FROM transactions_table
                             WHERE date_part('year', date) = _year
                                   AND date_part('month', date) = _month;
    END;
    $$
    LANGUAGE plpgsql;
    
  3. Вы также можете свернуть свои собственные INSERT операторы путем конкатенации текста.Затем вы можете выбрать их из transactions_table для строк с периодом времени.Возможно, поместите его в функцию, используя COPY, чтобы напрямую экспортировать составленные операторы в файл.COPY поддерживает WHERE (или запрос в целом), но не создает INSERT операторов самостоятельно.

    CREATE FUNCTION archive_transactions_table
                    (_year integer,
                     _month integer,
                     _path text)
                    RETURNS void
    AS
    $$
    DECLARE
      _copy_command text;
    BEGIN
      _copy_command := 'COPY (SELECT ''INSERT INTO transactions_table (id, date, transaction) VALUES ('' || id || '', '''''' || date || '''''', '' || transaction || '');'' insert_query'
                    || '             FROM transactions_table'
                    || '             WHERE date_part(''year'', date) = ' || _year
                    || '                   AND date_part(''month'', date) = ' || _month || ')'
                    || 'TO ''' || regexp_replace(_path, '([^/])$', '\1/') || _year || '-' || lpad(_month::text, 2, '0') || '.sql''';
      EXECUTE _copy_command;
    END;
    $$
    LANGUAGE plpgsql;
    

    (Примечание. Путь к COPY не может бытьВыражение (например, _year || '-' || _month || '.sql). Вот почему вся команда должна создаваться динамически.)

Или любое возможное сочетание вышеперечисленного.

Посмотритев pgAgent для создания запланированного задания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...