pgcopydb

Автоматизация миграции баз данных между кластерами PostgreSQL.
Утилита pgcopydb реализует полную миграцию всей базы данных PostgreSQL из исходного экземпляра в целевой. Оба экземпляра PostgreSQL должны быть доступны в течение всего срока действия команды. Также утилита реализует клиент полного логического декодирования для PostgreSQL. Это позволяет осуществлять захват изменений данных (DML), происходящих в исходной базе данных после моментального снимка базовой копии, для воспроизведения на целевом сервере. Клиентский код логического декодирования pgcopydb совместим с плагином логического декодирования test_decoding и с плагином wal2json, по умолчанию используется test_decoding.

Ограничения

  • утилита не запрашивает пароль для части команд, то есть пароль нужно или передавать параметром или использовать способы аутентификации не требующие пароля (например, аутентификация по сертификату);
  • утилита не поддерживает работу с хранилищем паролей, пароли необходимо вводить вручную либо использовать способы аутентификации не требующие пароля (например, аутентификация по сертификату);
  • при полной миграции БД набор установленных в мигрируемую БД расширений должен быть абсолютно идентичен в части версий и настроек GUC между источником и целевой базой, в противном случае возможны ошибки миграции;
  • заявленная возможность follow, позволяющая реализовать CDC, упадет в ошибку, если одна из БД по какой-либо причине будет перезапущена;
  • заявленная возможность follow требует прав суперпользователя в БД приемнике для выполнения команды SET session_replication_role;
  • заявленная возможность follow не работает с TDE.

Использование модуля

Утилита pgcopydb позволяет выполнять команды:
  • clone – клонирование базы данных из сервера источника в целевой;
  • fork – клонирование базы данных из сервера источника в целевой (alias для предыдущей команды clone);
  • follow – проигрывание изменения БД источника в целевой БД;
  • snapshot – создание и экспортирование снимка данных БД источника;
  • compare – сравнение БД источника и целевой БД:
    • schema – сравнение схемы в БД источника и целевой БД;
    • data – сравнение данных в БД источника и целевой БД.
  • copy – копирование объектов БД:
    • db – копирование БД из источника в целевую СУБД;
    • roles – копирование ролей из источника в целевую СУБД;
    • extensions – копирование расширений из источника в целевую СУБД;
    • schema – копирование схемы БД из источника в целевую БД;
    • data – копирование данных из источника в целевую БД;
    • table-data – копирование данных из всех таблиц источника в целевую БД;
    • blobs – копирование BLOB из источника в целевую БД;
    • sequences – копирование текущего значения всех последовательностей из источника в целевую БД;
    • indexes – создание всех индексов, найденных в БД источника, в целевой БД;
    • constraints – создание всех ограничений, найденных в БД источника, в целевой БД.
  • dump – создание логического дампа БД:
    • schema – создание дампа схемы БД источника;
    • pre-data – создание дампа схемы pre-data исходной базы данных в виде пользовательских файлов в рабочую директорию;
    • post-data – создание дампа схемы post-data исходной базы данных в виде пользовательских файлов в рабочую директорию;
    • roles – создание дампа ролей БД источника.
  • restore – восстановление БД из логической резервной копии:
    • schema – восстановление схемы БД из созданного ранее дампа;
    • pre-data – восстановление схемы pre-data базы данных из пользовательского файла в целевую базу данных;
    • post-data – восстановление схемы post-data базы данных из пользовательского файла в целевую базу данных;
    • roles – восстановление роли БД из созданного ранее дампа (файл SQL);
    • parse-list – парсинг вывода команды pg_restore --list из переданных файлов.
  • list – вывод списка объектов БД:
    • databases – список БД;
    • extensions – список расширений источника для копирования;
    • collations – список collations БД источника;
    • tables – список таблиц БД-источника;
    • table-parts – список партиций таблиц БД источника;
    • sequences – список всех последовательностей БД источника;
    • indexes – список всех индексов для создания после копирования данных;
    • depends – список всех зависимостей для фильтрации;
    • schema – список схем для миграции в формате JSON;
    • progress – состояние (прогресс) миграции.
  • stream – потоковое применение изменений из исходной базы данных:
    • setup – настройка СУБД источника и целевой СУБД для логического декодирования;
    • cleanup – очистка настроек логического декодирования СУБД источника и целевой СУБД;
    • prefetch – потоковая фиксация изменений БД источника в формате JSON и преобразование их в формат SQL;
    • catchup – применение сохраненных в формат SQL изменений в целевую БД;
    • replay – применение изменений данных из БД источника в целевую БД;
    • sentinel – обслуживание контрольной таблицы в БД источника:
      • setup – настройка контрольной таблицы;
      • get – получение значения из контрольной таблицы в БД источника;
      • set – обслуживание контрольной таблицы в БД источника:
        • startpos – установка контрольной стартовой позиции LSN в БД источника;
        • endpos – установка контрольной конечной позиции LSN в БД источника;
        • apply – установка режима apply в БД источника;
        • prefetch – установка режима prefetch в БД источника.
      • receive – потоковое применение изменений данных из БД источника;
      • transform – преобразование изменений БД источника в SQL-команды;
      • apply – применение изменений данных из БД источника в целевую БД.
  • ping – проверка подключения к БД источника и целевой БД;
  • help – вывод справки;
  • version – вывод версии.

Описание команд

  • pgcopydb help - вывод справки. Команда выводит информацию по основным командам утилиты на английском языке. Пример:
    Раскрыть type=sql
    $ pgcopydb help
    pgcopydb
    clone     Clone an entire database from source to target
    fork      Clone an entire database from source to target
    follow    Replay changes from the source database to the target database
    snapshot  Create and export a snapshot on the source database
    + compare   Compare source and target databases
    + copy      Implement the data section of the database copy
    + dump      Dump database objects from a Postgres instance
    + restore   Restore database objects into a Postgres instance
    + list      List database objects from a Postgres instance
    + stream    Stream changes from the source database
      ping      Attempt to connect to the source and target instances
      help      Print help message
      version   Print pgcopydb version
    
    pgcopydb compare
    schema  Compare source and target schema
    data    Compare source and target data
    
    pgcopydb copy
    db           Copy an entire database from source to target
    roles        Copy the roles from the source instance to the target instance
    extensions   Copy the extensions from the source instance to the target instance
    schema       Copy the database schema from source to target
    data         Copy the data section from source to target
    table-data   Copy the data from all tables in database from source to target
    blobs        Copy the blob data from the source database to the target
    sequences    Copy the current value from all sequences in database from source to target
    indexes      Create all the indexes found in the source database in the target
    constraints  Create all the constraints found in the source database in the target
    
    pgcopydb dump
    schema     Dump source database schema as custom files in work directory
    pre-data   Dump source database pre-data schema as custom files in work directory
    post-data  Dump source database post-data schema as custom files in work directory
    roles      Dump source database roles as custome file in work directory
    
    pgcopydb restore
    schema      Restore a database schema from custom files to target database
    pre-data    Restore a database pre-data schema from custom file to target database
    post-data   Restore a database post-data schema from custom file to target database
    roles       Restore database roles from SQL file to target database
    parse-list  Parse pg_restore --list output from custom file
    
    pgcopydb list
    databases    List databases
    extensions   List all the source extensions to copy
    collations   List all the source collations to copy
    tables       List all the source tables to copy data from
    table-parts  List a source table copy partitions
    sequences    List all the source sequences to copy data from
    indexes      List all the indexes to create again after copying the data
    depends      List all the dependencies to filter-out
    schema       List the schema to migrate, formatted in JSON
    progress     List the progress
    
    pgcopydb stream
    setup      Setup source and target systems for logical decoding
    cleanup    Cleanup source and target systems for logical decoding
    prefetch   Stream JSON changes from the source database and transform them to SQL
    catchup    Apply prefetched changes from SQL files to the target database
    replay     Replay changes from the source to the target database, live
    + sentinel   Maintain a sentinel table on the source database
      receive    Stream changes from the source database
      transform  Transform changes from the source database into SQL commands
      apply      Apply changes from the source database into the target database
    
    pgcopydb stream sentinel
    setup   Setup the sentinel table
    get     Get the sentinel table values on the source database
    + set     Maintain a sentinel table on the source database
    
    pgcopydb stream sentinel set
    startpos  Set the sentinel start position LSN on the source database
    endpos    Set the sentinel end position LSN on the source database
    apply     Set the sentinel apply mode on the source database
    prefetch  Set the sentinel prefetch mode on the source database
    
  • pgcopydb version - вывод версии утилиты. Для вывода версии в формате JSON используйте опцию --json. Информация об используемой версии PostgreSQL показывает версию, которая использовалась для сборки pgcopydb, она же является версией клиентской библиотеки libpq. Пример вывода:
    Раскрыть type=sql
    $ pgcopydb version --json
    {
    "pgcopydb": "0.13.1.g868ad77",
    "pg_major": "13",
    "pg_version": "13.11 (Debian 13.11-0+deb11u1)",
    "pg_version_str": "PostgreSQL 13.11 (Debian 13.11-0+deb11u1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit",
    "pg_version_num": 130011
    }
    
  • pgcopydb ping - проверка возможности подключения к исходной БД и к целевой БД PostgreSQL. Попытка подключения выполняется одновременно к обеим БД.
    Обязательные параметры:
    • --source – строка подключения к БД источника PostgreSQL (в формате libpq, может быть задана переменной окружения PGCOPYDB_SOURCE_PGURI);
    • --target – строка подключения к целевой БД PostgreSQL (в формате libpq, может быть задана переменной окружения PGCOPYDB_TARGET_PGURI).
    Раскрыть type=sql
    $ pgcopydb ping --source "host=hostname port=port dbname=plop user=username" --target "postgres://username@hostname:port/pagila?"
    18:04:48 84679 INFO   Running pgcopydb version 0.10.31.g7e5fbb8.dirty from "/Users/dim/dev/PostgreSQL/pgcopydb/src/bin/pgcopydb/pgcopydb"
    18:04:48 84683 INFO   Successfully could connect to target database at "postgres://username@hostname:port/plop?"
    18:04:48 84682 INFO   Successfully could connect to source database at "postgres://username@hostname:port/pagila?"
    
  • pgcopydb clone - команда clone реализует как базовую копию БД источника в целевую БД, так и полный клиент логического декодирования для плагина логического декодирования wal2json или test_decoding(определяется параметром plugin).
    Синопсис type=sql
    pgcopydb clone: Клонирование всей базы данных из источника в целевую
    Использование: pgcopydb clone  --source ... --target ... [ --table-jobs ... --index-jobs ... ]
    
    --source                      Postgres URI к исходной базе данных
    --target                      Postgres URI к целевой базе данных
    --dir                         Рабочий каталог для временных файлов
    --table-jobs                  Количество одновременно выполняемых заданий COPY
    --index-jobs                  Количество одновременно выполняемых заданий CREATE INDEX
    --restore-jobs                Количество параллельных заданий для pg_restore
    --large-objects-jobs          Количество одновременно выполняемых заданий копирования Large Objects
    --split-tables-larger-than    Порог размера параллелизма между таблицами
    --drop-if-exists              В целевой базе данных сначала выполняется очистка от предыдущего запуска
    --roles                       Скопировать роли, найденные в источнике, в целевую базу данных
    --no-role-passwords           Не клонировать пароли для ролей
    --no-owner                    Не устанавливать владельца на объекты в соответствии с исходной базой данных
    --no-acl                      Предотвращает восстановление привилегий доступа (команды grant/revoke)
    --no-comments                 Не выводить команды для восстановления комментариев
    --skip-large-objects          Пропускать копирование больших объектов (blobs)
    --skip-extensions             Пропускать восстановление расширений
    --skip-ext-comments           Пропустить восстановление COMMENT ON EXTENSION
    --skip-collations             Пропустить восстановление правил сортировки
    --skip-vacuum                 Пропустить запуск VACUUM ANALYZE
    --requirements <filename>     Список требований к расширениям
    --filters <filename>          Использовать фильтры, определенные в <filename>
    --fail-fast                   Досрочно прервать работу в случае ошибки
    --restart                     Разрешить перезапуск, если временные файлы уже существуют
    --resume                      Разрешить возобновление операций после сбоя
    --not-consistent              Разрешить создание нового моментального снимка исходной базы данных
    --snapshot                    Использовать снимок, полученный с помощью pg_export_snapshot
    --follow                      Реализовать логическое декодирование для воспроизведения изменений
    --plugin                      Какой плагин использовать для вывода (test_decoding, wal2json)
    --wal2json-numeric-as-string  Выводить числовой тип данных в виде строки при использовании плагина вывода wal2json
    --slot-name                   Использовать данное имя слота репликации Postgres
    --create-slot                 Создать слот репликации
    --origin                      Использовать это имя узла начала репликации Postgres
    --endpos                      Остановить воспроизведение изменений при достижении данного LSN
    
    Базовая копия или операция клонирования
    После вызова команды pgcopydb clone выполняются действия:
    1. pgcopydb получает список обычных и секционированных таблиц запросом из каталога в исходной базе данных, а также список индексов и список последовательностей с их текущими значениями. При использовании фильтрации на этом шаге создается список OID-объектов, которые должны быть отфильтрованы.
    2. pgcopydb вызывает pg_dump для создания разделов pre-data и post-data дампа, используя формат custom.
    3. Раздел дампа pre-data восстанавливается в целевой базе данных с помощью команды pg_restore, создающей все объекты PostgreSQL из исходной базы данных в целевой базе данных. При использовании фильтрации используется опция pg_restore --use-list для фильтрации списка объектов восстановления на этом шаге. На этом шаге используется столько заданий, сколько задано в параметре --restore-jobs для pg_restore, чтобы разделить рабочую нагрузку и восстановить объекты параллельно.
    4. Запускается столько подпроцессов COPY, сколько указано в параметре --table-jobs, чтобы разделить рабочую нагрузку и скопировать данные из источника в целевую базу данных по одной таблице за раз, в цикле. Подключение PostgreSQL и SQL-запрос к таблице каталога PostgreSQL pg_class используются для получения списка таблиц с данными для копирования, а статистика reltuples используется для того, чтобы сначала начать с таблиц с наибольшим количеством строк, в попытке минимизировать время копирования.
    5. Вспомогательный процесс перебирает все LOB, найденные в исходной базе данных, и копирует их в целевую базу данных, во многом так же, как это сделал бы сам pg_dump. Этот шаг во многом похож на pg_dump | pg_restore для данных LOB, за исключением того, что нет способа сделать это параллельно с помощью данных инструментов.
    6. Запускается столько подпроцессов CREATE INDEX, сколько задано в параметре --index-jobs, для распараллеливания рабочей нагрузки и построения индексов. Чтобы убедиться, что команды CREATE INDEX запускаются только после завершения операции копирования, используется механизм очереди. Как только копирование данных таблицы завершено, все индексы для таблицы ставятся в очередь для обработки подпроцессами CREATE INDEX. На этом этапе первичные индексы создаются как UNIQUE-индексы.
    7. Создаются ограничения первичного ключа с использованием только что созданных индексов. Этот двухэтапный подход позволяет создавать сам индекс первичного ключа параллельно с другими индексами в той же таблице, избегая исключительной блокировки при создании индекса.
    8. Для распределения рабочей нагрузки запускается столько подпроцессов VACUUM ANALYZE, сколько указано в параметре --table-jobs. Как только копирование данных таблицы завершено, таблица ставится в очередь для обработки подпроцессами VACUUM ANALYZE.
    9. Вспомогательный процесс перебирает последовательности в исходной базе данных и для каждой из них запускает отдельный запрос к источнику, чтобы получить метаданные last_value и is_called таким же образом, как это делает pg_dump. Для каждой последовательности pgcopydb затем вызывает pg_catalog.setval() в целевой базе данных с информацией, полученной в исходной базе данных.
    10. Заключительный этап состоит в запуске команды pg_restore для сценария раздела post-data для всей базы данных, и именно здесь создаются ограничения внешнего ключа и другие элементы. Сценарий post-data отфильтровывается с помощью параметра pg_restore --use-list, так что индексы и ограничения первичного ключа, уже созданные на шагах 6 и 7, теперь должным образом пропускаются. На этом шаге используется столько заданий, сколько указано в параметре --restore-jobs для pg_restore, чтобы разделить рабочую нагрузку и восстановить объекты параллельно.
    Влияние ролей при создании резервной копии и восстановлении
    В Компоненте есть понятие признака суперпользователя, который может быть присвоен любой роли в системе, и роль postgres по умолчанию имеет этот статус. Суперпользователь базы данных обходит все проверки прав доступа, за исключением права на вход в систему. Это опасная привилегия и она не должна использоваться небрежно. Лучше всего выполнять большую часть работы не как суперпользователь. Для создания нового суперпользователя используется CREATE ROLE имя SUPERUSER. Эту команду нужно выполнить из-под роли, которая также является суперпользователем.
    Некоторые объекты Компонента могут быть созданы только суперпользователями, а некоторые операции чтения и записи разрешены только ролям суперпользователя, например:
    • чтение пароля роли pg_authid (даже в зашифрованном виде) ограничено ролями со статусом суперпользователя. Чтение этой таблицы каталога выполняется при вызове pg_dumpall --roles-only, чтобы затем файл дампа можно было использовать для восстановления ролей, включая их пароли. Можно реализовать миграцию pgcopydb, которая полностью пропускает пароли при использовании опции --no-role-passwords. Однако в этом случае аутентификация может завершиться неудачей до тех пор, пока пароли не будут снова настроены правильно;
    • большинство доступных расширений PostgreSQL, по крайней мере, если они написаны на языке Си, могут быть созданы только ролями со статусом суперпользователя. Если такое расширение содержит таблицы конфигурации расширений и было создано с ролью, имеющей статус суперпользователя, то для pg_dump и pg_restore этого расширения и его текущей конфигурации снова требуется тот же статус суперпользователя;
    • опция follow выполняет в целевой базе данных команду session_replication_role , для выполнения которой требуются права суперпользователя в целевой базе данных.
    При использовании pgcopydb рекомендуется разделить миграцию на привилегированную и непривилегированную части, как в следующих примерах:
    Раскрыть type=sql
    $ coproc ( pgcopydb snapshot )
    
    # first two commands would use a superuser role to connect
    $ pgcopydb copy roles --source ... --target ...
    $ pgcopydb copy extensions --source ... --target ...
    
    # now it's possible to use a non-superuser role to connect
    $ pgcopydb clone --skip-extensions --source ... --target ...
    
    $ kill -TERM ${COPROC_PID}
    $ wait ${COPROC_PID}
    
    В таком сценарии вызовы операций pgcopydb copy и pgcopydb copy extensions будут выполняться со строками подключения, которые соединяются с ролью, имеющей статус суперпользователя; а затем вызов pgcopydb clone будет выполняться с непривилегированной ролью, обычно той, которая владеет исходной и целевой базами данных.
    В настоящее время в pg_dump существует ограничение, которое влияет на pgcopydb. Когда расширение с таблицей конфигурации установлено от имени суперпользователя, даже основная операция клонирования pgcopydb должна выполняться со статусом суперпользователя. Это связано с тем, что фильтрация pg_dump (имеется в виду параметр --exclude-table) не применяется к элементам расширения, а pg_dump не предоставляет механизма для исключения расширений.
    Реализация CDC (Change Data Capture) с использованием логического декодирования PostgreSQL
    При использовании опции --follow шаги из команды pgcopydb follow также выполняются одновременно с основной копией. Затем CDC автоматически переключается с фазы только предварительной выборки на фазу предварительной выборки и последующей обработки, которая включается, как только выполнится базовая копия.
    Смотрите описание команды pgcopydb stream sentinel, устанавливающей endpos для удаленного управления последующими частями команды, даже когда команда уже запущена.
    Команда pgcopydb stream cleanup должна использоваться для освобождения ресурсов, созданных для поддержки процесса отслеживания изменения данных.
    Обязательно ознакомьтесь с разделом о pgcopydb follow и подробностями об ограничениях логической репликации в документации PostgreSQL.
    Пример 1. Ниже приведен простой подход к применению изменений после создания первоначальной базовой копии:
    Раскрыть type=sql
    $ pgcopydb clone --follow &
    
    # later when the application is ready to make the switch
    $ pgcopydb stream sentinel set endpos --current
    
    # later when the migration is finished, clean-up both source and target
    $ pgcopydb stream cleanup
    
    Пример 2. В некоторых случаях может потребоваться больший контроль над некоторыми из описанных здесь шагов. Учитывая гибкость pgcopydb, можно реализовать следующие шаги:
  1. Сделайте снимок (snapshot) из исходной базы данных и удерживайте открытое соединение с PostgreSQL на время создания базовой копии. В случае сбоя или других проблем с основными операциями можно возобновить обработку базовой копии и применение изменений с тем же снимком еще раз. Этот шаг также применим при использовании pgcopydb clone --follow. Тем не менее, если команда была прервана (или завершилась сбоем), снимок может быть потерян.
  2. Настройте логическое декодирование на основе снимка, полученного на предыдущем шаге, и слежение за репликацией в целевой базе данных. Затем будут созданы следующие объекты SQL:
    • слот репликации в исходной базе данных;
    • таблица pgcopydb.sentinel в исходной базе данных;
    • источник репликации в целевой базе данных.
    Этот шаг также применим при использовании pgcopydb clone --follow. Не существует способа реализовать Change Data Capture с помощью pgcopydb и пропустить создание этих SQL-объектов.
  3. Запустите создание базовой копии исходной базы данных и выполните предварительную выборку изменений при помощи операции логического декодирования, чтобы гарантировать, что используются данные из слота репликации и сервер исходной базы данных может повторно использовать свои файлы WAL.
  4. Возможно удаленное управление процессом применения изменений, чтобы прекратить отслеживание и применение их к целевой базе данных. До отмены изменения будут отслеживаться и применяться к целевой БД.
  5. Повторно синхронизируйте последовательности с их текущими значениями. Последовательности не обрабатываются логическим декодированием PostgreSQL, поэтому необходимо перенести их вручную с особой осторожностью. В будущих версиях pgcopydb этот шаг будет включен в команду pgcopydb clone --snapshot, в результате чего синхронизация будет выполняться автоматически после того, как она перестанет использовать изменения и до завершения процесса.
  6. Очистите ресурсы, выделенные для поддержки возобновляемости всего процесса (слот репликации в исходной базе данных, контрольная таблица pgcopydb в исходной базе данных, настройки репликации в целевой базе данных).
  7. Прекратите хранение моментального снимка (snapshot) в исходной базе данных, остановив процесс создания моментального снимка pgcopydb, оставшийся запущенным в фоновом режиме.
Если команда pgcopydb clone --follow завершается неудачей, то ее можно запустить снова. Она автоматически обнаружит, какие шаги были выполнены успешно и что необходимо выполнить повторно, поскольку не запускалось или было прервано (копирование таблицы, создание индекса, возобновление использования слота репликации, возобновление применения изменений в правильной позиции LSN и т.д.).
Тем не менее, если завершение произошло по причине сбоя в БД и утерян моментальный снимок, удерживаемый на шаге 1, возобновить миграцию будет невозможно.
Команда pgcopydb clone --follow в целевой БД выполняет запрос session_replication_role, для выполнения которого, согласно документации PostgreSQL необходимы права суперпользователя, а значит для данного сценария подключение к целевой БД должно осуществляться суперпользователем.
Пример реализации описанных шагов:
Раскрыть type=sql
$ pgcopydb snapshot &

$ pgcopydb stream setup

$ pgcopydb clone --follow &

# later when the application is ready to make the switch
$ pgcopydb stream sentinel set endpos --current

# when the follow process has terminated, re-sync the sequences
$ pgcopydb copy sequences

# later when the migration is finished, clean-up both source and target
$ pgcopydb stream cleanup

# now stop holding the snapshot transaction (adjust PID to your environment)
$ kill %1
Пример клонирования БД:
Раскрыть type=sql
$ export PGCOPYDB_SOURCE_PGURI=postgres://pagila:0wn3d@source/pagila
$ export PGCOPYDB_TARGET_PGURI=postgres://pagila:0wn3d@target/pagila
$ export PGCOPYDB_DROP_IF_EXISTS=on

$ pgcopydb clone --table-jobs 8 --index-jobs 12
14:49:01 22 INFO   Running pgcopydb version 0.13.38.g22e6544.dirty from "/usr/local/bin/pgcopydb"
14:49:01 22 INFO   [SOURCE] Copying database from "postgres://pagila@source/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
14:49:01 22 INFO   [TARGET] Copying database into "postgres://pagila@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
14:49:01 22 INFO   Exported snapshot "00000003-00000022-1" from the source database
14:49:01 24 INFO   STEP 1: fetch source database tables, indexes, and sequences
14:49:01 24 INFO   Fetched information for 3 extensions
14:49:01 24 INFO   Splitting source candidate tables larger than 200 kB
14:49:01 24 INFO   Table public.rental is 1224 kB large, 7 COPY processes will be used, partitioning on rental_id.
14:49:01 24 INFO   Table public.film is 472 kB large, 3 COPY processes will be used, partitioning on film_id.
14:49:01 24 INFO   Table public.film_actor is 264 kB large which is larger than --split-tables-larger-than 200 kB, and does not have a unique column of type integer: splitting by CTID
14:49:01 24 INFO   Table public.film_actor is 264 kB large, 2 COPY processes will be used, partitioning on ctid.
14:49:01 24 INFO   Table public.inventory is 264 kB large, 2 COPY processes will be used, partitioning on inventory_id.
14:49:01 24 INFO   Fetched information for 21 tables, with an estimated total of 0 tuples and 3816 kB
14:49:01 24 INFO   Fetched information for 54 indexes
14:49:01 24 INFO   Fetching information for 13 sequences
14:49:01 24 INFO   STEP 2: dump the source database schema (pre/post data)
14:49:01 24 INFO    /usr/bin/pg_dump -Fc --snapshot 00000003-00000022-1 --section pre-data --file /tmp/pgcopydb/schema/pre.dump 'postgres://pagila@source/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60'
14:49:01 24 INFO    /usr/bin/pg_dump -Fc --snapshot 00000003-00000022-1 --section post-data --file /tmp/pgcopydb/schema/post.dump 'postgres://pagila@source/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60'
14:49:02 24 INFO   STEP 3: restore the pre-data section to the target database
14:49:02 24 INFO    /usr/bin/pg_restore --dbname 'postgres://pagila@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60' --single-transaction --use-list /tmp/pgcopydb/schema/pre-filtered.list /tmp/pgcopydb/schema/pre.dump
14:49:02 24 INFO   STEP 6: starting 12 CREATE INDEX processes
14:49:02 24 INFO   STEP 7: constraints are built by the CREATE INDEX processes
14:49:02 24 INFO   STEP 8: starting 8 VACUUM processes
14:49:02 24 INFO   STEP 9: reset sequences values
14:49:02 51 INFO   STEP 5: starting 4 Large Objects workers
14:49:02 30 INFO   STEP 4: starting 8 table data COPY processes
14:49:02 52 INFO   Reset sequences values on the target database
14:49:02 51 INFO   Added 0 large objects to the queue
14:49:04 24 INFO   STEP 10: restore the post-data section to the target database
14:49:04 24 INFO    /usr/bin/pg_restore --dbname 'postgres://pagila@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60' --single-transaction --use-list /tmp/pgcopydb/schema/post-filtered.list /tmp/pgcopydb/schema/post.dump

OID | Schema |             Name | copy duration | transmitted bytes | indexes | create index duration
------+--------+------------------+---------------+-------------------+---------+----------------------
16880 | public |           rental |         160ms |            188 kB |       3 |                 230ms
16880 | public |           rental |          77ms |            189 kB |       0 |                   0ms
16880 | public |           rental |         105ms |            189 kB |       0 |                   0ms
16880 | public |           rental |         107ms |            189 kB |       0 |                   0ms
16880 | public |           rental |          97ms |            190 kB |       0 |                   0ms
16880 | public |           rental |          82ms |            189 kB |       0 |                   0ms
16880 | public |           rental |          81ms |            189 kB |       0 |                   0ms
16758 | public |             film |         136ms |            112 kB |       5 |                 462ms
16758 | public |             film |          52ms |            110 kB |       0 |                   0ms
16758 | public |             film |          74ms |            111 kB |       0 |                   0ms
16770 | public |       film_actor |          74ms |            5334 B |       0 |                   0ms
16770 | public |       film_actor |          77ms |            156 kB |       0 |                   0ms
16825 | public |        inventory |         106ms |             74 kB |       2 |                 586ms
16825 | public |        inventory |         107ms |             76 kB |       0 |                   0ms
16858 | public | payment_p2022_03 |          86ms |            137 kB |       4 |                 468ms
16866 | public | payment_p2022_05 |          98ms |            136 kB |       4 |                 663ms
16870 | public | payment_p2022_06 |         106ms |            134 kB |       4 |                 571ms
16862 | public | payment_p2022_04 |         125ms |            129 kB |       4 |                 775ms
16854 | public | payment_p2022_02 |         117ms |            121 kB |       4 |                 684ms
16874 | public | payment_p2022_07 |         255ms |            118 kB |       1 |                 270ms
16724 | public |         customer |         247ms |             55 kB |       4 |                 1s091
16785 | public |          address |         128ms |             47 kB |       2 |                 132ms
16795 | public |             city |         163ms |             23 kB |       2 |                 270ms
16774 | public |    film_category |         172ms |             28 kB |       1 |                  47ms
16850 | public | payment_p2022_01 |         166ms |             36 kB |       4 |                 679ms
16738 | public |            actor |         399ms |            7999 B |       2 |                 116ms
16748 | public |         category |         170ms |             526 B |       1 |                 200ms
16805 | public |          country |          63ms |            3918 B |       1 |                 226ms
16900 | public |            staff |         170ms |             272 B |       1 |                 114ms
16832 | public |         language |         115ms |             276 B |       1 |                  68ms
16911 | public |            store |          88ms |              58 B |       2 |                 185ms


                                               Step   Connection    Duration    Transfer   Concurrency
 --------------------------------------------------   ----------  ----------  ----------  ------------
                                        Dump Schema       source        98ms                         1
Catalog Queries (table ordering, filtering, etc)       source       687ms                         1
Prepare Schema       target       667ms                         1
COPY, INDEX, CONSTRAINTS, VACUUM (wall clock)         both       1s256                    8 + 20
COPY (cumulative)         both       4s003     2955 kB             8
Large Objects (cumulative)         both       877ms                         4
CREATE INDEX, CONSTRAINTS (cumulative)       target       7s837                        12
Finalize Schema       target       487ms                         1
 --------------------------------------------------   ----------  ----------  ----------  ------------
                          Total Wall Clock Duration         both       3s208                    8 + 20
 --------------------------------------------------   ----------  ----------  ----------  ------------
  • pgcopydb fork - команда является alias команды pgcopydb clone. Команда присутствует в списке исторически и оставлена для обратной совместимости.
  • pgcopydb follow - проигрывает изменения базы данных, зарегистрированные в исходной базе данных, с помощью плагина логического декодирования по выбору (либо test_decoding (по умолчанию), либо wal2json), в целевую базу данных.
    Хотя pgcopydb follow реализует полноценный клиент для логического декодирования, основной вариант использования предполагает использование pgcopydb clone --follow, как описано в разделе про Change Data Capture в описании команды pgcopydb clone с использованием логического декодирования PostgreSQL.
    При использовании логического декодирования с помощью pgcopydb или другого инструмента убедитесь, что вы знакомы с применяемыми ограничениями логической репликации. В частности:
    • DDL не реплицируются. При использовании DDL для обслуживания схемы разделов, например, при использовании расширения pg_partman, рассмотрите возможность создания разделов на неделю или месяц вперед, чтобы создание новых разделов не происходило во время окна миграции;
    • последовательности не реплицируются. При использовании pgcopydb clone --follow (начиная с pgcopydb версии 0.9) последовательности синхронизируются в конце операции, после точки перехода, реализованной с помощью pgcopydb stream sentinel set endpos. Обновление последовательностей вручную также возможно путем выполнения команды pgcopydb copy sequences;
    • большие объекты (LOB) не реплицируются.
    Смотрите страницу документации PostgreSQL по ограничениям логической репликации, чтобы ознакомиться с исчерпывающим списком ограничений.
    Синопсис type=sql
    pgcopydb follow: Воспроизведение изменений из исходной базы данных в целевую базу данных
    Использование: pgcopydb follow  --source ... --target ...
    
    --source                      Postgres URI к исходной базе данных
    --target                      Postgres URI к целевой базы данных
    --dir                         Рабочий каталог для временных файлов
    --filters <filename>          Использовать фильтры, определенные в <filename>
    --restart                     Разрешить перезапуск, если временные файлы уже существуют
    --resume                      Разрешить возобновление операций после сбоя
    --not-consistent              Разрешить создание нового моментального снимка исходной базы данных
    --snapshot                    Использовать snapshot, полученный с помощью pg_export_snapshot
    --plugin                      Какой плагин использовать для вывода (test_decoding, wal2json)
    --wal2json-numeric-as-string  Выводить числовой тип данных в виде строки при использовании плагина вывода wal2json
    --slot-name                   Использовать данное имя слота репликации Postgres
    --create-slot                 Создать слот репликации
    --origin                      Использовать это имя узла начала репликации Postgres
    --endpos                      Остановить воспроизведение изменений при достижении данного LSN
    
    Команда запускает три параллельных подпроцесса в двух возможных режимах работы:
    • первый режим работы называется prefetch&catchup, при котором изменения из исходной базы данных сохраняются в промежуточных файлах JSON и SQL для последующего воспроизведения по одному файлу за раз в процессе catchup;
    • второй режим работы называется live replay, при котором изменения из исходной базы данных передаются потоком из процесса-получателя в процесс преобразования с использованием канала Unix, а затем с помощью того же механизма из процесса преобразования в процесс воспроизведения.
    В любой момент времени может быть активен только один режим работы, и pgcopydb автоматически переключается из одного режима в другой в цикле.
    Команда follow всегда запускается с использованием режима предварительной выборки и перехвата (prefetch&catchup), и как только процесс перехвата не может найти следующий SQL-файл для воспроизведения, он завершает работу, вызывая переключение в режим реального воспроизведения(live replay). Перед переходом в новый режим, чтобы убедиться в воспроизведении всех полученных изменений, pgcopydb реализует дополнительную фазу отслеживания без одновременной параллельной активности.
  • prefetch&catchup - в режиме предварительной выборки и перехвата операций три процесса взаимодействуют следующим образом:
    1. Первый процесс выполняет предварительную выборку изменений из исходной базы данных, используя протокол логического декодирования PostgreSQL, и сохраняет сообщения JSON в локальных файлах JSON.
    2. Второй процесс преобразует файлы JSON в SQL. Очередь сообщений Unix system V используется для передачи позиций LSN из процесса предварительной выборки в процесс преобразования.
    3. Третий процесс отслеживает изменения, происходящие в исходной базе данных, применяя файлы SQL к целевой базе данных.
    В этом процессе используется PostgreSQL API для отслеживания хода репликации, так что появляется возможность пропустить уже примененные транзакции при перезапуске или возобновлении работы.
    live replay
    В режиме реального воспроизведения три процесса взаимодействуют следующим образом.
    1. Первый процесс получает изменения из исходной базы данных, используя протокол логического декодирования PostgreSQL, и сохраняет сообщения JSON в локальных файлах JSON. Кроме того, изменения в формате JSON записываются в канал Unix, совместно используемый с процессом преобразования.
    2. Второй процесс преобразует строки JSON в SQL. Канал Unix используется для потоковой передачи строк JSON из процесса получения в процесс преобразования. Процесс преобразования в этом режиме по-прежнему записывает изменения в файлы SQL, так что по-прежнему возможно отслеживать полученные изменения, если процесс применения прерывается.
    3. Третий процесс воспроизводит изменения, происходящие в исходной базе данных, применяя команды SQL к целевой системе базы данных. Команды SQL считываются из канала Unix, совместно используемого с процессом преобразования.
    В этом процессе используется PostgreSQL API для отслеживания хода репликации, чтобы была возможность пропустить уже примененные транзакции при перезапуске или возобновлении работы.
    Управление командой follow
    Можно запустить команду pgcopydb follow, а затем позже, пока она все еще выполняется, установить LSN для конечной позиции с тем же эффектом, что и при использовании параметра командной строки --endpos, или переключиться из режима только предварительной выборки в режим предварительной выборки и перехвата. Для этого смотрите команды pgcopydb stream sentinel set endpos, pgcopydb stream sentinel set apply и pgcopydb stream sentinel set prefetch.
    Обратите внимание, что во многих случаях позиция --endpos LSN неизвестна при запуске этой команды. Также перед входом в режим предварительной выборки и применения важно убедиться, что начальная базовая копия завершена.
    Также возможно настроить параметры потоковой репликации перед использованием команды pgcopydb follow: смотрите описание команд pgcopydb stream setup и pgcopydb stream cleanup.
    Идентификаторы репликации при отсутствии первичных ключей
    Логическое декодирование Postgres работает с воспроизведением изменений с использованием инструкций SQL, для чего использует концепцию идентификаторов реплики, как описано в документации для команды ALTER TABLE ... REPLICA IDENTITY. Эта форма меняет информацию, записываемую в журнал предзаписи для идентификации изменяемых или удаляемых строк. В большинстве случаев старое значение в каждом столбце записывается, только если оно отличается от нового, но значение, хранящееся отдельно, записывается всегда, даже если оно не изменилось. Данный параметр действует только при использовании логической репликации.
    Чтобы поддерживать CDC с помощью логического декодирования PostgreSQL для таблиц, у которых нет первичного ключа, необходимо использовать команду ALTER TABLE ... REPLICA IDENTITY для этих таблиц.
    На практике следует рассмотреть два следующих варианта:
    • REPLICA IDENTITY USING INDEX index_name. Эта форма предпочтительнее, когда для таблицы существует уникальный индекс без первичного ключа. Индекс должен быть уникальным, не частичным, не подлежащим переносу и включать только столбцы, помеченные как NOT NULL.
    • REPLICA IDENTITY FULL. Когда этот вариант используется в таблице, записи WAL содержат старые значения всех столбцов в строке.
    Предварительная выборка логического декодирования
    При использовании pgcopydb clone --follow в исходной базе данных перед первоначальной копией создается логический слот репликации с использованием того же моментального снимка PostgreSQL. Это обеспечивает согласованность данных.
    В рамках подхода pgcopydb clone --follow можно начать применять изменения из исходной базы данных только после полного завершения базовой копии в целевой базе данных.
    Кроме того, из документации PostgreSQL мы знаем, что слоты репликации PostgreSQL предоставляют гарантию, что первичный сервер не удалит сегменты WAL до тех пор, пока они не будут получены всеми резервными серверами.
    Накопление сегментов WAL на основном диске в течение всего срока действия первоначальной базовой копии сопряжено с опасностями переполнения диска, которые приводят к потенциальным ошибкам переполнения файловой системы на диске WAL исходной базы данных. Крайне важно избегать такой ситуации.
    Вот почему pgcopydb реализует предварительную выборку CDC. Параллельно с первоначальной базовой копией команда pgcopydb clone --follow выполняет предварительную выборку изменений в локальных файлах JSON и SQL. Эти файлы помещаются в папку XDG_DATA_HOME, которая может быть точкой монтирования для бесконечной области хранения больших двоичных объектов.
    Команда pgcopydb follow – это удобная команда, доступная в качестве клиента логического декодирования, и она использует ту же реализацию, что и команда pgcopydb clone --follow. В результате стратегия предварительной выборки также имеет отношение к команде pgcopydb follow.
    Таблица контроля или управление процессом копирования
    Чтобы отслеживать прогресс и разрешать возобновление операций, pgcopydb использует контрольную таблицу в исходной базе данных. Таблица состоит из одной строки со следующими полями:
    Раскрыть type=sql
    $ pgcopydb stream sentinel get
    startpos   1/8D173AF8
    endpos     0/0
    apply      disabled
    write_lsn  0/0
    flush_lsn  0/0
    replay_lsn 0/0
    
    Обратите внимание: можно использовать команду pgcopydb stream sentinel get --json для получения выходных данных в формате JSON, тогда вывод будет таким:
    Раскрыть type=json
    {
      "startpos": "1/8D173AF8",
      "endpos": "1/8D173AF8",
      "apply": false,
      "write_lsn": "0/0",
      "flush_lsn": "0/0",
      "replay_lsn": "0/0"
    }
    
    Первые три поля (startpos, endpos, apply) специфичны для pgcopydb, остальные поля (write_lsn, flush_lsn, replay_lsn) соответствуют протоколу репликации PostgreSQL (о них можно почитать в документации PostgreSQL для функции pg_stat_replication):
    • startpos – текущий LSN в исходной базе данных на момент настройки CDC в pgcopydb, например, при использовании команды pgcopydb stream setup. Обратите внимание, что как команда pgcopydb follow, так и команда pgcopydb clone --follow реализуют части настройки, если pgcopydb stream setup еще не использовалась;
    • endpos – последняя позиция LSN из исходной базы данных, которую воспроизводит pgcopydb. Команда pgcopydb follow (или pgcopydb clone --follow) останавливается при выходе за пределы этой позиции LSN. Конечные точки могут быть установлены в начале процесса, что полезно для модульного тестирования, или во время выполнения команды, что полезно в производственной среде для определения точки перехода. Чтобы определить конечные точки во время выполнения команды, используйте pgcopydb stream sentinel set endpos;
    • apply – логическое значение (включено/отключено), которое управляет процессом перехвата. Процесс отслеживания pgcopydb воспроизводит изменения только тогда, когда логическому значению apply присвоено значение true. Команда pgcopydb clone --follow автоматически активирует поле apply таблицы sentinel, как только будет выполнено первоначальное копирование. Чтобы вручную управлять полем apply, используйте команду pgcopydb stream sentinel set apply;
    • write_lsn – последнее местоположение журнала предварительной записи, записанное на диск этим резервным сервером. В случае pgcopydb контрольное поле write_lsn - это позиция, которая была записана на диск (как JSON) потоковым процессом;
    • flush_lsn – последнее местоположение журнала предварительной записи, сброшенное на диск этим резервным сервером. В случае pgcopydb контрольное поле flush_lsn - это позиция, которая была записана и затем синхронизирована на диск (как JSON) потоковым процессом;
    • replay_lsn – последнее местоположение журнала предварительной записи, воспроизведенное в базу данных на этом резервном сервере. В случае pgcopydb контрольное поле replay_lsn - это позиция, которая была применена к целевой базе данных, что отслеживается из файлов WAL.json, а затем WAL.sql и с использованием PostgreSQL API для отслеживания хода репликации. replay_lsn также используется потоковым процессом pgcopydb, который использует протокол логической репликации PostgreSQL, поэтому запись pg_stat_replication, связанная со слотом репликации, используемым pgcopydb, может использоваться для мониторинга задержки репликации. Поскольку потоковые процессы pgcopydb поддерживают контрольную таблицу в исходной базе данных, ее также можно использовать для отслеживания хода логической репликации;
  • pgcopydb snapshot – создание и экспорт моментального снимка в исходной базе данных. Команда pgcopydb snapshot подключается к исходной базе данных и выполняет SQL-запрос для экспорта моментального снимка. Полученный снимок выводится как на стандартный вывод, так и в файл, где другие команды pgcopydb могут его найти.
    Синопсис type=sql
    pgcopydb snapshot: Создание и экспорт моментального снимка исходной базы данных
    Использование: pgcopydb snapshot  --source ...
    
    --source                      Postgres URI к исходной базе данных
    --dir                         Рабочий каталог для временных файлов
    --follow                      Реализовать логическое декодирование для воспроизведения изменений
    --plugin                      Какой плагин использовать для логического декодирования (test_decoding, wal2json)
    --wal2json-numeric-as-string  Выводить числовой тип данных в виде строки при использовании плагина вывода wal2json
    --slot-name                   Использовать данное имя слота репликации Postgres
    
    Пример: фоновое создание снимка в базе источнике при помощи утилиты pgcopydb и завершение поддержки снимка при завершении процесса:
    Раскрыть type=sql
    $ pgcopydb snapshot &
    [1] 72938
    17:31:52 72938 INFO  Running pgcopydb version 0.7.13.gcbf2d16.dirty from "/Users/dim/dev/PostgreSQL/pgcopydb/./src/bin/pgcopydb/pgcopydb"
    17:31:52 72938 INFO  Using work dir "/var/folders/d7/zzxmgs9s16gdxxcm0hs0sssw0000gn/T//pgcopydb"
    17:31:52 72938 INFO  Removing the stale pid file "/var/folders/d7/zzxmgs9s16gdxxcm0hs0sssw0000gn/T//pgcopydb/pgcopydb.aux.pid"
    17:31:52 72938 INFO  Work directory "/var/folders/d7/zzxmgs9s16gdxxcm0hs0sssw0000gn/T//pgcopydb" already exists
    17:31:52 72938 INFO  Exported snapshot "00000003-000CB5FE-1" from the source database
    00000003-000CB5FE-1
    $ #when the process is done, stop maintaining the snapshot in the background
    $ kill %1
    17:31:56 72938 INFO  Asked to terminate, aborting
    [1]+  Done                    pgcopydb snapshot
    
  • pgcopydb compare – сравнение исходной и целевой баз данных. Команда pgcopydb compare подключается к исходной и целевой базам данных и выполняет SQL-запросы для получения информации каталога Postgres о таблице, индексах и последовательностях, которые переносятся. Затем инструмент сравнивает либо определения схемы, либо содержимое данных выбранных таблиц и сообщает об успешном завершении с помощью кода возврата Unix, равного нулю.
    На данный момент инструмент сравнения pgcopydb довольно ограничен с точки зрения поддержки схем: он охватывает только то, что pgcopydb нужно знать о схеме базы данных.
    Существует два варианта сравнения:
    • pgcopydb compare schema;
    • pgcopydb compare data.
  • pgcopydb compare schema - сравнивает исходную и целевую схемы. Команда pgcopydb compare schema подключается к исходной и целевой базам данных и выполняет SQL-запросы, используя каталоги Postgres, чтобы получить там список таблиц, индексов, ограничений и последовательностей и сравнивает соответствие наборов.
    Синопсис type=sql
    pgcopydb compare schema: Сравнение исходной и целевой схем
    Использование: pgcopydb compare schema  --source ...
    
    --source         Postgres URI к исходной базе данных
    --target         Postgres URI к целевой базе данных
    --dir            Рабочий каталог для временных файлов
    
  • pgcopydb compare data – сравнивает исходные и целевые данные. Команда pgcopydb compare data подключается к исходной и целевой базам данных и выполняет SQL-запросы, используя каталоги Postgres, чтобы получить там список таблиц, индексов, ограничений и последовательностей. Затем он использует SQL-запрос со следующим шаблоном для вычисления количества строк и контрольной суммы для каждой таблицы:
    Раскрыть type=sql
    /*
    * Вычислите хэш-текст каждой отдельной строки в таблице и объедините
    * результаты в виде суммы чисел bigint. Поскольку сумма bigint может
    * переполниться до числового значения, агрегированная сумма затем хэшируется в MD5
    * значение: bigint - 64 бита, MD5 - 128 бит.
    *
    * Также, чтобы снизить вероятность коллизии, включите подсчет строк в
    * вычисление MD5, добавляя его к входной строке MD5
    * функции.
      */
      select count(1) as cnt,
      md5(
      format(
      '%%s-%%s',
      sum(hashtext(__COLS__::text)::bigint),
      count(1)
      )
      )::uuid as chksum
      from only __TABLE__
    
    Выполнение запроса на больших таблицах может занять продолжительное время.
    Синопсис type=sql
    pgcopydb compare data: Сравнение исходных и целевых данных
    Использование: pgcopydb compare data  --source ...
    
    --source         Postgres URI к исходной базе данных
    --target         Postgres URI к целевой базе данных
    --dir            Рабочая директория для временных файлов
    --json           Форматирование вывода с использованием JSON
    
    Пример сравнения схем:
    Раскрыть type=sql
    $ pgcopydb compare schema --notice
    INFO   Running pgcopydb version 0.12.28.g34343c8.dirty from "/Users/dim/dev/PostgreSQL/pgcopydb/src/bin/pgcopydb/pgcopydb"
    NOTICE Using work dir "/var/folders/d7/zzxmgs9s16gdxxcm0hs0sssw0000gn/T//pgcopydb"
    NOTICE Work directory "/var/folders/d7/zzxmgs9s16gdxxcm0hs0sssw0000gn/T//pgcopydb" already exists
    INFO   A previous run has run through completion
    INFO   SOURCE: Connecting to "postgres:///pagila"
    INFO   Fetched information for 1 extensions
    INFO   Fetched information for 25 tables, with an estimated total of 5179  tuples and 190 MB
    INFO   Fetched information for 49 indexes
    INFO   Fetching information for 16 sequences
    NOTICE Skipping target catalog preparation
    NOTICE Storing migration schema in JSON file "/var/folders/d7/zzxmgs9s16gdxxcm0hs0sssw0000gn/T//pgcopydb/compare/source-schema.json"
    INFO   TARGET: Connecting to "postgres:///plop"
    INFO   Fetched information for 6 extensions
    INFO   Fetched information for 25 tables, with an estimated total of 5219  tuples and 190 MB
    INFO   Fetched information for 49 indexes
    INFO   Fetching information for 16 sequences
    NOTICE Skipping target catalog preparation
    NOTICE Storing migration schema in JSON file "/var/folders/d7/zzxmgs9s16gdxxcm0hs0sssw0000gn/T//pgcopydb/compare/target-schema.json"
    INFO   [SOURCE] table: 25 index: 49 sequence: 16
    INFO   [TARGET] table: 25 index: 49 sequence: 16
    NOTICE Matched table "public"."test": 1 columns ok, 0 indexes ok
    NOTICE Matched table "public"."rental": 7 columns ok, 3 indexes ok
    NOTICE Matched table "public"."film": 14 columns ok, 5 indexes ok
    NOTICE Matched table "public"."film_actor": 3 columns ok, 2 indexes ok
    NOTICE Matched table "public"."inventory": 4 columns ok, 2 indexes ok
    NOTICE Matched table "public"."payment_p2022_03": 6 columns ok, 3 indexes ok
    NOTICE Matched table "public"."payment_p2022_05": 6 columns ok, 3 indexes ok
    NOTICE Matched table "public"."payment_p2022_06": 6 columns ok, 3 indexes ok
    NOTICE Matched table "public"."payment_p2022_04": 6 columns ok, 3 indexes ok
    NOTICE Matched table "public"."payment_p2022_02": 6 columns ok, 3 indexes ok
    NOTICE Matched table "public"."payment_p2022_07": 6 columns ok, 0 indexes ok
    NOTICE Matched table "public"."customer": 10 columns ok, 4 indexes ok
    NOTICE Matched table "public"."address": 8 columns ok, 2 indexes ok
    NOTICE Matched table "public"."city": 4 columns ok, 2 indexes ok
    NOTICE Matched table "public"."film_category": 3 columns ok, 1 indexes ok
    NOTICE Matched table "public"."payment_p2022_01": 6 columns ok, 3 indexes ok
    NOTICE Matched table "public"."actor": 4 columns ok, 2 indexes ok
    NOTICE Matched table "public"."bar": 2 columns ok, 1 indexes ok
    NOTICE Matched table "public"."bin": 2 columns ok, 0 indexes ok
    NOTICE Matched table "public"."category": 3 columns ok, 1 indexes ok
    NOTICE Matched table "public"."country": 3 columns ok, 1 indexes ok
    NOTICE Matched table "public"."foo": 2 columns ok, 1 indexes ok
    NOTICE Matched table "public"."staff": 11 columns ok, 1 indexes ok
    NOTICE Matched table "public"."language": 3 columns ok, 1 indexes ok
    NOTICE Matched table "public"."store": 4 columns ok, 2 indexes ok
    NOTICE Matched sequence "public"."actor_actor_id_seq" (last value 200)
    NOTICE Matched sequence "public"."address_address_id_seq" (last value 605)
    NOTICE Matched sequence "public"."bar_id_seq" (last value 1)
    NOTICE Matched sequence "public"."bin_id_seq" (last value 17)
    NOTICE Matched sequence "public"."category_category_id_seq" (last value 16)
    NOTICE Matched sequence "public"."city_city_id_seq" (last value 600)
    NOTICE Matched sequence "public"."country_country_id_seq" (last value 109)
    NOTICE Matched sequence "public"."customer_customer_id_seq" (last value 599)
    NOTICE Matched sequence "public"."film_film_id_seq" (last value 1000)
    NOTICE Matched sequence "public"."foo_id_seq" (last value 1)
    NOTICE Matched sequence "public"."inventory_inventory_id_seq" (last value 4581)
    NOTICE Matched sequence "public"."language_language_id_seq" (last value 6)
    NOTICE Matched sequence "public"."payment_payment_id_seq" (last value 32102)
    NOTICE Matched sequence "public"."rental_rental_id_seq" (last value 16053)
    NOTICE Matched sequence "public"."staff_staff_id_seq" (last value 2)
    NOTICE Matched sequence "public"."store_store_id_seq" (last value 2)
    INFO   pgcopydb schema inspection is successful
    
    Пример сравнения данных:
    Раскрыть type=sql
    $ pgcopydb compare data
    INFO   A previous run has run through completion
    INFO   SOURCE: Connecting to "postgres:///pagila"
    INFO   Fetched information for 1 extensions
    INFO   Fetched information for 25 tables, with an estimated total of 5179  tuples and 190 MB
    INFO   Fetched information for 49 indexes
    INFO   Fetching information for 16 sequences
    INFO   TARGET: Connecting to "postgres:///plop"
    INFO   Fetched information for 6 extensions
    INFO   Fetched information for 25 tables, with an estimated total of 5219  tuples and 190 MB
    INFO   Fetched information for 49 indexes
    INFO   Fetching information for 16 sequences
    INFO   Comparing data for 25 tables
    ERROR  Table "public"."test" has 5173526 rows on source, 5173525 rows on target
    ERROR  Table "public"."test" has checksum be66f291-2774-9365-400c-1ccd5160bdf on source, 8be89afa-bceb-f501-dc7b-0538dc17fa3 on target
    ERROR  Table "public"."foo" has 3 rows on source, 2 rows on target
    ERROR  Table "public"."foo" has checksum a244eba3-376b-75e6-6720-e853b485ef6 on source, 594ae64d-2216-f687-2f11-45cbd9c7153 on target
    Table Name | ! |                      Source Checksum |                      Target Checksum
    -------------------------------+---+--------------------------------------+-------------------------------------
    "public"."test" | ! |  be66f291-2774-9365-400c-1ccd5160bdf |  8be89afa-bceb-f501-dc7b-0538dc17fa3
    "public"."rental" |   |  e7dfabf3-baa8-473a-8fd3-76d59e56467 |  e7dfabf3-baa8-473a-8fd3-76d59e56467
    "public"."film" |   |  c5058d1e-aaf4-f058-6f1e-76d5db63da9 |  c5058d1e-aaf4-f058-6f1e-76d5db63da9
    "public"."film_actor" |   |  7534654a-0bcd-cb27-1a2e-ccd524899a9 |  7534654a-0bcd-cb27-1a2e-ccd524899a9
    "public"."inventory" |   |  72f9afd8-0064-3642-acd7-9ee1f444efe |  72f9afd8-0064-3642-acd7-9ee1f444efe
    "public"."payment_p2022_03" |   |  dc73311a-2ea2-e933-da80-123b44d06b9 |  dc73311a-2ea2-e933-da80-123b44d06b9
    "public"."payment_p2022_05" |   |  e788bf50-9809-9896-8110-91816edcc04 |  e788bf50-9809-9896-8110-91816edcc04
    "public"."payment_p2022_06" |   |  5f650b4c-d491-37ac-6d91-dc2ae484600 |  5f650b4c-d491-37ac-6d91-dc2ae484600
    "public"."payment_p2022_04" |   |  02beb400-1b82-c9ba-8fe9-690eca2e635 |  02beb400-1b82-c9ba-8fe9-690eca2e635
    "public"."payment_p2022_02" |   |  97154691-488e-9a36-9a4b-4da7b62dbc0 |  97154691-488e-9a36-9a4b-4da7b62dbc0
    "public"."payment_p2022_07" |   |  c6fdf7ef-4382-b301-41c3-1d190149dc5 |  c6fdf7ef-4382-b301-41c3-1d190149dc5
    "public"."customer" |   |  11973c6a-6df3-c502-5495-64f42e0386c |  11973c6a-6df3-c502-5495-64f42e0386c
    "public"."address" |   |  8c701dbf-c1ba-f386-a9ae-c3f6e478ba7 |  8c701dbf-c1ba-f386-a9ae-c3f6e478ba7
    "public"."city" |   |  f23ad758-f94a-a8fd-8c3f-25fedcadb06 |  f23ad758-f94a-a8fd-8c3f-25fedcadb06
    "public"."film_category" |   |  4b04cfee-e1bc-718d-d890-afdcd6729ce |  4b04cfee-e1bc-718d-d890-afdcd6729ce
    "public"."payment_p2022_01" |   |  fde341ed-0f3f-23bd-dedd-4e92c5a8e55 |  fde341ed-0f3f-23bd-dedd-4e92c5a8e55
    "public"."actor" |   |  b5ea389d-140f-10b4-07b9-a80d634d86b |  b5ea389d-140f-10b4-07b9-a80d634d86b
    "public"."bar" |   |  a7cae1c8-ed66-63ba-1b93-7ba7570ef63 |  a7cae1c8-ed66-63ba-1b93-7ba7570ef63
    "public"."bin" |   |  6832546a-333b-3bdb-fdf2-325cc7a028a |  6832546a-333b-3bdb-fdf2-325cc7a028a
    "public"."category" |   |  082f9cf9-92ab-6d6c-c74a-feb577611cc |  082f9cf9-92ab-6d6c-c74a-feb577611cc
    "public"."country" |   |  a3a0dd4f-68e0-4ca5-33d2-05c9fd60c34 |  a3a0dd4f-68e0-4ca5-33d2-05c9fd60c34
    "public"."foo" | ! |  a244eba3-376b-75e6-6720-e853b485ef6 |  594ae64d-2216-f687-2f11-45cbd9c7153
    "public"."staff" |   |  3eb5f007-7160-81ba-5aa5-973de3f5c3d |  3eb5f007-7160-81ba-5aa5-973de3f5c3d
    "public"."language" |   |  58aa8132-11ae-f3bc-fa82-c773bba2032 |  58aa8132-11ae-f3bc-fa82-c773bba2032
    "public"."store" |   |  d8477e63-0661-90a4-03fa-fcc26a95865 |  d8477e63-0661-90a4-03fa-fcc26a95865
    
  • pgcopydb copy – реализация копирования определенных объектов БД. Команда copy поддерживает следующие команды:
    Раскрыть type=sql
    pgcopydb copy: Имплементация раздела данных в копии базы данных
    
    Доступные команды:
    pgcopydb copy
    db           Копирование всей базы данных из источника в целевой экземпляр
    roles        Копирование ролей из исходного экземпляра в целевой экземпляр
    extensions   Копирование расширений из исходного экземпляра в целевой экземпляр
    schema       Копирование схемы базы данных из источника в целевой экземпляр
    data         Копирование раздела данных из источника в целевой экземпляр
    table-data   Копирование данных из всех таблиц базы данных из источника в целевой экземпляр
    blobs        Копирование данных blobs из исходной базы данных в целевой экземпляр
    sequences    Копирование текущего значения из всех последовательностей в базе данных из источника в целевой экземпляр
    indexes      Создание всех индексов, найденных в исходной базе данных, в целевой базе данных
    constraints  Создание всех ограничений, найденных в исходной базе данных, в целевой базе данных
    
    Эти команды реализуют часть общей операции копирования базы данных, как описано в разделе pgcopydb clone.
    Настоятельно рекомендуется использовать команду pgcopydb clone. Этот режим работы полезен только для отладки и расширенных вариантов использования.
    Эти команды позволяют выполнять определенный этап операций pgcopydb за один раз. Это полезно в основном для целей отладки, иногда некоторые расширенные и творческие задачи могут быть реализованы с помощью этих команд. Целевая структура не будет создана, поэтому сперва нужно позаботиться о ней. Для этого можно использовать команды pgcopydb dump schema, а затем pgcopydb restore pre-data.
    Чтобы выполнить те же операции, что и команда pgcopydb clone, достаточно выполнить следующие действия:
    Раскрыть type=sql
    $ export PGCOPYDB_SOURCE_PGURI="postgres://user@source/dbname"
    $ export PGCOPYDB_TARGET_PGURI="postgres://user@target/dbname"
    
    $ pgcopydb dump schema
    $ pgcopydb restore pre-data --resume --not-consistent
    $ pgcopydb copy table-data --resume --not-consistent
    $ pgcopydb copy sequences --resume --not-consistent
    $ pgcopydb copy indexes --resume --not-consistent
    $ pgcopydb copy constraints --resume --not-consistent
    $ vacuumdb -z
    $ pgcopydb restore post-data --resume --not-consistent
    
    Основная операция pgcopydb clone лучше справляется с параллелизмом, чем выполнение этих шагов вручную, поскольку она создаст индексы для каждой скопированной таблицы, как только копирование данных будет завершено, без необходимости ждать, пока будут скопированы последние табличные данные. То же самое относится и к ограничениям и к команде VACUUM ANALYZE.
    Описание субкоманд:
    • pgcopydb copy db - команда по сути является alias для pgcopydb clone (смотрите также раздел pgcopydb clone).
      Синопсис type=sql
      pgcopydb copy db: Копирование всей базы данных из источника в целевую
      Использование: pgcopydb copy db  --source ... --target ... [ --table-jobs ... --index-jobs ... ]
      
      --source              Postgres URI к исходной базе данных
      --target              Postgres URI к целевой базе данных
      --dir                 Рабочий каталог для временных файлов
      --table-jobs          Количество одновременно выполняемых заданий COPY
      --index-jobs          Количество одновременно выполняемых заданий CREATE INDEX
      --restore-jobs        Количество одновременно выполняемых заданий для pg_restore
      --drop-if-exists      В целевой базе данных сначала выполняется очистка от предыдущего запуска
      --roles               Копировать роли, найденные в источнике, в целевую базу данных
      --no-owner            Не устанавливать владельца на объекты в соответствии с исходной базой данных
      --no-acl              Предотвращать восстановление привилегий доступа (команды grant/revoke)
      --no-comments         Не выводить команды для восстановления комментариев
      --skip-large-objects  Пропускать копирование больших объектов (blobs)
      --filters <filename>  Использовать фильтры, определенные в <filename>
      --fail-fast           Досрочно прерывать работу в случае ошибки
      --restart             Разрешить перезапуск, если временные файлы уже существуют
      --resume              Разрешить возобновление операций после сбоя
      --not-consistent      Разрешить создание нового моментального снимка исходной базы данных
      --snapshot            Использовать снимок, полученный с помощью pg_export_snapshot
      
    • pgcopydb copy roles - реализует две другие команды – pgcopydb dump roles и после нее pgcopydb restore roles.
      Когда роль уже существует в целевой базе данных, ее восстановление полностью пропускается, что включает в себя пропуск как команд CREATE ROLE, так и команд ALTER ROLE, созданных в процессе работы pg_dumpall --roles-only.
      Команда pg_dumpall --roles-only используется для извлечения списка ролей из исходной базы данных и включает поддержку паролей. В результате для этой операции требуются привилегии суперпользователя. Возможно также использование опции --no-role-passwords.
      Рекомендуется также ознакомиться с документацией по командам pgcopydb dump roles и pgcopydb restore roles.
      В Postgres роли являются глобальными объектами. Это означает, что роли не принадлежат какой-либо конкретной базе данных, и, как следствие, даже если инструмент pgcopydb работает только в контексте конкретной базы данных, эта команда не ограничивается ролями, которые используются в рамках одной базы данных.
      Синопсис type=sql
      pgcopydb copy roles: Копирование ролей из исходного экземпляра в целевой экземпляр
      Использование: pgcopydb copy roles  --source ... --target ...
      
      --source              Postgres URI к исходной базе данных
      --target              Postgres URI к целевой базе данных
      --dir                 Рабочий каталог для временных файлов
      --no-role-passwords   Не сохранять пароли для ролей
      
    • pgcopydb copy extensions - копирование расширений из исходной БД в целевую БД. Команда pgcopydb copy extensions получает список расширений, установленных в исходной базе данных, и для каждого из них запускает SQL-команду CREATE EXTENSION IF NOT EXISTS. При копировании расширений эта команда также выполняет копирование данных любых таблиц расширений в целевую базу данных.
      Синопсис type=sql
      pgcopydb copy extensions: Копирование расширений из исходного экземпляра БД в целевой
      Использование: pgcopydb copy extensions  --source ... --target ...
      
      --source              Postgres URI к исходной базе данных
      --target              Postgres URI к целевой базе данных
      --dir                 Рабочий каталог для временных файлов
      --requirements        Список требований к расширениям
      
    • pgcopydb copy schema - копирование структуры базы данных из исходного экземпляра в целевой. Команда pgcopydb copy schema реализует раздел «schema only» шагов клонирования.
      Синопсис type=sql
      pgcopydb copy schema: Копирование схемы базы данных из источника в целевой экземпляр
      Использование: pgcopydb copy schema  --source ... --target ... [ --table-jobs ... --index-jobs ... ]
      
      --source              Postgres URI к исходной базе данных
      --target              Postgres URI к целевой базе данных
      --dir                 Рабочий каталог для временных файлов
      --filters <filename>  Использовать фильтры, определенные в <filename>
      --restart             Разрешить перезапуск, если временные файлы уже существуют
      --resume              Разрешить возобновление операций после сбоя
      --not-consistent      Разрешить создание нового моментального снимка исходной базы данных
      --snapshot            Использовать снимок, полученный с помощью pg_export_snapshot
      
    • pgcopydb copy data - копирование данных из источника в целевую БД. Команда pgcopydb copy data реализует раздел копирования данных операции клонирования (команда clone).
      В текущей реализации возможно применение обеих команд: pgcopydb copy table-data и pgcopydb copy data, которые выглядят похоже, но реализуют разные шаги. Будьте осторожны. Это поведение будет изменено в будущих версиях pgcopydb.
      По сути данная команда реализует следующие шаги:
      Раскрыть type=sql
      $ pgcopydb copy table-data
      $ pgcopydb copy blobs
      $ pgcopydb copy indexes
      $ pgcopydb copy constraints
      $ pgcopydb copy sequences
      $ vacuumdb -z
      
      Эти шаги по возможности выполняются параллельно, точно так же, как это сделала бы основная команда pgcopydb clone. Единственное отличие заключается в том, что команда pgcopydb clone также подготавливает и завершает копирование структуры (pre-data, post-data), которые команда pgcopydb copy data игнорирует.
      Синопсис type=sql
      pgcopydb copy data: Копирование раздела данных из источника в целевой экземпляр
      Использование: pgcopydb copy data  --source ... --target ... [ --table-jobs ... --index-jobs ... ]
      
      --source              Postgres URI к исходной базе данных
      --target              Postgres URI к целевой базе данных
      --dir                 Рабочий каталог для временных файлов
      --table-jobs          Количество одновременно выполняемых заданий COPY
      --index-jobs          Количество одновременно выполняемых заданий CREATE INDEX
      --restore-jobs        Количество одновременно выполняемых для pg_restore
      --skip-large-objects  Пропускать копирование больших объектов (blobs)
      --filters <filename>  Использовать фильтры, определенные в <filename>
      --restart             Разрешить перезапуск, если временные файлы уже существуют
      --resume              Разрешить возобновление операций после сбоя
      --not-consistent      Разрешить создание нового моментального снимка исходной базы данных
      --snapshot            Использовать снимок, полученный с помощью pg_export_snapshot
      
    • pgcopydb copy table-data - копирование данных всех таблиц базы данных источника в целевую. Команда pgcopydb copy table-data извлекает список таблиц из исходной базы данных и запускает команду COPY TO в исходной базе данных, затем отправляет результат в целевую базу данных, используя команду COPY FROM напрямую, полностью избегая промежуточного взаимодействия с диском.
      Синопсис type=sql
      pgcopydb copy table-data: Копирование данных из всех таблиц базы данных из источника в целевую БД
      Использование: pgcopydb copy table-data  --source ... --target ... [ --table-jobs ... --index-jobs ... ]
      
      --source             Postgres URI к исходной базе данных
      --target             Postgres URI к целевой базе данных
      --dir                Рабочий каталог для временных файлов
      --table-jobs         Количество одновременных заданий COPY для запуска
      --filters <filename> Использовать фильтры, определенные в <filename>
      --restart            Разрешить перезапуск, если временные файлы уже существуют
      --resume             Разрешить возобновление операций после сбоя
      --not-consistent     Разрешить создание нового моментального снимка исходной базы данных
      --snapshot           Использовать снимок, полученный с помощью pg_export_snapshot
      
    • pgcopydb copy blobs - копирование данных больших двоичных объектов (blobs) из исходной базы данных в целевую. Команда pgcopydb copy blobs извлекает список LOB (также называемых BLOB) из исходной базы данных и копирует их данные в целевую базу данных. По умолчанию команда предполагает, что метаданные больших объектов уже обработаны из-за выполнения pg_dump --section=pre-data.
      Синопсис type=sql
      pgcopydb copy blobs: Копирование данных blobs из исходной базы данных в целевую
      Использование: pgcopydb copy blobs  --source ... --target ... [ --table-jobs ... --index-jobs ... ]
      
      --source             Postgres URI к исходной базе данных
      --target             Postgres URI к целевой базе данных
      --dir                Рабочий каталог для временных файлов
      --large-objects-jobs Количество одновременных заданий Large Objects для запуска
      --drop-if-exists     На целевой базе данных сбрасывать и создавать большие объекты
      --restart            Разрешить перезапуск, если временные файлы уже существуют
      --resume             Разрешить возобновление операций после сбоя
      --not-consistent     Разрешить создание нового моментального снимка исходной базы данных
      --snapshot           Использовать снимок, полученный с помощью pg_export_snapshot
      
    • pgcopydb copy sequences - копирование текущего значения всех последовательностей в исходной базе данных в целевую. Команда pgcopydb copy sequences извлекает список последовательностей из исходной базы данных, затем для каждой последовательности извлекает свойства last_value и is_called таким же образом, как это делает pg_dump в исходной базе данных, а затем для каждой последовательности вызывает pg_catalog.setval() в целевой базе данных.
      Синопсис type=sql
      pgcopydb copy sequences: Копирование текущего значения из всех последовательностей в базе данных из источника в целевую
      Использование: pgcopydb copy sequences  --source ... --target ... [ --table-jobs ... --index-jobs ... ]
      
      --source             Postgres URI к исходной базе данных
      --target             Postgres URI к целевой базе данных
      --dir                Рабочий каталог для временных файлов
      --filters <filename> Использовать фильтры, определенные в <filename>
      --restart            Разрешить перезапуск, если временные файлы уже существуют
      --resume             Разрешить возобновление операций после сбоя
      --not-consistent     Разрешить создание нового моментального снимка исходной базы данных
      --snapshot           Использовать снимок, полученный с помощью pg_export_snapshot
      
    • pgcopydb copy indexes - поиск всех индексов в исходной базе данных и последующее их создание в целевой базе данных. Команда pgcopydb copy indexes извлекает список индексов из исходной базы данных и запускает для каждого индекса операцию CREATE INDEX в целевой базе данных. SQL – инструкции для создания индексов изменяются, чтобы включить IF NOT EXISTS и разрешить пропуск индексов, которые уже существуют в целевой базе данных.
      Синопсис type=sql
      pgcopydb copy indexes: Создание всех индексов, найденных в исходной базе данных, в целевой базе данных
      Использование: pgcopydb copy indexes  --source ... --target ... [ --table-jobs ... --index-jobs ... ]
      
      --source             Postgres URI к исходной базе данных
      --target             Postgres URI к целевой базе данных
      --dir                Рабочий каталог для временных файлов
      --index-jobs         Количество одновременных заданий CREATE INDEX для запуска
      --restore-jobs       Количество одновременных заданий для pg_restore
      --filters <filename> Использовать фильтры, определенные в <filename>
      --restart            Разрешить перезапуск, если временные файлы уже существуют
      --resume             Разрешить возобновление операций после сбоя
      --not-consistent     Разрешить создание нового моментального снимка исходной базы данных
      
    • pgcopydb copy constraints - команда pgcopydb copy constraints извлекает список индексов из исходной базы данных и запускает для каждого индекса конструкцию вида ALTER TABLE ... ADD CONSTRAINT ... USING INDEX в целевой базе данных. Индексы должны уже существовать в целевой БД, также, команда завершится ошибкой, если будет обнаружено какое-либо ограничение, уже существующее в целевой базе данных.
      Синопсис type=sql
      pgcopydb copy constraints: Создание всех ограничений, найденный в исходной базе данных, в целевой базе данных
      Использование: pgcopydb copy constraints  --source ... --target ... [ --table-jobs ... --index-jobs ... ]
      
      --source             Postgres URI к исходной базе данных
      --target             Postgres URI к целевой базе данных
      --dir                Рабочий каталог для временных файлов
      --filters <filename> Использовать фильтры, определенные в <filename>
      --restart            Разрешить перезапуск, если временные файлы уже существуют
      --resume             Разрешить возобновление операций после сбоя
      --not-consistent     Разрешить создание нового моментального снимка исходной базы данных
      
      Пример:
      1. Для упрощения выгрузите URI целевой и исходной БД в переменные окружения:
      Раскрыть type=sql
      $ export PGCOPYDB_SOURCE_PGURI=postgres://pagila:0wn3d@source/pagila
      $ export PGCOPYDB_TARGET_PGURI=postgres://pagila:0wn3d@target/pagila
      
      1. Выгрузите структуру БД источника:
      Раскрыть type=sql
      $ pgcopydb dump schema
      14:28:50 22 INFO   Running pgcopydb version 0.13.38.g22e6544.dirty from "/usr/local/bin/pgcopydb"
      14:28:50 22 INFO   Dumping database from "postgres://pagila@source/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
      14:28:50 22 INFO   Dumping database into directory "/tmp/pgcopydb"
      14:28:50 22 INFO   Using pg_dump for Postgres "16.1" at "/usr/bin/pg_dumpall"
      14:28:50 22 INFO   Exported snapshot "00000003-00000022-1" from the source database
      14:28:50 22 INFO    /usr/bin/pg_dump -Fc --snapshot 00000003-00000022-1 --section pre-data --file /tmp/pgcopydb/schema/pre.dump 'postgres://pagila@source/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60'
      14:28:51 22 INFO    /usr/bin/pg_dump -Fc --snapshot 00000003-00000022-1 --section post-data --file /tmp/pgcopydb/schema/post.dump 'postgres://pagila@source/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60'
      
      1. Восстановите структуру данных в целевой базе данных, очистив уже существующие объекты, если таковые имеются. Это позволит запускать этот тестовый сценарий повторно сколько угодно раз. Это опциональный шаг, возможно, в вашем целевом экземпляре рабочей среды этого делать не нужно:
      Раскрыть type=sql
      $ PGCOPYDB_DROP_IF_EXISTS=on pgcopydb restore pre-data --no-owner --resume --not-consistent
      14:28:51 26 INFO   Running pgcopydb version 0.13.38.g22e6544.dirty from "/usr/local/bin/pgcopydb"
      14:28:51 26 INFO   Schema dump for pre-data and post-data section have been done
      14:28:51 26 INFO   Restoring database from existing files at "/tmp/pgcopydb"
      14:28:51 26 INFO   Using pg_restore for Postgres "16.1" at "/usr/bin/pg_restore"
      14:28:51 26 INFO   [TARGET] Restoring database into "postgres://pagila@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
      14:28:51 26 INFO   Drop tables on the target database, per --drop-if-exists
      14:28:51 26 INFO   No tables to migrate, skipping drop tables on the target database
      14:28:51 26 INFO    /usr/bin/pg_restore --dbname 'postgres://pagila@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60' --single-transaction --clean --
      
      1. Скопируйте данные:
      Раскрыть type=sql
      $ pgcopydb copy table-data --resume --not-consistent
      14:28:52 30 INFO   Running pgcopydb version 0.13.38.g22e6544.dirty from "/usr/local/bin/pgcopydb"
      14:28:52 30 INFO   [SOURCE] Copying database from "postgres://pagila@source/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
      14:28:52 30 INFO   [TARGET] Copying database into "postgres://pagila@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
      14:28:52 30 INFO   Schema dump for pre-data and post-data section have been done
      14:28:52 30 INFO   Pre-data schema has been restored on the target instance
      14:28:52 30 INFO   Copy data from source to target in sub-processes
      ...
                                                     Step   Connection    Duration    Transfer   Concurrency
       --------------------------------------------------   ----------  ----------  ----------  ------------
                                              Dump Schema       source         0ms                         1
         Catalog Queries (table ordering, filtering, etc)       source         0ms                         1
                                           Prepare Schema       target         0ms                         1
            COPY, INDEX, CONSTRAINTS, VACUUM (wall clock)         both         0ms                     4 + 8
                                        COPY (cumulative)         both       1s671     2955 kB             4
                               Large Objects (cumulative)         both                                     4
                   CREATE INDEX, CONSTRAINTS (cumulative)       target         0ms                         4
                                          Finalize Schema       target         0ms                         1
       --------------------------------------------------   ----------  ----------  ----------  ------------
                                Total Wall Clock Duration         both       753ms                     4 + 8
       --------------------------------------------------   ----------  ----------  ----------  ------------
      
      1. Создайте индексы:
      Раскрыть type=sql
      $ pgcopydb copy indexes --resume --not-consistent
      14:28:53 47 INFO   Running pgcopydb version 0.13.38.g22e6544.dirty from "/usr/local/bin/pgcopydb"
      14:28:53 47 INFO   [SOURCE] Copying database from "postgres://pagila@source/pagila?keepalives=1&keepalives_idle=10& keepalives_interval=10&keepalives_count=60"
      14:28:53 47 INFO   [TARGET] Copying database into "postgres://pagila@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
      14:28:53 47 INFO   Schema dump for pre-data and post-data section have been done
      14:28:53 47 INFO   Pre-data schema has been restored on the target instance
      14:28:53 47 INFO   All the table data has been copied to the target instance
      14:28:53 47 INFO   All the indexes have been copied to the target instance
      14:28:53 47 INFO   Fetched information for 54 indexes
      14:28:53 47 INFO   Creating 54 indexes in the target database using 4 processes
      
                                                     Step   Connection    Duration    Transfer   Concurrency
       --------------------------------------------------   ----------  ----------  ----------  ------------
                                              Dump Schema       source         0ms                         1
         Catalog Queries (table ordering, filtering, etc)       source         0ms                         1
                                           Prepare Schema       target         0ms                         1
            COPY, INDEX, CONSTRAINTS, VACUUM (wall clock)         both         0ms                     4 + 8
                                        COPY (cumulative)         both         0ms         0 B             4
                               Large Objects (cumulative)         both                                     4
                   CREATE INDEX, CONSTRAINTS (cumulative)       target         0ms                         4
                                          Finalize Schema       target         0ms                         1
       --------------------------------------------------   ----------  ----------  ----------  ------------
                                Total Wall Clock Duration         both       696ms                     4 + 8
       --------------------------------------------------   ----------  ----------  ----------  ------------
      
      1. Создайте ограничения:
      Раскрыть type=sql
      $ pgcopydb copy constraints --resume --not-consistent
      14:28:54 53 INFO   Running pgcopydb version 0.13.38.g22e6544.dirty from "/usr/local/bin/pgcopydb"
      14:28:54 53 INFO   [SOURCE] Copying database from "postgres://pagila@source/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
      14:28:54 53 INFO   [TARGET] Copying database into "postgres://pagila@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
      14:28:54 53 INFO   Schema dump for pre-data and post-data section have been done
      14:28:54 53 INFO   Pre-data schema has been restored on the target instance
      14:28:54 53 INFO   All the table data has been copied to the target instance
      14:28:54 53 INFO   All the indexes have been copied to the target instance
      14:28:54 53 INFO   Create constraints
      14:28:54 53 INFO   Fetched information for 54 indexes
      14:28:54 53 INFO   Creating 54 indexes in the target database using 4 processes
      
                                                     Step   Connection    Duration    Transfer   Concurrency
       --------------------------------------------------   ----------  ----------  ----------  ------------
                                              Dump Schema       source         0ms                         1
         Catalog Queries (table ordering, filtering, etc)       source         0ms                         1
                                           Prepare Schema       target         0ms                         1
            COPY, INDEX, CONSTRAINTS, VACUUM (wall clock)         both         0ms                     4 + 8
                                        COPY (cumulative)         both         0ms         0 B             4
                               Large Objects (cumulative)         both                                     4
                   CREATE INDEX, CONSTRAINTS (cumulative)       target         0ms                         4
                                          Finalize Schema       target         0ms                         1
       --------------------------------------------------   ----------  ----------  ----------  ------------
                             Total Wall Clock Duration         both       283ms                     4 + 8
       --------------------------------------------------   ----------  ----------  ----------  ------------
      
      1. Следующим шагом является VACUUM ANALYZE для каждой таблицы, которая только что была заполнена данными, и для этого можно просто использовать команду vacuumdb из PostgreSQL:
      Раскрыть type=sql
      $ vacuumdb --analyze --dbname "$PGCOPYDB_TARGET_PGURI" --jobs 4
      vacuumdb: vacuuming database "pagila"
      
      1. Восстановите post-data:
      Раскрыть type=sql
      $ pgcopydb restore post-data --resume --not-consistent
      14:28:54 60 INFO   Running pgcopydb version 0.13.38.g22e6544.dirty from "/usr/local/bin/pgcopydb"
      14:28:54 60 INFO   Schema dump for pre-data and post-data section have been done
      14:28:54 60 INFO   Pre-data schema has been restored on the target instance
      14:28:54 60 INFO   All the table data has been copied to the target instance
      14:28:54 60 INFO   All the indexes have been copied to the target instance
      14:28:54 60 INFO   Restoring database from existing files at "/tmp/pgcopydb"
      14:28:54 60 INFO   Using pg_restore for Postgres "16.1" at "/usr/bin/pg_restore"
      14:28:54 60 INFO   [TARGET] Restoring database into "postgres://pagila@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
      14:28:55 60 INFO    /usr/bin/pg_restore --dbname 'postgres://pagila@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60' --single-transaction --use-list /tmp/pgcopydb/schema/post-filtered.list /tmp/pgcopydb/schema/post.dump
      
  • pgcopydb dump - команда реализует первый шаг полной миграции базы данных и генерирует команды создания структуры исходной базы данных. Когда команда выполняется, она вызывает pg_dump, чтобы сначала получить вывод данных pre-data, а затем получить вывод данных post-data в файлах в формате custom для pgdump. Выходные файлы записываются в подкаталог schema каталога указанного в опции --target. pgcopydb dump pre-data и pgcopydb dump post-data ограничивают свое действие соответственно разделами pre-data и post-data в pg_dump.
    Данная команда содержит следующие подкоманды:
    Раскрыть type=sql
    pgcopydb dump: Выгрузка объектов базы данных из экземпляра Postgres
    
    Доступные команды:
    pgcopydb dump
    schema     Выгрузить схему исходной базы данных в виде пользовательских файлов в рабочую директорию
    pre-data   Выгрузить схему исходной базы данных pre-data в виде пользовательских файлов в рабочем каталоге
    post-data  Выгрузить схему post-data исходной базы данных в виде пользовательских файлов в рабочем каталоге
    roles      Дамп ролей исходной базы данных в виде пользовательских файлов в рабочем каталоге
    
    Далее следует описание подкоманд.
    • pgcopydb dump schema - выгрузка структуры базы данных в виде пользовательских файлов в целевом каталоге. Команда pgcopydb dump schema использует pg_dump для экспорта определений структуры SQL из данного исходного экземпляра PostgreSQL.
    Синопсис type=sql
    pgcopydb dump schema: Сбрасывает схему исходной базы данных в виде пользовательских файлов в рабочую директорию
    Использование: pgcopydb dump schema  --source <URI>
    
    --source          Postgres URI к исходной базе данных
    --target          Postgres URI к целевой базе данных
    --dir             Рабочий каталог для временных файлов
    --skip-extensions Пропустить восстановление расширений
    --snapshot        Использовать снимок, полученный с помощью pg_export_snapshot
    
    • pgcopydb dump pre-data - выгрузка секции pre-data базы данных источника в виде пользовательских файлов в целевом каталоге. Команда pgcopydb dump pre-data использует pg_dump для экспорта определений структуры SQL секции pre-data из данного исходного экземпляра PostgreSQL.
    Синопсис type=sql
    pgcopydb dump pre-data: Сбрасывает схему предварительных данных исходной базы данных в виде пользовательских файлов в рабочую директорию
    Использование: pgcopydb dump pre-data  --source <URI>
    
    --source          Postgres URI к исходной базе данных
    --target          Postgres URI к целевой базе данных
    --dir             Рабочий каталог для временных файлов
    --skip-extensions Пропустить восстановление расширений
    --snapshot        Использовать снимок, полученный с помощью pg_export_snapshot
    
    • pgcopydb dump post-data - выгрузка post-data исходной базы данных в виде пользовательских файлов в целевом каталоге. Команда pgcopydb dump post-data использует pg_dump для экспорта определений post-data SQL из данного исходного экземпляра Postgres.
    Синопсис type=sql
    pgcopydb dump post-data: Сбрасывает схему post-data исходной базы данных в виде пользовательских файлов в рабочую директорию
    Использование: pgcopydb dump post-data  --source <URI>
    
    --source          Postgres URI к исходной базе данных
    --target          Postgres URI к целевой базе данных
    --dir             Рабочий каталог для временных файлов
    --snapshot        Использовать снимок, полученный с помощью pg_export_snapshot
    
    • pgcopydb dump roles - выгрузка ролей исходной базы данных в виде файла в рабочем каталоге. Команда pgcopydb dump roles использует pg_dumpall --roles-only для экспорта SQL-определений ролей, найденных в исходном экземпляре PostgreSQL.
    Команда включает поддержку паролей, в результате для этой операции требуются привилегии суперпользователя. Можно использовать параметр --no-role-passwords для работы без привилегий суперпользователя. Однако в этом случае пароли не являются частью дампа, и аутентификация может завершиться неудачей, пока пароли не будут настроены должным образом.
    Синопсис type=sql
    pgcopydb dump roles: Сброс ролей исходной базы данных в виде файла custom в рабочем каталоге
    Использование: pgcopydb dump roles  --source <URI>
    
    --source            Postgres URI к исходной базе данных
    --target            Postgres URI к целевой базе данных
    --dir               Рабочий каталог для временных файлов
    --no-role-passwords Не создавать дамп паролей для ролей
    
    Пример:
    В данном примере наглядно демонстрируется разница между командами schema, pre-data и post-data:
    Раскрыть type=sql
    $ pgcopydb dump schema --source "port=5501 dbname=demo" --target "port=5501 dbname=demo2"
    09:35:21 3926 INFO  Dumping database from "port=5501 dbname=demo"
    09:35:21 3926 INFO  Dumping database into directory "/tmp/pgcopydb"
    09:35:21 3926 INFO  Found a stale pidfile at "/tmp/pgcopydb/pgcopydb.pid"
    09:35:21 3926 WARN  Removing the stale pid file "/tmp/pgcopydb/pgcopydb.pid"
    09:35:21 3926 INFO  Using pg_dump for Postgres "12.9" at "/Applications/Postgres.app/Contents/Versions/12/bin/pg_dump"
    09:35:21 3926 INFO   /Applications/Postgres.app/Contents/Versions/12/bin/pg_dump -Fc --section pre-data --file /tmp/pgcopydb/schema/pre.dump 'port=5501 dbname=demo'
    09:35:22 3926 INFO   /Applications/Postgres.app/Contents/Versions/12/bin/pg_dump -Fc --section post-data --file /tmp/pgcopydb/schema/post.dump 'port=5501 dbname=demo'
    
    $ find /tmp/pgcopydb
    /tmp/pgcopydb
    /tmp/pgcopydb/pgcopydb.pid
    /tmp/pgcopydb/schema
    /tmp/pgcopydb/schema/post.dump
    /tmp/pgcopydb/schema/pre.dump
    /tmp/pgcopydb/run
    /tmp/pgcopydb/run/tables
    /tmp/pgcopydb/run/indexes
    
    $ pgcopydb dump pre-data --source "port=5501 dbname=demo" --target /tmp/pgcopydb
    09:35:21 3926 INFO  Dumping database from "port=5501 dbname=demo"
    09:35:21 3926 INFO  Dumping database into directory "/tmp/pgcopydb"
    09:35:21 3926 INFO  Found a stale pidfile at "/tmp/pgcopydb/pgcopydb.pid"
    09:35:21 3926 WARN  Removing the stale pid file "/tmp/pgcopydb/pgcopydb.pid"
    09:35:21 3926 INFO  Using pg_dump for Postgres "12.9" at "/Applications/Postgres.app/Contents/Versions/12/bin/pg_dump"
    09:35:21 3926 INFO   /Applications/Postgres.app/Contents/Versions/12/bin/pg_dump -Fc --section pre-data --file /tmp/pgcopydb/schema/pre.dump 'port=5501 dbname=demo'
    
    $ pgcopydb dump post-data --source "port=5501 dbname=demo" --target /tmp/pgcopydb
    09:35:21 3926 INFO  Dumping database from "port=5501 dbname=demo"
    09:35:21 3926 INFO  Dumping database into directory "/tmp/pgcopydb"
    09:35:21 3926 INFO  Found a stale pidfile at "/tmp/pgcopydb/pgcopydb.pid"
    09:35:21 3926 WARN  Removing the stale pid file "/tmp/pgcopydb/pgcopydb.pid"
    09:35:21 3926 INFO  Using pg_dump for Postgres "12.9" at "/Applications/Postgres.app/Contents/Versions/12/bin/pg_dump"
    09:35:21 3926 INFO   /Applications/Postgres.app/Contents/Versions/12/bin/pg_dump -Fc --section post-data --file /tmp/pgcopydb/schema/post.dump 'port=5501 dbname=demo'
    
  • pgcopydb restore - восстановление объектов БД из файлов. Команда поддерживает следующие действия (подкоманды):
    Раскрыть type=sql
    pgcopydb restore: Восстановление объектов базы данных в экземпляр Postgres
    
    Available commands:
    pgcopydb restore
    schema      Восстановление схемы базы данных из пользовательских файлов в целевую базу данных
    pre-data    Восстановление схемы базы данных pre-data из пользовательского файла в целевую базу данных
    post-data   Восстановление схемы базы данных post-data из пользовательского файла в целевую базу данных
    roles       Восстановление ролей базы данных из SQL-файла в целевую базу данных
    parse-list  Разбор вывода pg_restore --list из пользовательского файла
    
    Команда pgcopydb restore использует pg_restore для создания определений структуры SQL из заданного каталога, экспортированной с помощью pgcopydb dump, структуры. Эта команда несовместима с прямым использованием файлов PostgreSQL, она должна работать с результатами работы команды pgcopydb dump.
    Далее следует развернутое описание каждой подкоманды.
    • pgcopydb restore schema - восстановление структуры базы данных из пользовательских файлов в целевую базу данных.
    Синопсис type=sql
    pgcopydb restore schema: Восстановление схемы базы данных из пользовательских файлов в целевую базу данных
    Использование: pgcopydb restore schema  --dir <dir> --source <URI> --target <URI>
    
    --source             Postgres URI к исходной базе данных
    --target             Postgres URI к целевой базе данных
    --dir                Рабочий каталог для временных файлов
    --restore-jobs       Количество одновременных заданий для pg_restore
    --drop-if-exists     В целевой базе данных сначала выполнить очистку после предыдущего запуска
    --no-owner           Не устанавливать права собственности на объекты в соответствии с исходной базой данных
    --no-acl             Запретить восстановление привилегий доступа (команды grant/revoke)
    --no-comments        Не выводить команды для восстановления комментариев
    --filters <filename> Использовать фильтры, определенные в <filename>
    --restart            Разрешить перезапуск, если временные файлы уже существуют
    --resume             Разрешить возобновление операций после сбоя
    --not-consistent     Разрешить создание нового моментального снимка исходной базы данных
    
    • pgcopydb restore pre-data - восстановление структуры секции pre-data базы данных источника из пользовательских файлов в целевую базу данных.
    Синопсис type=sql
    pgcopydb restore pre-data: Восстановление схемы pre-data базы данных из пользовательского файла в целевую базу данных
    Использование: pgcopydb restore pre-data  --dir <dir> --source <URI> --target <URI>
    
    --source             Postgres URI к исходной базе данных
    --target             Postgres URI к целевой базы данных
    --dir                Рабочий каталог для временных файлов
    --restore-jobs       Количество одновременных заданий для pg_restore
    --drop-if-exists     В целевой базе данных сначала выполнить очистку от предыдущего запуска
    --no-owner           Не устанавливать права собственности на объекты в соответствии с исходной базой данных
    --no-acl             Запретить восстановление привилегий доступа (команды grant/revoke)
    --no-comments        Не выводить команды для восстановления комментариев
    --skip-extensions    Пропускать восстановление расширений
    --skip-ext-comments  Пропускать восстановление COMMENT ON EXTENSION
    --filters <filename> Использовать фильтры, определенные в <filename>
    --restart            Разрешить перезапуск, если временные файлы уже существуют
    --resume             Разрешить возобновление операций после сбоя
    --not-consistent     Разрешить создание нового моментального снимка исходной базы данных
    
    • pgcopydb restore post-data - восстановление структуры секции post-data базы данных источника из пользовательских файлов в целевую базу данных.
    Синопсис type=sql
    pgcopydb restore post-data: Восстановление схемы post-data базы данных из пользовательского файла в целевую базу данных
    Использование: pgcopydb restore post-data  --dir <dir> --source <URI> --target <URI>
    
    --source             Postgres URI к исходной базе данных
    --target             Postgres URI к целевой базе данных
    --dir                Рабочий каталог для временных файлов
    --restore-jobs       Количество одновременных заданий для pg_restore
    --no-owner           Не устанавливать права собственности на объекты, чтобы они соответствовали исходной базе данных
    --no-acl             Запретить восстановление привилегий доступа (команды grant/revoke)
    --no-comments        Не выводить команды для восстановления комментариев
    --skip-extensions    Пропускать восстановление расширений
    --skip-ext-comments  Пропускать восстановление COMMENT ON EXTENSION
    --filters <filename> Использовать фильтры, определенные в <filename>
    --restart            Разрешить перезапуск, если временные файлы уже существуют
    --resume             Разрешить возобновление операций после сбоя
    --not-consistent     Разрешить создание нового моментального снимка исходной базы данных
    
    • pgcopydb restore roles - команда выполняет команды из SQL-скрипта создания ролей, полученного из команды pgcopydb dump roles. Роли, которые уже существуют в целевой базе данных, пропускаются. Команда pg_dumpall генерирует две строки для каждой роли, первая — это SQL-команда CREATE ROLE, вторая - SQL-команда ALTER ROLE. Обратите внимание, что если роль уже существует в целевой базе данных, то пропускаются обе команды (и CREATE и ALTER).
    Синопсис type=sql
    pgcopydb restore roles: Восстановление ролей базы данных из SQL-файла в целевую базу данных
    Использование: pgcopydb restore roles  --dir <dir> --source <URI> --target <URI>
    
    --source             Postgres URI к исходной базе данных
    --target             Postgres URI к целевой базе данных
    --dir                Рабочий каталог для временных файлов
    --restore-jobs       Количество одновременных заданий для pg_restore
    
    • pgcopydb restore parse-list - вывод команды pg_restore –list для пользовательского дампа. Команда pgcopydb restore parse-list выводит результат работы утилиты pg_restore для отображения каталога архива файла в формате custom, который был экспортирован для раздела post-data.
    При использовании опции --filters подключение к исходной базе данных используется для захвата всех зависимых объектов, которые также должны быть отфильтрованы, в выходных данных команды отображаются только закомментированные записи каталога pg_restore.
    Запись архивного каталога Up_restore считается закомментированной, если ее строка начинается с символа точки с запятой (;).
    Синопсис type=sql
    pgcopydb restore parse-list: Разбор вывода pg_restore --list из пользовательского файла
    Использование: pgcopydb restore parse-list  [ <pre.list> ]
    
    --source             Postgres URI к исходной базе данных
    --target             Postgres URI к целевой базе данных
    --dir                Рабочий каталог для временных файлов
    --filters <filename> Использовать фильтры, определенные в <filename>
    --skip-extensions    Пропустить восстановление расширений
    --skip-ext-comments  Пропустить восстановление COMMENT ON EXTENSION
    --restart            Разрешить перезапуск, если временные файлы уже существуют
    --resume             Разрешить возобновление операций после сбоя
    --not-consistent     Разрешить создание нового снимка исходной базы данных
    
    Пример: восстановление структуры с использованием подкоманды schema:
    Раскрыть type=sql
    $ PGCOPYDB_DROP_IF_EXISTS=on pgcopydb restore schema --source "port=54314 dbname=demo2" --target "port=54314 dbname=demo"
    09:54:37 20401 INFO  Restoring database from "/tmp/pgcopydb/"
    09:54:37 20401 INFO  Restoring database into "port=54314 dbname=demo"
    09:54:37 20401 INFO  Found a stale pidfile at "/tmp/pgcopydb//pgcopydb.pid"
    09:54:37 20401 WARN  Removing the stale pid file "/tmp/pgcopydb//pgcopydb.pid"
    09:54:37 20401 INFO  Using pg_restore for Postgres "12.9" at "/Applications/Postgres.app/Contents/Versions/12/bin/pg_restore"
    09:54:37 20401 INFO   /Applications/Postgres.app/Contents/Versions/12/bin/pg_restore --dbname 'port=54314 dbname=demo' --clean --if-exists /tmp/pgcopydb//schema/pre.dump
    09:54:38 20401 INFO   /Applications/Postgres.app/Contents/Versions/12/bin/pg_restore --dbname 'port=54314 dbname=demo' --clean --if-exists --use-list /tmp/pgcopydb//schema/post.list /tmp/pgcopydb//schema/post.dump
    
    Восстановление структуры с использованием подкоманды schema аналогично последовательному вызову подкоманд pre-data и post-data, поэтому они не демонстрируются. Использование pgcopydb restore parse-list позволяет просмотреть параметры фильтрации и то, как закомментированы записи каталога pg_restore.
    Раскрыть type=json
    $ cat ./tests/filtering/include.ini
    [include-only-table]
    public.actor
    public.category
    public.film
    public.film_actor
    public.film_category
    public.language
    public.rental
    
    [exclude-index]
    public.idx_store_id_film_id
    
    [exclude-table-data]
    public.rental
    
    $ pgcopydb restore parse-list --dir /tmp/pagila/pgcopydb --resume --not-consistent --filters ./tests/filtering/include.ini
    11:41:22 75175 INFO  Running pgcopydb version 0.5.8.ge0d2038 from "/Users/dim/dev/PostgreSQL/pgcopydb/./src/bin/pgcopydb/pgcopydb"
    11:41:22 75175 INFO  [SOURCE] Restoring database from "postgres://@:54311/pagila?"
    11:41:22 75175 INFO  [TARGET] Restoring database into "postgres://@:54311/plop?"
    11:41:22 75175 INFO  Using work dir "/tmp/pagila/pgcopydb"
    11:41:22 75175 INFO  Removing the stale pid file "/tmp/pagila/pgcopydb/pgcopydb.pid"
    11:41:22 75175 INFO  Work directory "/tmp/pagila/pgcopydb" already exists
    11:41:22 75175 INFO  Schema dump for pre-data and post-data section have been done
    11:41:22 75175 INFO  Restoring database from existing files at "/tmp/pagila/pgcopydb"
    11:41:22 75175 INFO  Using pg_restore for Postgres "12.9" at "/Applications/Postgres.app/Contents/Versions/12/bin/pg_restore"
    11:41:22 75175 INFO  Exported snapshot "00000003-0003209A-1" from the source database
    3242; 2606 317973 CONSTRAINT public actor actor_pkey postgres
    ;3258; 2606 317975 CONSTRAINT public address address_pkey postgres
    3245; 2606 317977 CONSTRAINT public category category_pkey postgres
    ;3261; 2606 317979 CONSTRAINT public city city_pkey postgres
    ;3264; 2606 317981 CONSTRAINT public country country_pkey postgres
    ;3237; 2606 317983 CONSTRAINT public customer customer_pkey postgres
    3253; 2606 317985 CONSTRAINT public film_actor film_actor_pkey postgres
    3256; 2606 317987 CONSTRAINT public film_category film_category_pkey postgres
    3248; 2606 317989 CONSTRAINT public film film_pkey postgres
    ;3267; 2606 317991 CONSTRAINT public inventory inventory_pkey postgres
    3269; 2606 317993 CONSTRAINT public language language_pkey postgres
    3293; 2606 317995 CONSTRAINT public rental rental_pkey postgres
    ;3295; 2606 317997 CONSTRAINT public staff staff_pkey postgres
    ;3298; 2606 317999 CONSTRAINT public store store_pkey postgres
    3246; 1259 318000 INDEX public film_fulltext_idx postgres
    3243; 1259 318001 INDEX public idx_actor_last_name postgres
    ;3238; 1259 318002 INDEX public idx_fk_address_id postgres
    ;3259; 1259 318003 INDEX public idx_fk_city_id postgres
    ;3262; 1259 318004 INDEX public idx_fk_country_id postgres
    ;3270; 1259 318005 INDEX public idx_fk_customer_id postgres
    3254; 1259 318006 INDEX public idx_fk_film_id postgres
    3290; 1259 318007 INDEX public idx_fk_inventory_id postgres
    3249; 1259 318008 INDEX public idx_fk_language_id postgres
    3250; 1259 318009 INDEX public idx_fk_original_language_id postgres
    ;3272; 1259 318010 INDEX public idx_fk_payment_p2020_01_customer_id postgres
    ;3271; 1259 318011 INDEX public idx_fk_staff_id postgres
    ;3273; 1259 318012 INDEX public idx_fk_payment_p2020_01_staff_id postgres
    ;3275; 1259 318013 INDEX public idx_fk_payment_p2020_02_customer_id postgres
    ;3276; 1259 318014 INDEX public idx_fk_payment_p2020_02_staff_id postgres
    ;3278; 1259 318015 INDEX public idx_fk_payment_p2020_03_customer_id postgres
    ;3279; 1259 318016 INDEX public idx_fk_payment_p2020_03_staff_id postgres
    ;3281; 1259 318017 INDEX public idx_fk_payment_p2020_04_customer_id postgres
    ;3282; 1259 318018 INDEX public idx_fk_payment_p2020_04_staff_id postgres
    ;3284; 1259 318019 INDEX public idx_fk_payment_p2020_05_customer_id postgres
    ;3285; 1259 318020 INDEX public idx_fk_payment_p2020_05_staff_id postgres
    ;3287; 1259 318021 INDEX public idx_fk_payment_p2020_06_customer_id postgres
    ;3288; 1259 318022 INDEX public idx_fk_payment_p2020_06_staff_id postgres
    ;3239; 1259 318023 INDEX public idx_fk_store_id postgres
    ;3240; 1259 318024 INDEX public idx_last_name postgres
    ;3265; 1259 318025 INDEX public idx_store_id_film_id postgres
    3251; 1259 318026 INDEX public idx_title postgres
    ;3296; 1259 318027 INDEX public idx_unq_manager_staff_id postgres
    3291; 1259 318028 INDEX public idx_unq_rental_rental_date_inventory_id_customer_id postgres
    ;3274; 1259 318029 INDEX public payment_p2020_01_customer_id_idx postgres
    ;3277; 1259 318030 INDEX public payment_p2020_02_customer_id_idx postgres
    ;3280; 1259 318031 INDEX public payment_p2020_03_customer_id_idx postgres
    ;3283; 1259 318032 INDEX public payment_p2020_04_customer_id_idx postgres
    ;3286; 1259 318033 INDEX public payment_p2020_05_customer_id_idx postgres
    ;3289; 1259 318034 INDEX public payment_p2020_06_customer_id_idx postgres
    ;3299; 0 0 INDEX ATTACH public idx_fk_payment_p2020_01_staff_id postgres
    ;3301; 0 0 INDEX ATTACH public idx_fk_payment_p2020_02_staff_id postgres
    ;3303; 0 0 INDEX ATTACH public idx_fk_payment_p2020_03_staff_id postgres
    ;3305; 0 0 INDEX ATTACH public idx_fk_payment_p2020_04_staff_id postgres
    ;3307; 0 0 INDEX ATTACH public idx_fk_payment_p2020_05_staff_id postgres
    ;3309; 0 0 INDEX ATTACH public idx_fk_payment_p2020_06_staff_id postgres
    ;3300; 0 0 INDEX ATTACH public payment_p2020_01_customer_id_idx postgres
    ;3302; 0 0 INDEX ATTACH public payment_p2020_02_customer_id_idx postgres
    ;3304; 0 0 INDEX ATTACH public payment_p2020_03_customer_id_idx postgres
    ;3306; 0 0 INDEX ATTACH public payment_p2020_04_customer_id_idx postgres
    ;3308; 0 0 INDEX ATTACH public payment_p2020_05_customer_id_idx postgres
    ;3310; 0 0 INDEX ATTACH public payment_p2020_06_customer_id_idx postgres
    3350; 2620 318035 TRIGGER public film film_fulltext_trigger postgres
    3348; 2620 318036 TRIGGER public actor last_updated postgres
    ;3354; 2620 318037 TRIGGER public address last_updated postgres
    3349; 2620 318038 TRIGGER public category last_updated postgres
    ;3355; 2620 318039 TRIGGER public city last_updated postgres
    ;3356; 2620 318040 TRIGGER public country last_updated postgres
    ;3347; 2620 318041 TRIGGER public customer last_updated postgres
    3351; 2620 318042 TRIGGER public film last_updated postgres
    3352; 2620 318043 TRIGGER public film_actor last_updated postgres
    3353; 2620 318044 TRIGGER public film_category last_updated postgres
    ;3357; 2620 318045 TRIGGER public inventory last_updated postgres
    3358; 2620 318046 TRIGGER public language last_updated postgres
    3359; 2620 318047 TRIGGER public rental last_updated postgres
    ;3360; 2620 318048 TRIGGER public staff last_updated postgres
    ;3361; 2620 318049 TRIGGER public store last_updated postgres
    ;3319; 2606 318050 FK CONSTRAINT public address address_city_id_fkey postgres
    ;3320; 2606 318055 FK CONSTRAINT public city city_country_id_fkey postgres
    ;3311; 2606 318060 FK CONSTRAINT public customer customer_address_id_fkey postgres
    ;3312; 2606 318065 FK CONSTRAINT public customer customer_store_id_fkey postgres
    3315; 2606 318070 FK CONSTRAINT public film_actor film_actor_actor_id_fkey postgres
    3316; 2606 318075 FK CONSTRAINT public film_actor film_actor_film_id_fkey postgres
    3317; 2606 318080 FK CONSTRAINT public film_category film_category_category_id_fkey postgres
    3318; 2606 318085 FK CONSTRAINT public film_category film_category_film_id_fkey postgres
    3313; 2606 318090 FK CONSTRAINT public film film_language_id_fkey postgres
    3314; 2606 318095 FK CONSTRAINT public film film_original_language_id_fkey postgres
    ;3321; 2606 318100 FK CONSTRAINT public inventory inventory_film_id_fkey postgres
    ;3322; 2606 318105 FK CONSTRAINT public inventory inventory_store_id_fkey postgres
    ;3323; 2606 318110 FK CONSTRAINT public payment_p2020_01 payment_p2020_01_customer_id_fkey postgres
    ;3324; 2606 318115 FK CONSTRAINT public payment_p2020_01 payment_p2020_01_rental_id_fkey postgres
    ;3325; 2606 318120 FK CONSTRAINT public payment_p2020_01 payment_p2020_01_staff_id_fkey postgres
    ;3326; 2606 318125 FK CONSTRAINT public payment_p2020_02 payment_p2020_02_customer_id_fkey postgres
    ;3327; 2606 318130 FK CONSTRAINT public payment_p2020_02 payment_p2020_02_rental_id_fkey postgres
    ;3328; 2606 318135 FK CONSTRAINT public payment_p2020_02 payment_p2020_02_staff_id_fkey postgres
    ;3329; 2606 318140 FK CONSTRAINT public payment_p2020_03 payment_p2020_03_customer_id_fkey postgres
    ;3330; 2606 318145 FK CONSTRAINT public payment_p2020_03 payment_p2020_03_rental_id_fkey postgres
    ;3331; 2606 318150 FK CONSTRAINT public payment_p2020_03 payment_p2020_03_staff_id_fkey postgres
    ;3332; 2606 318155 FK CONSTRAINT public payment_p2020_04 payment_p2020_04_customer_id_fkey postgres
    ;3333; 2606 318160 FK CONSTRAINT public payment_p2020_04 payment_p2020_04_rental_id_fkey postgres
    ;3334; 2606 318165 FK CONSTRAINT public payment_p2020_04 payment_p2020_04_staff_id_fkey postgres
    ;3335; 2606 318170 FK CONSTRAINT public payment_p2020_05 payment_p2020_05_customer_id_fkey postgres
    ;3336; 2606 318175 FK CONSTRAINT public payment_p2020_05 payment_p2020_05_rental_id_fkey postgres
    ;3337; 2606 318180 FK CONSTRAINT public payment_p2020_05 payment_p2020_05_staff_id_fkey postgres
    ;3338; 2606 318185 FK CONSTRAINT public payment_p2020_06 payment_p2020_06_customer_id_fkey postgres
    ;3339; 2606 318190 FK CONSTRAINT public payment_p2020_06 payment_p2020_06_rental_id_fkey postgres
    ;3340; 2606 318195 FK CONSTRAINT public payment_p2020_06 payment_p2020_06_staff_id_fkey postgres
    ;3341; 2606 318200 FK CONSTRAINT public rental rental_customer_id_fkey postgres
    ;3342; 2606 318205 FK CONSTRAINT public rental rental_inventory_id_fkey postgres
    ;3343; 2606 318210 FK CONSTRAINT public rental rental_staff_id_fkey postgres
    ;3344; 2606 318215 FK CONSTRAINT public staff staff_address_id_fkey postgres
    ;3345; 2606 318220 FK CONSTRAINT public staff staff_store_id_fkey postgres
    ;3346; 2606 318225 FK CONSTRAINT public store store_address_id_fkey postgres
    
  • pgcopydb list - вывод списка объектов БД из экземпляра PostgreSQL. Возможно использование со следующими подкомандами:
    Раскрыть type=sql
    pgcopydb list: Вывод списка объектов базы данных из экземпляра Postgres
    
    Доступные команды:
    pgcopydb list
    databases    Список баз данных
    extensions   Список всех исходных расширений для копирования
    collations   Список всех исходных правил сортировки для копирования
    tables       Список всех исходных таблиц для копирования данных из них
    table-parts  Список разделов для копирования исходных таблиц
    sequences    Список всех исходных последовательностей для копирования данных
    indexes      Список всех индексов, которые нужно создать заново после копирования данных
    depends      Список всех зависимостей, которые необходимо отфильтровать
    schema       Список схем для миграции, отформатированных в JSON
    progress     Список прогресса
    
    Описание подкоманд:
    • pgcopydb list databases - получает список баз данных в экземпляре БД источника.
    Синопсис type=sql
    pgcopydb list databases: Список баз данных
    Использование: pgcopydb list databases  --source ...
    
    --source            Postgres URI к исходной базе данных
    
    • pgcopydb list extensions - получение списка доступных для установки расширений.
    Синопсис type=sql
    pgcopydb list extensions: Список всех исходных расширений для копирования
    Использование: pgcopydb list extensions  --source ...
    
    --source              Postgres URI к исходной базе данных
    --json                Форматировать вывод с помощью JSON
    --available-versions  Список доступных версий расширений
    --requirements        Список требований к расширениям
    
    Данную команду обычно используют для получения списка из целевой БД, в таком случае в аргументе source необходимо указать целевую БД, в случае, если используются переменные окружения, необходимо сделать так:
    pgcopydb list extensions --available-versions --source ${PGCOPYDB_TARGET_PGURI}
    • pgcopydb list collations - получение списка правил сортировки для копирования. Используемый SQL-запрос выводит список правил сортировки базы данных, а также правила сортировки, отличные от стандартных, которые используются в пользовательском столбце или пользовательском индексе.
    Синопсис type=sql
    pgcopydb list collations: Список всех исходных правил сортировки для копирования
    Использование: pgcopydb list collations  --source ...
    
    --source            Postgres URI к исходной базе данных
    
    • pgcopydb list tables - выводит список таблиц для копирования из БД источника. Параметр --cache позволяет кэшировать результат pg_table_size() во вновь созданной таблице pgcopydb.pgcopydb_table_size. Это может быть полезно в инсталляциях PostgreSQL, где это вычисление выполняется довольно медленно, и когда операция pgcopydb будет выполняться несколько раз.
    Синопсис type=sql
    pgcopydb list tables: Перечисление всех исходных таблицы, из которых нужно скопировать данные
    Использование: pgcopydb list tables  --source ...
    
    --source            Postgres URI к исходной базе данных
    --filter <filename> Использовать фильтры, определенные в <filename>
    --force             Повторная принудительная выборка каталогов
    --cache             Кэшировать размер таблицы в отношении pgcopydb.pgcopydb_table_size
    --drop-cache        Удалить отношение pgcopydb.pgcopydb_table_size
    --list-skipped      Перечислить только те таблицы, которые настроены на пропуск
    --without-pkey      Перечислить только таблицы, у которых нет первичного ключа
    
    • pgcopydb list table-parts - получение списка частей таблиц из БД источника. Команда pgcopydb list table-parts подключается к исходной базе данных и выполняет SQL-запрос к каталогам PostgreSQL для получения подробной информации об исходной таблице, а затем другой SQL-запрос для вычисления того, как разделить эту исходную таблицу с учетом аргумента size threshold.
    Синопсис type=sql
    pgcopydb list table-parts: Список разделов копии исходной таблицы
    Использование: pgcopydb list table-parts  --source ...
    
    --source                    Postgres URI к исходной базе данных
    --force                     Повторная принудительная выборка каталогов
    --schema-name               Имя схемы, в которой нужно найти таблицу
    --table-name                Имя целевой таблицы
    --split-tables-larger-than  Порог размера для рассмотрения возможности разбиения на разделы
    
    • pgcopydb list sequences - получение списка последовательностей исходной БД.
    Синопсис type=sql
    pgcopydb list sequences: Перечислить все исходные последовательности, из которых нужно скопировать данные
    Использование: pgcopydb list sequences  --source ...
    
    --source            Postgres URI к исходной базе данных
    --force             Принудительная повторная выборка каталогов
    --filter <filename> Использовать фильтры, определенные в <filename>
    --list-skipped      Перечислите только те таблицы, которые настроены на пропуск
    
    • pgcopydb list indexes - получение списка индексов из исходной базы данных для создания в целевой БД.
    Синопсис type=sql
    pgcopydb list indexes: Перечисляет все индексы, которые необходимо создать заново после копирования данных
    Использование: pgcopydb list indexes  --source ... [ --schema-name [ --table-name ] ]
    
    --source            Postgres URI к исходной базе данных
    --force             Принудительная повторная выборка каталогов
    --schema-name       Имя схемы, в которой нужно найти таблицу
    --table-name        Имя целевой таблицы
    --filter <filename> Использовать фильтры, определенные в <filename>
    --list-skipped      Перечислить только те таблицы, которые настроены на пропуск
    
    • pgcopydb list depends - получение списка всех объектов, которые зависят от исключенных правилами фильтрации объектов.
    Синопсис type=sql
    pgcopydb list depends: Список всех зависимостей, которые необходимо отфильтровать
    Использование: pgcopydb list depends  --source ... [ --schema-name [ --table-name ] ]
    
    --source            Postgres URI к исходной базе данных
    --force             Принудительная повторная выборка каталогов
    --schema-name       Имя схемы, в которой нужно найти таблицу
    --table-name        Имя целевой таблицы
    --filter <filename> Использовать фильтры, определенные в <filename>
    --list-skipped      Перечислить только те таблицы, которые настроены на пропуск
    
    • pgcopydb list schema - получение списка таблиц, индексов и последовательностей для переноса. Затем команда выводит строку в формате JSON, содержащую подробную информацию обо всех этих объектах.
    Синопсис type=sql
    pgcopydb list schema: Список схем для миграции, отформатированный в JSON
    Использование: pgcopydb list schema  --source ...
    
    --source            Postgres URI к исходной базе данных
    --force             Принудительная повторная выборка каталогов
    --filter <filename> Использовать фильтры, определенные в <filename>
    
    • pgcopydb list progress - команда считывает собственные внутренние каталоги SQLite в рабочем каталоге, анализирует их, а затем вычисляет, сколько таблиц и индексов планируется скопировать и создать в целевой базе данных, сколько уже сделано и сколько находится в процессе выполнения.
    Параметр --summary отображает сводку верхнего уровня и может использоваться во время выполнения команды или постфактум.
    При использовании параметра --json выходные данные в формате JSON также содержат список всех таблиц и индексов, которые в данный момент обрабатываются.
    Синопсис type=sql
    pgcopydb list progress: Вывести список прогресса
    Использование: pgcopydb list progress  --source ...
    
    --source  Postgres URI к исходной базе данных
    --summary Вывести список итогов, требуется --json
    --json    Форматирование вывода с помощью JSON
    --dir     Рабочий каталог для временных файлов
    
    Примеры:
    Раскрыть type=sql
    $ pgcopydb list tables
    14:35:18 13827 INFO  Listing ordinary tables in "port=54311 host=localhost dbname=pgloader"
    14:35:19 13827 INFO  Fetched information for 56 tables
    OID |          Schema Name |           Table Name |  Est. Row Count |    On-disk size
    ---------+----------------------+----------------------+-----------------+----------------
    17085 |                  csv |                track |            3503 |          544 kB
    17098 |             expected |                track |            3503 |          544 kB
    17290 |             expected |           track_full |            3503 |          544 kB
    17276 |               public |           track_full |            3503 |          544 kB
    17016 |             expected |            districts |             440 |           72 kB
    17007 |               public |            districts |             440 |           72 kB
    16998 |                  csv |               blocks |             460 |           48 kB
    17003 |             expected |               blocks |             460 |           48 kB
    17405 |                  csv |              partial |               7 |           16 kB
    17323 |                  err |               errors |               0 |           16 kB
    16396 |             expected |              allcols |               0 |           16 kB
    17265 |             expected |                  csv |               0 |           16 kB
    17056 |             expected |      csv_escape_mode |               0 |           16 kB
    17331 |             expected |               errors |               0 |           16 kB
    17116 |             expected |                group |               0 |           16 kB
    17134 |             expected |                 json |               0 |           16 kB
    17074 |             expected |             matching |               0 |           16 kB
    17201 |             expected |               nullif |               0 |           16 kB
    17229 |             expected |                nulls |               0 |           16 kB
    17417 |             expected |              partial |               0 |           16 kB
    17313 |             expected |              reg2013 |               0 |           16 kB
    17437 |             expected |               serial |               0 |           16 kB
    17247 |             expected |                 sexp |               0 |           16 kB
    17378 |             expected |                test1 |               0 |           16 kB
    17454 |             expected |                  udc |               0 |           16 kB
    17471 |             expected |                xzero |               0 |           16 kB
    17372 |               nsitra |                test1 |               0 |           16 kB
    16388 |               public |              allcols |               0 |           16 kB
    17256 |               public |                  csv |               0 |           16 kB
    17047 |               public |      csv_escape_mode |               0 |           16 kB
    17107 |               public |                group |               0 |           16 kB
    17125 |               public |                 json |               0 |           16 kB
    17065 |               public |             matching |               0 |           16 kB
    17192 |               public |               nullif |               0 |           16 kB
    17219 |               public |                nulls |               0 |           16 kB
    17307 |               public |              reg2013 |               0 |           16 kB
    17428 |               public |               serial |               0 |           16 kB
    17238 |               public |                 sexp |               0 |           16 kB
    17446 |               public |                  udc |               0 |           16 kB
    17463 |               public |                xzero |               0 |           16 kB
    17303 |             expected |              copyhex |               0 |      8192 bytes
    17033 |             expected |           dateformat |               0 |      8192 bytes
    17366 |             expected |                fixed |               0 |      8192 bytes
    17041 |             expected |              jordane |               0 |      8192 bytes
    17173 |             expected |           missingcol |               0 |      8192 bytes
    17396 |             expected |             overflow |               0 |      8192 bytes
    17186 |             expected |              tab_csv |               0 |      8192 bytes
    17213 |             expected |                 temp |               0 |      8192 bytes
    17299 |               public |              copyhex |               0 |      8192 bytes
    17029 |               public |           dateformat |               0 |      8192 bytes
    17362 |               public |                fixed |               0 |      8192 bytes
    17037 |               public |              jordane |               0 |      8192 bytes
    17164 |               public |           missingcol |               0 |      8192 bytes
    17387 |               public |             overflow |               0 |      8192 bytes
    17182 |               public |              tab_csv |               0 |      8192 bytes
    17210 |               public |                 temp |               0 |      8192 bytes
    
    Раскрыть type=sql
    $ pgcopydb list table-parts --table-name rental --split-at 300kB
    16:43:26 73794 INFO  Running pgcopydb version 0.8.8.g0838291.dirty from "/Users/dim/dev/PostgreSQL/pgcopydb/src/bin/pgcopydb/pgcopydb"
    16:43:26 73794 INFO  Listing COPY partitions for table "public"."rental" in "postgres://@:/pagila?"
    16:43:26 73794 INFO  Table "public"."rental" COPY will be split 5-ways
          Part |        Min |        Max |      Count
    -----------+------------+------------+-----------
           1/5 |          1 |       3211 |       3211
           2/5 |       3212 |       6422 |       3211
           3/5 |       6423 |       9633 |       3211
           4/5 |       9634 |      12844 |       3211
           5/5 |      12845 |      16049 |       3205
    
    Раскрыть type=sql
    $ pgcopydb list indexes
    14:35:07 13668 INFO  Listing indexes in "port=54311 host=localhost dbname=pgloader"
    14:35:07 13668 INFO  Fetching all indexes in source database
    14:35:07 13668 INFO  Fetched information for 12 indexes
         OID |     Schema |           Index Name |         conname |                Constraint | DDL
    ---------+------------+----------------------+-----------------+---------------------------+---------------------
       17002 |        csv |      blocks_ip4r_idx |                 |                           | CREATE INDEX blocks_ip4r_idx ON csv.blocks USING gist (iprange)
       17415 |        csv |        partial_b_idx |                 |                           | CREATE INDEX partial_b_idx ON csv.partial  USING btree (b)
       17414 |        csv |        partial_a_key |   partial_a_key |                UNIQUE (a) | CREATE UNIQUE INDEX partial_a_key ON csv.partial USING btree (a)
       17092 |        csv |           track_pkey |      track_pkey |     PRIMARY KEY (trackid) | CREATE UNIQUE INDEX track_pkey ON csv.track USING btree (trackid)
       17329 |        err |          errors_pkey |     errors_pkey |           PRIMARY KEY (a) | CREATE UNIQUE INDEX errors_pkey ON err.errors USING btree (a)
       16394 |     public |         allcols_pkey |    allcols_pkey |           PRIMARY KEY (a) | CREATE UNIQUE INDEX allcols_pkey ON public.allcols USING btree (a)
       17054 |     public | csv_escape_mode_pkey | csv_escape_mode_pkey |          PRIMARY KEY (id) | CREATE UNIQUE INDEX csv_escape_mode_pkey ON public.csv_escape_mode USING btree (id)
       17199 |     public |          nullif_pkey |     nullif_pkey |          PRIMARY KEY (id) | CREATE UNIQUE INDEX nullif_pkey ON public."nullif" USING btree (id)
       17435 |     public |          serial_pkey |     serial_pkey |           PRIMARY KEY (a) | CREATE UNIQUE INDEX serial_pkey ON public.serial USING btree (a)
       17288 |     public |      track_full_pkey | track_full_pkey |     PRIMARY KEY (trackid) | CREATE UNIQUE INDEX track_full_pkey ON public.track_full USING btree (trackid)
       17452 |     public |             udc_pkey |        udc_pkey |           PRIMARY KEY (b) | CREATE UNIQUE INDEX udc_pkey ON public.udc USING btree (b)
       17469 |     public |           xzero_pkey |      xzero_pkey |           PRIMARY KEY (a) | CREATE UNIQUE INDEX xzero_pkey ON public.xzero USING btree (a)
    
    Раскрыть type=js
    $ pgcopydb list schema --split-at 200kB
    
    {
        "setup": {
            "snapshot": "00000003-00051AAE-1",
            "source_pguri": "postgres:\/\/@:\/pagila?",
            "target_pguri": "postgres:\/\/@:\/plop?",
            "table-jobs": 4,
            "index-jobs": 4,
          "split-tables-larger-than": 204800
        },
        "tables": [
            {
                "oid": 317934,
                "schema": "public",
                "name": "rental",
                "reltuples": 16044,
                "bytes": 1253376,
                "bytes-pretty": "1224 kB",
                "exclude-data": false,
                "restore-list-name": "public rental postgres",
                "part-key": "rental_id",
                "parts": [
                    {
                        "number": 1,
                        "total": 7,
                        "min": 1,
                        "max": 2294,
                        "count": 2294
                    },
                    {
                        "number": 2,
                        "total": 7,
                        "min": 2295,
                        "max": 4588,
                        "count": 2294
                    },
                    {
                        "number": 3,
                        "total": 7,
                        "min": 4589,
                        "max": 6882,
                        "count": 2294
                    },
                    {
                        "number": 4,
                        "total": 7,
                        "min": 6883,
                        "max": 9176,
                        "count": 2294
                    },
                    {
                        "number": 5,
                        "total": 7,
                        "min": 9177,
                        "max": 11470,
                        "count": 2294
                    },
                    {
                        "number": 6,
                        "total": 7,
                        "min": 11471,
                        "max": 13764,
                        "count": 2294
                    },
                    {
                        "number": 7,
                        "total": 7,
                        "min": 13765,
                        "max": 16049,
                        "count": 2285
                    }
                ]
            },
            {
                "oid": 317818,
                "schema": "public",
                "name": "film",
                "reltuples": 1000,
                "bytes": 483328,
                "bytes-pretty": "472 kB",
                "exclude-data": false,
                "restore-list-name": "public film postgres",
                "part-key": "film_id",
                "parts": [
                    {
                        "number": 1,
                        "total": 3,
                        "min": 1,
                        "max": 334,
                        "count": 334
                    },
                    {
                        "number": 2,
                        "total": 3,
                        "min": 335,
                        "max": 668,
                        "count": 334
                    },
                    {
                        "number": 3,
                        "total": 3,
                        "min": 669,
                        "max": 1000,
                        "count": 332
                    }
                ]
            },
            {
                "oid": 317920,
                "schema": "public",
                "name": "payment_p2020_04",
                "reltuples": 6754,
                "bytes": 434176,
                "bytes-pretty": "424 kB",
                "exclude-data": false,
                "restore-list-name": "public payment_p2020_04 postgres",
                "part-key": ""
            },
            {
                "oid": 317916,
                "schema": "public",
                "name": "payment_p2020_03",
                "reltuples": 5644,
                "bytes": 368640,
                "bytes-pretty": "360 kB",
                "exclude-data": false,
                "restore-list-name": "public payment_p2020_03 postgres",
                "part-key": ""
            },
            {
                "oid": 317830,
                "schema": "public",
                "name": "film_actor",
                "reltuples": 5462,
                "bytes": 270336,
                "bytes-pretty": "264 kB",
                "exclude-data": false,
                "restore-list-name": "public film_actor postgres",
                "part-key": ""
            },
            {
                "oid": 317885,
                "schema": "public",
                "name": "inventory",
                "reltuples": 4581,
                "bytes": 270336,
                "bytes-pretty": "264 kB",
                "exclude-data": false,
                "restore-list-name": "public inventory postgres",
                "part-key": "inventory_id",
                "parts": [
                    {
                        "number": 1,
                        "total": 2,
                        "min": 1,
                        "max": 2291,
                        "count": 2291
                    },
                    {
                        "number": 2,
                        "total": 2,
                        "min": 2292,
                        "max": 4581,
                        "count": 2290
                    }
                ]
            },
            {
                "oid": 317912,
                "schema": "public",
                "name": "payment_p2020_02",
                "reltuples": 2312,
                "bytes": 163840,
                "bytes-pretty": "160 kB",
                "exclude-data": false,
                "restore-list-name": "public payment_p2020_02 postgres",
                "part-key": ""
            },
            {
                "oid": 317784,
                "schema": "public",
                "name": "customer",
                "reltuples": 599,
                "bytes": 106496,
                "bytes-pretty": "104 kB",
                "exclude-data": false,
                "restore-list-name": "public customer postgres",
                "part-key": "customer_id"
            },
            {
                "oid": 317845,
                "schema": "public",
                "name": "address",
                "reltuples": 603,
                "bytes": 98304,
                "bytes-pretty": "96 kB",
                "exclude-data": false,
                "restore-list-name": "public address postgres",
                "part-key": "address_id"
            },
            {
                "oid": 317908,
                "schema": "public",
                "name": "payment_p2020_01",
                "reltuples": 1157,
                "bytes": 98304,
                "bytes-pretty": "96 kB",
                "exclude-data": false,
                "restore-list-name": "public payment_p2020_01 postgres",
                "part-key": ""
            },
            {
                "oid": 317855,
                "schema": "public",
                "name": "city",
                "reltuples": 600,
                "bytes": 73728,
                "bytes-pretty": "72 kB",
                "exclude-data": false,
                "restore-list-name": "public city postgres",
                "part-key": "city_id"
            },
            {
                "oid": 317834,
                "schema": "public",
                "name": "film_category",
                "reltuples": 1000,
                "bytes": 73728,
                "bytes-pretty": "72 kB",
                "exclude-data": false,
                "restore-list-name": "public film_category postgres",
                "part-key": ""
            },
            {
                "oid": 317798,
                "schema": "public",
                "name": "actor",
                "reltuples": 200,
                "bytes": 49152,
                "bytes-pretty": "48 kB",
                "exclude-data": false,
                "restore-list-name": "public actor postgres",
                "part-key": "actor_id"
            },
            {
                "oid": 317924,
                "schema": "public",
                "name": "payment_p2020_05",
                "reltuples": 182,
                "bytes": 40960,
                "bytes-pretty": "40 kB",
                "exclude-data": false,
                "restore-list-name": "public payment_p2020_05 postgres",
                "part-key": ""
            },
            {
                "oid": 317808,
                "schema": "public",
                "name": "category",
                "reltuples": 0,
                "bytes": 16384,
                "bytes-pretty": "16 kB",
                "exclude-data": false,
                "restore-list-name": "public category postgres",
                "part-key": "category_id"
            },
            {
                "oid": 317865,
                "schema": "public",
                "name": "country",
                "reltuples": 109,
                "bytes": 16384,
                "bytes-pretty": "16 kB",
                "exclude-data": false,
                "restore-list-name": "public country postgres",
                "part-key": "country_id"
            },
            {
                "oid": 317946,
                "schema": "public",
                "name": "staff",
                "reltuples": 0,
                "bytes": 16384,
                "bytes-pretty": "16 kB",
                "exclude-data": false,
                "restore-list-name": "public staff postgres",
                "part-key": "staff_id"
            },
            {
                "oid": 378280,
                "schema": "pgcopydb",
                "name": "sentinel",
                "reltuples": 1,
                "bytes": 8192,
                "bytes-pretty": "8192 bytes",
                "exclude-data": false,
                "restore-list-name": "pgcopydb sentinel dim",
               "part-key": ""
            },
            {
                "oid": 317892,
                "schema": "public",
                "name": "language",
                "reltuples": 0,
                "bytes": 8192,
                "bytes-pretty": "8192 bytes",
                "exclude-data": false,
                "restore-list-name": "public language postgres",
                "part-key": "language_id"
            },
            {
                "oid": 317928,
                "schema": "public",
                "name": "payment_p2020_06",
                "reltuples": 0,
                "bytes": 8192,
                "bytes-pretty": "8192 bytes",
                "exclude-data": false,
                "restore-list-name": "public payment_p2020_06 postgres",
                "part-key": ""
            },
            {
                "oid": 317957,
                "schema": "public",
                "name": "store",
                "reltuples": 0,
                "bytes": 8192,
                "bytes-pretty": "8192 bytes",
                "exclude-data": false,
                "restore-list-name": "public store postgres",
                "part-key": "store_id"
            }
        ],
        "indexes": [
            {
                "oid": 378283,
                "schema": "pgcopydb",
                "name": "sentinel_expr_idx",
                "isPrimary": false,
                "isUnique": true,
                "columns": "",
                "sql": "CREATE UNIQUE INDEX sentinel_expr_idx ON pgcopydb.sentinel USING btree ((1))",
                "restore-list-name": "pgcopydb sentinel_expr_idx dim",
                "table": {
                    "oid": 378280,
                    "schema": "pgcopydb",
                    "name": "sentinel"
                }
            },
            {
                "oid": 318001,
                "schema": "public",
                "name": "idx_actor_last_name",
                "isPrimary": false,
                "isUnique": false,
                "columns": "last_name",
                "sql": "CREATE INDEX idx_actor_last_name ON public.actor USING btree (last_name)",
                "restore-list-name": "public idx_actor_last_name postgres",
                "table": {
                    "oid": 317798,
                    "schema": "public",
                    "name": "actor"
                }
            },
            {
                "oid": 317972,
                "schema": "public",
                "name": "actor_pkey",
                "isPrimary": true,
                "isUnique": true,
                "columns": "actor_id",
                "sql": "CREATE UNIQUE INDEX actor_pkey ON public.actor USING btree (actor_id)",
                "restore-list-name": "",
                "table": {
                    "oid": 317798,
                    "schema": "public",
                    "name": "actor"
                },
                "constraint": {
                    "oid": 317973,
                    "name": "actor_pkey",
                    "sql": "PRIMARY KEY (actor_id)"
                }
            },
            {
                "oid": 317974,
                "schema": "public",
                "name": "address_pkey",
                "isPrimary": true,
                "isUnique": true,
                "columns": "address_id",
                "sql": "CREATE UNIQUE INDEX address_pkey ON public.address USING btree (address_id)",
                "restore-list-name": "",
                "table": {
                    "oid": 317845,
                    "schema": "public",
                    "name": "address"
                },
                "constraint": {
                    "oid": 317975,
                    "name": "address_pkey",
                    "sql": "PRIMARY KEY (address_id)"
                }
            },
            {
                "oid": 318003,
                "schema": "public",
                "name": "idx_fk_city_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "city_id",
                "sql": "CREATE INDEX idx_fk_city_id ON public.address USING btree (city_id)",
                "restore-list-name": "public idx_fk_city_id postgres",
                "table": {
                    "oid": 317845,
                    "schema": "public",
                    "name": "address"
                }
            },
            {
                "oid": 317976,
                "schema": "public",
                "name": "category_pkey",
                "isPrimary": true,
                "isUnique": true,
                "columns": "category_id",
                "sql": "CREATE UNIQUE INDEX category_pkey ON public.category USING btree (category_id)",
                "restore-list-name": "",
                "table": {
                    "oid": 317808,
                    "schema": "public",
                    "name": "category"
                },
                "constraint": {
                    "oid": 317977,
                    "name": "category_pkey",
                    "sql": "PRIMARY KEY (category_id)"
                }
            },
            {
                "oid": 317978,
                "schema": "public",
                "name": "city_pkey",
                "isPrimary": true,
                "isUnique": true,
                "columns": "city_id",
                "sql": "CREATE UNIQUE INDEX city_pkey ON public.city USING btree (city_id)",
                "restore-list-name": "",
                "table": {
                    "oid": 317855,
                    "schema": "public",
                    "name": "city"
                },
                "constraint": {
                    "oid": 317979,
                    "name": "city_pkey",
                    "sql": "PRIMARY KEY (city_id)"
                }
            },
            {
                "oid": 318004,
                "schema": "public",
                "name": "idx_fk_country_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "country_id",
                "sql": "CREATE INDEX idx_fk_country_id ON public.city USING btree (country_id)",
                "restore-list-name": "public idx_fk_country_id postgres",
                "table": {
                    "oid": 317855,
                    "schema": "public",
                    "name": "city"
                }
            },
            {
                "oid": 317980,
                "schema": "public",
                "name": "country_pkey",
                "isPrimary": true,
                "isUnique": true,
                "columns": "country_id",
                "sql": "CREATE UNIQUE INDEX country_pkey ON public.country USING btree (country_id)",
                "restore-list-name": "",
                "table": {
                    "oid": 317865,
                    "schema": "public",
                    "name": "country"
                },
                "constraint": {
                    "oid": 317981,
                    "name": "country_pkey",
                    "sql": "PRIMARY KEY (country_id)"
                }
            },
            {
                "oid": 318024,
                "schema": "public",
                "name": "idx_last_name",
                "isPrimary": false,
                "isUnique": false,
                "columns": "last_name",
                "sql": "CREATE INDEX idx_last_name ON public.customer USING btree (last_name)",
                "restore-list-name": "public idx_last_name postgres",
                "table": {
                    "oid": 317784,
                    "schema": "public",
                    "name": "customer"
                }
            },
            {
                "oid": 318002,
                "schema": "public",
                "name": "idx_fk_address_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "address_id",
                "sql": "CREATE INDEX idx_fk_address_id ON public.customer USING btree (address_id)",
                "restore-list-name": "public idx_fk_address_id postgres",
                "table": {
                    "oid": 317784,
                    "schema": "public",
                    "name": "customer"
                }
            },
            {
                "oid": 317982,
                "schema": "public",
                "name": "customer_pkey",
                "isPrimary": true,
                "isUnique": true,
                "columns": "customer_id",
                "sql": "CREATE UNIQUE INDEX customer_pkey ON public.customer USING btree (customer_id)",
                "restore-list-name": "",
                "table": {
                    "oid": 317784,
                    "schema": "public",
                    "name": "customer"
                },
                "constraint": {
                    "oid": 317983,
                    "name": "customer_pkey",
                    "sql": "PRIMARY KEY (customer_id)"
                }
            },
            {
                "oid": 318023,
                "schema": "public",
                "name": "idx_fk_store_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "store_id",
                "sql": "CREATE INDEX idx_fk_store_id ON public.customer USING btree (store_id)",
                "restore-list-name": "public idx_fk_store_id postgres",
                "table": {
                    "oid": 317784,
                    "schema": "public",
                    "name": "customer"
                }
            },
            {
                "oid": 318009,
                "schema": "public",
                "name": "idx_fk_original_language_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "original_language_id",
                "sql": "CREATE INDEX idx_fk_original_language_id ON public.film USING btree (original_language_id)",
                "restore-list-name": "public idx_fk_original_language_id postgres",
                "table": {
                    "oid": 317818,
                    "schema": "public",
                    "name": "film"
                }
            },
            {
                "oid": 318026,
                "schema": "public",
                "name": "idx_title",
                "isPrimary": false,
                "isUnique": false,
                "columns": "title",
                "sql": "CREATE INDEX idx_title ON public.film USING btree (title)",
                "restore-list-name": "public idx_title postgres",
                "table": {
                    "oid": 317818,
                    "schema": "public",
                    "name": "film"
                }
            },
            {
                "oid": 318000,
                "schema": "public",
                "name": "film_fulltext_idx",
                "isPrimary": false,
                "isUnique": false,
                "columns": "fulltext",
                "sql": "CREATE INDEX film_fulltext_idx ON public.film USING gist (fulltext)",
                "restore-list-name": "public film_fulltext_idx postgres",
                "table": {
                    "oid": 317818,
                    "schema": "public",
                    "name": "film"
                }
            },
            {
                "oid": 317988,
                "schema": "public",
                "name": "film_pkey",
                "isPrimary": true,
                "isUnique": true,
                "columns": "film_id",
                "sql": "CREATE UNIQUE INDEX film_pkey ON public.film USING btree (film_id)",
                "restore-list-name": "",
                "table": {
                    "oid": 317818,
                    "schema": "public",
                    "name": "film"
                },
                "constraint": {
                    "oid": 317989,
                    "name": "film_pkey",
                    "sql": "PRIMARY KEY (film_id)"
                }
            },
            {
                "oid": 318008,
                "schema": "public",
                "name": "idx_fk_language_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "language_id",
                "sql": "CREATE INDEX idx_fk_language_id ON public.film USING btree (language_id)",
                "restore-list-name": "public idx_fk_language_id postgres",
                "table": {
                    "oid": 317818,
                    "schema": "public",
                    "name": "film"
                }
            },
            {
                "oid": 317984,
                "schema": "public",
                "name": "film_actor_pkey",
                "isPrimary": true,
                "isUnique": true,
                "columns": "actor_id,film_id",
                "sql": "CREATE UNIQUE INDEX film_actor_pkey ON public.film_actor USING btree (actor_id, film_id)",
                "restore-list-name": "",
                "table": {
                    "oid": 317830,
                    "schema": "public",
                    "name": "film_actor"
                },
                "constraint": {
                    "oid": 317985,
                    "name": "film_actor_pkey",
                    "sql": "PRIMARY KEY (actor_id, film_id)"
                }
            },
            {
                "oid": 318006,
                "schema": "public",
                "name": "idx_fk_film_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "film_id",
                "sql": "CREATE INDEX idx_fk_film_id ON public.film_actor USING btree (film_id)",
                "restore-list-name": "public idx_fk_film_id postgres",
                "table": {
                    "oid": 317830,
                    "schema": "public",
                    "name": "film_actor"
                }
            },
            {
                "oid": 317986,
                "schema": "public",
                "name": "film_category_pkey",
                "isPrimary": true,
                "isUnique": true,
                "columns": "film_id,category_id",
                "sql": "CREATE UNIQUE INDEX film_category_pkey ON public.film_category USING btree (film_id, category_id)",
                "restore-list-name": "",
                "table": {
                    "oid": 317834,
                    "schema": "public",
                    "name": "film_category"
                },
                "constraint": {
                    "oid": 317987,
                    "name": "film_category_pkey",
                    "sql": "PRIMARY KEY (film_id, category_id)"
                }
            },
            {
                "oid": 318025,
                "schema": "public",
                "name": "idx_store_id_film_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "film_id,store_id",
                "sql": "CREATE INDEX idx_store_id_film_id ON public.inventory USING btree (store_id, film_id)",
                "restore-list-name": "public idx_store_id_film_id postgres",
                "table": {
                    "oid": 317885,
                    "schema": "public",
                    "name": "inventory"
                }
            },
            {
                "oid": 317990,
                "schema": "public",
                "name": "inventory_pkey",
                "isPrimary": true,
                "isUnique": true,
                "columns": "inventory_id",
                "sql": "CREATE UNIQUE INDEX inventory_pkey ON public.inventory USING btree (inventory_id)",
                "restore-list-name": "",
                "table": {
                    "oid": 317885,
                    "schema": "public",
                    "name": "inventory"
                },
                "constraint": {
                    "oid": 317991,
                    "name": "inventory_pkey",
                    "sql": "PRIMARY KEY (inventory_id)"
                }
            },
            {
                "oid": 317992,
                "schema": "public",
                "name": "language_pkey",
                "isPrimary": true,
                "isUnique": true,
                "columns": "language_id",
                "sql": "CREATE UNIQUE INDEX language_pkey ON public.language USING btree (language_id)",
                "restore-list-name": "",
                "table": {
                    "oid": 317892,
                    "schema": "public",
                    "name": "language"
                },
                "constraint": {
                    "oid": 317993,
                    "name": "language_pkey",
                    "sql": "PRIMARY KEY (language_id)"
                }
            },
            {
                "oid": 318010,
                "schema": "public",
                "name": "idx_fk_payment_p2020_01_customer_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "customer_id",
                "sql": "CREATE INDEX idx_fk_payment_p2020_01_customer_id ON public.payment_p2020_01 USING btree (customer_id)",
                "restore-list-name": "public idx_fk_payment_p2020_01_customer_id postgres",
                "table": {
                    "oid": 317908,
                    "schema": "public",
                    "name": "payment_p2020_01"
                }
            },
            {
                "oid": 318029,
                "schema": "public",
                "name": "payment_p2020_01_customer_id_idx",
                "isPrimary": false,
                "isUnique": false,
                "columns": "customer_id",
                "sql": "CREATE INDEX payment_p2020_01_customer_id_idx ON public.payment_p2020_01 USING btree (customer_id)",
                "restore-list-name": "public payment_p2020_01_customer_id_idx postgres",
                "table": {
                    "oid": 317908,
                    "schema": "public",
                    "name": "payment_p2020_01"
                }
            },
            {
                "oid": 318012,
                "schema": "public",
                "name": "idx_fk_payment_p2020_01_staff_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "staff_id",
                "sql": "CREATE INDEX idx_fk_payment_p2020_01_staff_id ON public.payment_p2020_01 USING btree (staff_id)",
                "restore-list-name": "public idx_fk_payment_p2020_01_staff_id postgres",
                "table": {
                    "oid": 317908,
                    "schema": "public",
                    "name": "payment_p2020_01"
                }
            },
            {
                "oid": 318013,
                "schema": "public",
                "name": "idx_fk_payment_p2020_02_customer_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "customer_id",
                "sql": "CREATE INDEX idx_fk_payment_p2020_02_customer_id ON public.payment_p2020_02 USING btree (customer_id)",
                "restore-list-name": "public idx_fk_payment_p2020_02_customer_id postgres",
                "table": {
                    "oid": 317912,
                    "schema": "public",
                    "name": "payment_p2020_02"
                }
            },
            {
                "oid": 318014,
                "schema": "public",
                "name": "idx_fk_payment_p2020_02_staff_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "staff_id",
                "sql": "CREATE INDEX idx_fk_payment_p2020_02_staff_id ON public.payment_p2020_02 USING btree (staff_id)",
                "restore-list-name": "public idx_fk_payment_p2020_02_staff_id postgres",
                "table": {
                    "oid": 317912,
                    "schema": "public",
                    "name": "payment_p2020_02"
                }
            },
            {
                "oid": 318030,
                "schema": "public",
                "name": "payment_p2020_02_customer_id_idx",
                "isPrimary": false,
                "isUnique": false,
                "columns": "customer_id",
                "sql": "CREATE INDEX payment_p2020_02_customer_id_idx ON public.payment_p2020_02 USING btree (customer_id)",
                "restore-list-name": "public payment_p2020_02_customer_id_idx postgres",
                "table": {
                    "oid": 317912,
                    "schema": "public",
                    "name": "payment_p2020_02"
                }
            },
            {
                "oid": 318016,
                "schema": "public",
                "name": "idx_fk_payment_p2020_03_staff_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "staff_id",
                "sql": "CREATE INDEX idx_fk_payment_p2020_03_staff_id ON public.payment_p2020_03 USING btree (staff_id)",
                "restore-list-name": "public idx_fk_payment_p2020_03_staff_id postgres",
                "table": {
                    "oid": 317916,
                    "schema": "public",
                    "name": "payment_p2020_03"
                }
            },
            {
                "oid": 318031,
                "schema": "public",
                "name": "payment_p2020_03_customer_id_idx",
                "isPrimary": false,
                "isUnique": false,
                "columns": "customer_id",
                "sql": "CREATE INDEX payment_p2020_03_customer_id_idx ON public.payment_p2020_03 USING btree (customer_id)",
                "restore-list-name": "public payment_p2020_03_customer_id_idx postgres",
                "table": {
                    "oid": 317916,
                    "schema": "public",
                    "name": "payment_p2020_03"
                }
            },
            {
                "oid": 318015,
                "schema": "public",
                "name": "idx_fk_payment_p2020_03_customer_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "customer_id",
                "sql": "CREATE INDEX idx_fk_payment_p2020_03_customer_id ON public.payment_p2020_03 USING btree (customer_id)",
                "restore-list-name": "public idx_fk_payment_p2020_03_customer_id postgres",
                "table": {
                    "oid": 317916,
                    "schema": "public",
                    "name": "payment_p2020_03"
                }
            },
            {
                "oid": 318032,
                "schema": "public",
                "name": "payment_p2020_04_customer_id_idx",
                "isPrimary": false,
                "isUnique": false,
                "columns": "customer_id",
                "sql": "CREATE INDEX payment_p2020_04_customer_id_idx ON public.payment_p2020_04 USING btree (customer_id)",
                "restore-list-name": "public payment_p2020_04_customer_id_idx postgres",
                "table": {
                    "oid": 317920,
                    "schema": "public",
                    "name": "payment_p2020_04"
                }
            },
            {
                "oid": 318018,
                "schema": "public",
                "name": "idx_fk_payment_p2020_04_staff_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "staff_id",
                "sql": "CREATE INDEX idx_fk_payment_p2020_04_staff_id ON public.payment_p2020_04 USING btree (staff_id)",
                "restore-list-name": "public idx_fk_payment_p2020_04_staff_id postgres",
                "table": {
                    "oid": 317920,
                    "schema": "public",
                    "name": "payment_p2020_04"
                }
            },
            {
                "oid": 318017,
                "schema": "public",
                "name": "idx_fk_payment_p2020_04_customer_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "customer_id",
                "sql": "CREATE INDEX idx_fk_payment_p2020_04_customer_id ON public.payment_p2020_04 USING btree (customer_id)",
                "restore-list-name": "public idx_fk_payment_p2020_04_customer_id postgres",
                "table": {
                    "oid": 317920,
                    "schema": "public",
                    "name": "payment_p2020_04"
                }
            },
            {
                "oid": 318019,
                "schema": "public",
                "name": "idx_fk_payment_p2020_05_customer_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "customer_id",
                "sql": "CREATE INDEX idx_fk_payment_p2020_05_customer_id ON public.payment_p2020_05 USING btree (customer_id)",
                "restore-list-name": "public idx_fk_payment_p2020_05_customer_id postgres",
                "table": {
                    "oid": 317924,
                    "schema": "public",
                    "name": "payment_p2020_05"
                }
            },
            {
                "oid": 318020,
                "schema": "public",
                "name": "idx_fk_payment_p2020_05_staff_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "staff_id",
                "sql": "CREATE INDEX idx_fk_payment_p2020_05_staff_id ON public.payment_p2020_05 USING btree (staff_id)",
                "restore-list-name": "public idx_fk_payment_p2020_05_staff_id postgres",
                "table": {
                    "oid": 317924,
                    "schema": "public",
                    "name": "payment_p2020_05"
                }
            },
            {
                "oid": 318033,
                "schema": "public",
                "name": "payment_p2020_05_customer_id_idx",
                "isPrimary": false,
                "isUnique": false,
                "columns": "customer_id",
                "sql": "CREATE INDEX payment_p2020_05_customer_id_idx ON public.payment_p2020_05 USING btree (customer_id)",
                "restore-list-name": "public payment_p2020_05_customer_id_idx postgres",
                "table": {
                    "oid": 317924,
                    "schema": "public",
                    "name": "payment_p2020_05"
                }
            },
            {
                "oid": 318022,
                "schema": "public",
                "name": "idx_fk_payment_p2020_06_staff_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "staff_id",
                "sql": "CREATE INDEX idx_fk_payment_p2020_06_staff_id ON public.payment_p2020_06 USING btree (staff_id)",
                "restore-list-name": "public idx_fk_payment_p2020_06_staff_id postgres",
                "table": {
                    "oid": 317928,
                    "schema": "public",
                    "name": "payment_p2020_06"
                }
            },
            {
                "oid": 318034,
                "schema": "public",
                "name": "payment_p2020_06_customer_id_idx",
                "isPrimary": false,
                "isUnique": false,
                "columns": "customer_id",
                "sql": "CREATE INDEX payment_p2020_06_customer_id_idx ON public.payment_p2020_06 USING btree (customer_id)",
                "restore-list-name": "public payment_p2020_06_customer_id_idx postgres",
                "table": {
                    "oid": 317928,
                    "schema": "public",
                    "name": "payment_p2020_06"
                }
            },
            {
                "oid": 318021,
                "schema": "public",
                "name": "idx_fk_payment_p2020_06_customer_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "customer_id",
                "sql": "CREATE INDEX idx_fk_payment_p2020_06_customer_id ON public.payment_p2020_06 USING btree (customer_id)",
                "restore-list-name": "public idx_fk_payment_p2020_06_customer_id postgres",
                "table": {
                    "oid": 317928,
                    "schema": "public",
                    "name": "payment_p2020_06"
                }
            },
            {
                "oid": 318028,
                "schema": "public",
                "name": "idx_unq_rental_rental_date_inventory_id_customer_id",
                "isPrimary": false,
                "isUnique": true,
                "columns": "rental_date,inventory_id,customer_id",
                "sql": "CREATE UNIQUE INDEX idx_unq_rental_rental_date_inventory_id_customer_id ON public.rental USING btree (rental_date, inventory_id, customer_id)",
                "restore-list-name": "public idx_unq_rental_rental_date_inventory_id_customer_id postgres",
                "table": {
                    "oid": 317934,
                    "schema": "public",
                    "name": "rental"
                }
            },
            {
                "oid": 317994,
                "schema": "public",
                "name": "rental_pkey",
                "isPrimary": true,
                "isUnique": true,
                "columns": "rental_id",
                "sql": "CREATE UNIQUE INDEX rental_pkey ON public.rental USING btree (rental_id)",
                "restore-list-name": "",
                "table": {
                    "oid": 317934,
                    "schema": "public",
                    "name": "rental"
                },
                "constraint": {
                    "oid": 317995,
                    "name": "rental_pkey",
                    "sql": "PRIMARY KEY (rental_id)"
                }
            },
            {
                "oid": 318007,
                "schema": "public",
                "name": "idx_fk_inventory_id",
                "isPrimary": false,
                "isUnique": false,
                "columns": "inventory_id",
                "sql": "CREATE INDEX idx_fk_inventory_id ON public.rental USING btree (inventory_id)",
                "restore-list-name": "public idx_fk_inventory_id postgres",
                "table": {
                    "oid": 317934,
                    "schema": "public",
                    "name": "rental"
                }
            },
            {
                "oid": 317996,
                "schema": "public",
                "name": "staff_pkey",
                "isPrimary": true,
                "isUnique": true,
                "columns": "staff_id",
                "sql": "CREATE UNIQUE INDEX staff_pkey ON public.staff USING btree (staff_id)",
                "restore-list-name": "",
                "table": {
                    "oid": 317946,
                    "schema": "public",
                    "name": "staff"
                },
                   "constraint": {
                    "oid": 317997,
                    "name": "staff_pkey",
                    "sql": "PRIMARY KEY (staff_id)"
                }
            },
            {
                "oid": 318027,
                "schema": "public",
                "name": "idx_unq_manager_staff_id",
                "isPrimary": false,
                "isUnique": true,
                "columns": "manager_staff_id",
                "sql": "CREATE UNIQUE INDEX idx_unq_manager_staff_id ON public.store USING btree (manager_staff_id)",
                "restore-list-name": "public idx_unq_manager_staff_id postgres",
                "table": {
                    "oid": 317957,
                    "schema": "public",
                    "name": "store"
                }
            },
            {
                "oid": 317998,
                "schema": "public",
                "name": "store_pkey",
                "isPrimary": true,
                "isUnique": true,
                "columns": "store_id",
                "sql": "CREATE UNIQUE INDEX store_pkey ON public.store USING btree (store_id)",
                "restore-list-name": "",
                "table": {
                    "oid": 317957,
                    "schema": "public",
                    "name": "store"
                },
                "constraint": {
                    "oid": 317999,
                    "name": "store_pkey",
                    "sql": "PRIMARY KEY (store_id)"
                }
            }
       ],
        "sequences": [
            {
                "oid": 317796,
                "schema": "public",
                "name": "actor_actor_id_seq",
                "last-value": 200,
                "is-called": true,
                "restore-list-name": "public actor_actor_id_seq postgres"
            },
            {
                "oid": 317843,
                "schema": "public",
                "name": "address_address_id_seq",
                "last-value": 605,
                "is-called": true,
                "restore-list-name": "public address_address_id_seq postgres"
            },
            {
                "oid": 317806,
                "schema": "public",
                "name": "category_category_id_seq",
                "last-value": 16,
                "is-called": true,
                "restore-list-name": "public category_category_id_seq postgres"
            },
            {
                "oid": 317853,
                "schema": "public",
                "name": "city_city_id_seq",
                "last-value": 600,
                "is-called": true,
                "restore-list-name": "public city_city_id_seq postgres"
            },
            {
                "oid": 317863,
                "schema": "public",
                "name": "country_country_id_seq",
                "last-value": 109,
                "is-called": true,
                "restore-list-name": "public country_country_id_seq postgres"
            },
            {
                "oid": 317782,
                "schema": "public",
                "name": "customer_customer_id_seq",
                "last-value": 599,
                "is-called": true,
                "restore-list-name": "public customer_customer_id_seq postgres"
            },
            {
                "oid": 317816,
                "schema": "public",
                "name": "film_film_id_seq",
                "last-value": 1000,
                "is-called": true,
                "restore-list-name": "public film_film_id_seq postgres"
            },
            {
                "oid": 317883,
                "schema": "public",
                "name": "inventory_inventory_id_seq",
                "last-value": 4581,
                "is-called": true,
                "restore-list-name": "public inventory_inventory_id_seq postgres"
            },
            {
                "oid": 317890,
                "schema": "public",
                "name": "language_language_id_seq",
                "last-value": 6,
                "is-called": true,
                "restore-list-name": "public language_language_id_seq postgres"
            },
            {
                "oid": 317902,
                "schema": "public",
                "name": "payment_payment_id_seq",
                "last-value": 32099,
                "is-called": true,
                "restore-list-name": "public payment_payment_id_seq postgres"
            },
            {
                "oid": 317932,
                "schema": "public",
                "name": "rental_rental_id_seq",
                "last-value": 16050,
                "is-called": true,
                "restore-list-name": "public rental_rental_id_seq postgres"
            },
            {
                "oid": 317944,
                "schema": "public",
                "name": "staff_staff_id_seq",
                "last-value": 2,
                "is-called": true,
                "restore-list-name": "public staff_staff_id_seq postgres"
            },
            {
                "oid": 317955,
                "schema": "public",
                "name": "store_store_id_seq",
                "last-value": 2,
                "is-called": true,
                "restore-list-name": "public store_store_id_seq postgres"
            }
        ]
    }
    
    Раскрыть type=sql
    $ pgcopydb list progress 2>/dev/null
    |  Total Count |  In Progress |         Done
    -------------+--------------+--------------+-------------
    Tables |           21 |            4 |            7
    Indexes |           48 |           14 |            7
    
    Раскрыть type=sql
    $ pgcopydb list progress --json 2>/dev/null
    {
    "table-jobs": 4,
    "index-jobs": 4,
    "tables": {
    "total": 21,
    "done": 9,
    "in-progress": [
    {
    "oid": 317908,
    "schema": "public",
    "name": "payment_p2020_01",
    "reltuples": 1157,
    "bytes": 98304,
    "bytes-pretty": "96 kB",
    "exclude-data": false,
    "restore-list-name": "public payment_p2020_01 postgres",
    "part-key": "",
    "process": {
    "pid": 75159,
    "start-time-epoch": 1662476249,
    "start-time-string": "2022-09-06 16:57:29 CEST",
    "command": "COPY \"public\".\"payment_p2020_01\""
    }
    },
    {
    "oid": 317855,
    "schema": "public",
    "name": "city",
    "reltuples": 600,
    "bytes": 73728,
    "bytes-pretty": "72 kB",
    "exclude-data": false,
    "restore-list-name": "public city postgres",
    "part-key": "city_id",
    "process": {
    "pid": 75157,
    "start-time-epoch": 1662476249,
    "start-time-string": "2022-09-06 16:57:29 CEST",
    "command": "COPY \"public\".\"city\""
    }
    }
    ]
    },
    "indexes": {
    "total": 48,
    "done": 39,
    "in-progress": [
    {
    "oid": 378283,
    "schema": "pgcopydb",
    "name": "sentinel_expr_idx",
    "isPrimary": false,
    "isUnique": true,
    "columns": "",
    "sql": "CREATE UNIQUE INDEX sentinel_expr_idx ON pgcopydb.sentinel USING btree ((1))",
    "restore-list-name": "pgcopydb sentinel_expr_idx dim",
    "table": {
    "oid": 378280,
    "schema": "pgcopydb",
    "name": "sentinel"
    },
    "process": {
    "pid": 74372,
    "start-time-epoch": 1662476080,
    "start-time-string": "2022-09-06 16:54:40 CEST"
    }
    },
    {
    "oid": 317980,
    "schema": "public",
    "name": "country_pkey",
    "isPrimary": true,
    "isUnique": true,
    "columns": "country_id",
    "sql": "CREATE UNIQUE INDEX country_pkey ON public.country USING btree (country_id)",
    "restore-list-name": "public country_pkey postgres",
    "table": {
    "oid": 317865,
    "schema": "public",
    "name": "country"
    },
    "constraint": {
    "oid": 317981,
    "name": "country_pkey",
    "sql": "PRIMARY KEY (country_id)",
    "restore-list-name": ""
    },
    "process": {
    "pid": 74358,
    "start-time-epoch": 1662476080,
    "start-time-string": "2022-09-06 16:54:40 CEST"
    }
    },
    {
    "oid": 317996,
    "schema": "public",
    "name": "staff_pkey",
    "isPrimary": true,
    "isUnique": true,
    "columns": "staff_id",
    "sql": "CREATE UNIQUE INDEX staff_pkey ON public.staff USING btree (staff_id)",
    "restore-list-name": "public staff_pkey postgres",
    "table": {
    "oid": 317946,
    "schema": "public",
    "name": "staff"
    },
    "constraint": {
    "oid": 317997,
    "name": "staff_pkey",
    "sql": "PRIMARY KEY (staff_id)",
    "restore-list-name": ""
    },
    "process": {
    "pid": 74368,
    "start-time-epoch": 1662476080,
    "start-time-string": "2022-09-06 16:54:40 CEST"
    }
    }
    ]
    }
    }
    
  • pgcopydb stream - потоковое применение изменений с БД источника в целевой БД. Этот режим работы был разработан только для модульного тестирования. Рассмотрите возможность использования операции клонирования pgcopydb clone (с параметром --follow) или команды pgcopydb follow вместо этого.
    Некоторые команды pgcopydb stream по-прежнему предназначены для обычных операций, а не только для модульного тестирования.
    Команды pgcopydb stream sentinel set startpos, pgcopydb stream sentinel set endpos, pgcopydb stream sentinel set apply и pgcopydb stream sentinel set prefetch необходимы для взаимодействия с основным процессом pgcopydb clone --follow или pgcopydb follow. Смотрите пример 1 раздела про CDC для получения подробного примера использования pgcopydb stream sentinel set endpos.
    Также команды pgcopydb stream setup и pgcopydb stream cleanup могут использоваться непосредственно в обычных операциях. Подробный пример приведен в примере 2 раздела про CDC.
    Данная команда поддерживает следующие подкоманды:
    Раскрыть type=sql
    pgcopydb stream: Поток изменений из исходной базы данных
    
    Доступные команды:
    pgcopydb stream
    setup       Настройка исходной и целевой систем для логического декодирования
    cleanup     Очистка исходной и целевой систем для логического декодирования
    prefetch    Потоковая передача изменений в формате JSON из исходной базы данных и преобразование их в SQL
    catchup     Применить предварительно выбранные изменения из файлов SQL к целевой базе данных
    replay      Воспроизведение изменений из исходной в целевую базу данных в реальном времени
    + sentinel  Ведение таблицы sentinel в исходной базе данных
      receive   Получать потоковые изменения из исходной базы данных
      transform Преобразовывать изменения из исходной базы данных в команды SQL
      apply     Применять изменения из исходной базы данных в целевой базе данных
    
    Раскрыть type=sql
    pgcopydb stream sentinel: Ведение таблицы sentinel в исходной базе данных
    
    Доступные команды:
    pgcopydb stream sentinel
    setup Установить таблицу sentinel
    get   Получить значения таблицы sentinel в исходной базе данных
    + set Ведение таблицы sentinel в исходной базе данных
    
    Раскрыть type=sql
    pgcopydb stream sentinel set: Ведение таблицы sentinel в исходной базе данных.
    
    Доступные команды:
    pgcopydb stream sentinel set
    startpos Задать начальную позицию LSN отправителя в исходной базе данных
    endpos   Установить LSN конечной позиции sentinel в исходной базе данных
    apply    Установить режим применения sentinel в исходной базе данных
    prefetch Установить режим предварительной выборки sentinel в исходной базе данных
    
    Раскрыть type=sql
    pgcopydb stream sentinel setup: Настройка таблицы sentinel
    Использование: pgcopydb stream sentinel setup
    
    --startpos    Начать воспроизведение изменений при достижении этого LSN
    --endpos      Остановить воспроизведение изменений по достижении этого LSN
    
    Данные команды реализуют части общей операции проигрывания изменений базы данных, которые подробно описаны в разделе pgcopydb follow. Используйте эти команды только для отладки определенной части или если уверены, что необходимо выполнить этот шаг.
    Подкоманды stream setup, stream prefetch и stream catchup - это команды более высокого уровня, которые используют внутреннюю информацию, чтобы знать, какие файлы обрабатывать. Эти команды также отслеживают ход выполнения.
    Подкоманды stream receive, stream transform и stream apply представляют собой интерфейс более низкого уровня, который работает с заданными файлами. Эти команды по-прежнему отслеживают выполнение, но для работы им необходимо предоставить больше информации.
    • pgcopydb stream setup - настройка исходной и целевой систем для логического декодирования. Команда pgcopydb stream setup подключается к целевой базе данных и создает источник репликации, расположенный в позиции LSN слота репликации логического декодирования, который должен быть уже создан. Смотрите документацию команды pgcopydb snapshot, чтобы создать слот репликации и экспортировать моментальный снимок.
    Синопсис type=sql
    pgcopydb stream setup: Настройка исходной и целевой систем для логического декодирования
    Использование: pgcopydb stream setup
    
    --source                      Postgres URI к исходной базе данных
    --target                      Postgres URI к целевой базе данных
    --dir                         Рабочий каталог для временных файлов
    --restart                     Разрешить перезапуск, если временные файлы уже существуют
    --resume                      Разрешить возобновление операций после сбоя
    --not-consistent              Разрешить создание нового моментального снимка исходной базы данных
    --snapshot                    Использовать снимок, полученный с помощью pg_export_snapshot
    --plugin                      Какой плагин использовать для вывода (test_decoding, wal2json)
    --wal2json-numeric-as-string  Выводить числовой тип данных в виде строки при использовании плагина вывода wal2json
    --slot-name                   Поток изменений, записанных этим слотом
    --origin                      Имя источника репликации Postgres
    
    • pgcopydb stream cleanup - очистка исходной и целевой систем для логического декодирования. Команда pgcopydb stream cleanup подключается к исходной и целевой базам данных для удаления объектов, созданных на этапе pgcopydb stream setup.
    Синопсис type=sql
    pgcopydb stream cleanup: Очистка исходной и целевой систем для логического декодирования
    Использование: pgcopydb stream cleanup
    
    --source         Postgres URI к исходной базе данных
    --target         Postgres URI к целевой базе данных
    --restart        Разрешить перезапуск, если временные файлы уже существуют
    --resume         Разрешить возобновление операций после сбоя
    --not-consistent Разрешить создание нового моментального снимка исходной базы данных
    --snapshot       Использовать снимок, полученный с помощью pg_export_snapshot
    --slot-name      Поток изменений, записанных этим слотом
    --origin         Имя источника репликации Postgres
    
    • pgcopydb stream prefetch - предварительная выборка потока pgcopydb – потоковая фиксация изменений из исходной базы данных в формат JSON и преобразование их в SQL. Команда pgcopydb stream prefetch подключается к исходной базе данных, используя протокол логической репликации и указанный слот репликации.
    Команда предварительной выборки получает изменения из исходной базы данных в потоковом режиме и записывает их в серию файлов JSON с именами, совпадающими с исходным именем файла WAL (за исключением расширения json). Каждый раз, когда файл JSON закрывается, запускается подпроцесс для преобразования JSON в SQL-файл.
    Синопсис type=sql
    pgcopydb stream prefetch: Поток изменений JSON из исходной базы данных и преобразование их в SQL
    Использование: pgcopydb stream prefetch
    
    --source         Postgres URI к исходной базе данных
    --dir            Рабочий каталог для временных файлов
    --restart        Разрешить перезапуск, если временные файлы уже существуют
    --resume         Разрешить возобновление операций после сбоя
    --not-consistent Разрешить создание нового моментального снимка исходной базы данных
    --slot-name      Поток изменений, записанных этим слотом
    --endpos         LSN-позиция, в которой следует прекратить прием изменений
    
    • pgcopydb stream catchup - применяет предварительно выбранные изменения из SQL-файлов к целевой базе данных. Команда pgcopydb stream catchup подключается к целевой базе данных и применяет изменения из SQL-файлов, которые были подготовлены с помощью команды pgcopydb stream prefetch.
    Синопсис type=sql
    pgcopydb stream catchup: Применение предварительно сгенерированных изменений из SQL-файлов к целевой базе данных
    Использование: pgcopydb stream catchup
    
    --source         Postgres URI к исходной базе данных
    --target         Postgres URI к целевой базе данных
    --dir            Рабочий каталог для временных файлов
    --restart        Разрешить перезапуск, если временные файлы уже существуют
    --resume         Разрешить возобновление операций после сбоя
    --not-consistent Разрешить создание нового моментального снимка исходной базы данных
    --slot-name      Поток изменений, записанных этим слотом
    --endpos         Позиция LSN, в которой следует прекратить прием изменений
    --origin         Имя источника репликации Postgres
    
    • pgcopydb stream replay - воспроизведение изменений из исходной базы данных в целевую в режиме реального времени. Команда pgcopydb stream replay подключается к исходной базе данных и передает изменения, используя протокол логического декодирования, и внутренне передает эти изменения в процесс преобразования, а затем в процесс воспроизведения, который подключается к целевой базе данных и применяет изменения SQL.
    Синопсис type=sql
    pgcopydb stream replay: Воспроизведение изменений из исходной базы данных в целевую базу данных в реальном времени
    Использование: pgcopydb stream replay
    
    --source         Postgres URI к исходной базе данных
    --target         Postgres URI к целевой базе данных
    --dir            Рабочий каталог для временных файлов
    --restart        Разрешить перезапуск, если временные файлы уже существуют
    --resume         Разрешить возобновление операций после сбоя
    --not-consistent Разрешить создание нового моментального снимка исходной базы данных
    --slot-name      Поток изменений, записанных этим слотом
    --endpos         Позиция LSN, в которой следует прекратить прием изменений
    --origin         Имя источника репликации Postgres
    
    Выполнение данной команды эквивалентно следующему скрипту:
    Раскрыть type=sql
    pgcopydb stream receive --to-stdout
    | pgcopydb stream transform - -
    | pgcopydb stream apply -
    
    • pgcopydb stream sentinel get - получить значения из контрольной таблицы в БД источнике.
    Синопсис type=sql
    pgcopydb stream sentinel get: Получение значений таблицы sentinel в исходной базе данных
    Использование: pgcopydb stream sentinel get  --source ...
    
    --source      Postgres URI к исходной базе данных
    --json        Форматирование вывода с помощью JSON
    
    • pgcopydb stream sentinel set startpos - установить начальное значение LSN в контрольной таблице БД источника.
    Синопсис type=sql
    pgcopydb stream sentinel set startpos: Установка LSN стартовой позиции sentinel в исходной базе данных
    Использование: pgcopydb stream sentinel set startpos  --source ... <start LSN>
    
    --source      Postgres URI к исходной базе данных
    
    • pgcopydb stream sentinel set endpos - установить конечное значение LSN в контрольной таблице БД источника.
    Синопсис type=sql
    pgcopydb stream sentinel set endpos: Установка LSN конечной позиции sentinel в исходной базе данных
    Использование: pgcopydb stream sentinel set endpos  --source ... <end LSN>
    
    --source      Postgres URI к исходной базе данных
    --current     В качестве endpos используется pg_current_wal_flush_lsn()
    
    • pgcopydb stream sentinel set apply - установить режим применения (apply) в контрольной таблице БД источника.
    Синопсис type=sql
    pgcopydb stream sentinel set apply: Установка режима применения sentinel в исходной базе данных
    Использование: pgcopydb stream sentinel set apply
    
    --source      Postgres URI к исходной базе данных
    
    • pgcopydb stream sentinel set prefetch - установить режим предварительной выборки (prefetch) в контрольной таблице в исходной базе данных.
    Синопсис type=sql
    pgcopydb stream sentinel set prefetch: Установка режима предварительной выборки sentinel для исходной базы данных
    Использование: pgcopydb stream sentinel set prefetch
    
    --source      Postgres URI к исходной базе данных
    
    • pgcopydb stream receive - потоковая фиксация изменений из исходной базы данных. Команда pgcopydb stream receive подключается к исходной базе данных, используя протокол логической репликации и указанный слот репликации.
    Команда receive получает изменения из исходной базы данных в потоковом режиме и записывает их в серию файлов JSON с именами, совпадающими с их исходным именем файла WAL (с расширением .json).
    Синопсис type=sql
    pgcopydb stream receive: Поток изменений из исходной базы данных
    Использование: pgcopydb stream receive
    
    --source         Postgres URI к исходной базе данных
    --dir            Рабочий каталог для временных файлов
    --to-stdout      Поток сообщений логического декодирования в stdout
    --restart        Разрешить перезапуск, если временные файлы уже существуют
    --resume         Разрешить возобновление операций после сбоя
    --not-consistent Разрешить создание нового снапшота исходной базы данных
    --slot-name      Поток изменений, записанных этим слотом
    --endpos         LSN-позиция, в которой следует прекратить прием изменений
    
    • pgcopydb stream transform - преобразует изменения из исходной базы данных в команды SQL. Команда pgcopydb stream transform преобразует файл JSON, полученный командой pgcopydb stream receive, в файл SQL с одним запросом в каждой строке.
    Команда поддерживает использование – в качестве имени файла либо для ввода JSON, либо для вывода SQL, либо для обоих. В этом случае чтение из стандартного ввода и/или запись в стандартный вывод реализуются потоковым способом. Классическим вариантом использования является использование Unix-каналов, смотрите также команду pgcopydb stream replay.
    Синопсис type=sql
    pgcopydb stream transform: реобразование изменений из исходной базы данных в команды SQL
    Использование: pgcopydb stream transform  <json filename> <sql filename>
    
    --target         Postgres URI к целевой базе данных
    --dir            Рабочий каталог для временных файлов
    --restart        Разрешить перезапуск, если временные файлы уже существуют
    --resume         Разрешить возобновление операций после сбоя
    --not-consistent Разрешить создание нового моментального снимка исходной базы данных
    
    • pgcopydb stream apply - применить изменения из исходной базы данных в целевую базу данных. Команда pgcopydb stream apply применяет SQL-файл, подготовленный командой pgcopydb stream transform в целевой базе данных. Процесс применения отслеживает прогресс с помощью PostgreSQL API для отслеживания прогресса репликации.
    Эта команда поддерживает использование - в качестве имени файла для чтения, вместо этого выполняется потоковое считывание из стандартного ввода.
    Синопсис type=sql
    pgcopydb stream apply: Применить изменения из исходной базы данных в целевую базу данных
    Использование: pgcopydb stream apply  <sql filename>
    
    --target         Postgres URI к целевой базе данных
    --dir            Рабочий каталог для временных файлов
    --restart        Разрешить перезапуск, если временные файлы уже существуют
    --resume         Разрешить возобновление операций после сбоя
    --not-consistent Разрешить создание нового моментального снимка исходной базы данных
    --origin         Имя источника репликации Postgres
    
    Примеры
    В качестве примера здесь приведены выходные данные, сгенерированные в результате выполнения тестового примера CDC, где перед первоначальной копией данных создается слот репликации, а затем выполняется следующая инструкция INSERT:
    Раскрыть type=sql
    begin;
    
    with r as
    (
    insert into rental(rental_date, inventory_id, customer_id, staff_id, last_update)
    select '2022-06-01', 371, 291, 1, '2022-06-01'
    returning rental_id, customer_id, staff_id
    )
    insert into payment(customer_id, staff_id, rental_id, amount, payment_date)
    select customer_id, staff_id, rental_id, 5.99, '2020-06-01'
    from r;
    
    commit;
    
    Следующая команда выглядит следующим образом, где --endpos был извлечен путем вызова SQL-функции pg_current_wal_lsn():
    Раскрыть type=sql
    $ pgcopydb stream receive --slot-name test_slot --restart --endpos 0/236D668 -vv
    16:01:57 157 INFO  Running pgcopydb version 0.7 from "/usr/local/bin/pgcopydb"
    16:01:57 157 DEBUG copydb.c:406 Change Data Capture data is managed at "/var/lib/postgres/.local/share/pgcopydb"
    16:01:57 157 INFO  copydb.c:73 Using work dir "/tmp/pgcopydb"
    16:01:57 157 DEBUG pidfile.c:143 Failed to signal pid 34: No such process
    16:01:57 157 DEBUG pidfile.c:146 Found a stale pidfile at "/tmp/pgcopydb/pgcopydb.pid"
    16:01:57 157 INFO  pidfile.c:147 Removing the stale pid file "/tmp/pgcopydb/pgcopydb.pid"
    16:01:57 157 INFO  copydb.c:254 Work directory "/tmp/pgcopydb" already exists
    16:01:57 157 INFO  copydb.c:258 A previous run has run through completion
    16:01:57 157 INFO  copydb.c:151 Removing directory "/tmp/pgcopydb"
    16:01:57 157 DEBUG copydb.c:445 rm -rf "/tmp/pgcopydb" && mkdir -p "/tmp/pgcopydb"
    16:01:57 157 DEBUG copydb.c:445 rm -rf "/tmp/pgcopydb/schema" && mkdir -p "/tmp/pgcopydb/schema"
    16:01:57 157 DEBUG copydb.c:445 rm -rf "/tmp/pgcopydb/run" && mkdir -p "/tmp/pgcopydb/run"
    16:01:57 157 DEBUG copydb.c:445 rm -rf "/tmp/pgcopydb/run/tables" && mkdir -p "/tmp/pgcopydb/run/tables"
    16:01:57 157 DEBUG copydb.c:445 rm -rf "/tmp/pgcopydb/run/indexes" && mkdir -p "/tmp/pgcopydb/run/indexes"
    16:01:57 157 DEBUG copydb.c:445 rm -rf "/var/lib/postgres/.local/share/pgcopydb" && mkdir -p "/var/lib/postgres/.local/share/pgcopydb"
    16:01:57 157 DEBUG pgsql.c:2476 starting log streaming at 0/0 (slot test_slot)
    16:01:57 157 DEBUG pgsql.c:485 Connecting to [source] "postgres://postgres@source:/postgres?password=****&replication=database"
    16:01:57 157 DEBUG pgsql.c:2009 IDENTIFY_SYSTEM: timeline 1, xlogpos 0/236D668, systemid 7104302452422938663
    16:01:57 157 DEBUG pgsql.c:3188 RetrieveWalSegSize: 16777216
    16:01:57 157 DEBUG pgsql.c:2547 streaming initiated
    16:01:57 157 INFO  stream.c:237 Now streaming changes to "/var/lib/postgres/.local/share/pgcopydb/000000010000000000000002.json"
    16:01:57 157 DEBUG stream.c:341 Received action B for XID 488 in LSN 0/236D638
    16:01:57 157 DEBUG stream.c:341 Received action I for XID 488 in LSN 0/236D178
    16:01:57 157 DEBUG stream.c:341 Received action I for XID 488 in LSN 0/236D308
    16:01:57 157 DEBUG stream.c:341 Received action C for XID 488 in LSN 0/236D638
    16:01:57 157 DEBUG pgsql.c:2867 pgsql_stream_logical: endpos reached at 0/236D668
    16:01:57 157 DEBUG stream.c:382 Flushed up to 0/236D668 in file "/var/lib/postgres/.local/share/pgcopydb/000000010000000000000002.json"
    16:01:57 157 INFO  pgsql.c:3030 Report write_lsn 0/236D668, flush_lsn 0/236D668
    16:01:57 157 DEBUG pgsql.c:3107 end position 0/236D668 reached by WAL record at 0/236D668
    16:01:57 157 DEBUG pgsql.c:408 Disconnecting from [source] "postgres://postgres@source:/postgres?password=****&replication=database"
    16:01:57 157 DEBUG stream.c:414 streamClose: closing file "/var/lib/postgres/.local/share/pgcopydb/000000010000000000000002.json"
    16:01:57 157 INFO  stream.c:171 Streaming is now finished after processing 4 messages
    
    Получившийся в результате файл JSON содержит следующее содержимое из плагина логической репликации wal2json. Обратите внимание, что в примере ниже вы видите разные LSN, потому что при каждом запуске создаются разные файлы, и не все файлы были сделаны из одного и того же запуска:
    Раскрыть type=sql
    $ cat /var/lib/postgres/.local/share/pgcopydb/000000010000000000000002.json
    {"action":"B","xid":489,"timestamp":"2022-06-27 13:24:31.460822+00","lsn":"0/236F5A8","nextlsn":"0/236F5D8"}
    {"action":"I","xid":489,"timestamp":"2022-06-27 13:24:31.460822+00","lsn":"0/236F0E8","schema":"public","table":"rental","columns":[{"name":"rental_id","type":"integer","value":16050},{"name":"rental_date","type":"timestamp with time zone","value":"2022-06-01 00:00:00+00"},{"name":"inventory_id","type":"integer","value":371},{"name":"customer_id","type":"integer","value":291},{"name":"return_date","type":"timestamp with time zone","value":null},{"name":"staff_id","type":"integer","value":1},{"name":"last_update","type":"timestamp with time zone","value":"2022-06-01 00:00:00+00"}]}
    {"action":"I","xid":489,"timestamp":"2022-06-27 13:24:31.460822+00","lsn":"0/236F278","schema":"public","table":"payment_p2020_06","columns":[{"name":"payment_id","type":"integer","value":32099},{"name":"customer_id","type":"integer","value":291},{"name":"staff_id","type":"integer","value":1},{"name":"rental_id","type":"integer","value":16050},{"name":"amount","type":"numeric(5,2)","value":5.99},{"name":"payment_date","type":"timestamp with time zone","value":"2020-06-01 00:00:00+00"}]}
    {"action":"C","xid":489,"timestamp":"2022-06-27 13:24:31.460822+00","lsn":"0/236F5A8","nextlsn":"0/236F5D8"}
    
    Теперь можно преобразовать JSON в SQL:
    $ pgcopydb stream transform ./tests/cdc/000000010000000000000002.json /tmp/000000010000000000000002.sql
    Получившийся файл выглядит следующим образом (далее его можно применить в целевую БД):
    Раскрыть type=sql
    $ cat /tmp/000000010000000000000002.sql
    BEGIN; -- {"xid":489,"lsn":"0/236F5A8"}
    INSERT INTO "public"."rental" (rental_id, rental_date, inventory_id, customer_id, return_date, staff_id, last_update) VALUES (16050, '2022-06-01 00:00:00+00', 371, 291, NULL, 1, '2022-06-01 00:00:00+00');
    INSERT INTO "public"."payment_p2020_06" (payment_id, customer_id, staff_id, rental_id, amount, payment_date) VALUES (32099, 291, 1, 16050, 5.99, '2020-06-01 00:00:00+00');
    COMMIT; -- {"xid": 489,"lsn":"0/236F5A8"}
    

Конфигурирование pgcopydb

Команда pgcopydb принимает подкоманды и параметры командной строки, подробности смотрите в документации по этим командам. Единственная настройка, которую принимают команды pgcopydb – это фильтрация.

Фильтрация

Фильтрация позволяет пропускать некоторые определения объектов и данные при копировании из исходной базы данных в целевую. Команды pgcopydb, которые принимают параметр --filter (или --filters), ожидают существующее имя файла в качестве аргумента параметра. Данное имя файла считывается в формате INI, но используются только разделы и ключи параметров. Значения параметров не используются.
Фильтрация выполняется с помощью правил, которые также являются именами разделов INI-файла:
  • include-only-table. Раздел позволяет вывести эксклюзивный список исходных таблиц для копирования в целевую базу данных. Никакая другая таблица не будет обработана pgcopydb. Каждая строка в этом разделе должна содержать имя таблицы с соответствующей схемой. Во избежание двусмысленности можно использовать кавычки. Если в конфигурации фильтрации используется раздел include-only-table, то разделы exclude-schema и exclude-table запрещены. Нет способа обрабатывать таблицы, которые существуют в исходной базе данных и не являются частью какого-либо фильтра;
  • exclude-schema. Раздел позволяет добавлять схемы (пространства имен PostgreSQL) к фильтрам исключения. Все таблицы, которые принадлежат к любой схеме, указанной в этом разделе, будут проигнорированы командой pgcopydb. Этот раздел недопустим, если используется раздел include-only-table;
  • include-only-schema. Раздел позволяет добавлять схемы (пространства имен PostgreSQL) для фильтров исключения, перечисляя схемы, которые не будут исключены. Это синтаксический инструмент, который помогает вводить длинный список схем для исключения, когда необходимо копировать только одну схему или небольшое их количество. Несмотря на название, этот раздел является фильтром исключения. Этот раздел нельзя использовать, если используется exclude-schema;
  • exclude-table. Раздел позволяет добавить список полных имен таблиц в фильтры исключения. Все таблицы, перечисленные в разделе exclude-table, будут проигнорированы командой pgcopydb. Этот раздел нельзя использовать, если используется раздел include-only-table;
  • exclude-index. Раздел позволяет добавить список квалифицированных имен индексов в фильтры исключения. В этом случае pgcopydb может работать с таблицей и пропускать определения индексов, относящихся к таблице, которая еще обрабатывается;
  • exclude-table-data. Раздел позволяет пропустить копирование данных из перечисленных таблиц. Схема, индекс, ограничения и другая информация о таблице по-прежнему копируются.

Просмотр и отладка фильтров

Фильтрация архивного файла pg_restore выполняется путем перезаписи каталога архивов, полученного с помощью pg_restore --list. Это не всегда правильно и тогда приходится иметь дело с зависимостями в самом pgcopydb.
Следующие команды можно использовать для изучения набора правил фильтрации:
  • pgcopydb list depends;
  • pgcopydb restore parse-list.
Пример конфигурации фильтра, основанного на включении:
Раскрыть type=sql
[include-only-table]
public.allcols
public.csv
public.serial
public.xzero

[exclude-index]
public.foo_gin_tsvector

[exclude-table-data]
public.csv
Пример конфигурации фильтра на основе исключения:
Раскрыть type=sql
[exclude-schema]
foo
bar
expected

[exclude-table]
"schema"."name"
schema.othername
err.errors
public.serial

[exclude-index]
schema.indexname

[exclude-table-data]
public.bar
nsitra.test1
Опции параметров:
  • --source. Строка подключения к БД источника. Полное описание возможного формата можно найти в документации PostgreSQL. Коротко – поддерживается и формат host=... dbname=..., а также формат URI postgres://user@host:5432/dbname;
  • --target. Строка подключения к целевой БД. К формату применимы те же утверждения, что и к строке подключения к источнику;
  • --schema-name. Для команды list. Вывести только индексы в указанной схеме;
  • --table-name. Для команды list. Вывести только индексы указанной таблицы (используйте совместно с параметром --schema-name для более точного определения таблицы);
  • --without-pkey. Для команды list. Перечислить только таблицы без первичного ключа из исходной базы данных;
  • --filter <filename>. Этот параметр позволяет исключить объекты из вывода;
  • --list-skipped. Для команды list. Вместо перечисления объектов, выбранных для копирования фильтрами, установленными с параметром --filter, перечислить объекты, которые будут пропущены при использовании фильтров;
  • --summary. Для команды list. Вместо того, чтобы перечислять текущий прогресс, когда команда все еще выполняется, выводит сводку с подробной информацией о времени для каждого шага и для всех таблиц, индексов и ограничений. Для этого параметра также требуется параметр --json: на данный момент поддерживается только этот формат вывода;
  • --dir. В процессе своей работы pgcopydb создает довольно много временных файлов для отслеживания прогресса подпроцессов. Временные файлы создаются в директории, переданной с помощью данной опции. Если параметр не задан, но существует переменная окружения, то файлы будут создаваться в директории ${TMPDIR}/pgcopydb, если нет переменной окружения, то файлы создаются в /tmp/pgcopydb;
  • --table-jobs. Количество таблиц, обрабатываемых параллельно. Данное ограничение применяется только к операции COPY, одновременно с этим ограничением будут запущены дополнительные подпроцессы для операций создания индексов (данные процессы отслеживают прогресс, непосредственно создание индексов выполняет целевой экземпляр PostgreSQL);
  • --index-jobs. Сколько индексов может быть построено параллельно, глобально. Хорошая практика — установить этот параметр равным количеству ядер процессора, доступных в целевой системе PostgreSQL, за вычетом некоторых ядер, которые будут использоваться для обработки операций копирования;
  • --restore-jobs. Сколько потоков или процессов может быть использовано во время pg_restore. Хороший вариант – установить этот параметр равным количеству ядер процессора, доступных в целевой системе PostgreSQL. Если это значение не задано, повторно используется значение --index-jobs. Если это значение также не задано, используется значение по умолчанию для --index-jobs;
  • --large-object-jobs. Сколько процессов возможно запустить для одновременного копирования больших объектов;
  • --split-tables-larger-than. Разрешить параллелизм с одной таблицей при обработке исходной базы данных. Ожидается, что значение параметра будет задано в байтах, но возможно также указание единиц измерения: B, kB, MB, GB, TB, PB и EB;
  • --drop-if-exists. При восстановлении схемы в целевом экземпляре PostgreSQL pgcopydb фактически использует pg_restore. Когда задан параметр --drop-if-exists, также используются следующие параметры pg_restore: --clean --if-exists. Эта опция полезна, когда одна и та же команда выполняется несколько раз подряд, либо для исправления предыдущей ошибки, либо, например, при использовании в системах автоматизации. Опция включает использование DROP TABLE, DROP INDEX и других команд удаления;
  • --roles. Данный параметр добавляет предварительный шаг, который копирует роли, найденные в исходном экземпляре, в целевой экземпляр. Поскольку роли PostgreSQL являются глобальными объектами, они существуют не только в контексте конкретной базы данных, поэтому при использовании этого параметра копируются все роли. Для извлечения списка ролей из исходной базы данных используется команда pg_dumpall --roles-only, эта команда включает также миграцию паролей. Поэтому для этой операции требуются привилегии суперпользователя. Смотрите также команду pgcopydb copy roles;
  • --no-role-passwords. Не копировать пароли для ролей. При восстановлении роли будут иметь нулевой пароль, и проверка подлинности по паролю всегда будет завершаться неудачей, пока пароль не будет установлен. Поскольку при указании этого параметра значения паролей не требуются, информация о роли считывается из представления pg_roles вместо pg_authid. Таким образом, этот параметр также помогает, если доступ к pg_authid ограничен какой-либо политикой безопасности;
  • --no-owner. Не выводить команды для установки владельца на объекты в соответствии с исходной базой данных. По умолчанию pg_restore выдает инструкции ALTER OWNER или SET SESSION AUTHORIZATION для установки владельца на созданные объекты схемы. Эти инструкции завершатся ошибкой, если первоначальное подключение к базе данных не будет выполнено суперпользователем (или тем же пользователем, которому принадлежат все объекты в скрипте). С параметром --no-owner для первоначального подключения можно использовать любое имя пользователя, этот пользователь будет владельцем всех созданных объектов;
  • --skip-large-objects. Пропустить копирование больших объектов (BLOB), при копировании данных из исходной базы данных в целевую базу данных;
  • --skip-extensions. Пропустить копирование расширений из исходной базы данных в целевую базу данных. При использовании создание схемы, в которую установлены расширения, также будет пропущено. Ожидается, что за создание необходимых расширений в целевой системе отвечает другая команда (например, pgcopydb copy extensions), схемы, в которые должны быть установлены расширения, будут созданы этой командой. Поскольку для создания расширений требуются привилегии суперпользователя, данная опция помогает использовать многоступенчатый подход, при котором расширения обрабатываются с привилегиями суперпользователя, а затем остальные операции с pgcopydb выполняются без привилегий суперпользователя;
  • --skip-ext-comments. Не копировать комментарии, созданные командой COMMENT ON EXTENSION. Опция избыточна при использовании параметра --skip-extensions;
  • --requirements <filename>. Этот параметр позволяет указать, какую версию расширения установить в целевой базе данных. Ожидается, что будет передано имя файла в формате JSON, а содержимое JSON должно представлять собой массив объектов с ключами name и version. Команда pgcopydb list extension --requirements --json создает такой файл JSON и может быть использована в целевом экземпляре базы данных для начала работы. Смотрите также команды: pgcopydb list extension --available-versions и pgcopydb list extensions;
  • --skip-collations. Пропустить копирование правил сортировки из исходной базы данных в целевую базу данных. В некоторых сценариях список правил сортировки, предоставляемый операционной системой в исходной и целевой системах, может отличаться, в таком случае правила сортировки необходимо установить вручную перед вызовом pgcopydb. Данный параметр позволяет pgcopydb пропустить копирование правил сортировки и предположить, что все они уже развернуты в целевой базе данных. Смотрите также pgcopydb list collations;
  • --skip-vacuum. Не выполнять команду VACUUM ANALYZE для целевой БД после того, как скопированы таблицы и для них созданы индексы и ограничения;
  • --filters <filename>. Этот параметр позволяет исключить таблицы и индексы из операций копирования;
  • --fail-fast. Прервать досрочно в случае ошибки, отправив SIGTERM всем процессам в группе процессов pgcopydb;
  • --restart. При повторном запуске команды pgcopydb, если рабочий каталог уже содержит информацию от предыдущего запуска, команда прервет выполнение и удалит диагностическую информацию. Для таких случаев возможно использовать параметр --restart, чтобы разрешить pgcopydb удалять трассировки предыдущих запусков;
  • --resume. Если команда pgcopydb была прервана до завершения либо по сигналу прерывания (например, Ctrl+C или SIGTERM), либо из-за сбоя, можно возобновить миграцию базы данных. При возобновлении работы с предыдущего запуска, данные таблиц, которые были полностью скопированы на целевой сервер, больше не отправляются. Данные таблиц, копирование которых было прервано во время выполнения команды COPY, запускаются с начала даже при использовании --resume: команда COPY в PostgreSQL является транзакционной и при сбое будет отменена. Та же причина применима к командам CREATE INDEX и ALTER TABLE, которые генерирует pgcopydb, эти команды пропускаются при запуске с параметром --resume только в том случае, если известно, что они были выполнены до завершения в предыдущем. Наконец, использование --resume требует использования --not-consistent;
  • --not-consistent. Игнорировать отсутствующий снимок данных (snapshot). Для сохранения консистентности pgcopydb экспортирует снимок данных (snapshot) PostgreSQL, вызывая функцию pg_export_snapshot() на сервере исходной базы данных. Снимок данных (snapshot) затем повторно используется во всех подключениях к исходному серверу базы данных с помощью команды SET TRANSACTION SNAPSHOT. pg_export_snapshot сохраняет текущий моментальный снимок транзакции и возвращает текстовую строку, идентифицирующую снимок данных (snapshot). Эта строка должна быть передана (вне базы данных) клиентам, которые хотят импортировать моментальный снимок. Моментальный снимок доступен для импорта только до окончания транзакции, которая его экспортировала. Когда процесс pgcopydb прерывается по какой-либо причине, можно возобновить операции копирования, но снимок данных (snapshot), который был экспортирован, больше не существует. Команда pgcopydb может возобновить операции только с новым моментальным снимком и, таким образом, не может обеспечить согласованность всего набора данных, поскольку каждый запуск теперь использует свой собственный моментальный снимок;
  • --snapshot. Вместо экспорта собственного моментального снимка путем вызова функции pg_export_snapshot() pgcopydb может повторно использовать уже экспортированный моментальный снимок;
  • --follow. Когда используется опция --follow, pgcopydb реализует CDC (Change Data Capture), как описано на странице этого документа для pgcopydb follow, параллельно с основными шагами копирования базы данных. Слот репликации создается с использованием того же моментального снимка, что и операция копирования основной базы данных, и изменения в исходной базе данных предварительно выбираются только во время первоначального копирования, затем предварительно выбираются и применяются в процессе перехвата. Возможно указать для pgcopydb clone --follow точку завершения (LSN endpos) во время выполнения команды с помощью команды pgcopydb stream sentinel set endpos;
  • --plugin. Использовать плагин вывода логического декодирования. По умолчанию используется test_decoding, который поставляется с самим ядром PostgreSQL, поэтому, вероятно, уже доступен на исходном сервере. Вместо этого можно использовать wal2json. Поддержка wal2json в pgcopydb в основном историческая, для пользователя не должно быть заметной разницы, используется ли test_decoding по умолчанию или wal2json;
  • --wal2json-numeric-as-string. При использовании плагина вывода wal2json можно использовать параметр --wal2json-numeric-as-string, чтобы указать плагину wal2json выводить числовые значения в виде строк и, таким образом, предотвратить некоторую потерю точности. Для использования этой опции в исходной базе данных должна быть версия плагина wal2json, которая поддерживает параметр --numeric-data-types-as-string. Смотрите также документацию для wal2json, касающуюся этой опции, для получения подробной информации;
  • --slot-name. Используемое имя слота логического декодирования. По умолчанию используется pgcopydb, что делает невозможным перенос более одной базы данных с исходного сервера;
  • --create-slot. Создать слот логической репликации для использования;
  • --endpos. Целевой LSN для логической репликации. Автоматически остановите репликацию и завершите работу с обычным статусом завершения 0, когда получатель достигнет указанного LSN. Если есть запись с LSN, точно равным lsn, запись будет выведена. Параметр --endpos не знает границ транзакции и может частично усекать выходные данные в транзакции. Любая частично выводимая транзакция не будет использована и будет заменена снова при следующем считывании из слота. Отдельные сообщения никогда не усекаются. Смотрите также документацию для pg_recvlogical;
  • --origin. Целевой системе логической репликации необходимо отслеживать транзакции, которые уже были применены, чтобы в случае отключения или необходимости возобновления операций можно было пропустить уже воспроизведенную транзакцию. PostgreSQL использует понятие имени исходного узла. Этот параметр позволяет выбрать ваше собственное имя узла и по умолчанию имеет значение pgcopydb. Выбор другого имени полезен в некоторых сложных сценариях, таких как перенос нескольких источников в одном целевом объекте, где у каждого источника должно быть свое собственное уникальное имя исходного узла;
  • --verbose, --notice. Увеличить детализацию лога. Уровень детализации по умолчанию – INFO. В порядке возрастания pgcopydb поддерживает следующие уровни детализации: FATAL, ERROR, WARN, INFO, NOTICE, SQL, DEBUG, TRACE;
  • --debug. Установить для уровня детализации лога уровень DEBUG;
  • --trace. Установить для уровня детализации лога уровень TRACE;
  • --quiet. Установить для уровня детализации лога уровень ERROR.
Переменные окружения:
  • PGCOPYDB_SOURCE_PGURI. Строка подключения к БД источнику PostgreSQL. Если опция --source не задана в командной строке вызова утилиты, используется эта переменная окружения;
  • PGCOPYDB_TARGET_PGURI. Строка подключения к целевой БД PostgreSQL. Если опция --target не задана в командной строке вызова утилиты, используется эта переменная окружения;
  • PGCOPYDB_TABLE_JOBS. Количество одновременно запускаемых операций копирования таблиц. Если опция --table-jobs не задана в командной строке вызова утилиты, используется эта переменная окружения;
  • PGCOPYDB_INDEX_JOBS. Количество одновременно запускаемых операций CREATE INDEX. Если опция --index-jobs не задана в командной строке вызова утилиты, используется эта переменная окружения;
  • PGCOPYDB_RESTORE_JOBS. Количество одновременно запускаемых операций pg_restore. Если опция --restore-jobs не задана в командной строке вызова утилиты, используется эта переменная окружения;
  • PGCOPYDB_LARGE_OBJECTS_JOBS. Количество одновременно запускаемых операций копирования Large Objects. Если опция --large-objects-jobs не задана в командной строке вызова утилиты, используется эта переменная окружения;
  • PGCOPYDB_SPLIT_TABLES_LARGER_THAN. Разрешить параллелизм с одной таблицей при обработке исходной базы данных. Ожидается, что значение переменной будет задано в байтах, но возможно также указание единиц измерения: B, kB, MB, GB, TB, PB и EB. Если опция --split-tables-larger-than не задана в командной строке вызова утилиты, используется эта переменная окружения;
  • PGCOPYDB_OUTPUT_PLUGIN. Плагин логического декодирования. Если опция --plugin не задана в командной строке вызова утилиты, используется эта переменная окружения;
  • PGCOPYDB_WAL2JSON_NUMERIC_AS_STRING. Если true (также возможны варианты yes, on или 1, в формате PostgreSQL boolean), тогда pgcopydb использует опции wal2json --numeric-data-types-as-string, если используется плагин wal2json. Если опция --wal2json-numeric-as-string не задана в командной строке вызова утилиты, используется эта переменная окружения;
  • PGCOPYDB_DROP_IF_EXISTS. Если true (также возможны варианты yes, on или 1, в формате PostgreSQL boolean), тогда pgcopydb использует опции pg_restore --clean --if-exists при создании схемы в целевой БД PostgreSQL. Если опция --drop-if-exists не задана в командной строке вызова утилиты, используется эта переменная окружения;
  • PGCOPYDB_FAIL_FAST. Если true (также возможны варианты yes, on или 1, в формате PostgreSQL boolean), тогда pgcopydb отправит сигнал TERM всем дочерним процессам как только один из его подпроцессов завершится с ненулевым кодом. Если опция --fail-fast не задана в командной строке вызова утилиты, используется эта переменная окружения;
  • PGCOPYDB_SKIP_VACUUM. Если true (также возможны варианты yes, on или 1, в формате PostgreSQL boolean), тогда pgcopydb пропустит операцию VACUUM ANALYZE, аналогично использованию опции --skip-vacuum;
  • PGCOPYDB_SNAPSHOT. Идентификатор снимка PostgreSQL для повторного использования, аналогично опции --snapshot;
  • TMPDIR. pgcopydb создает рабочие файлы в директории ${TMPDIR}/pgcopydb, или, если не задана переменная и не задана опция --dir, то в /tmp/pgcopydb;
  • PGCOPYDB_LOG_TIME_FORMAT. По умолчанию формат времени в логе формируется по шаблону %H:%M:%S когда pgcopydb запускается интерактивно в терминале, и %Y-%m-%d %H:%M:%S в других случаях. Данная переменная окружения позволяет установить другие форматы вывода временной отметки, отличной от перечисленных. Смотрите документацию метода strftime(3) для подробностей о возможных форматах времени. Смотрите документацию метода isatty(3) для подробностей, если pgcopydb запущен в интерактивном терминале;
  • PGCOPYDB_LOG_JSON. Если true (также возможны варианты yes, on или 1, в формате PostgreSQL boolean), тогда pgcopydb форматирует свой лог в формате JSON:
    Раскрыть type=js
    {
    "timestamp": "2023-04-13 16:53:14",
    "pid": 87956,
    "error_level": 4,
    "error_severity": "INFO",
    "file_name": "main.c",
    "file_line_num": 165,
    "message": "Running pgcopydb version 0.11.19.g2290494.dirty from \"/Users/dim/dev/PostgreSQL/pgcopydb/src/bin/pgcopydb/pgcopydb\""
    }
    
  • PGCOPYDB_LOG_FILENAME. Когда указано имя файла (директория, в которой будет создан файл должна существовать), тогда pgcopydb пишет свой лог в этот файл в дополнение к логу в стандартном потоке вывода ошибок. Если файл уже существует его содержимое будет перезаписано. Другими словами, предыдущее содержимое будет потеряно при повторном выполнении одной и той же команды;
  • PGCOPYDB_LOG_JSON_FILE. Если true (также возможны варианты yes, on или 1, в формате PostgreSQL boolean), тогда pgcopydb форматирует свой лог в формате JSON для записи его в PGCOPYDB_LOG_FILENAME;
  • XDG_DATA_HOME. Стандартная спецификация базового каталога XDG определяет несколько переменных окружения, которые позволяют управлять тем, где программы должны хранить свои файлы. XDG_DATA_HOME определяет базовый каталог, относительно которого должны храниться файлы пользовательских данных. Если $XDG_DATA_HOME либо не задан, либо пуст, будет использоваться значение по умолчанию, равное $HOME/.local/share.
При использовании Change Data Capture (с помощью опции --follow и логического декодирования PostgreSQL с помощью wal2json) pgcopydb предварительно извлекает изменения в файлах JSON и преобразует их в файлы SQL для применения к целевой базе данных.
Поиск этих файлов будет выполнен в следующих расположениях, в таком порядке:
  1. Когда используется --dir, pgcopydb использует подкаталог cdc в расположении --dir.
  2. Когда задана переменная окружения XDG_DATA_HOME, pgcopydb проверит это местоположение.
  3. Если ни одна из предыдущих настроек не была использована, pgcopydb по умолчанию использует ${HOME}/.local/share.
Предыдущий раздел
pgcompacttable
Следующий раздел
pg_cron
Была ли страница полезной?