pgcopydb#

pgcopydb

pgcopydb

pgcopydb — инструмент, который автоматизирует запуск pg_dump | pg_restore между двумя работающими серверами Postgres.

pgcopydb

Проект pgcopydb является проектом с открытым исходным кодом. Разработка происходит на https://github.com/dimitri/pgcopydb и является публичной: каждый может принять участие, открывая задачи, запросы на внесение изменений, предоставляя отзывы и т.д.

Помните, что первые шаги заключаются в том, чтобы на самом деле поиграть с pgcopydb командой, затем прочитать всю доступную документацию (в конце концов, я потратил время на её написание), а затем обратиться к сообществу в добром и вежливом тоне — так же, как вы ожидали бы, чтобы люди обращались к вам.

Как скопировать базу данных Postgres

pgcopydb — это инструмент, который автоматизирует копирование базы данных Tantor SE-1C на другой сервер. Основной случай использования pgcopydb — это миграция на новую систему Postgres, будь то новое оборудование, новая архитектура или новая основная версия Postgres.

Идея заключается в том, чтобы запустить pg_dump -jN | pg_restore -jN между двумя работающими серверами Postgres. Чтобы как можно быстрее сделать копию базы данных на другой сервер, хотелось бы использовать параллельные опции pg_dump и при этом иметь возможность передавать данные в как можно большее количество задач pg_restore. К сожалению, этот подход не может быть реализован с использованием pg_dump и pg_restore напрямую, см. Обход промежуточных файлов для TABLE DATA.

При использовании pgcopydb можно достичь как параллелизма, так и потоковой передачи с помощью этой простой командной строки:

$ export PGCOPYDB_SOURCE_PGURI="postgres://[email protected]/dbname"
$ export PGCOPYDB_TARGET_PGURI="postgres://[email protected]/dbname"

$ pgcopydb clone --table-jobs 4 --index-jobs 4

См. страницу руководства для pgcopydb clone для получения подробной информации о том, как реализована команда, а также о многих других поддерживаемых опциях.

Основные функции pgcopydb

Bypass intermediate files

При использовании pg_dump и pg_restore с опцией -jobs, данные таблицы сначала копируются в файлы на диске, прежде чем снова будут прочитаны и отправлены на целевой сервер. pgcopydb избегает этих шагов и вместо этого передает буферы COPY от источника к цели без обработки.

Use COPY FREEZE

Postgres имеет оптимизацию, которая уменьшает работу по очистке после миграции, помечая импортированные строки как замороженные уже во время импорта, это опция FREEZE для команды VACUUM. pgcopydb использует эту опцию, за исключением случаев использования параллельности для одной и той же таблицы.

Create Index Concurrency

При создании индекса на таблице, Postgres должен выполнить полный последовательный скан для чтения всех строк. В Postgres 8.3 реализована оптимизация synchronize_seqscans, при которой одно такое чтение с диска может обслуживать несколько SQL-команд, выполняющихся одновременно в разных клиентских сессиях.

pgcopydb использует эту функцию, выполняя множество команд CREATE INDEX на одной и той же таблице одновременно. Это количество ограничено опцией --index-jobs.

Same Table Concurrency

При миграции очень большой таблицы может быть полезно разделить таблицу и выполнить несколько команд COPY, распределяя исходные данные с помощью непересекающихся условий WHERE. pgcopydb реализует этот подход с опцией split-table-larger-than.

Change Data Capture

Самый простой и безопасный способ миграции базы данных на новый сервер Postgres требует окна обслуживания, продолжительность которого зависит от размера данных для миграции.

Иногда контекст миграции требует уменьшения этого окна простоя. Для этих сложных и продвинутых случаев pgcopydb включает полное решение для репликации, используя низкоуровневые API логического декодирования Postgres, доступные с Postgres 9.4.

См. руководство по эксплуатации для pgcopydb fork --follow команды.

Введение в pgcopydb

pgcopydb — это инструмент, который автоматизирует копирование базы данных Tantor SE-1C на другой сервер. Основной случай использования pgcopydb — это миграция на новую систему Postgres, будь то новое оборудование, новая архитектура или новая основная версия Postgres.

Идея заключается в том, чтобы запустить pg_dump -jN | pg_restore -jN между двумя работающими серверами Postgres. Чтобы как можно быстрее сделать копию базы данных на другой сервер, хотелось бы использовать параллельные опции pg_dump и при этом иметь возможность передавать данные в как можно большее количество задач pg_restore. К сожалению, этот подход не может быть реализован с использованием pg_dump и pg_restore напрямую, см. Обход промежуточных файлов для TABLE DATA.

При использовании pgcopydb можно достичь как параллелизма, так и потоковой передачи с помощью этой простой командной строки:

$ export PGCOPYDB_SOURCE_PGURI="postgres://[email protected]/dbname"
$ export PGCOPYDB_TARGET_PGURI="postgres://[email protected]/dbname"

$ pgcopydb clone --table-jobs 4 --index-jobs 4

См. страницу руководства для pgcopydb clone для получения подробной информации о том, как реализована команда, а также о многих других поддерживаемых опциях.

Матрица возможностей

Здесь приведено сравнение возможностей, доступных при использовании pg_dump и pg_restore напрямую по сравнению с использованием pgcopydb для копирования базы данных:

Функция pgcopydb pg_dump ; pg_restore
Операция с одной командой
Согласованность снимка
Возможность возобновления частичного выполнения
Продвинутая фильтрация
Конкуренция таблиц
Конкуренция в одной таблице
Конкурентность индекса
Конкуренция индексов ограничений
Схема
Большие объекты
Вакуум Анализ
Копирование заморожено
Роли ✗ (требуется pg_dumpall)
Табличные пространства ✗ (требуется pg_dumpall)
Следить за изменениями

Обратитесь к документации о конфигурации pgcopydb для его Расширенные возможности фильтрации.

pgcopydb использует pg_dump и pg_restore

Реализация pgcopydb фактически вызывает бинарные файлы pg_dump и pg_restore для выполнения значительной части работы, такой как секции до данных и после данных. Обратитесь к документации pg_dump для получения дополнительной информации о трех поддерживаемых секциях.

После использования pg_dump для получения частей до данных и после данных, pgcopydb восстанавливает части до данных в целевой экземпляр Postgres с помощью pg_restore.

pgcopydb затем использует SQL-команды и протокол потоковой передачи COPY для миграции содержимого таблицы, данных больших объектов и для выполнения VACUUM ANALYZE таблиц, как только данные становятся доступными на целевом экземпляре.

Затем pgcopydb использует SQL-команды для создания индексов на целевом экземпляре Postgres, как подробно описано в проектной документации Для каждой таблицы создавайте все индексы одновременно. Это позволяет включать индексы ограничений, такие как первичные ключи, в список индексов, создаваемых одновременно.

Изменение захвата данных, или разветвление и отслеживание

Также возможно с помощью pgcopydb реализовать захват изменений данных и воспроизведение изменений данных, происходящих в исходной базе данных, в целевую базу данных. См. команду pgcopydb follow и параметр командной строки pgcopydb clone --follow в разделе pgcopydb clone в руководстве.

Самая простая реализация онлайн миграции с помощью pgcopydb, при которой изменения, вносимые в базу данных исходного экземпляра Postgres, воспроизводятся на целевой системе, выглядит следующим образом:

$ 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

Руководство

Этот раздел документации для pgcopydb содержит список классических случаев использования pgcopydb. Для получения подробной информации о командах и их параметрах см. руководство по каждой команде на странице pgcopydb.

Копирование базы данных Postgres на новый сервер

Самый простой способ использовать pgcopydb — это просто использовать команду pgcopydb clone, как в следующем примере.

$ export PGCOPYDB_SOURCE_PGURI="dbname=pagila"
$ export PGCOPYDB_TARGET_PGURI="postgres://user@target:5432/pagila"

$ pgcopydb clone

Обратите внимание, что опции --source и --target также могут быть использованы для установки строк подключения Postgres к базам данных; однако использование переменных окружения особенно полезно при использовании контейнеров Docker.

Вы также можете заметить здесь, что обе базы данных Postgres, исходная и целевая, должны уже существовать для работы pgcopydb.

Копировать пользователей и расширения Postgres

Чтобы скопировать пользователей Postgres, необходимо установить привилегированное соединение с целевой базой данных, а для включения паролей необходимо также установить привилегированное соединение с исходной базой данных. Если требуется свести эти привилегированные соединения к минимуму, можно использовать следующий подход:

$ coproc ( pgcopydb snapshot --source ... )

# first two commands would use a superuser role
$ pgcopydb copy roles --source ... --target ...
$ pgcopydb copy extensions --source ... --target ...

# now it's possible to use a non-superuser role
$ pgcopydb clone --skip-extensions --source ... --target ...

$ kill -TERM ${COPROC_PID}
$ wait ${COPROC_PID}

Как редактировать схему при копировании базы данных?

Возможно разделить операции pgcopydb и выполнять их по одной.

Однако, пожалуйста, обратите внимание, что в этих случаях характеристики параллелизма и производительности, зависящие от параллелизма, будут довольно ограничены по сравнению с основной командой pgcopydb clone, где разные секции выполняются параллельно друг с другом.

Тем не менее, в некоторых случаях может потребоваться выполнение операций с большим контролем над различными этапами. Интересный такой случай использования состоит в том, чтобы внести изменения в схему перед копированием данных:

#
# pgcopydb uses the environment variables
#
$ export PGCOPYDB_SOURCE_PGURI=...
$ export PGCOPYDB_TARGET_PGURI=...

#
# we need to export a snapshot, and keep it while the indivual steps are
# running, one at a time
#
$ coproc ( pgcopydb snapshot )

$ pgcopydb dump schema --resume
$ pgcopydb restore pre-data --resume

#
# Here you can implement your own SQL commands on the target database.
#
$ psql -d ${PGCOPYDB_TARGET_PGURI} -f schema-changes.sql

# Now get back to copying the table-data, indexes, constraints, sequences
$ pgcopydb copy data --resume   
$ pgcopydb restore post-data --resume

$ kill -TERM ${COPROC_PID}
$ wait ${COPROC_PID}

$ pgcopydb list progress --summary

Обратите внимание, что для обеспечения согласованности операций использовалась команда pgcopydb snapshot. См. Возобновление операций (снимки) для получения подробной информации.

Режим отслеживания, или Захват изменений данных

При реализации захвата изменений данных требуется больше точек синхронизации между pgcopydb и приложением для осуществления чистого перехода.

Начните с первоначального копирования и настройки репликации:

$ export PGCOPYDB_SOURCE_PGURI="dbname=pagila"
$ export PGCOPYDB_TARGET_PGURI="postgres://user@target:5432/pagila"

$ pgcopydb clone --follow

Пока команда выполняется, проверьте прогресс репликации, достигнутый pgcopydb с помощью Postgres pg_stat_replication представления.

Когда отставание достаточно близко к вашим спецификациям окна обслуживания, тогда пора отключить приложения от исходной базы данных, завершить миграцию и снова подключить ваши приложения к целевой базе данных:

$ pgcopydb stream sentinel set endpos --current

Эта команда должна быть выполнена в том же --dir, что и основная pgcopydb clone --follow команда, чтобы использовать те же внутренние каталоги с работающими процессами.

Когда миграция завершена, очистите ресурсы, созданные для захвата изменений данных, с помощью следующей команды:

$ pgcopydb stream cleanup

См. также Изменение захвата данных с использованием логического декодирования Postgres для получения более подробной информации и других режимов работы.

Как проверить схему и миграцию данных?

Команда pgcopydb compare schema в настоящее время ограничена сравнением метаданных, которые pgcopydb захватывает о схеме Postgres. Это относится к сравнению списка таблиц, их атрибутов, их индексов и ограничений, а также значений последовательностей.

Команда pgcopydb compare data выполняет SQL-запрос, который вычисляет контрольную сумму данных на каждом экземпляре Postgres (т.е. исходном и целевом) для каждой таблицы, а затем сравнивает только контрольные суммы. Это не является полным сравнением набора данных и может привести к ложноположительным результатам в случаях, когда контрольные суммы совпадают, но данные различаются.

$ pgcopydb compare schema
$ pgcopydb compare data

Установка pgcopydb

Несколько дистрибутивов доступны для pgcopydb.

пакеты debian

Бинарные пакеты для debian и производных (ubuntu) доступны из apt.postgresql.org репозитория, установите, следуя документации по ссылке, а затем:

$ sudo apt-get install pgcopydb

Пакеты RPM

Репозиторий сообщества Postgres для пакетов RPM находится на yum.postgresql.org и включает бинарные пакеты для pgcopydb. Способ сборки пакетов для систем на основе RPM означает, что пользователю нужно выбрать, с какой версией Postgres был собран pgcopydb. На практике это не имеет большого значения, потому что libpq предназначен для совместимости с многими различными версиями сервера Postgres.

После выполнения инструкций по установке репозитория, в этом примере в образе Docker для Rocky Linux (docker run --rm -it rockylinux:9), мы получаем следующее:

# dnf search --all --quiet pgcopydb
======================== Name & Description & URL Matched: pgcopydb ========================
pgcopydb.x86_64 : Automate pg_dump | pg_restore between two running Postgres servers
pgcopydb_11.x86_64 : Automate pg_dump | pg_restore between two running Postgres servers
pgcopydb_12.x86_64 : Automate pg_dump | pg_restore between two running Postgres servers
pgcopydb_13.x86_64 : Automate pg_dump | pg_restore between two running Postgres servers
pgcopydb_14.x86_64 : Automate pg_dump | pg_restore between two running Postgres servers
pgcopydb_15.x86_64 : Automate pg_dump | pg_restore between two running Postgres servers

Образы Docker

Docker-образы поддерживаются для каждого помеченного выпуска на dockerhub, а также создаются из интеграции CI/CD на GitHub при каждом коммите в основную ветку.

Репозиторий DockerHub dimitri/pgcopydb — это место, где доступны помеченные выпуски. Образ использует версию Postgres, которая в настоящее время находится в debian stable.

Чтобы использовать этот образ Docker:

$ docker run --rm -it dimitri/pgcopydb:v0.17 pgcopydb --version

Или вы можете использовать интеграцию CI/CD, которая публикует пакеты из основной ветки в репозиторий Docker на GitHub:

$ docker pull ghcr.io/dimitri/pgcopydb:latest
$ docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb --fversion
$ docker run --rm -it ghcr.io/dimitri/pgcopydb:latest pgcopydb --help

Сборка из исходников

Сборка из исходного кода требует списка зависимостей для сборки, который сопоставим с таковым для самого Postgres. Исходный код pgcopydb написан на C, и процесс сборки использует GNU Makefile.

См. наш основной Dockerfile для полного рецепта сборки pgcopydb в виде пакета debian при использовании окружения debian.

В частности, для сборки pgcopydb требуются следующие зависимости сборки. Список длинный, потому что pgcopydb требует много тех же пакетов, что и сам Postgres:

$ apt-get install -y --no-install-recommends \
    build-essential \
    autotools-dev \
    libedit-dev \
    libgc-dev \
    libpam0g-dev \
    libreadline-dev \
    libselinux1-dev \
    libxslt1-dev \
    libssl-dev \
    libkrb5-dev \
    zlib1g-dev \
    liblz4-dev \
    libpq5 \
    libpq-dev \
    libzstd-dev \
    postgresql-server-dev-all \
    postgresql-common \
    postgresql \
    python3-sphinx

Затем процесс сборки довольно прост, в его самой простой форме вы можете просто использовать make clean install. Если вы хотите быть более изысканным, вы также можете рассмотреть:

$ make -s clean
$ make -s -j12 install

Как только вы дошли до этого момента, хорошей идеей будет ознакомиться с нашим Руководством по вкладу.

Основные особенности

pgcopydb проект был начат для того, чтобы позволить определенные улучшения и соображения, которые иначе было невозможно достичь напрямую с командами pg_dump и pg_restore. Ниже приведены подробности о том, чего может достичь pgcopydb.

Пропуск промежуточных файлов для ДАННЫХ ТАБЛИЦ

Первый аспект заключается в том, что для pg_dump и pg_restore для реализации параллелизма, они сначала должны записать во временный файл.

Документация для pg_dump говорит следующее о --jobs параметре:

Из документации Tantor SE-1C

Эту опцию можно использовать только с форматом вывода в виде каталога, потому что это единственный формат вывода, где несколько процессов могут записывать свои данные одновременно.

В документации для pg_restore говорится следующее о --jobs параметре:

Из документации Tantor SE-1C

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

Итак, первая идея с pgcopydb заключается в том, чтобы обеспечить параллелизм с помощью --jobs и полностью обойти промежуточные файлы (и каталоги), по крайней мере, что касается набора данных TABLE DATA.

Трюк для достижения этого заключается в том, что pgcopydb должен иметь возможность подключаться к исходной базе данных на протяжении всей операции, тогда как pg_restore может быть использован с экспортом на диске, без необходимости сохранять возможность подключения к исходной базе данных. В контексте pgcopydb требование доступа к исходной базе данных приемлемо. В контексте pg_restore это было бы неприемлемо.

Поддержка больших объектов

API Postgres Large-Objects никому не нравится, хотя компромиссы, реализованные в этом API, находят очень полезными многие разработчики приложений. В контексте дампа и восстановления, Postgres отделяет метаданные больших объектов от содержимого больших объектов.

В частности, метаданные состоят из OID большого объекта и ACL, и считаются частью секции предварительных данных дампа Postgres.

Это означает, что pgcopydb полагается на pg_dump для импорта метаданных больших объектов с исходного на целевой сервер Postgres, но затем реализует собственную логику для миграции содержимого больших объектов, используя несколько рабочих процессов в зависимости от настройки параметра командной строки --large-objects-jobs.

Параллельность (Concurrency)

Основной особенностью pgcopydb является реализация параллелизма, включая опции для получения параллелизма COPY для одной и той же таблицы. См. главу Заметки о параллелизме документации для получения дополнительной информации.

Изменение захвата данных

pgcopydb реализует полное решение для репликации Postgres, основанное на низкоуровневом API для логического декодирования Postgres. Это позволяет pgcopydb быть совместимым со старыми версиями Postgres, начиная с версии 9.4.

Всегда сначала выполняйте тестовую миграцию без опции --follow, чтобы иметь представление о необходимом окне простоя для вашего конкретного случая. Это поможет вам принять решение о использовании режима Change Data Capture, который делает миграцию гораздо более сложной для успешного выполнения.

Tantor SE-1C Клиент логического декодирования

Клиент репликации pgcopydb был разработан для того, чтобы иметь возможность получать изменения из исходного экземпляра Postgres одновременно с начальным копированием данных. Для обработки клиента логического декодирования создаются три рабочих процесса:

  • Процесс потоковой передачи извлекает данные из слота репликации Postgres, используя протокол репликации Postgres.

  • Процесс преобразования преобразует данные, полученные из промежуточного формата JSON, в производную от языка SQL. В режиме предварительной выборки это реализуется как пакетная операция; в режиме воспроизведения это делается в потоковом режиме, по одной строке за раз, считывая из unix pipe.

  • Процесс применения затем применяет SQL-скрипт к целевой системе базы данных Postgres и использует API Postgres для Отслеживания Прогресса Репликации.

Во время начальной фазы COPY операций, pgcopydb follow работает в режиме предварительной выборки и пока не применяет изменения. После завершения начальной COPY, система репликации pgcopy входит в цикл, который переключается между следующими двумя режимами работы:

  1. В режиме предварительной выборки, изменения сохраняются в JSON файлы на диске, процесс преобразования работает с файлами, когда происходит ПЕРЕКЛЮЧЕНИЕ, и процесс применения догоняет изменения на диске, применяя по одному файлу за раз.

    Когда следующий файл для применения еще не существует, тогда 3 рабочих процесса преобразования останавливаются, и основной процесс наблюдения затем переключается в режим воспроизведения.

  2. В режиме воспроизведения изменения передаются от процесса потоковой передачи к процессу преобразования с использованием механизма Unix PIPE, а полученные SQL-запросы отправляются процессу воспроизведения с использованием другого Unix PIPE.

    Изменения затем воспроизводятся в потоковом режиме, от начала до конца, с гранулярностью транзакций.

Внутренний SQL-подобный формат скрипта

API логической декодировки Postgres не предоставляет формат CDC, вместо этого он позволяет разработчикам расширений Postgres реализовывать плагины вывода логической декодировки. Основное дистрибутивное ядро Postgres реализует такой плагин вывода под названием test_decoding. Другой часто используемый плагин вывода называется wal2json.

pgcopydb совместим как с test_decoding, так и с wal2json плагинами. Пользователь может выбрать выходной плагин с помощью --plugin опции командной строки.

Совместимость с плагином вывода означает, что pgcopydb должен реализовать код для разбора синтаксиса плагина вывода и интерпретации его. Внутренне, сообщения от плагина вывода сохраняются pgcopydb в файле формата JSON Lines, где каждая строка является JSON-записью с декодированными метаданными об изменениях и сообщением плагина вывода, как есть.

Этот формат JSON Lines преобразуется в SQL-скрипты. Сначала pgcopydb использовал бы SQL для промежуточного формата, но затем была добавлена поддержка подготовленных выражений в качестве оптимизации. Это означает, что наш SQL-скрипт использует команды, такие как следующие примеры:

PREPARE d33a643f AS INSERT INTO public.rental ("rental_id", "rental_date", "inventory_id", "customer_id", "return_date", "staff_id", "last_update") overriding system value VALUES ($1, $2, $3, $4, $5, $6, $7), ($8, $9, $10, $11, $12, $13, $14);
EXECUTE d33a643f["16050","2022-06-01 00:00:00+00","371","291",null,"1","2022-06-01 00:00:00+00","16051","2022-06-01 00:00:00+00","373","293",null,"2","2022-06-01 00:00:00+00"];

Как видно из примера, pgcopydb теперь может использовать одиночный оператор INSERT с несколькими значениями VALUES, что значительно повышает производительность. Чтобы упростить разбор SQL-синтаксиса в pgcopydb, было принято решение форматировать список аргументов EXECUTE в виде массива JSON, который не соответствует фактическому синтаксису SQL, но прост и быстр в обработке.

Наконец, процесс преобразования не может предвидеть фактическое управление сеансом процесса применения, поэтому SQL-запросы всегда включаются как в шаги PREPARE, так и в шаги EXECUTE. Код pgcopydb apply знает, как пропустить повторную подготовку, конечно.

К сожалению, это означает, что наши SQL-файлы на самом деле не используют синтаксис SQL и не могут быть обработаны как есть с помощью любого клиентского программного обеспечения SQL. В данный момент требуется либо использовать pgcopydb stream apply, либо написать собственный код обработки.

Внутренние каталоги (SQLite)

Чтобы иметь возможность выполнять операции pgcopydb, требуется внутренний список SQL-объектов, таких как таблицы, индексы, ограничения и последовательности. Ранее pgcopydb обрабатывал такой список как массив в памяти, также используя хеш-таблицу для прямого поиска (по oid и по имени списка восстановления), но в некоторых случаях исходная база данных содержит так много объектов, что эти массивы не помещаются в память.

Так как pgcopydb написан на языке C, текущий лучший подход для обработки массива объектов, который необходимо сбрасывать на диск и поддерживает прямой поиск, на самом деле это библиотека SQLite, формат файла и встроенный движок базы данных.

Вот почему текущая версия pgcopydb использует SQLite для работы со своими каталогами.

Внутренне pgcopydb хранит метаданные в трех различных каталогах, все они находятся в ${TMPDIR}/pgcopydb/schema/ по умолчанию, если не используется рекомендуемая опция --dir.

  • Каталог source регистрирует метаданные о исходной базе данных, а также некоторые метаданные о контексте, согласованности и прогрессе pgcopydb.

  • Каталог filters используется только при наличии опции --filters, и он регистрирует метаданные об объектах в исходной базе данных, которые будут пропущены.

    Это необходимо, потому что фильтрация реализована с использованием опций pg_restore --list и pg_restore --use-list. Формат оглавления архива Postgres содержит OID объекта и его имя в списке восстановления, и pgcopydb должен иметь возможность искать этот OID или имя в своих каталогах фильтрации.

  • Каталог target регистрирует метаданные о целевой базе данных, такие как список ролей, список схем или список уже существующих ограничений, найденных в целевой базе данных.

Параллельность (Concurrency)

Причина, по которой был разработан pgcopydb, главным образом заключается в том, чтобы позволить два аспекта, которые невозможно достичь напрямую с помощью pg_dump и pg_restore, и которые требуют достаточно много возни, чтобы не было доступно много скриптов для автоматизации.

Заметки о параллелизме

Утилита pgcopydb также выполняет многие операции параллельно друг с другом, используя системный вызов fork(). Это означает, что pgcopydb создает подпроцессы, каждый из которых обрабатывает часть работы.

Дерево процессов выглядит следующим образом:

$ pgcopydb clone --follow --table-jobs 4 --index-jobs 4 --large-objects-jobs 4
 + pgcopydb clone worker
    + pgcopydb copy supervisor [ --table-jobs 4 ]
      - pgcopydb copy queue worker
      - pgcopydb copy worker
      - pgcopydb copy worker
      - pgcopydb copy worker
      - pgcopydb copy worker

    + pgcopydb blob metadata worker [ --large-objects-jobs 4 ]
      - pgcopydb blob data worker
      - pgcopydb blob data worker
      - pgcopydb blob data worker
      - pgcopydb blob data worker

    + pgcopydb index supervisor [ --index-jobs 4 ]
      - pgcopydb index/constraints worker
      - pgcopydb index/constraints worker
      - pgcopydb index/constraints worker
      - pgcopydb index/constraints worker

    + pgcopydb vacuum supervisor [ --table-jobs 4 ]
      - pgcopydb vacuum analyze worker
      - pgcopydb vacuum analyze worker
      - pgcopydb vacuum analyze worker
      - pgcopydb vacuum analyze worker

    + pgcopydb sequences reset worker

 + pgcopydb follow worker [ --follow ]
   - pgcopydb stream receive
   - pgcopydb stream transform
   - pgcopydb stream catchup

Обратите внимание, что при использовании pgcopydb clone --follow --table-jobs 4 --index-jobs 4 --large-objects-jobs 4, pgcopydb создает 27 подпроцессов.

Общее количество 27 подсчитывается из:

  • 1 клон-работник + 1 копия-супервайзер + 1 копия-очередь-работник + 4 копия-работника + 1 метаданные-blob-работник + 4 данные-blob-работника + 1 индекс-супервайзер + 4 индекс-работника + 1 вакуум-супервайзер + 4 вакуум-работника + 1 сброс-последовательности-работник

    это 1 + 1 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 4 + 1 = 23

  • 1 следящий рабочий + 1 поток получения + 1 поток преобразования + 1 поток догоняющий

    это 1 + 1 + 1 + 1 = 4

  • В конце концов, это 23 + 4 = 27 всего

Вот описание дерева процессов:

  • Когда начинается шаг копирования ДАННЫХ ТАБЛИЦЫ, pgcopydb создает столько подпроцессов, сколько указано в параметре командной строки --table-jobs (или в переменной окружения PGCOPYDB_TABLE_JOBS), и создается дополнительный процесс для отправки таблицы в очередь и обработки команд TRUNCATE для таблиц, разделенных на части с помощью COPY.

  • Один подпроцесс создается pgcopydb для копирования метаданных больших объектов Postgres (BLOB), найденных в исходной базе данных, в целевую базу данных, и столько же процессов, сколько указано в --large-objects-jobs, запускаются для копирования данных больших объектов.

  • Чтобы управлять созданием индексов и ограничений в целевой базе данных, pgcopydb создает столько подпроцессов, сколько указано в параметре командной строки --index-jobs (или в переменной окружения PGCOPYDB_INDEX_JOBS).

    С Postgres возможно создать несколько индексов для одной и той же таблицы параллельно, для этого клиенту нужно просто открыть отдельное подключение к базе данных для каждого индекса и выполнить каждую команду CREATE INDEX в своем собственном подключении, одновременно. В pgcopydb это реализовано путем запуска одного подпроцесса на каждый создаваемый индекс.

    Опция --index-jobs является глобальной для всей операции, поэтому её проще настроить в соответствии с количеством доступных ядер ЦП на целевом экземпляре Postgres. Обычно, данная команда CREATE INDEX использует 100% одного ядра.

  • Чтобы запустить рабочую нагрузку VACUUM ANALYZE на целевой базе данных, pgcopydb создает столько подпроцессов, сколько указано в --table-jobs параметре командной строки.

  • Чтобы сбросить последовательности параллельно с копированием данных таблицы, pgcopydb создает один выделенный подпроцесс.

  • При использовании опции --follow создается еще один лидер подпроцесса для обработки трех процессов захвата изменений данных.

    • Один процесс реализует pgcopydb stream receive для получения изменений в формате JSON и предварительной выборки их в файлы JSON.

    • Как только JSON файл завершен, рабочий процесс pgcopydb stream transform преобразует JSON файл в SQL, как если бы вызвал команду pgcopydb stream transform.

    • Другой процесс реализует pgcopydb stream catchup для применения изменений SQL к целевому экземпляру Postgres. Этот процесс циклически запрашивает таблицу pgcopydb sentinel до тех пор, пока режим применения не будет включен, а затем циклически обрабатывает SQL файлы и выполняет запросы из них.

Одновременное создание индексов для каждой таблицы

pgcopydb делает дополнительный шаг и гарантирует создание всех ваших индексов параллельно друг другу, прилагая дополнительные усилия, когда дело касается индексов, связанных с ограничением.

Postgres ввел параметр конфигурации synchronize_seqscans в версии 8.3, много лет назад. По умолчанию он включен и позволяет следующее поведение:

Из документации Tantor SE-1C

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

Другой аспект, о котором pg_dump и pg_restore не очень хорошо осведомлены, это то, как они работают с индексами, которые используются для поддержки ограничений, в частности уникальных ограничений и первичных ключей.

Эти индексы экспортируются с использованием команды ALTER TABLE напрямую. Это нормально, потому что команда создает как ограничение, так и базовый индекс, так что схема в итоге строится как ожидалось.

Тем не менее, эти команды ALTER TABLE ... ADD CONSTRAINT требуют уровня блокировки, который предотвращает любую параллельность. Как мы можем прочитать в документации для ALTER TABLE:

Из документации Tantor SE-1C

Хотя большинство форм ADD table_constraint требуют блокировки ACCESS EXCLUSIVE, ADD FOREIGN KEY требует только блокировки SHARE ROW EXCLUSIVE. Обратите внимание, что ADD FOREIGN KEY также получает блокировку SHARE ROW EXCLUSIVE на ссылочной таблице, в дополнение к блокировке на таблице, в которой объявлено ограничение.

Трюк заключается в том, чтобы сначала выполнить CREATE UNIQUE INDEX оператор, и когда индекс будет создан, затем выполнить вторую команду в форме ALTER TABLE ... ADD CONSTRAINT ... PRIMARY KEY USING INDEX ..., как в следующем примере, который взят из журналов фактического запуска pgcopydb:

21:52:06 68898 INFO  COPY "demo"."tracking";
21:52:06 68899 INFO  COPY "demo"."client";
21:52:06 68899 INFO  Creating 2 indexes for table "demo"."client"
21:52:06 68906 INFO  CREATE UNIQUE INDEX client_pkey ON demo.client USING btree (client);
21:52:06 68907 INFO  CREATE UNIQUE INDEX client_pid_key ON demo.client USING btree (pid);
21:52:06 68898 INFO  Creating 1 indexes for table "demo"."tracking"
21:52:06 68908 INFO  CREATE UNIQUE INDEX tracking_pkey ON demo.tracking USING btree (client, ts);
21:52:06 68907 INFO  ALTER TABLE "demo"."client" ADD CONSTRAINT "client_pid_key" UNIQUE USING INDEX "client_pid_key";
21:52:06 68906 INFO  ALTER TABLE "demo"."client" ADD CONSTRAINT "client_pkey" PRIMARY KEY USING INDEX "client_pkey";
21:52:06 68908 INFO  ALTER TABLE "demo"."tracking" ADD CONSTRAINT "tracking_pkey" PRIMARY KEY USING INDEX "tracking_pkey";

Этот трюк сам по себе стоит множества приростов производительности, как было обнаружено, испытано и оценено пользователями pgloader уже.

Одновременный доступ к одной таблице

Для некоторых баз данных так получается, что большая часть размера базы данных на диске содержится в одной гигантской таблице или в коротком списке гигантских таблиц. Когда это происходит, модель параллелизма, реализованная с --table-jobs, все равно выделяет один процесс для копирования всех данных из исходной таблицы.

Одновременный доступ к одной и той же таблице позволяет pgcopydb использовать более одного процесса одновременно для обработки одной исходной таблицы. Данные затем логически разделяются (на лету) и распределяются между процессами:

  • Чтобы извлечь данные из исходной базы данных, процессы COPY затем используют запросы SELECT, как в следующем примере:

    COPY (SELECT * FROM source.table WHERE id BETWEEN      1 AND 123456)
    COPY (SELECT * FROM source.table WHERE id BETWEEN 123457 AND 234567)
    COPY (SELECT * FROM source.table WHERE id BETWEEN 234568 AND 345678)
    ...
    

    Это возможно только в том случае, если source.table имеет хотя бы одну колонку целочисленного типа (int2, int4 и int8 поддерживаются) и с ограничением UNIQUE или PRIMARY KEY. Мы должны убедиться, что любая данная строка выбирается только один раз в целом, чтобы избежать появления дубликатов в целевой базе данных.

    Когда в таблице отсутствует такой столбец первичного ключа с целочисленным типом данных, pgcopydb автоматически переходит к использованию сравнений на основе CTID. См. раздел документации Postgres о системных столбцах для получения дополнительной информации о CTID в Postgres.

    Процессы COPY затем используют запросы SELECT, как в следующем примере:

    COPY (SELECT * FROM source.table WHERE ctid >= '(0,0)'::tid and ctid < '(5925,0)'::tid)
    COPY (SELECT * FROM source.table WHERE ctid >= '(5925,0)'::tid and ctid < '(11850,0)'::tid)
    COPY (SELECT * FROM source.table WHERE ctid >= '(11850,0)'::tid and ctid < '(17775,0)'::tid)
    COPY (SELECT * FROM source.table WHERE ctid >= '(17775,0)'::tid and ctid < '(23698,0)'::tid)
    COPY (SELECT * FROM source.table WHERE ctid >= '(23698,0)'::tid)
    
  • Чтобы решить, следует ли разделить обработку таблицы COPY, используется параметр командной строки split-tables-larger-than или переменная окружения PGCOPYDB_SPLIT_TABLES_LARGER_THAN.

    Ожидаемое значение - это либо простое количество байтов, либо красиво отформатированное количество байтов, например, 250 GB.

    При использовании этого параметра таблицы, которые содержат как минимум это количество данных и также имеют кандидатный ключ для разделения COPY, распределяются между несколькими процессами COPY.

    Количество процессов COPY вычисляется путем деления размера таблицы на порог, установленный с помощью опции split. Например, если порог составляет 250 ГБ, то таблица размером 400 ГБ будет распределена между 2 процессами COPY.

    Команда pgcopydb list table-part может использоваться для перечисления разделов COPY, которые pgcopydb вычисляет для заданной исходной таблицы и порогового значения.

Значительные различия при использовании параллельного COPY для одной и той же таблицы

Когда для исходной таблицы происходит одновременный доступ, некоторые операции не выполняются так, как они выполнялись бы без одновременного доступа. В частности:

  • ОПТИМИЗАЦИЯ TRUNCATE и COPY FREEZE в Postgres

    При использовании одного процесса COPY, затем возможно TRUNCATE целевую таблицу в той же транзакции, что и команда COPY, как в следующем синтетическом примере:

    BEGIN;
    TRUNCATE table ONLY;
    COPY table FROM stdin WITH (FREEZE);
    COMMIT
    

    Этот метод позволяет Postgres реализовать несколько оптимизаций, выполняя работу во время COPY, которая в противном случае должна была бы выполняться позже при выполнении первых запросов к таблице.

    При использовании конкурентного доступа к одной и той же таблице у нас есть несколько транзакций, происходящих одновременно в целевой системе, которые копируют данные из исходной таблицы. Это означает, что нам нужно выполнять TRUNCATE отдельно, и опцию FREEZE использовать нельзя.

  • СОЗДАТЬ ИНДЕКС и VACUUM

    Даже когда включена параллельная работа COPY для одной и той же таблицы, создание индексов на целевой системе происходит только после того, как весь набор данных будет скопирован. Это означает, что только когда последний процесс завершит копирование, этот процесс займется индексами и операцией vacuum analyze.

Ограничения производительности параллельного COPY для одной таблицы

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

  • Пропускная способность сети

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

  • Диски IOPS

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

    Исходная система базы данных использует операции ввода-вывода при чтении, целевая система базы данных использует как операции ввода-вывода при чтении, так и при записи (копирование данных записывает на диск, создание индексов как читает данные таблицы с диска, так и записывает данные индекса на диск).

  • Организация данных на диске

    При использовании одного процесса COPY целевая система может заполнять таблицу Postgres кластерным способом, используя каждую страницу диска полностью перед открытием следующей, последовательно.

    При использовании параллельной команды COPY для одной и той же таблицы, целевая система Postgres должна обрабатывать параллельные записи в одну и ту же таблицу, что может привести к менее эффективному использованию диска.

    Как это может повлиять на производительность вашего приложения, необходимо протестировать.

  • synchronize_seqscans

    Postgres реализовал эту опцию еще в версии 8.3. Сейчас эта опция задокументирована в разделе Совместимость версий и платформ.

    Документация гласит: "Это позволяет последовательным сканированиям больших таблиц синхронизироваться друг с другом, так что параллельные сканирования читают один и тот же блок примерно в одно и то же время и, следовательно, разделяют нагрузку на ввод-вывод."

    Влияние на производительность при одновременном выполнении процессов COPY, читающих одну и ту же исходную таблицу одновременно, должно быть оценено. В данный момент в pgcopydb нет опции для установки synchronize_seqscans в off при использовании параллельного COPY для одной и той же таблицы.

    Используйте вашу обычную конфигурацию Postgres для тестирования.

Возобновление операций (снимки)

Важный аспект дизайна pgcopydb подробно описан в разделе документации Заметки о параллелизме и связан с использованием множества параллельных рабочих процессов для реализации параллелизма.

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

Согласованность с несколькими сеансами Postgres достигается благодаря способности Postgres экспортировать и импортировать снимки. Согласно документации Postgres о Функции синхронизации снимков:

Из документации Tantor SE-1C

Tantor SE-1C позволяет сеансам базы данных синхронизировать свои снимки. Снимок определяет, какие данные видны для транзакции, использующей этот снимок. Синхронизированные снимки необходимы, когда двум или более сеансам нужно видеть идентичное содержимое в базе данных. Если два сеанса просто начинают свои транзакции независимо, всегда существует вероятность того, что какая-то третья транзакция завершится между выполнением двух команд START TRANSACTION, так что один сеанс увидит эффекты этой транзакции, а другой - нет.

Чтобы решить эту проблему, Tantor SE-1C позволяет транзакции экспортировать снимок, который она использует. Пока экспортирующая транзакция остается открытой, другие транзакции могут импортировать ее снимок и, таким образом, гарантировать, что они видят точно такое же представление базы данных, как и первая транзакция. Но обратите внимание, что любые изменения базы данных, сделанные любой из этих транзакций, остаются невидимыми для других транзакций, как это обычно бывает для изменений, сделанных незавершенными транзакциями. Таким образом, транзакции синхронизированы по отношению к существующим данным, но ведут себя нормально в отношении изменений, которые они делают сами.

Снимки экспортируются с помощью функции pg_export_snapshot, показанной в Таблице 9.94, и импортируются с помощью команды SET TRANSACTION.

Использование этих API Postgres позволяет pgcopydb выполнять согласованные операции даже при использовании нескольких рабочих процессов.

Обход проблем с согласованностью

Если вы можете гарантировать, что на исходной базе данных не будет записей на протяжении всех операций pgcopydb, что означает отсутствие изменений схемы (DDL) и данных (DML), тогда проблемы с согласованностью не могут возникнуть: это потому, что база данных статична в нашем контексте, вероятно, в рамках окна обслуживания, где приложения отключены от службы исходной базы данных.

Обратите внимание, что pgcopydb предлагает --not-consistent опцию, которая позволяет обойти всю сложность совместного использования снимка на протяжении операций. В частности, возобновление операций после сбоя или даже реализация многоэтапных операций становится проще при полном обходе аспектов согласованности.

Когда вы можете работать в рамках окна обслуживания, где база данных изолирована от любого трафика приложений, рассмотрите возможность использования --not-consistent.

Согласованность и параллелизм: Снимки Postgres

Как видно выше, Postgres предлагает различные API для экспорта и импорта снимка:

  1. Функция pg_export_snapshot() экспортирует текущий снимок.

  2. SQL команда SET TRANSACTION SNAPSHOT импортирует данный снимок.

  3. Протокол репликации команда CREATE_REPLICATION_SLOT позволяет экспортировать его снимок.

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

Также помните, что один снимок должен использоваться на протяжении всех операций pgcopydb, как для начального COPY схемы и данных, так и для аспектов захвата изменений данных, чтобы обеспечить согласованность (без потери данных, без дубликатов в потоке изменений данных).

Чтобы иметь возможность реализовать несколько рабочих процессов в pgcopydb и иметь согласованное представление одной и той же базы данных (схема, данные) в каждом отдельном процессе, pgcopydb необходимо сначала экспортировать единый общий снимок, а затем каждый рабочий процесс должен импортировать этот снимок при подключении к исходной базе данных.

При реализации захвата изменений данных благодаря опции --follow, также требуется, чтобы не было разрыва между начальной снимком и первым полученным изменением, а также чтобы не отправлялись изменения, которые были частью начальной копии. Postgres знает, как предоставить эту гарантию через свою функцию экспорта снимков в команде репликации CREATE_REPLICATION_SLOT.

В результате команда pgcopydb snapshot --follow требуется API Postgres для создания слота репликации pgcopydb, и экспортирует снимок слота репликации.

Команда pgcopydb snapshot, когда опция --follow не используется, просто подключается к исходной базе данных Postgres, используя обычный протокол запросов, и выполняет команду select pg_export_snapshot(), чтобы захватить снимок, который может быть использован всеми рабочими процессами.

Более того, API Postgres для экспорта снимка имеет следующее ограничение:

Из документации Tantor SE-1C

Снимок доступен для импорта только до конца транзакции, которая его экспортировала.

Это означает, что команда pgcopydb snapshot должна продолжать работать на протяжении всех операций начального копирования pgcopydb. Клиент репликации использует слот репликации только для обеспечения согласованности, поэтому, когда работают только процессы follow worker, удерживать снимок больше не требуется.

Возобновляемость операций pgcopydb

Возможность возобновления операций при использовании pgcopydb сталкивается с тремя совершенно разными контекстами. В зависимости от контекста и момента, когда предыдущая операция была прервана, повторный запуск той же команды pgcopydb с опцией --resume может просто сработать, или может завершиться ошибкой, потому что ситуация не позволяет последовательно возобновить прерванную операцию.

Обход проблем с согласованностью

Когда используются опции --resume --not-consistent, то нет ограничений на повторное использование снимка при попытке возобновить прерванные операции.

Последовательная копия данных

При использовании pgcopydb clone --resume снимок, использованный в предыдущих попытках, будет повторно использован. Для того чтобы Postgres смог снова импортировать этот снимок, транзакция, экспортировавшая снимок, должна все еще выполняться в исходной системе базы данных.

Single pgcopydb command

При использовании pgcopydb clone процесс удержания снимка является частью этого единого процесса, и любое прерывание этой команды (сигнал, C-c, сбой) также завершает подпроцесс удержания снимка, и снимок затем теряется.

Separate pgcopydb snapshot command

Вот почему команду pgcopydb snapshot можно использовать отдельно. Затем основная команда pgcopydb clone повторно использует снимок автоматически и может удерживать снимок даже в случае прерывания команды pgcopydb clone.

External snapshot

Также можно использовать другую команду или программное обеспечение для экспорта и поддержания снимка, который использует pgcopydb, а затем использовать pgcopydb clone --snapshot ... чтобы поделиться снимком с pgcopydb.

Последовательная копия данных с CDC

При использовании захвата данных изменений с --follow опцией, для возобновления операций последовательно требуется следующая ситуация:

  1. Начальная команда COPY данных должна по-прежнему иметь доступ к экспортированной моментальной копии.

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

  2. Логическая репликация на стороне клиента не связана с операциями снимков, это выполняется на стороне сервера при создании слота репликации; с этого момента все, что должен делать клиент, это потреблять данные из слота репликации.

Снимок и каталоги (инвалидация кэша)

Исходная таблица каталога setup регистрирует информацию о текущей команде pgcopydb. Информация проверяется при запуске, чтобы избежать повторного использования данных в другом контексте.

Зарегистрированная информация следующая, и также содержит информацию снимка. В случае несоответствия, рассмотрите возможность использования --resume --not-consistent, когда это актуально для ваших операций.

Вот как просмотреть текущую информацию setup, которую pgcopydb хранит в своем локальном кэше каталога:

$ sqlite3 /tmp/pgcopydb/schema/source.db
sqlite> .mode line
sqlite> select * from setup;
                      id = 1
           source_pg_uri = postgres:///pagila
           target_pg_uri = postgres:///plop
                snapshot = 00000003-00000048-1
split_tables_larger_than = 0
                 filters = {"type":"SOURCE_FILTER_TYPE_NONE"}
                  plugin =
               slot_name =

Строки подключения источника и цели содержат только имя хоста серверов Postgres, порт, имя базы данных и имя роли подключения. В частности, учетные данные для аутентификации не хранятся в каталогах.

pgcopydb

pgcopydb - скопировать всю базу данных Postgres из источника в цель

Краткий обзор

pgcopydb предоставляет следующие команды

pgcopydb: pgcopydb tool
usage: pgcopydb [ --verbose --quiet ]


Available commands:
  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 реализует полную миграцию всей базы данных Postgres из исходного экземпляра в целевой экземпляр. Оба экземпляра Postgres должны быть доступны на протяжении всего времени выполнения команды.

Команда pgcopydb также реализует полный клиент Логического Декодирования для Postgres, позволяя Захвату Изменений Данных воспроизводить изменения данных (DML), происходящие в исходной базе данных после снимка базового копирования. Код клиента логического декодирования pgcopydb совместим как с test_decoding, так и с wal2json плагинами вывода, и по умолчанию использует test_decoding.

pgcopydb help

Команда 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
  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
  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
+ set    Set the sentinel table values

pgcopydb stream sentinel set
  startpos  Set the sentinel start position LSN
  endpos    Set the sentinel end position LSN
  apply     Set the sentinel apply mode
  prefetch  Set the sentinel prefetch mode

версия pgcopydb

Команда pgcopydb version выводит строку версии используемой версии pgcopydb и может делать это в формате JSON при использовании опции --json.

$ pgcopydb version
pgcopydb version 0.13.1.g868ad77
compiled with 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
compatible with Postgres 10, 11, 12, 13, 14, and 15

В JSON:

$ 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
}

Детали о версии Postgres относятся к версии, которая была использована для сборки pgcopydb из исходников, так что это действительно версия клиентской библиотеки libpq.

pgcopydb ping

Команда pgcopydb ping пытается подключиться как к исходной, так и к целевой базам данных Postgres, одновременно.

pgcopydb ping: Attempt to connect to the source and target instances
usage: pgcopydb ping  --source ... --target ... 

  --source              Postgres URI to the source database
  --target              Postgres URI to the target database

Пример вывода выглядит следующим образом:

$ pgcopydb ping
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://@:/plop?"
18:04:48 84682 INFO   Successfully could connect to source database at "postgres://@:/pagila?"

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

pgcopydb clone

Основная операция pgcopydb - это операция клонирования, и по историческим и удобным для пользователя причинам доступны два псевдонима, которые выполняют ту же операцию:

pgcopydb
  clone     Clone an entire database from source to target
  fork      Clone an entire database from source to target

pgcopydb clone

Команда pgcopydb clone копирует базу данных из указанного исходного экземпляра Postgres в целевой экземпляр Postgres.

pgcopydb clone: Clone an entire database from source to target
usage: pgcopydb clone  --source ... --target ... [ --table-jobs ... --index-jobs ... ] 

  --source                      Postgres URI to the source database
  --target                      Postgres URI to the target database
  --dir                         Work directory to use
  --table-jobs                  Number of concurrent COPY jobs to run
  --index-jobs                  Number of concurrent CREATE INDEX jobs to run
  --restore-jobs                Number of concurrent jobs for pg_restore
  --large-objects-jobs          Number of concurrent Large Objects jobs to run
  --split-tables-larger-than    Same-table concurrency size threshold
  --split-max-parts             Maximum number of jobs for Same-table concurrency 
  --estimate-table-sizes        Allow using estimates for relation sizes
  --drop-if-exists              On the target database, clean-up from a previous run first
  --roles                       Also copy roles found on source to target
  --no-role-passwords           Do not dump passwords for roles
  --no-owner                    Do not set ownership of objects to match the original database
  --no-acl                      Prevent restoration of access privileges (grant/revoke commands).
  --no-comments                 Do not output commands to restore comments
  --no-tablespaces              Do not output commands to select tablespaces
  --skip-large-objects          Skip copying large objects (blobs)
  --skip-extensions             Skip restoring extensions
  --skip-ext-comments           Skip restoring COMMENT ON EXTENSION
  --skip-collations             Skip restoring collations
  --skip-vacuum                 Skip running VACUUM ANALYZE
  --skip-analyze                Skip running vacuumdb --analyze-only
  --skip-db-properties          Skip copying ALTER DATABASE SET properties
  --skip-split-by-ctid          Skip spliting tables by ctid
  --requirements <filename>     List extensions requirements
  --filters <filename>          Use the filters defined in <filename>
  --fail-fast                   Abort early in case of error
  --restart                     Allow restarting when temp files exist already
  --resume                      Allow resuming operations after a failure
  --not-consistent              Allow taking a new snapshot on the source database
  --snapshot                    Use snapshot obtained with pg_export_snapshot
  --follow                      Implement logical decoding to replay changes
  --plugin                      Output plugin to use (test_decoding, wal2json)
  --wal2json-numeric-as-string  Print numeric data type as string when using wal2json output plugin
  --slot-name                   Use this Postgres replication slot name
  --create-slot                 Create the replication slot
  --origin                      Use this Postgres replication origin node name
  --endpos                      Stop replaying changes when reaching this LSN
  --use-copy-binary             Use the COPY BINARY format for COPY operations

pgcopydb fork

Команда pgcopydb fork копирует базу данных из указанного исходного экземпляра Postgres в целевой экземпляр Postgres. Эта команда является псевдонимом для команды pgcopydb clone, показанной выше.

Описание

Команда pgcopydb clone реализует как базовое копирование исходной базы данных в целевую базу данных, так и полный Логический Декодирующий клиент для wal2json логического декодирующего плагина.

Базовая копия, или операция клонирования

Команда pgcopydb clone выполняет следующие шаги:

  1. pgcopydb получает список обычных и секционированных таблиц из каталожного запроса к исходной базе данных, а также список индексов и список последовательностей с их текущими значениями.

    Когда используется фильтрация, список OID объектов, которые должны быть отфильтрованы, создается на этом этапе.

  2. pgcopydb вызывает pg_dump для создания pre-data секции и post-data секции дампа, используя пользовательский формат Postgres.

  3. Секция pre-data дампа восстанавливается в целевой базе данных с помощью команды pg_restore, создавая все объекты Postgres из исходной базы данных в целевой базе данных.

    Когда используется фильтрация, функция pg_restore --use-list используется для фильтрации списка объектов для восстановления на этом этапе.

    Этот шаг использует до --restore-jobs заданий для pg_restore для распределения нагрузки и параллельного восстановления объектов.

  4. Затем запускается столько под-процессов --table-jobs COPY, чтобы разделить рабочую нагрузку и скопировать данные из исходной базы данных в целевую по одной таблице за раз, в цикле.

    Соединение с Postgres и SQL-запрос к таблице каталога Postgres pg_class используются для получения списка таблиц с данными для копирования, и статистика reltuples используется для начала с таблиц с наибольшим количеством строк, чтобы минимизировать время копирования.

  5. Вспомогательный процесс проходит через все большие объекты, найденные в исходной базе данных, и копирует их части данных в целевую базу данных, подобно тому, как это делает pg_dump.

    Этот шаг очень похож на pg_dump | pg_restore для частей данных больших объектов, за исключением того, что нет хорошего способа сделать это только с помощью инструментов.

  6. Как можно больше --index-jobs под-процессов CREATE INDEX запускаются для распределения рабочей нагрузки и создания индексов. Чтобы убедиться, что команды CREATE INDEX запускаются только после завершения операции COPY, используется механизм очереди. Как только копирование данных таблицы завершено, все индексы для таблицы ставятся в очередь для обработки под-процессами CREATE INDEX.

    Основные индексы создаются как уникальные индексы на этом этапе.

  7. Затем ограничения PRIMARY KEY создаются ИСПОЛЬЗУЯ только что построенные индексы. Такой двухэтапный подход позволяет самому индексу первичного ключа создаваться параллельно с другими индексами на той же таблице, избегая ИСКЛЮЧИТЕЛЬНОЙ БЛОКИРОВКИ при создании индекса.

  8. Столько, сколько --table-jobs VACUUM ANALYZE под-процессов запускается для распределения рабочей нагрузки. Как только копирование данных таблицы завершено, таблица ставится в очередь для обработки под-процессами 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, суперпользователь, и дамп и восстановление

Postgres имеет понятие статуса суперпользователя, который может быть назначен любой роли в системе, и роль по умолчанию postgres имеет этот статус. Из страницы документации Атрибуты ролей мы видим, что:

статус суперпользователя:

Суперпользователь базы данных обходит все проверки разрешений, кроме права на вход в систему. Это опасная привилегия и не должна использоваться небрежно; лучше выполнять большую часть работы под ролью, которая не является суперпользователем. Чтобы создать нового суперпользователя базы данных, используйте CREATE ROLE name SUPERUSER. Вы должны сделать это под ролью, которая уже является суперпользователем.

Некоторые объекты Postgres могут быть созданы только суперпользователями, и некоторые операции чтения и записи разрешены только ролям суперпользователей, например, следующий неполный список:

  • Чтение pg_authid пароля роли (даже если он зашифрован) ограничено ролями со статусом суперпользователя. Чтение этой таблицы каталога выполняется при вызове pg_dumpall --roles-only, чтобы файл дампа мог быть использован для восстановления ролей, включая их пароли.

    Возможно выполнить миграцию pgcopydb, которая полностью пропускает пароли при использовании опции --no-role-passwords. В этом случае аутентификация может не пройти до тех пор, пока пароли не будут настроены снова правильно.

  • Большинство доступных расширений Postgres, по крайней мере, когда они написаны на C, могут быть созданы только ролями с статусом суперпользователя.

    Когда такое расширение содержит Таблицы конфигурации расширения и было создано с ролью, имеющей статус суперпользователя, то тот же статус суперпользователя снова необходим для pg_dump и pg_restore этого расширения и его текущей конфигурации.

При использовании pgcopydb можно разделить вашу миграцию на привилегированные и непривилегированные части, как в следующих примерах:

$ 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 roles и pgcopydb copy extensions будут выполняться с строками подключения, которые подключаются с ролью, имеющей статус суперпользователя; а затем вызов pgcopydb clone будет выполнен с непривилегированной ролью, обычно ролью, которая владеет исходной и целевой базами данных.

Предупреждение

Тем не менее, в настоящее время существует ограничение в pg_dump, которое влияет на pgcopydb. Когда расширение с таблицей конфигурации установлено как суперпользователь, даже основная операция pgcopydb clone должна выполняться с правами суперпользователя.

Это потому, что фильтрация pg_dump (здесь опция --exclude-table) не применяется к членам расширений, и pg_dump не предоставляет механизма для исключения расширений.

Изменение захвата данных с использованием логического декодирования Postgres

При использовании опции --follow шаги из команды pgcopydb follow также выполняются параллельно с основной копией. Захват данных изменений затем автоматически переходит от фазы только предварительной выборки к фазе предварительной выборки и догонки, которая включается, как только основная копия завершена.

См. команду pgcopydb stream sentinel set endpos для удаленного управления следующими частями команды, даже когда команда уже выполняется.

Команда pgcopydb stream cleanup должна использоваться для освобождения ресурсов, созданных для поддержки процесса захвата изменений данных.

Предостережение

Убедитесь, что вы прочитали документацию для pgcopydb follow и подробности о Ограничения логической репликации, как это задокументировано в Postgres.

Пример захвата изменений данных 1

Простой подход к применению изменений после выполнения начального базового копирования выглядит следующим образом:

$ 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. Сделайте снимок с исходной базы данных и удерживайте открытое соединение с Postgres на протяжении всей базовой копии.

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

    Этот шаг также выполняется при использовании pgcopydb clone --follow. Тем не менее, если команда была прервана (или произошел сбой), то снимок будет потерян.

  2. Настройте логическое декодирование в рамках снимка, полученного на предыдущем шаге, и отслеживание репликации на целевой базе данных.

    Затем создаются следующие SQL-объекты:

    • слот репликации на исходной базе данных,

    • репликационное происхождение в целевой базе данных.

    Этот шаг также выполняется при использовании pgcopydb clone --follow. Нет способа реализовать захват изменений данных с помощью pgcopydb и пропустить создание этих SQL объектов.

  3. Запустите базовую копию исходной базы данных и предварительно извлеките логические изменения декодирования, чтобы гарантировать, что мы потребляем из слота репликации и позволяем серверу исходной базы данных перерабатывать свои файлы WAL.

  4. Удалённое управление процессом применения для остановки потребления изменений и их применения в целевой базе данных.

  5. Повторно синхронизировать последовательности с их текущими значениями.

    Последовательности не обрабатываются логическим декодированием Postgres, поэтому здесь необходимо применять дополнительные меры вручную.

    Предостережение

    Следующая версия pgcopydb будет включать этот шаг в команду pgcopydb clone --snapshot автоматически, после того как она прекратит потребление изменений и перед завершением процесса.

  6. Очистите конкретные ресурсы, созданные для поддержки возобновляемости всего процесса (слот репликации на исходной базе данных, происхождение репликации на целевой базе данных).

  7. Прекратите удерживать снимок на исходной базе данных, остановив процесс pgcopydb snapshot, оставленный работающим в фоновом режиме.

Если команда pgcopydb clone --follow завершится неудачно, её можно запустить снова. Она автоматически определит, что было успешно выполнено и что нужно сделать снова из-за сбоя или прерывания (копирование таблицы, создание индекса, возобновление потребления слота репликации, возобновление применения изменений на правильной позиции LSN и т.д.).

Вот пример реализации предыдущих шагов:

$ 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

Опции

Следующие параметры доступны для pgcopydb clone:

--source

Строка подключения к исходному экземпляру Postgres. См. документацию Postgres для строк подключения для получения подробной информации. Вкратце, поддерживаются как форма в кавычках "host=... dbname=...", так и форма URI postgres://user@host:5432/dbname.

--target

Строка подключения к целевому экземпляру Postgres.

--dir

Во время нормальной работы pgcopydb создает много временных файлов для отслеживания прогресса подпроцессов. Временные файлы создаются в каталоге, указанном в этой опции, или по умолчанию в ${TMPDIR}/pgcopydb, когда установлена переменная окружения, или иначе в /tmp/pgcopydb.

--table-jobs

Сколько таблиц может обрабатываться параллельно.

Этот лимит применяется только к операциям COPY, больше под-процессов будет выполняться одновременно с этим лимитом, пока операции CREATE INDEX находятся в процессе, хотя тогда процессы только ожидают, пока целевая инстанция Postgres выполнит всю работу.

--index-jobs

Сколько индексов может быть построено параллельно, глобально. Хорошим вариантом является установка этого параметра в количество ядер процессора, доступных на целевой системе Postgres, за вычетом некоторых ядер, которые будут использоваться для обработки операций COPY.

--restore-jobs

Сколько потоков или процессов можно использовать во время pg_restore. Хорошим вариантом является установка этого параметра в количество ядер ЦП, доступных на целевой системе Postgres.

Если это значение не установлено, мы повторно используем --index-jobs. Если это значение также не установлено, мы используем значение по умолчанию для --index-jobs.

--large-object-jobs

Сколько рабочих процессов запустить для одновременного копирования больших объектов.

--split-tables-larger-than

Разрешить Конкурентный доступ к одной и той же таблице при обработке исходной базы данных. Ожидается, что значение этой переменной окружения будет указано в байтах, и известны единицы измерения байт: B, kB, MB, GB, TB, PB и EB.

--estimate-table-sizes

Используйте оценки размеров таблиц, чтобы решить, как разделить таблицы при использовании Параллельная обработка одной таблицы.

Когда используется этот параметр, мы выполняем vacuumdb --analyze-only --jobs=<table-jobs> команду на исходной базе данных, которая обновляет статистику по количеству страниц для каждой таблицы. Позже мы используем количество страниц и размер каждой страницы для оценки фактического размера таблиц.

Если вы хотите выполнить команду ANALYZE вручную перед запуском pgcopydb, вы можете использовать --skip-analyze опцию. Таким образом, вы можете сократить время, затрачиваемое на миграцию.

--drop-if-exists

При восстановлении схемы на целевом экземпляре Postgres, pgcopydb фактически использует pg_restore. Когда этот параметр указан, также используются следующие параметры pg_restore: --clean --if-exists.

Эта опция полезна, когда одна и та же команда выполняется несколько раз подряд, либо для исправления предыдущей ошибки, либо, например, при использовании в системе непрерывной интеграции.

Эта опция вызывает использование DROP TABLE и DROP INDEX и других команд DROP. Убедитесь, что вы понимаете, что делаете!

--roles

Опция --roles добавляет предварительный шаг, который копирует роли, найденные в исходном экземпляре, в целевой экземпляр. Поскольку роли Postgres являются глобальными объектами, они не существуют только в контексте конкретной базы данных, поэтому все роли копируются при использовании этой опции.

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

Пропустить копирование больших объектов, также известных как блобы, при копировании данных из исходной базы данных в целевую базу данных.

--skip-extensions

Пропустить копирование расширений из исходной базы данных в целевую базу данных.

Когда используется, схемы, от которых зависят расширения, также пропускаются: предполагается, что создание необходимых расширений на целевой системе является обязанностью другой команды (например, pgcopydb copy extensions), и схемы, от которых зависят расширения, являются частью этой обязанности.

Поскольку создание расширений требует прав суперпользователя, это позволяет использовать многоэтапный подход, при котором расширения обрабатываются с привилегиями суперпользователя, а затем остальные операции pgcopydb выполняются без привилегий суперпользователя.

--skip-ext-comments

Пропустить копирование команд COMMENT ON EXTENSION. Это подразумевается при использовании –skip-extensions.

--requirements <filename>

Эта опция позволяет указать, какую версию расширения установить в целевой базе данных. Ожидается, что указанный файл будет файлом JSON, и содержимое JSON должно быть массивом объектов с ключами "name" и "version".

Команда pgcopydb list extensions --requirements --json создает такой JSON файл и может быть использована на целевой базе данных для начала работы.

См. также команду pgcopydb list extensions --available-versions.

См. также pgcopydb list extensions.

--skip-collations

Пропустить копирование колляций из исходной базы данных в целевую базу данных.

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

Тогда эта опция позволяет pgcopydb пропускать коллации и предполагать, что все необходимые коллации уже развернуты в целевой базе данных.

См. также pgcopydb list collations.

--skip-vacuum

Пропустите выполнение VACUUM ANALYZE на целевой базе данных после того, как таблица была скопирована, ее индексы были созданы и ограничения установлены.

--skip-analyze

Пропустите выполнение vacuumdb --analyze-only на исходной базе данных для обновления статистики, которая требуется при оценке размеров таблиц.

Эта опция полезна только при использовании --estimate-table-sizes и если пользователь вручную запускает соответствующую команду ANALYZE перед запуском pgcopydb.

--skip-db-properties

Пропустить получение свойств базы данных и их копирование с помощью SQL команды ALTER DATABASE ... SET name = value. Это полезно, когда исходная и целевая базы данных имеют разные наборы свойств, или когда целевая база данных размещена таким образом, что установка некоторых свойств, установленных в исходной базе данных, отключена, или также когда копирование этих настроек не требуется.

--skip-split-by-ctid

Пропустить разделение таблиц на основе CTID во время операции копирования. По умолчанию pgcopydb разделяет большие таблицы на меньшие части на основе столбца CTID, если в таблице нет уникального целочисленного столбца. Однако в некоторых случаях вы можете захотеть пропустить этот процесс разделения, если сканирование диапазона CTID медленно в базовой системе.

--filters <filename>

Эта опция позволяет исключить таблицы и индексы из операций копирования. См. Фильтрация для получения подробной информации о ожидаемом формате файла и доступных опциях фильтрации.

--fail-fast

Прервать выполнение в случае ошибки, отправив сигнал TERM всем процессам в группе процессов pgcopydb.

--restart

При повторном запуске команды pgcopydb, если рабочий каталог уже содержит информацию от предыдущего запуска, то команда отказывается продолжать и удалять информацию, которая может быть использована для диагностики и судебной экспертизы.

В этом случае можно использовать опцию --restart, чтобы позволить pgcopydb удалить следы от предыдущего запуска.

--resume

Когда команда pgcopydb была завершена до завершения, либо по сигналу прерывания (например, C-c или SIGTERM), либо из-за сбоя, возможно возобновить миграцию базы данных.

При возобновлении активности после предыдущего запуска данные таблицы, которые были полностью скопированы на целевой сервер, не отправляются снова. Данные таблицы, копирование которых было прервано во время команды COPY, должны быть начаты с нуля, даже при использовании --resume: команда COPY в Postgres является транзакционной и была отменена.

Та же логика применяется к командам CREATE INDEX и ALTER TABLE, которые выполняет pgcopydb, эти команды пропускаются при --resume запуске только в том случае, если известно, что они были выполнены до конца в предыдущий раз.

Наконец, использование --resume требует использования --not-consistent.

--not-consistent

Для обеспечения согласованности pgcopydb экспортирует снимок Postgres, вызывая функцию pg_export_snapshot() на сервере исходной базы данных. Затем этот снимок повторно используется во всех соединениях с сервером исходной базы данных с помощью команды SET TRANSACTION SNAPSHOT.

Согласно документации Postgres о pg_export_snapshot: Сохраняет текущий снимок транзакции и возвращает текстовую строку, идентифицирующую снимок. Эта строка должна быть передана (вне базы данных) клиентам, которые хотят импортировать снимок. Снимок доступен для импорта только до конца транзакции, которая его экспортировала.

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

--snapshot

Вместо экспорта собственной моментальной копии, вызывая функцию Tantor SE-1C pg_export_snapshot(), pgcopydb может повторно использовать уже экспортированную моментальную копию.

--follow

Когда используется опция --follow, pgcopydb реализует захват данных изменений, как описано на странице руководства для pgcopydb follow параллельно с основными шагами копирования базы данных.

Репликационный слот создается с использованием той же моментальной копии, что и основная операция копирования базы данных, и изменения в исходной базе данных предварительно выбираются только во время начального копирования, затем предварительно выбираются и применяются в процессе догоняющего обновления.

Возможно задать pgcopydb clone --follow точку завершения (LSN endpos) во время выполнения команды с помощью команды pgcopydb stream sentinel set endpos.

--plugin

Плагин вывода логического декодирования для использования. По умолчанию это test_decoding, который поставляется с ядром Postgres, поэтому, вероятно, уже доступен на вашем исходном сервере.

Возможно использовать 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

Укажите pgcopydb создать слот логической репликации для использования.

--endpos

Целевой LSN для логической репликации. Автоматически остановить репликацию и выйти с нормальным статусом выхода 0, когда прием достигнет указанного LSN. Если существует запись с LSN, точно равным lsn, запись будет выведена.

Опция --endpos не учитывает границы транзакций и может обрезать вывод посередине транзакции. Любая частично выведенная транзакция не будет потреблена и будет воспроизведена снова при следующем чтении слота. Отдельные сообщения никогда не обрезаются.

См. также документацию для pg_recvlogical.

--use-copy-binary

Используйте COPY WITH (FORMAT BINARY) вместо команды COPY.

См. также документацию для COPY.

--origin

Целевой системе логической репликации необходимо отслеживать транзакции, которые уже были применены, чтобы в случае разрыва соединения или необходимости возобновления операций мы могли пропустить уже воспроизведенные транзакции.

Postgres использует понятие имени исходного узла, как это задокументировано в Отслеживание прогресса репликации. Эта опция позволяет выбрать собственное имя узла и по умолчанию устанавливается в “pgcopydb”. Выбор другого имени полезен в некоторых сложных сценариях, таких как миграция нескольких источников в одну и ту же цель, где каждый источник должен иметь свое уникальное имя исходного узла.

--verbose, --notice

Увеличьте текущий уровень подробности. Уровень подробности по умолчанию - INFO. В порядке возрастания pgcopydb знает о следующих уровнях подробности: FATAL, ERROR, WARN, INFO, NOTICE, SQL, DEBUG, TRACE.

--debug

Установить текущий уровень подробности на уровень DEBUG.

--trace

Установить текущий уровень подробности на уровень TRACE.

--quiet

Установить текущий уровень подробности на уровень ERROR.

Окружение

PGCOPYDB_SOURCE_PGURI

Строка подключения к исходному экземпляру Postgres. Когда --source опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_TARGET_PGURI

Строка подключения к целевому экземпляру Postgres. Когда --target опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_TABLE_JOBS

Количество параллельных задач, разрешенных для выполнения операций COPY. Когда --table-jobs опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_INDEX_JOBS

Количество параллельных задач, разрешенных для выполнения операций CREATE INDEX. Когда --index-jobs не указан в командной строке, используется эта переменная окружения.

PGCOPYDB_RESTORE_JOBS

Количество параллельных задач, разрешенных для выполнения операций pg_restore. Когда --restore-jobs не указан в командной строке, используется эта переменная окружения.

PGCOPYDB_LARGE_OBJECTS_JOBS

Количество параллельных задач, разрешенных для копирования данных больших объектов. Когда --large-objects-jobs опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_SPLIT_TABLES_LARGER_THAN

Разрешить одновременный доступ к одной и той же таблице при обработке исходной базы данных. Значение этой переменной окружения ожидается в байтах, и известны единицы измерения байт: B, kB, MB, GB, TB, PB и EB.

Когда --split-tables-larger-than опущен из командной строки, используется эта переменная окружения.

PGCOPYDB_SPLIT_MAX_PARTS

Ограничьте максимальное количество частей, когда используется Параллельная обработка одной таблицы. Когда --split-max-parts не указан в командной строке, используется эта переменная окружения.

PGCOPYDB_ESTIMATE_TABLE_SIZES

Когда true (или yes, или on, или 1, тот же ввод, что и для boolean в Postgres), тогда pgcopydb оценивает размер таблиц, чтобы определить, нужно ли разделять таблицы. Этот параметр полезен только в том случае, если запрос размеров отношений в исходной базе данных является затратным.

Когда --estimate-table-sizes опущен из командной строки, используется эта переменная окружения.

Когда используется этот параметр, мы запускаем vacuumdb --analyze-only --jobs=<table-jobs> команду на исходной базе данных, которая обновляет статистику по количеству страниц для каждой таблицы. Позже мы используем количество страниц и размер каждой страницы для оценки фактического размера таблиц.

Если вы хотите выполнить команду ANALYZE вручную перед запуском pgcopydb, вы можете использовать опцию --skip-analyze или переменную окружения PGCOPYDB_SKIP_ANALYZE. Таким образом, вы можете сократить время, затрачиваемое на миграцию.

PGCOPYDB_OUTPUT_PLUGIN

Плагин вывода логического декодирования для использования. Когда --plugin опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_WAL2JSON_NUMERIC_AS_STRING

Когда true (или yes, или on, или 1, тот же ввод, что и у Postgres boolean), тогда pgcopydb использует опцию wal2json --numeric-data-types-as-string при использовании плагина вывода wal2json.

Когда --wal2json-numeric-as-string опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_DROP_IF_EXISTS

Когда true (или yes, или on, или 1, тот же ввод, что и у boolean в Postgres), тогда pgcopydb использует параметры pg_restore --clean --if-exists при создании схемы на целевом экземпляре Postgres.

Когда --drop-if-exists опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_FAIL_FAST

Когда true (или yes, или on, или 1, тот же ввод, что и у Postgres boolean), тогда pgcopydb отправляет сигнал TERM всем процессам в своей группе процессов, как только один процесс завершится с ненулевым кодом возврата.

Когда --fail-fast опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_SKIP_VACUUM

Когда true (или yes, или on, или 1, тот же ввод, что и у Postgres boolean), тогда pgcopydb полностью пропускает задания VACUUM ANALYZE, так же, как при использовании опции --skip-vacuum.

PGCOPYDB_SKIP_ANALYZE

Когда true (или yes, или on, или 1, тот же ввод, что и для boolean в Postgres) тогда pgcopydb пропускает команды vacuumdb --analyze-only полностью, так же, как при использовании опции --skip-analyze.

PGCOPYDB_SKIP_DB_PROPERTIES

Когда true (или yes, или on, или 1, тот же ввод, что и у Postgres boolean), тогда pgcopydb пропускает команды ALTER DATABASE SET properties, которые копируют настройки из исходной базы данных в целевую базу данных, так же, как при использовании опции --skip-db-properties.

PGCOPYDB_SKIP_CTID_SPLIT

Когда true (или yes, или on, или 1, тот же ввод, что и у Postgres boolean), тогда pgcopydb пропускает операцию разделения CTID во время процесса клонирования, так же, как при использовании опции --skip-split-by-ctid.

PGCOPYDB_USE_COPY_BINARY

Когда true (или yes, или on, или 1, тот же ввод, что и у Postgres boolean), тогда pgcopydb использует COPY WITH (FORMAT BINARY) вместо команды COPY, так же, как при использовании опции --use-copy-binary.

PGCOPYDB_SNAPSHOT

Идентификатор снимка Postgres для повторного использования, см. также --snapshot.

TMPDIR

Команда pgcopydb создает все свои рабочие файлы и каталоги в ${TMPDIR}/pgcopydb, и по умолчанию в /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, тот же ввод, что и у Postgres boolean), тогда pgcopydb форматирует свои логи, используя JSON.

{
  "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, тот же ввод, что и у Postgres boolean), тогда pgcopydb форматирует свои логи, используя JSON при записи в PGCOPYDB_LOG_FILENAME.

XDG_DATA_HOME

Стандарт XDG Base Directory Specification определяет несколько переменных окружения, которые позволяют контролировать, где программы должны хранить свои файлы.

XDG_DATA_HOME определяет базовый каталог, относительно которого должны храниться пользовательские файлы данных. Если $XDG_DATA_HOME не установлен или пуст, следует использовать значение по умолчанию, равное $HOME/.local/share.

При использовании захвата данных изменений (через --follow опцию и логическое декодирование Postgres с wal2json) pgcopydb предварительно загружает изменения в JSON файлы и преобразует их в SQL файлы для применения к целевой базе данных.

Эти файлы хранятся в следующем месте, проверяются в следующем порядке:

  1. когда используется --dir, тогда pgcopydb использует подкаталог cdc в расположении --dir,

  2. когда XDG_DATA_HOME установлено в окружении, тогда pgcopydb использует это расположение,

  3. если ни один из предыдущих параметров не был использован, тогда pgcopydb по умолчанию использует ${HOME}/.local/share.

Примеры

$ 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
08:13:13.961 42893 INFO   [SOURCE] Copying database from "postgres://pagila:0wn3d@source/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
08:13:13.961 42893 INFO   [TARGET] Copying database into "postgres://pagila:0wn3d@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
08:13:14.009 42893 INFO   Using work dir "/tmp/pgcopydb"
08:13:14.017 42893 INFO   Exported snapshot "00000003-000000EB-1" from the source database
08:13:14.019 42904 INFO   STEP 1: fetch source database tables, indexes, and sequences
08:13:14.339 42904 INFO   Fetched information for 5 tables (including 0 tables split in 0 partitions total), with an estimated total of 1000 thousands tuples and 128 MB on-disk
08:13:14.342 42904 INFO   Fetched information for 4 indexes (supporting 4 constraints)
08:13:14.343 42904 INFO   Fetching information for 1 sequences
08:13:14.353 42904 INFO   Fetched information for 1 extensions
08:13:14.436 42904 INFO   Found 1 indexes (supporting 1 constraints) in the target database
08:13:14.443 42904 INFO   STEP 2: dump the source database schema (pre/post data)
08:13:14.448 42904 INFO    /usr/bin/pg_dump -Fc --snapshot 00000003-000000EB-1 --section=pre-data --section=post-data --file /tmp/pgcopydb/schema/schema.dump 'postgres://pagila:0wn3d@source/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60'
08:13:14.513 42904 INFO   STEP 3: restore the pre-data section to the target database
08:13:14.524 42904 INFO    /usr/bin/pg_restore --dbname 'postgres://pagila:0wn3d@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60' --section pre-data --jobs 2 --use-list /tmp/pgcopydb/schema/pre-filtered.list /tmp/pgcopydb/schema/schema.dump
08:13:14.608 42919 INFO   STEP 4: starting 8 table-data COPY processes
08:13:14.678 42921 INFO   STEP 8: starting 8 VACUUM processes
08:13:14.678 42904 INFO   Skipping large objects: none found.
08:13:14.693 42920 INFO   STEP 6: starting 2 CREATE INDEX processes
08:13:14.693 42920 INFO   STEP 7: constraints are built by the CREATE INDEX processes
08:13:14.699 42904 INFO   STEP 9: reset sequences values
08:13:14.700 42959 INFO   Set sequences values on the target database
08:13:16.716 42904 INFO   STEP 10: restore the post-data section to the target database
08:13:16.726 42904 INFO    /usr/bin/pg_restore --dbname 'postgres://pagila:0wn3d@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60' --section post-data --jobs 2 --use-list /tmp/pgcopydb/schema/post-filtered.list /tmp/pgcopydb/schema/schema.dump
08:13:16.751 42904 INFO   All step are now done,  2s728 elapsed
08:13:16.752 42904 INFO   Printing summary for 5 tables and 4 indexes

  OID | Schema |             Name | Parts | copy duration | transmitted bytes | indexes | create index duration
------+--------+------------------+-------+---------------+-------------------+---------+----------------------
16398 | public | pgbench_accounts |     1 |         1s496 |             91 MB |       1 |                 302ms
16395 | public |  pgbench_tellers |     1 |          37ms |            1002 B |       1 |                  15ms
16401 | public | pgbench_branches |     1 |          45ms |              71 B |       1 |                  18ms
16386 | public |           table1 |     1 |          36ms |             984 B |       1 |                  21ms
16392 | public |  pgbench_history |     1 |          41ms |               0 B |       0 |                   0ms


                                               Step   Connection    Duration    Transfer   Concurrency
 --------------------------------------------------   ----------  ----------  ----------  ------------
   Catalog Queries (table ordering, filtering, etc)       source       119ms                         1
                                        Dump Schema       source        66ms                         1
                                     Prepare Schema       target        59ms                         1
      COPY, INDEX, CONSTRAINTS, VACUUM (wall clock)         both       2s125                        18
                                  COPY (cumulative)         both       1s655      128 MB             8
                          CREATE INDEX (cumulative)       target       343ms                         2
                           CONSTRAINTS (cumulative)       target        13ms                         2
                                VACUUM (cumulative)       target       144ms                         8
                                    Reset Sequences         both        15ms                         1
                         Large Objects (cumulative)       (null)         0ms                         0
                                    Finalize Schema         both        27ms                         2
 --------------------------------------------------   ----------  ----------  ----------  ------------
                          Total Wall Clock Duration         both       2s728                        24

pgcopydb follow

Команда pgcopydb follow воспроизводит изменения базы данных, зарегистрированные в исходной базе данных с помощью выбранного вами плагина логического декодирования, либо по умолчанию test_decoding или wal2json, в целевую базу данных.

Важно

В то время как pgcopydb follow является полноценным клиентом для логического декодирования, общий случай использования включает pgcopydb clone --follow, как это задокументировано в Захват изменений данных с использованием логического декодирования Postgres.

При использовании логического декодирования с pgcopydb или другим инструментом, убедитесь, что вы знакомы с ограничениями логической репликации, которые применяются. В частности:

  • DDL не реплицируются.

    При использовании DDL для обслуживания схемы разделов, например, при использовании pg_partman расширения, рассмотрите возможность создания разделов на неделю или месяц вперед, чтобы создание новых разделов не происходило в течение окна миграции.

  • Данные последовательностей не реплицируются.

    При использовании pgcopydb clone --follow (начиная с версии pgcopydb 0.9), данные последовательности синхронизируются в конце операции, после точки переключения, реализованной через pgcopydb stream sentinel set endpos.

    Обновление последовательностей вручную также возможно путем выполнения команды pgcopydb copy sequences.

  • Большие объекты не реплицируются.

См. страницу документации Postgres для Ограничения логической репликации чтобы прочитать исчерпывающий список ограничений.

pgcopydb follow

pgcopydb follow: Replay changes from the source database to the target database
usage: pgcopydb follow  --source ... --target ...

  --source                      Postgres URI to the source database
  --target                      Postgres URI to the target database
  --dir                         Work directory to use
  --filters <filename>          Use the filters defined in <filename>
  --restart                     Allow restarting when temp files exist already
  --resume                      Allow resuming operations after a failure
  --not-consistent              Allow taking a new snapshot on the source database
  --snapshot                    Use snapshot obtained with pg_export_snapshot
  --plugin                      Output plugin to use (test_decoding, wal2json)
  --wal2json-numeric-as-string  Print numeric data type as string when using wal2json output plugin
  --slot-name                   Use this Postgres replication slot name
  --create-slot                 Create the replication slot
  --origin                      Use this Postgres replication origin node name
  --endpos                      Stop replaying changes when reaching this LSN

Описание

Эта команда запускает три параллельных подпроцесса в двух возможных режимах работы:

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

  • Второй режим работы называется живое воспроизведение, где изменения из исходной базы данных передаются от процесса-получателя к процессу преобразования с использованием канала Unix, а затем с тем же механизмом от процесса преобразования к процессу воспроизведения.

Только один режим работы может быть активен в любой момент времени, и pgcopydb автоматически переключается с одного режима на другой, в цикле.

Следующая команда всегда запускается в режиме предварительной выборки и догонки, и как только процесс догонки не может найти следующий SQL файл для воспроизведения, он завершает работу, вызывая переключение в режим живого воспроизведения. Перед входом в новый режим, чтобы убедиться, что все полученные изменения воспроизведены, pgcopydb реализует дополнительную фазу догонки без параллельной активности.

Предварительная выборка и Догоняющий режим

В режиме предварительной выборки и догонки три процесса реализуют следующий подход:

  1. Первый процесс предварительно извлекает изменения из исходной базы данных, используя протокол логической декодировки Postgres, и сохраняет сообщения JSON в локальные файлы JSON.

  2. Второй процесс преобразует файлы JSON в SQL. Для передачи позиций LSN от процесса предварительной выборки к процессу преобразования используется очередь сообщений Unix system V.

  3. Третий процесс догоняет изменения, происходящие в исходной базе данных, применяя SQL файлы к целевой системе баз данных.

    API Postgres для Отслеживания Прогресса Репликации используется в этом процессе, чтобы мы могли пропускать уже примененные транзакции при перезапуске или возобновлении.

Живая Повторная Трансляция

В режиме живого воспроизведения операций, три процесса реализуют следующий подход:

  1. Первый процесс получает изменения из исходной базы данных, используя протокол логической декодировки Postgres, и сохраняет сообщения JSON в локальные файлы JSON.

    Дополнительно, изменения JSON записываются в канал Unix, общий с процессом преобразования.

  2. Второй процесс преобразует строки JSON в SQL. Для передачи строк JSON от процесса получения к процессу преобразования используется канал Unix.

    Процесс преобразования в этом режиме все еще записывает изменения в SQL файлы, так что все еще возможно догнать полученные изменения, если процесс применения будет прерван.

  3. Третий процесс воспроизводит изменения, происходящие в исходной базе данных, применяя SQL-команды к целевой системе баз данных. SQL-команды читаются из Unix pipe, который используется совместно с процессом преобразования.

    API Postgres для Отслеживания Прогресса Репликации используется в этом процессе, чтобы мы могли пропускать уже примененные транзакции при перезапуске или возобновлении.

Удаленное управление командой follow

Можно запустить команду pgcopydb follow и затем позже, пока она еще выполняется, установить LSN для конечной позиции с тем же эффектом, что и при использовании опции командной строки --endpos, или переключиться с режима предварительной выборки только на режим предварительной выборки и догоняющего режима. Для этого см. команды pgcopydb stream sentinel set endpos, pgcopydb stream sentinel set apply и pgcopydb stream sentinel set prefetch.

Обратите внимание, что во многих случаях позиция LSN --endpos неизвестна в начале этой команды. Также перед переходом в режим предварительной выборки и применения важно убедиться, что начальное базовое копирование завершено.

Наконец, также возможно настроить параметры потоковой репликации перед использованием команды pgcopydb follow: см. команды pgcopydb stream setup и pgcopydb stream cleanup.

Репликационная идентичность и отсутствие первичных ключей

Postgres Logical Decoding работает с воспроизведением изменений с использованием SQL операторов, и для этого вводит концепцию Идентичность Реплики, как описано в документации для команды ALTER TABLE … REPLICA IDENTITY.

To quote Postgres docs: Эта форма изменяет информацию, которая записывается в журнал предзаписи для идентификации строк, которые обновляются или удаляются. В большинстве случаев старое значение каждого столбца записывается только если оно отличается от нового значения; однако, если старое значение хранится внешне, оно всегда записывается независимо от того, изменилось ли оно. Этот параметр не имеет эффекта, кроме случаев, когда используется логическая репликация.

Чтобы поддерживать захват данных изменений с помощью логической декодировки Postgres для таблиц, которые не имеют первичного ключа, необходимо использовать команду ALTER TABLE ... REPLICA IDENTITY для этих таблиц.

На практике следует рассмотреть два следующих варианта:

  • REPLICA IDENTITY ИСПОЛЬЗУЯ ИНДЕКС index_name

    Эта форма предпочтительна, когда для таблицы существует уникальный индекс без первичного ключа. Индекс должен быть уникальным, не частичным, не откладываемым и включать только столбцы, помеченные как NOT NULL.

  • REPLICA IDENTITY FULL

    Когда это используется для таблицы, записи WAL содержат старые значения всех столбцов в строке.

Логическое декодирование Предварительная выборка

При использовании pgcopydb clone --follow логический слот репликации создается на исходной базе данных перед начальным COPY, используя тот же снимок Postgres. Это обеспечивает согласованность данных.

В рамках подхода pgcopydb clone --follow, возможно начать применять изменения из исходной базы данных только после завершения начального COPY в целевой базе данных.

Также, из документации Postgres мы читаем, что слоты репликации Postgres предоставляют автоматизированный способ гарантировать, что первичный сервер не удаляет сегменты WAL, пока они не будут получены всеми резервными серверами.

Накопление сегментов WAL на первичном сервере в течение всего времени выполнения начальной команды COPY связано с рисками по емкости, которые могут привести к потенциальным ошибкам Файловая система заполнена на диске WAL исходной базы данных. Крайне важно избежать такой ситуации.

Это причина, по которой pgcopydb реализует предварительную выборку CDC. Параллельно с начальным COPY команда pgcopydb clone --follow предварительно выбирает изменения в локальные файлы JSON и SQL. Эти файлы размещаются в расположении XDG_DATA_HOME, которое может быть точкой монтирования для бесконечной области Blob Storage.

Команда pgcopydb follow является удобной командой, доступной в качестве клиента логического декодирования, и она использует ту же реализацию, что и команда pgcopydb clone --follow. В результате стратегия предварительной выборки также актуальна для команды pgcopydb follow.

Таблица-сентинел, или Дистанционное управление

Чтобы отслеживать прогресс и позволять возобновление операций, pgcopydb использует таблицу-сентинел. Таблица-сентинел состоит из одной строки со следующими полями:

$ 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, например, следующего:

{
  "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) следуют протоколу репликации Postgres, как это видно в документации для pg_stat_replication функции.

  • startpos

    Поле startpos — это текущий LSN в исходной базе данных на момент настройки захвата данных изменений в pgcopydb, например, при использовании команды pgcopydb stream setup.

    Обратите внимание, что как команда pgcopydb follow, так и команда pgcopydb clone --follow выполняют части настройки, если pgcopydb stream setup еще не был использован.

  • endpos

    Поле endpos является последней позицией LSN из исходной базы данных, которую воспроизводит pgcopydb. Команда pgcopydb follow (или pgcopydb clone --follow) останавливается при достижении этой позиции LSN.

    endpos можно установить в начале процесса, что полезно для модульного тестирования, или во время выполнения команды, что полезно в производственной среде для определения точки переключения.

    Чтобы определить endpos во время выполнения команды, используйте pgcopydb stream sentinel set endpos.

  • apply

    Поле apply является булевым (включено/выключено), которое контролирует процесс догонки. Процесс догонки pgcopydb воспроизводит изменения только тогда, когда булево значение apply установлено в true.

    Команда pgcopydb clone --follow автоматически включает поле apply в таблице sentinel, как только начальное копирование (COPY) завершено.

    Чтобы вручную управлять полем apply, используйте команду pgcopydb stream sentinel set apply.

  • write_lsn

    Документация Postgres для pg_stat_replication.write_lsn такова: Последнее местоположение журнала предзаписи, записанное на диск этим резервным сервером.

    В случае pgcopydb поле sentinel write_lsn является позицией, которая была записана на диск (в формате JSON) процессом потоковой передачи.

  • flush_lsn

    Документация Postgres для pg_stat_replication.flush_lsn такова: Последнее местоположение журнала предзаписи, сброшенное на диск этим резервным сервером

    В случае pgcopydb поле sentinel flush_lsn является позицией, которая была записана и затем синхронизирована на диск (в формате JSON) процессом потоковой передачи.

  • replay_lsn

    Документация Postgres для pg_stat_replication.replay_lsn такова: Последнее местоположение журнала предзаписи, воспроизведенное в базу данных на этом резервном сервере

    В случае pgcopydb поле sentinel replay_lsn является позицией, которая была применена к целевой базе данных, как отслеживается из файлов WAL.json и затем WAL.sql, и с использованием API Postgres для Отслеживания Прогресса Репликации.

    replay_lsn также используется процессом потоковой передачи pgcopydb, который использует протокол логической репликации Postgres, поэтому pg_stat_replication запись, связанная с репликационным слотом, используемым pgcopydb, может быть использована для мониторинга задержки репликации.

Поскольку процессы потоковой передачи pgcopydb поддерживают таблицу sentinel в исходной базе данных, также возможно использовать её для отслеживания прогресса логической репликации.

Опции

Следующие параметры доступны для pgcopydb follow:

--source

Строка подключения к исходному экземпляру Postgres. См. документацию Postgres для строк подключения для подробностей. Кратко, поддерживаются как форма в кавычках "host=... dbname=...", так и форма URI postgres://user@host:5432/dbname.

--target

Строка подключения к целевому экземпляру Postgres.

--dir

Во время своей нормальной работы pgcopydb создает много временных файлов для отслеживания прогресса подпроцессов. Временные файлы создаются в каталоге, указанном в этой опции, или по умолчанию в ${TMPDIR}/pgcopydb, если установлена переменная окружения, или иначе в /tmp/pgcopydb.

--restart

При повторном запуске команды pgcopydb, если рабочий каталог уже содержит информацию от предыдущего запуска, то команда отказывается продолжать и удалять информацию, которая может быть использована для диагностики и криминалистики.

В этом случае можно использовать опцию --restart, чтобы позволить pgcopydb удалить следы от предыдущего запуска.

--resume

Когда команда pgcopydb была завершена до завершения, либо из-за сигнала прерывания (например, C-c или SIGTERM), либо из-за сбоя, возможно возобновить миграцию базы данных.

Когда возобновляется активность после предыдущего запуска, данные таблицы, которые были полностью скопированы на целевой сервер, не отправляются снова. Данные таблицы, копирование которых было прервано во время COPY, должны быть начаты с нуля, даже при использовании --resume: команда COPY в Postgres является транзакционной и была откатана.

Та же логика применяется к командам CREATE INDEX и ALTER TABLE, которые выполняет pgcopydb, эти команды пропускаются при --resume запуске только в том случае, если известно, что они были выполнены до конца в предыдущем запуске.

Наконец, использование --resume требует использования --not-consistent.

--not-consistent

Для обеспечения согласованности pgcopydb экспортирует снимок Postgres, вызывая функцию pg_export_snapshot() на сервере исходной базы данных. Затем снимок повторно используется во всех соединениях с сервером исходной базы данных с помощью команды SET TRANSACTION SNAPSHOT.

Согласно документации Postgres о pg_export_snapshot: Сохраняет текущий снимок транзакции и возвращает текстовую строку, идентифицирующую снимок. Эта строка должна быть передана (вне базы данных) клиентам, которые хотят импортировать снимок. Снимок доступен для импорта только до конца транзакции, которая экспортировала его.

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

--snapshot

Вместо экспорта собственной моментальной копии с помощью функции Tantor SE-1C pg_export_snapshot() возможно, чтобы pgcopydb повторно использовал уже экспортированную моментальную копию.

--plugin

Плагин вывода логического декодирования для использования. По умолчанию это test_decoding, который поставляется с самим ядром Postgres, поэтому, вероятно, уже доступен на вашем исходном сервере.

Возможно использовать 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

Укажите pgcopydb создать логический слот репликации для использования.

--endpos

Целевой LSN для логического декодирования. Автоматически остановить репликацию и выйти с нормальным статусом выхода 0, когда прием достигает указанного LSN. Если существует запись с LSN, точно равным lsn, запись будет выведена.

Опция --endpos не учитывает границы транзакций и может обрезать вывод на полпути через транзакцию. Любая частично выведенная транзакция не будет потреблена и будет воспроизведена снова при следующем чтении слота. Отдельные сообщения никогда не обрезаются.

См. также документацию для pg_recvlogical.

--origin

Целевой системе логической репликации необходимо отслеживать транзакции, которые уже были применены, чтобы в случае разрыва соединения или необходимости возобновления операций мы могли пропустить уже воспроизведенные транзакции.

Postgres использует понятие имени исходного узла, как описано в Отслеживание прогресса репликации. Эта опция позволяет выбрать собственное имя узла и по умолчанию устанавливается в “pgcopydb”. Выбор другого имени полезен в некоторых сложных сценариях, таких как миграция нескольких источников в одну и ту же цель, где каждый источник должен иметь свое уникальное имя исходного узла.

--verbose

Увеличьте текущий уровень подробности. Уровень подробности по умолчанию - INFO. В порядке возрастания pgcopydb знает о следующих уровнях подробности: FATAL, ERROR, WARN, INFO, NOTICE, DEBUG, TRACE.

--debug

Установить текущий уровень подробности на уровень DEBUG.

--trace

Установить текущий уровень подробности на уровень TRACE.

--quiet

Установить текущий уровень подробности на уровень ERROR.

Окружение

PGCOPYDB_SOURCE_PGURI

Строка подключения к исходному экземпляру Postgres. Когда --source опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_TARGET_PGURI

Строка подключения к целевому экземпляру Postgres. Когда --target опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_OUTPUT_PLUGIN

Плагин вывода логического декодирования для использования. Когда --plugin опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_WAL2JSON_NUMERIC_AS_STRING

Когда true (или yes, или on, или 1, тот же ввод, что и у Postgres boolean), тогда pgcopydb использует опцию wal2json --numeric-data-types-as-string при использовании плагина вывода wal2json.

Когда --wal2json-numeric-as-string опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_SNAPSHOT

Идентификатор снимка Postgres для повторного использования, см. также --snapshot.

TMPDIR

Команда pgcopydb создает все свои рабочие файлы и каталоги в ${TMPDIR}/pgcopydb, и по умолчанию в /tmp/pgcopydb.

XDG_DATA_HOME

Стандарт XDG Base Directory Specification определяет несколько переменных окружения, которые позволяют контролировать, где программы должны хранить свои файлы.

XDG_DATA_HOME определяет базовый каталог, относительно которого должны храниться пользовательские файлы данных. Если $XDG_DATA_HOME не установлен или пуст, следует использовать значение по умолчанию, равное $HOME/.local/share.

При использовании захвата данных изменений (через --follow опцию и логическое декодирование Postgres) pgcopydb предварительно загружает изменения в файлы JSON и преобразует их в SQL файлы для применения к целевой базе данных.

Эти файлы хранятся в следующем месте, проверяются в следующем порядке:

  1. когда используется --dir, тогда pgcopydb использует подкаталог cdc в расположении --dir,

  2. когда XDG_DATA_HOME установлено в окружении, тогда pgcopydb использует это расположение,

  3. если ни один из предыдущих параметров не был использован, тогда pgcopydb по умолчанию использует ${HOME}/.local/share.

pgcopydb snapshot

pgcopydb snapshot - Создать и экспортировать снимок на исходной базе данных

Команда pgcopydb snapshot подключается к исходной базе данных и выполняет SQL-запрос для экспорта снимка. Полученный снимок выводится как на stdout, так и в файл, где другие команды pgcopydb могут ожидать его найти.

pgcopydb snapshot: Create and export a snapshot on the source database
usage: pgcopydb snapshot  --source ...

  --source                      Postgres URI to the source database
  --dir                         Work directory to use
  --follow                      Implement logical decoding to replay changes
  --plugin                      Output plugin to use (test_decoding, wal2json)
  --wal2json-numeric-as-string  Print numeric data type as string when using wal2json output plugin
  --slot-name                   Use this Postgres replication slot name

Опции

Следующие параметры доступны для pgcopydb snapshot:

--source

Строка подключения к исходному экземпляру Postgres. См. документацию Postgres для строк подключения для подробностей. Вкратце, поддерживаются как цитируемая форма "host=... dbname=...", так и форма URI postgres://user@host:5432/dbname.

--dir

Во время своей нормальной работы pgcopydb создает много временных файлов для отслеживания прогресса подпроцессов. Временные файлы создаются в каталоге, указанном в этой опции, или по умолчанию в ${TMPDIR}/pgcopydb, если установлена переменная окружения, или иначе в /tmp/pgcopydb.

--follow

Когда используется опция --follow, тогда pgcopydb реализует Захват Изменений Данных, как описано на странице руководства для pgcopydb follow параллельно с основными шагами копирования базы данных.

Репликационный слот создается с использованием команды протокола репликации Postgres CREATE_REPLICATION_SLOT, которая затем экспортирует снимок, используемый в этой команде.

--plugin

Плагин вывода логического декодирования для использования. По умолчанию это test_decoding, который поставляется с самим ядром Postgres, поэтому, вероятно, уже доступен на вашем исходном сервере.

Возможно использовать 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

Имя слота логического декодирования для использования.

--verbose

Увеличьте текущий уровень подробности. Уровень подробности по умолчанию - INFO. В порядке возрастания pgcopydb знает о следующих уровнях подробности: FATAL, ERROR, WARN, INFO, NOTICE, DEBUG, TRACE.

--debug

Установить текущий уровень подробности на уровень DEBUG.

--trace

Установить текущий уровень подробности на уровень TRACE.

--quiet

Установить текущий уровень подробности на уровень ERROR.

Окружение

PGCOPYDB_SOURCE_PGURI

Строка подключения к исходному экземпляру Postgres. Когда --source опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_OUTPUT_PLUGIN

Плагин вывода логического декодирования для использования. Когда --plugin опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_WAL2JSON_NUMERIC_AS_STRING

Когда true (или yes, или on, или 1, тот же ввод, что и у Postgres boolean), тогда pgcopydb использует опцию wal2json --numeric-data-types-as-string при использовании плагина вывода wal2json.

Когда --wal2json-numeric-as-string опущен в командной строке, используется эта переменная окружения.

Примеры

Создайте снимок на исходной базе данных в фоновом режиме:

$ 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

И когда процесс завершен, прекратите поддерживать снимок в фоновом режиме:

$ kill %1
17:31:56 72938 INFO  Asked to terminate, aborting
[1]+  Done                    pgcopydb snapshot

pgcopydb compare

pgcopydb compare - Сравнить исходную и целевую базы данных

Команда pgcopydb compare подключается к исходной и целевой базам данных и выполняет SQL-запросы для получения информации из каталога Postgres о таблицах, индексах и последовательностях, которые мигрированы.

Инструмент затем сравнивает либо определения схем, либо содержимое данных выбранных таблиц и сообщает об успехе с помощью кода возврата Unix, равного нулю.

На данный момент инструмент pgcopydb compare довольно ограничен с точки зрения поддержки схем: он охватывает только то, что pgcopydb нужно знать о схеме базы данных, а это не так уж много.

pgcopydb compare: Compare source and target databases

Available commands:
  pgcopydb compare
    schema  Compare source and target schema
    data    Compare source and target data

pgcopydb compare schema

pgcopydb compare schema - Сравнить схему источника и цели

Команда pgcopydb compare schema подключается к исходной и целевой базам данных и выполняет SQL-запросы, используя каталоги Postgres для получения списка таблиц, индексов, ограничений и последовательностей.

pgcopydb compare schema: Compare source and target schema
usage: pgcopydb compare schema  --source ...

  --source         Postgres URI to the source database
  --target         Postgres URI to the target database
  --dir            Work directory to use

pgcopydb compare data

pgcopydb compare data - Сравнить данные источника и цели

Команда pgcopydb compare data подключается к исходной и целевой базам данных и выполняет SQL-запросы, используя каталоги Postgres для получения списка таблиц, индексов, ограничений и последовательностей.

Затем используется SQL-запрос с следующим шаблоном для вычисления количества строк и контрольной суммы для каждой таблицы:

/*
 * Compute the hashtext of every single row in the table, and aggregate the
 * results as a sum of bigint numbers. Because the sum of bigint could
 * overflow to numeric, the aggregated sum is then hashed into an MD5
 * value: bigint is 64 bits, MD5 is 128 bits.
 *
 * Also, to lower the chances of a collision, include the row count in the
 * computation of the MD5 by appending it to the input string of the MD5
 * function.
 */
select count(1) as cnt,
       md5(
         format(
           '%%s-%%s',
           sum(hashtext(__COLS__::text)::bigint),
           count(1)
         )
       )::uuid as chksum
from only __TABLE__

Выполнение такого запроса на большой таблице может занять много времени.

pgcopydb compare data: Compare source and target data
usage: pgcopydb compare data  --source ...

  --source         Postgres URI to the source database
  --target         Postgres URI to the target database
  --dir            Work directory to use
  --json           Format the output using JSON

Опции

Следующие параметры доступны для pgcopydb compare schema и pgcopydb compare data подкоманд:

--source

Строка подключения к исходному экземпляру Postgres. См. документацию Postgres для строк подключения для подробностей. Вкратце, поддерживаются как форма в кавычках "host=... dbname=...", так и форма URI postgres://user@host:5432/dbname.

--target

Строка подключения к целевому экземпляру Postgres.

--dir

Во время своей нормальной работы pgcopydb создает много временных файлов для отслеживания прогресса подпроцессов. Временные файлы создаются в каталоге, указанном в этой опции, или по умолчанию в ${TMPDIR}/pgcopydb, если установлена переменная окружения, или иначе в /tmp/pgcopydb.

--json

Вывод команды форматируется в JSON, если поддерживается. В противном случае игнорируется.

--verbose

Увеличьте текущий уровень подробности. Уровень подробности по умолчанию - INFO. В порядке возрастания pgcopydb знает о следующих уровнях подробности: FATAL, ERROR, WARN, INFO, NOTICE, DEBUG, TRACE.

--debug

Установить текущий уровень подробности на уровень DEBUG.

--trace

Установить текущий уровень подробности на уровень TRACE.

--quiet

Установить текущий уровень подробности на уровень ERROR.

Окружение

PGCOPYDB_SOURCE_PGURI

Строка подключения к исходному экземпляру Postgres. Когда --source опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_TARGET_PGURI

Строка подключения к целевому экземпляру Postgres. Когда --target опущен в командной строке, используется эта переменная окружения.

Примеры

Сравнение ограниченного понимания схемы pgcopydb:

$ 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

Сравнение данных:

$ 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

pgcopydb copy - Реализация секции данных копирования базы данных

Эта команда добавляет префикс к следующим подкомандам:

pgcopydb copy: Implement the data section of the database copy

Available commands:
  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 clone. Используйте эти команды только для отладки конкретной части или потому, что вы знаете, что хотите выполнить только этот шаг.

Предупреждение

Использование команды pgcopydb clone настоятельно рекомендуется.

Этот режим работы полезен только для отладки и продвинутых случаев использования.

pgcopydb copy db

pgcopydb copy db - Копировать всю базу данных из источника в цель

Команда pgcopydb copy db является псевдонимом для pgcopydb clone. См. также pgcopydb clone.

pgcopydb copy db: Copy an entire database from source to target
usage: pgcopydb copy db  --source ... --target ... [ --table-jobs ... --index-jobs ... ]

  --source              Postgres URI to the source database
  --target              Postgres URI to the target database
  --dir                 Work directory to use
  --table-jobs          Number of concurrent COPY jobs to run
  --index-jobs          Number of concurrent CREATE INDEX jobs to run
  --restore-jobs        Number of concurrent jobs for pg_restore
  --drop-if-exists      On the target database, clean-up from a previous run first
  --roles               Also copy roles found on source to target
  --no-owner            Do not set ownership of objects to match the original database
  --no-acl              Prevent restoration of access privileges (grant/revoke commands).
  --no-comments         Do not output commands to restore comments
  --no-tablespaces      Do not output commands to select tablespaces
  --skip-large-objects  Skip copying large objects (blobs)
  --filters <filename>  Use the filters defined in <filename>
  --fail-fast           Abort early in case of error
  --restart             Allow restarting when temp files exist already
  --resume              Allow resuming operations after a failure
  --not-consistent      Allow taking a new snapshot on the source database
  --snapshot            Use snapshot obtained with pg_export_snapshot
  --use-copy-binary     Use the COPY BINARY format for COPY operations

pgcopydb copy roles

pgcopydb copy roles - Копировать роли из исходного экземпляра в целевой экземпляр

Команда pgcopydb copy roles реализует как pgcopydb dump roles, так и pgcopydb restore roles.

pgcopydb copy roles: Copy the roles from the source instance to the target instance
usage: pgcopydb copy roles  --source ... --target ...

  --source              Postgres URI to the source database
  --target              Postgres URI to the target database
  --dir                 Work directory to use
  --no-role-passwords   Do not dump passwords for roles

Примечание

В Postgres роли являются глобальным объектом. Это означает, что роли не принадлежат какой-либо конкретной базе данных, и, как результат, даже когда инструмент pgcopydb в остальном работает только в контексте конкретной базы данных, эта команда не ограничивается ролями, которые используются в одной базе данных.

Когда роль уже существует в целевой базе данных, ее восстановление полностью пропускается, что включает пропуск как CREATE ROLE, так и ALTER ROLE команд, создаваемых pg_dumpall --roles-only.

pg_dumpall --roles-only используется для получения списка ролей из исходной базы данных, и эта команда поддерживает пароли. В результате, эта операция требует привилегий суперпользователя.

pgcopydb copy extensions

pgcopydb copy extensions - Копирование расширений из исходного экземпляра в целевой экземпляр

Команда pgcopydb copy extensions получает список расширений, установленных в исходной базе данных, и для каждого из них выполняет SQL-команду CREATE EXTENSION IF NOT EXISTS.

pgcopydb copy extensions: Copy the extensions from the source instance to the target instance
usage: pgcopydb copy extensions  --source ... --target ...

  --source              Postgres URI to the source database
  --target              Postgres URI to the target database
  --dir                 Work directory to use
  --requirements        List extensions requirements

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

pgcopydb copy schema

pgcopydb copy schema - Копировать схему базы данных из источника в цель

Команда pgcopydb copy schema реализует только схему в процессе клонирования.

pgcopydb copy schema: Copy the database schema from source to target
usage: pgcopydb copy schema  --source ... --target ... [ --table-jobs ... --index-jobs ... ]

  --source              Postgres URI to the source database
  --target              Postgres URI to the target database
  --dir                 Work directory to use
  --filters <filename>  Use the filters defined in <filename>
  --restart             Allow restarting when temp files exist already
  --resume              Allow resuming operations after a failure
  --not-consistent      Allow taking a new snapshot on the source database
  --snapshot            Use snapshot obtained with pg_export_snapshot

pgcopydb copy data

pgcopydb copy data - Копировать раздел данных из источника в цель

Команда pgcopydb copy data реализует секцию данных шагов клонирования.

pgcopydb copy data: Copy the data section from source to target
usage: pgcopydb copy data  --source ... --target ... [ --table-jobs ... --index-jobs ... ]

  --source              Postgres URI to the source database
  --target              Postgres URI to the target database
  --dir                 Work directory to use
  --table-jobs          Number of concurrent COPY jobs to run
  --index-jobs          Number of concurrent CREATE INDEX jobs to run
  --restore-jobs        Number of concurrent jobs for pg_restore
  --skip-large-objects  Skip copying large objects (blobs)
  --filters <filename>  Use the filters defined in <filename>
  --restart             Allow restarting when temp files exist already
  --resume              Allow resuming operations after a failure
  --not-consistent      Allow taking a new snapshot on the source database
  --snapshot            Use snapshot obtained with pg_export_snapshot

Примечание

Текущая командная строка содержит как команды pgcopydb copy table-data, так и pgcopydb copy data, которые выглядят похоже, но реализуют разные шаги. Будьте внимательны. Это изменится позже.

Команда pgcopydb copy data выполняет следующие шаги:

$ 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 игнорирует.

pgcopydb copy table-data

pgcopydb copy table-data - Копировать данные из всех таблиц в базе данных от источника к цели

Команда pgcopydb copy table-data получает список таблиц из исходной базы данных и выполняет команду COPY TO в исходной базе данных, отправляя результат в целевую базу данных с использованием команды COPY FROM напрямую, полностью избегая дисков.

pgcopydb copy table-data: Copy the data from all tables in database from source to target
usage: pgcopydb copy table-data  --source ... --target ... [ --table-jobs ... --index-jobs ... ]

  --source             Postgres URI to the source database
  --target             Postgres URI to the target database
  --dir                Work directory to use
  --table-jobs         Number of concurrent COPY jobs to run
  --filters <filename> Use the filters defined in <filename>
  --restart            Allow restarting when temp files exist already
  --resume             Allow resuming operations after a failure
  --not-consistent     Allow taking a new snapshot on the source database
  --snapshot           Use snapshot obtained with pg_export_snapshot

pgcopydb copy blobs

pgcopydb copy blobs - Копировать данные blob из исходной базы данных в целевую

Команда pgcopydb copy blobs получает список больших объектов (также известных как блобы) из исходной базы данных и копирует их данные в целевую базу данных. По умолчанию команда предполагает, что метаданные больших объектов уже обработаны, из-за поведения pg_dump --section=pre-data.

pgcopydb copy blobs: Copy the blob data from the source database to the target
usage: pgcopydb copy blobs  --source ... --target ... [ --table-jobs ... --index-jobs ... ]

  --source             Postgres URI to the source database
  --target             Postgres URI to the target database
  --dir                Work directory to use
  --large-objects-jobs Number of concurrent Large Objects jobs to run
  --drop-if-exists     On the target database, drop and create large objects
  --restart            Allow restarting when temp files exist already
  --resume             Allow resuming operations after a failure
  --not-consistent     Allow taking a new snapshot on the source database
  --snapshot           Use snapshot obtained with pg_export_snapshot

pgcopydb copy sequences

pgcopydb copy sequences - Копировать текущее значение всех последовательностей в базе данных с источника на цель

Команда pgcopydb copy sequences извлекает список последовательностей из исходной базы данных, затем для каждой последовательности извлекает свойства last_value и is_called таким же образом, как pg_dump делает это в исходной базе данных, а затем для каждой последовательности вызывает pg_catalog.setval() в целевой базе данных.

pgcopydb copy sequences: Copy the current value from all sequences in database from source to target
usage: pgcopydb copy sequences  --source ... --target ... [ --table-jobs ... --index-jobs ... ]

  --source             Postgres URI to the source database
  --target             Postgres URI to the target database
  --dir                Work directory to use
  --filters <filename> Use the filters defined in <filename>
  --restart            Allow restarting when temp files exist already
  --resume             Allow resuming operations after a failure
  --not-consistent     Allow taking a new snapshot on the source database
  --snapshot           Use snapshot obtained with pg_export_snapshot

pgcopydb copy indexes

pgcopydb copy indexes - Создать все индексы, найденные в исходной базе данных, в целевой

Команда pgcopydb copy indexes извлекает список индексов из исходной базы данных и запускает каждый индекс CREATE INDEX в целевой базе данных. Операторы для определения индексов модифицируются, чтобы включить IF NOT EXISTS и позволяют пропускать индексы, которые уже существуют в целевой базе данных базе данных.

pgcopydb copy indexes: Create all the indexes found in the source database in the target
usage: pgcopydb copy indexes  --source ... --target ... [ --table-jobs ... --index-jobs ... ]

  --source             Postgres URI to the source database
  --target             Postgres URI to the target database
  --dir                Work directory to use
  --index-jobs         Number of concurrent CREATE INDEX jobs to run
  --restore-jobs       Number of concurrent jobs for pg_restore
  --filters <filename> Use the filters defined in <filename>
  --restart            Allow restarting when temp files exist already
  --resume             Allow resuming operations after a failure
  --not-consistent     Allow taking a new snapshot on the source database

pgcopydb copy constraints

pgcopydb copy constraints - Создать все ограничения, найденные в исходной базе данных, в целевой

Команда pgcopydb copy constraints извлекает список индексов из исходной базы данных и выполняет для каждого индекса оператор ALTER TABLE … ADD CONSTRAINT … USING INDEX в целевой базе данных.

Индексы должны уже существовать, и команда завершится с ошибкой, если в целевой базе данных уже существует какое-либо ограничение.

pgcopydb copy constraints: Create all the constraints found in the source database in the target
usage: pgcopydb copy constraints  --source ... --target ... [ --table-jobs ... --index-jobs ... ]

  --source             Postgres URI to the source database
  --target             Postgres URI to the target database
  --dir                Work directory to use
  --filters <filename> Use the filters defined in <filename>
  --restart            Allow restarting when temp files exist already
  --resume             Allow resuming operations after a failure
  --not-consistent     Allow taking a new snapshot on the source database

Описание

Эти команды позволяют выполнять конкретный шаг операций pgcopydb за раз. Это полезно в основном для целей отладки, хотя можно найти некоторые продвинутые и креативные способы использования этих команд.

Целевая схема не создается, поэтому о ней нужно позаботиться заранее. Можно использовать команды pgcopydb dump schema, а затем pgcopydb restore pre-data, чтобы подготовить вашу целевую базу данных.

Чтобы выполнить те же операции, что и команда pgcopydb clone, используйте следующий рецепт:

$ 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 подкоманд:

--source

Строка подключения к исходному экземпляру Postgres. См. документацию Postgres для строк подключения для подробностей. Вкратце, поддерживаются как форма в кавычках "host=... dbname=...", так и форма URI postgres://user@host:5432/dbname.

--target

Строка подключения к целевому экземпляру Postgres.

--dir

Во время своей нормальной работы pgcopydb создает много временных файлов для отслеживания прогресса подпроцессов. Временные файлы создаются в каталоге, указанном в этой опции, или по умолчанию в ${TMPDIR}/pgcopydb, если установлена переменная окружения, или иначе в /tmp/pgcopydb.

--no-role-passwords

Не выгружать пароли для ролей. При восстановлении роли будут иметь нулевой пароль, и аутентификация по паролю всегда будет проваливаться, пока пароль не будет установлен. Поскольку значения паролей не нужны, когда указана эта опция, информация о ролях читается из представления каталога pg_roles вместо pg_authid. Таким образом, эта опция также помогает, если доступ к pg_authid ограничен какой-либо политикой безопасности.

--table-jobs

Сколько таблиц может обрабатываться параллельно.

Этот лимит применяется только к операциям COPY, больше подпроцессов будет выполняться одновременно с этим лимитом, пока операции CREATE INDEX находятся в процессе, хотя тогда процессы только ждут, пока целевая инстанция Postgres выполнит всю работу.

--index-jobs

Сколько индексов может быть построено параллельно, глобально. Хорошим вариантом является установка этого параметра в количество доступных ядер ЦП на целевой системе Postgres, за вычетом некоторых ядер, которые будут использоваться для обработки операций COPY.

--large-object-jobs

Сколько рабочих процессов запустить для одновременного копирования больших объектов.

--split-tables-larger-than

Разрешить одновременный доступ к одной и той же таблице при обработке исходной базы данных. Ожидается, что значение этой переменной окружения будет указано в байтах, и известны единицы измерения байтов: B, kB, MB, GB, TB, PB и EB.

--skip-large-objects

Пропустить копирование больших объектов, также известных как блобы, при копировании данных из исходной базы данных в целевую базу данных.

--restart

При повторном запуске команды pgcopydb, если рабочий каталог уже содержит информацию от предыдущего запуска, то команда отказывается продолжать и удалять информацию, которая может быть использована для диагностики и криминалистики.

В этом случае можно использовать опцию --restart, чтобы позволить pgcopydb удалить следы от предыдущего запуска.

--resume

Когда команда pgcopydb была завершена до завершения, либо из-за сигнала прерывания (например, C-c или SIGTERM), либо из-за сбоя, возможно возобновить миграцию базы данных.

Когда возобновляется активность после предыдущего запуска, данные таблицы, которые были полностью скопированы на целевой сервер, не отправляются снова. Данные таблицы, копирование которых было прервано во время COPY, должны быть начаты с нуля, даже при использовании --resume: команда COPY в Postgres является транзакционной и была откатана.

Та же логика применяется к командам CREATE INDEX и ALTER TABLE, которые выполняет pgcopydb, эти команды пропускаются при --resume запуске только в том случае, если известно, что они были выполнены до конца в предыдущем запуске.

Наконец, использование --resume требует использования --not-consistent.

--not-consistent

Для обеспечения согласованности pgcopydb экспортирует снимок Postgres, вызывая функцию pg_export_snapshot() на сервере исходной базы данных. Затем снимок повторно используется во всех соединениях с сервером исходной базы данных с помощью команды SET TRANSACTION SNAPSHOT.

Согласно документации Postgres о pg_export_snapshot: Сохраняет текущий снимок транзакции и возвращает текстовую строку, идентифицирующую снимок. Эта строка должна быть передана (вне базы данных) клиентам, которые хотят импортировать снимок. Снимок доступен для импорта только до конца транзакции, которая экспортировала его.

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

--snapshot

Вместо экспорта собственной моментальной копии с помощью функции Tantor SE-1C pg_export_snapshot() возможно, чтобы pgcopydb повторно использовал уже экспортированную моментальную копию.

--use-copy-binary

Используйте COPY WITH (FORMAT BINARY) вместо команды COPY.

См. также документацию для COPY.

--verbose

Увеличьте текущий уровень подробности. Уровень подробности по умолчанию - INFO. В порядке возрастания pgcopydb знает о следующих уровнях подробности: FATAL, ERROR, WARN, INFO, NOTICE, DEBUG, TRACE.

--debug

Установить текущий уровень подробности на уровень DEBUG.

--trace

Установить текущий уровень подробности на уровень TRACE.

--quiet

Установить текущий уровень подробности на уровень ERROR.

Окружение

PGCOPYDB_SOURCE_PGURI

Строка подключения к исходному экземпляру Postgres. Когда --source опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_TARGET_PGURI

Строка подключения к целевому экземпляру Postgres. Когда --target опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_TABLE_JOBS

Количество параллельных задач, разрешенных для выполнения операций COPY. Когда --table-jobs опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_INDEX_JOBS

Количество параллельных задач, разрешенных для выполнения операций CREATE INDEX. Когда --index-jobs не указан в командной строке, используется эта переменная окружения.

PGCOPYDB_RESTORE_JOBS

Количество параллельных задач, разрешенных для выполнения операций pg_restore. Когда --restore-jobs не указан в командной строке, используется эта переменная окружения.

PGCOPYDB_LARGE_OBJECTS_JOBS

Количество параллельных задач, разрешенных для копирования данных больших объектов. Когда --large-objects-jobs опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_SPLIT_TABLES_LARGER_THAN

Разрешить Конкуренцию для одной таблицы при обработке исходной базы данных. Ожидается, что значение этой переменной окружения будет указано в байтах, и известны единицы измерения байт: B, kB, MB, GB, TB, PB и EB.

Когда --split-tables-larger-than опущен из командной строки, используется эта переменная окружения.

PGCOPYDB_SPLIT_MAX_PARTS

Ограничьте максимальное количество частей, когда используется Параллельная работа с одной таблицей. Когда --split-max-parts не указан в командной строке, используется эта переменная окружения.

PGCOPYDB_ESTIMATE_TABLE_SIZES

Когда true (или yes, или on, или 1, тот же ввод, что и для boolean в Postgres), тогда pgcopydb оценивает размер таблиц, чтобы определить, нужно ли разделять таблицы. Этот параметр полезен только в том случае, если запрос размеров отношений в исходной базе данных является затратным.

Когда --estimate-table-sizes опущен из командной строки, используется эта переменная окружения.

PGCOPYDB_DROP_IF_EXISTS

Когда true (или yes, или on, или 1, тот же ввод, что и у boolean в Postgres), тогда pgcopydb использует параметры pg_restore --clean --if-exists при создании схемы на целевом экземпляре Postgres.

PGCOPYDB_SNAPSHOT

Идентификатор снимка Postgres для повторного использования, см. также --snapshot.

PGCOPYDB_USE_COPY_BINARY

Когда true (или yes, или on, или 1, тот же ввод, что и у Postgres boolean), тогда pgcopydb использует COPY WITH (FORMAT BINARY) вместо команды COPY, так же, как при использовании опции --use-copy-binary.

TMPDIR

Команда pgcopydb создает все свои рабочие файлы и каталоги в ${TMPDIR}/pgcopydb, и по умолчанию в /tmp/pgcopydb.

Примеры

Давайте экспортируем строки подключения к базам данных Postgres, чтобы их было легко повторно использовать:

$ export PGCOPYDB_SOURCE_PGURI=postgres://pagila:0wn3d@source/pagila
$ export PGCOPYDB_TARGET_PGURI=postgres://pagila:0wn3d@target/pagila

Теперь сначала создайте дамп схемы:

$ pgcopydb dump schema
08:27:48.633 44371 INFO   Using work dir "/tmp/pgcopydb"
08:27:48.634 44371 INFO   Dumping database from "postgres://pagila:0wn3d@source/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
08:27:48.634 44371 INFO   Dumping database into directory "/tmp/pgcopydb"
08:27:48.634 44371 INFO   Using pg_dump for Postgres "16.2" at "/usr/bin/pg_dump"
08:27:48.971 44371 INFO   Fetched information for 5 tables (including 0 tables split in 0 partitions total), with an estimated total of 1000 thousands tuples and 128 MB on-disk
08:27:48.978 44371 INFO   Fetched information for 4 indexes (supporting 4 constraints)
08:27:48.983 44371 INFO   Fetching information for 1 sequences
08:27:48.996 44371 INFO   Fetched information for 1 extensions
08:27:49.072 44371 INFO   Found 5 indexes (supporting 5 constraints) in the target database
08:27:49.078 44371 INFO    /usr/bin/pg_dump -Fc --section=pre-data --section=post-data --file /tmp/pgcopydb/schema/schema.dump 'postgres://pagila:0wn3d@source/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60'

Теперь восстановите схему предварительных данных в целевой базе данных, удаляя уже существующие объекты, если таковые имеются, что позволяет запускать этот тестовый сценарий снова и снова. Однако это может быть не то, что вы хотите делать в вашей производственной целевой инстанции!

$ PGCOPYDB_DROP_IF_EXISTS=on pgcopydb restore pre-data --no-owner --resume --not-consistent
08:30:13.621 44597 INFO   Using work dir "/tmp/pgcopydb"
08:30:13.621 44597 INFO   Restoring database from existing files at "/tmp/pgcopydb"
08:30:13.706 44597 INFO   Found 5 indexes (supporting 5 constraints) in the target database
08:30:13.710 44597 INFO   Using pg_restore for Postgres "16.2" at "/usr/bin/pg_restore"
08:30:13.711 44597 INFO   [TARGET] Restoring database into "postgres://pagila:0wn3d@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
08:30:13.730 44597 INFO   Drop tables on the target database, per --drop-if-exists
08:30:13.774 44597 INFO    /usr/bin/pg_restore --dbname 'postgres://pagila:0wn3d@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60' --section pre-data --jobs 4 --clean --if-exists --no-owner --use-list /tmp/pgcopydb/schema/pre-filtered.list /tmp/pgcopydb/schema/schema.dump

Затем скопируйте данные:

$ pgcopydb copy table-data --resume --not-consistent
08:34:02.813 44834 INFO   [SOURCE] Copying database from "postgres://pagila:0wn3d@source/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
08:34:02.813 44834 INFO   [TARGET] Copying database into "postgres://pagila:0wn3d@target/pagila?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
08:34:02.861 44834 INFO   Using work dir "/tmp/pgcopydb"
08:34:02.862 44834 INFO   Copy data from source to target in sub-processes
08:34:02.863 44834 INFO   Re-using catalog caches
08:34:02.863 44834 INFO   STEP 4: starting 4 table-data COPY processes

А теперь создайте индексы в целевой базе данных, используя определения индексов из исходной базы данных:

$ 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
 --------------------------------------------------   ----------  ----------  ----------  ------------

Теперь воссоздайте ограничения (первичный ключ, уникальные ограничения) из схемы исходной базы данных в целевую базу данных:

$ 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
 --------------------------------------------------   ----------  ----------  ----------  ------------

Следующим шагом является выполнение команды VACUUM ANALYZE для каждой таблицы, которая была только что заполнена данными, и для этого мы можем просто использовать команду vacuumdb из Postgres:

$ vacuumdb --analyze --dbname "$PGCOPYDB_TARGET_PGURI" --jobs 4
vacuumdb: vacuuming database "pagila"

Наконец, мы можем восстановить пост-данные раздела схемы:

$ 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/schema.dump

pgcopydb dump

pgcopydb dump - Выгрузка объектов базы данных из экземпляра Postgres

Эта команда добавляет префикс к следующим подкомандам:

pgcopydb dump: Dump database objects from a Postgres instance

Available commands:
  pgcopydb dump
    schema  Dump source database schema as custom files in work directory
    roles   Dump source database roles as custome file in work directory

pgcopydb dump schema

pgcopydb dump schema - Снимок схемы исходной базы данных в виде пользовательских файлов в целевом каталоге

Команда pgcopydb dump schema использует pg_dump для экспорта SQL-определений схем из указанного исходного экземпляра Postgres.

pgcopydb dump schema: Dump source database schema as custom files in work directory
usage: pgcopydb dump schema  --source <URI>

  --source             Postgres URI to the source database
  --target             Directory where to save the dump files
  --dir                Work directory to use
  --skip-extensions    Skip restoring extensions
  --filters <filename> Use the filters defined in <filename>
  --snapshot           Use snapshot obtained with pg_export_snapshot

pgcopydb dump roles

pgcopydb dump roles - Сохранить роли исходной базы данных как файл custome в рабочем каталоге

Команда pgcopydb dump roles использует pg_dumpall –roles-only для экспорта SQL-определений ролей, найденных в исходном экземпляре Postgres.

pgcopydb dump roles: Dump source database roles as custome file in work directory
usage: pgcopydb dump roles  --source <URI>

  --source            Postgres URI to the source database
  --target            Directory where to save the dump files
  --dir               Work directory to use
  --no-role-passwords Do not dump passwords for roles

pg_dumpall --roles-only используется для получения списка ролей из исходной базы данных, и эта команда поддерживает пароли. В результате, эта операция требует привилегий суперпользователя.

Возможно использовать опцию --no-role-passwords для работы без привилегий суперпользователя. Однако в этом случае пароли не будут частью дампа, и аутентификация может не пройти до тех пор, пока пароли не будут правильно настроены.

Описание

Команда pgcopydb dump schema реализует первый шаг полной миграции базы данных и извлекает определения схем из исходной базы данных.

Когда команда выполняется, она вызывает pg_dump, чтобы получить схему предварительных данных и схему последующих данных в файле Postgres custom, называемом schema.dump.

Выходные файлы записываются в подкаталог schema каталога --target.

Опции

Следующие параметры доступны для pgcopydb dump schema подкоманды:

--source

Строка подключения к исходному экземпляру Postgres. См. документацию Postgres для строк подключения для подробностей. Вкратце, поддерживаются как форма в кавычках "host=... dbname=...", так и форма URI postgres://user@host:5432/dbname.

--target

Строка подключения к целевому экземпляру Postgres.

--dir

Во время своей нормальной работы pgcopydb создает много временных файлов для отслеживания прогресса подпроцессов. Временные файлы создаются в каталоге, указанном в этой опции, или по умолчанию в ${TMPDIR}/pgcopydb, если установлена переменная окружения, или иначе в /tmp/pgcopydb.

--no-role-passwords

Не выгружать пароли для ролей. При восстановлении роли будут иметь нулевой пароль, и аутентификация по паролю всегда будет проваливаться, пока пароль не будет установлен. Поскольку значения паролей не нужны, когда указана эта опция, информация о ролях читается из представления каталога pg_roles вместо pg_authid. Таким образом, эта опция также помогает, если доступ к pg_authid ограничен какой-либо политикой безопасности.

--snapshot

Вместо экспорта собственной моментальной копии с помощью функции Tantor SE-1C pg_export_snapshot() возможно, чтобы pgcopydb повторно использовал уже экспортированную моментальную копию.

--verbose

Увеличьте текущий уровень подробности. Уровень подробности по умолчанию - INFO. В порядке возрастания pgcopydb знает о следующих уровнях подробности: FATAL, ERROR, WARN, INFO, NOTICE, DEBUG, TRACE.

--debug

Установить текущий уровень подробности на уровень DEBUG.

--trace

Установить текущий уровень подробности на уровень TRACE.

--quiet

Установить текущий уровень подробности на уровень ERROR.

Окружение

PGCOPYDB_SOURCE_PGURI

Строка подключения к исходному экземпляру Postgres. Когда --source опущен в командной строке, используется эта переменная окружения.

Примеры

Сначала, используя pgcopydb dump schema

$ pgcopydb dump schema --source "port=5501 dbname=demo" --target /tmp/target
09:35:21 3926 INFO  Dumping database from "port=5501 dbname=demo"
09:35:21 3926 INFO  Dumping database into directory "/tmp/target"
09:35:21 3926 INFO  Found a stale pidfile at "/tmp/target/pgcopydb.pid"
09:35:21 3926 WARN  Removing the stale pid file "/tmp/target/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 --section post-data --file /tmp/target/schema/schema.dump 'port=5501 dbname=demo'

После завершения предыдущей команды, файл вывода pg_dump можно найти в /tmp/target/schema и он называется schema.dump. Кроме того, были созданы другие файлы и каталоги.

$ find /tmp/target
/tmp/target
/tmp/target/pgcopydb.pid
/tmp/target/schema
/tmp/target/schema/schema.dump
/tmp/target/run
/tmp/target/run/tables
/tmp/target/run/indexes

pgcopydb restore

pgcopydb restore - Восстановление объектов базы данных в экземпляре Postgres

Эта команда добавляет префикс к следующим подкомандам:

pgcopydb restore: Restore database objects into a Postgres instance

Available commands:
  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 restore schema

pgcopydb restore schema - Восстановление схемы базы данных из пользовательских файлов в целевую базу данных

Команда pgcopydb restore schema использует pg_restore для создания SQL-определений схем из указанного каталога экспорта pgcopydb dump schema. Эта команда несовместима с использованием файлов Postgres напрямую, она должна получать данные из каталога, созданного командами pgcopydb dump ....

pgcopydb restore schema: Restore a database schema from custom files to target database
usage: pgcopydb restore schema  --dir <dir> [ --source <URI> ] --target <URI>

  --source             Postgres URI to the source database
  --target             Postgres URI to the target database
  --dir                Work directory to use
  --restore-jobs       Number of concurrent jobs for pg_restore
  --drop-if-exists     On the target database, clean-up from a previous run first
  --no-owner           Do not set ownership of objects to match the original database
  --no-acl             Prevent restoration of access privileges (grant/revoke commands).
  --no-comments        Do not output commands to restore comments
  --no-tablespaces     Do not output commands to select tablespaces
  --filters <filename> Use the filters defined in <filename>
  --restart            Allow restarting when temp files exist already
  --resume             Allow resuming operations after a failure
  --not-consistent     Allow taking a new snapshot on the source database

pgcopydb restore pre-data

pgcopydb restore pre-data - Восстановление схемы предварительных данных базы данных из пользовательского файла в целевую базу данных

Команда pgcopydb restore pre-data использует pg_restore для создания SQL-определений схем из указанного каталога экспорта pgcopydb dump schema. Эта команда несовместима с использованием файлов Postgres напрямую, она должна получать данные из каталога, созданного командами pgcopydb dump ....

pgcopydb restore pre-data: Restore a database pre-data schema from custom file to target database
usage: pgcopydb restore pre-data  --dir <dir> [ --source <URI> ] --target <URI>

  --source             Postgres URI to the source database
  --target             Postgres URI to the target database
  --dir                Work directory to use
  --restore-jobs       Number of concurrent jobs for pg_restore
  --drop-if-exists     On the target database, clean-up from a previous run first
  --no-owner           Do not set ownership of objects to match the original database
  --no-acl             Prevent restoration of access privileges (grant/revoke commands).
  --no-comments        Do not output commands to restore comments
  --no-tablespaces     Do not output commands to select tablespaces
  --skip-extensions    Skip restoring extensions
  --skip-ext-comments  Skip restoring COMMENT ON EXTENSION
  --filters <filename> Use the filters defined in <filename>
  --restart            Allow restarting when temp files exist already
  --resume             Allow resuming operations after a failure
  --not-consistent     Allow taking a new snapshot on the source database

pgcopydb restore post-data

pgcopydb restore post-data - Восстановление схемы post-data базы данных из пользовательского файла в целевую базу данных

Команда pgcopydb restore post-data использует pg_restore для создания SQL-определений схем из указанного каталога экспорта pgcopydb dump schema. Эта команда несовместима с использованием файлов Postgres напрямую, она должна получать данные из каталога, созданного командами pgcopydb dump ....

pgcopydb restore post-data: Restore a database post-data schema from custom file to target database
usage: pgcopydb restore post-data  --dir <dir> [ --source <URI> ] --target <URI>

  --source             Postgres URI to the source database
  --target             Postgres URI to the target database
  --dir                Work directory to use
  --restore-jobs       Number of concurrent jobs for pg_restore
  --no-owner           Do not set ownership of objects to match the original database
  --no-acl             Prevent restoration of access privileges (grant/revoke commands).
  --no-comments        Do not output commands to restore comments
  --no-tablespaces     Do not output commands to select tablespaces
  --skip-extensions    Skip restoring extensions
  --skip-ext-comments  Skip restoring COMMENT ON EXTENSION
  --filters <filename> Use the filters defined in <filename>
  --restart            Allow restarting when temp files exist already
  --resume             Allow resuming operations after a failure
  --not-consistent     Allow taking a new snapshot on the source database

pgcopydb restore roles

pgcopydb restore roles - Восстановление ролей базы данных из SQL файла в целевую базу данных

Команда pgcopydb restore roles выполняет команды из SQL-скрипта, полученного с помощью команды pgcopydb dump roles. Роли, которые уже существуют в целевой базе данных, пропускаются.

Команда pg_dumpall выдает две строки на роль, первая из которых является SQL-командой CREATE ROLE, а вторая - SQL-командой ALTER ROLE. Обе эти строки пропускаются, если роль уже существует в целевой базе данных.

pgcopydb restore roles: Restore database roles from SQL file to target database
usage: pgcopydb restore roles  --dir <dir> [ --source <URI> ] --target <URI>

  --source             Postgres URI to the source database
  --target             Postgres URI to the target database
  --dir                Work directory to use
  --restore-jobs       Number of concurrent jobs for pg_restore

pgcopydb restore parse-list

pgcopydb restore parse-list - Разбор вывода pg_restore –list из пользовательского файла

Команда pgcopydb restore parse-list выводит pg_restore для перечисления каталога архива в формате файла custom, который был экспортирован для секции post-data.

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

Запись каталога архива pg_restore закомментирована, если строка начинается с символа точка с запятой (;).

pgcopydb restore parse-list: Parse pg_restore --list output from custom file
usage: pgcopydb restore parse-list  [ <pre.list> ]

  --source             Postgres URI to the source database
  --target             Postgres URI to the target database
  --dir                Work directory to use
  --filters <filename> Use the filters defined in <filename>
  --skip-extensions    Skip restoring extensions
  --skip-ext-comments  Skip restoring COMMENT ON EXTENSION
  --restart            Allow restarting when temp files exist already
  --resume             Allow resuming operations after a failure
  --not-consistent     Allow taking a new snapshot on the source database

Описание

Команда pgcopydb restore schema реализует создание SQL объектов в целевой базе данных, второй и последний шаги полной миграции базы данных.

Когда команда выполняется, она вызывает pg_restore на файлах, найденных в ожидаемом месте в --target каталоге, который обычно был создан с помощью команды pgcopydb dump schema.

The pgcopydb restore pre-data и pgcopydb restore post-data ограничивают свои действия файлом с pre-data и post-data в исходном каталоге..

Опции

Следующие параметры доступны для pgcopydb restore schema:

--source

Строка подключения к исходному экземпляру Postgres. См. документацию Postgres для строк подключения для подробностей. Вкратце, поддерживаются как форма в кавычках "host=... dbname=...", так и форма URI postgres://user@host:5432/dbname.

--target

Строка подключения к целевому экземпляру Postgres.

--dir

Во время своей нормальной работы pgcopydb создает много временных файлов для отслеживания прогресса подпроцессов. Временные файлы создаются в каталоге, указанном в этой опции, или по умолчанию в ${TMPDIR}/pgcopydb, если установлена переменная окружения, или иначе в /tmp/pgcopydb.

--restore-jobs

Сколько потоков или процессов можно использовать во время pg_restore. Хорошим вариантом является установка этого параметра в количество ядер ЦП, доступных на целевой системе Postgres.

Если это значение не установлено, мы повторно используем --index-jobs. Если это значение также не установлено, мы используем значение по умолчанию для --index-jobs.

--drop-if-exists

При восстановлении схемы на целевом экземпляре Postgres, pgcopydb фактически использует pg_restore. Когда этот параметр указан, также используются следующие параметры pg_restore: --clean --if-exists.

Эта опция полезна, когда одна и та же команда выполняется несколько раз подряд, либо для исправления предыдущей ошибки, либо, например, при использовании в системе непрерывной интеграции.

Эта опция вызывает использование DROP TABLE и DROP INDEX и других команд DROP. Убедитесь, что вы понимаете, что делаете!

--no-owner

Не выводить команды для установки владельцев объектов в соответствии с оригинальной базой данных. По умолчанию, pg_restore выполняет ALTER OWNER или SET SESSION AUTHORIZATION инструкции для установки владельцев созданных элементов схемы. Эти инструкции будут неудачными, если начальное подключение к базе данных выполнено не суперпользователем (или тем же пользователем, который владеет всеми объектами в скрипте). С --no-owner, любое имя пользователя может быть использовано для начального подключения, и этот пользователь будет владельцем всех созданных объектов.

--filters <filename>

Эта опция позволяет исключить таблицы и индексы из операций копирования. См. Фильтрация для получения подробной информации о ожидаемом формате файла и доступных опциях фильтрации.

--skip-extensions

Пропустить копирование расширений из исходной базы данных в целевую базу данных.

Когда используется, схемы, от которых зависят расширения, также пропускаются: предполагается, что создание необходимых расширений на целевой системе является обязанностью другой команды (например, pgcopydb copy extensions), и схемы, от которых зависят расширения, являются частью этой обязанности.

Поскольку создание расширений требует прав суперпользователя, это позволяет использовать многоэтапный подход, при котором расширения обрабатываются с привилегиями суперпользователя, а затем остальные операции pgcopydb выполняются без привилегий суперпользователя.

--skip-ext-comments

Пропустить команды COMMENT ON EXTENSION. Это подразумевается при использовании –skip-extensions.

--restart

При повторном запуске команды pgcopydb, если рабочий каталог уже содержит информацию от предыдущего запуска, то команда отказывается продолжать и удалять информацию, которая может быть использована для диагностики и криминалистики.

В этом случае можно использовать опцию --restart, чтобы позволить pgcopydb удалить следы от предыдущего запуска.

--resume

Когда команда pgcopydb была завершена до завершения, либо из-за сигнала прерывания (например, C-c или SIGTERM), либо из-за сбоя, возможно возобновить миграцию базы данных.

Когда возобновляется активность после предыдущего запуска, данные таблицы, которые были полностью скопированы на целевой сервер, не отправляются снова. Данные таблицы, копирование которых было прервано во время COPY, должны быть начаты с нуля, даже при использовании --resume: команда COPY в Postgres является транзакционной и была откатана.

Та же логика применяется к командам CREATE INDEX и ALTER TABLE, которые выполняет pgcopydb, эти команды пропускаются при --resume запуске только в том случае, если известно, что они были выполнены до конца в предыдущем запуске.

Наконец, использование --resume требует использования --not-consistent.

--not-consistent

Для обеспечения согласованности pgcopydb экспортирует снимок Postgres, вызывая функцию pg_export_snapshot() на сервере исходной базы данных. Затем снимок повторно используется во всех соединениях с сервером исходной базы данных с помощью команды SET TRANSACTION SNAPSHOT.

Согласно документации Postgres о pg_export_snapshot: Сохраняет текущий снимок транзакции и возвращает текстовую строку, идентифицирующую снимок. Эта строка должна быть передана (вне базы данных) клиентам, которые хотят импортировать снимок. Снимок доступен для импорта только до конца транзакции, которая экспортировала его.

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

--snapshot

Вместо экспорта собственной моментальной копии с помощью функции Tantor SE-1C pg_export_snapshot() возможно, чтобы pgcopydb повторно использовал уже экспортированную моментальную копию.

--verbose

Увеличьте текущий уровень подробности. Уровень подробности по умолчанию - INFO. В порядке возрастания pgcopydb знает о следующих уровнях подробности: FATAL, ERROR, WARN, INFO, NOTICE, DEBUG, TRACE.

--debug

Установить текущий уровень подробности на уровень DEBUG.

--trace

Установить текущий уровень подробности на уровень TRACE.

--quiet

Установить текущий уровень подробности на уровень ERROR.

Окружение

PGCOPYDB_TARGET_PGURI

Строка подключения к целевому экземпляру Postgres. Когда --target опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_DROP_IF_EXISTS

Когда true (или yes, или on, или 1, тот же ввод, что и у boolean в Postgres), тогда pgcopydb использует параметры pg_restore --clean --if-exists при создании схемы на целевом экземпляре Postgres.

Примеры

Сначала, используя pgcopydb restore schema

$ PGCOPYDB_DROP_IF_EXISTS=on pgcopydb restore schema --source /tmp/target/ --target "port=54314 dbname=demo"
07:45:10.626 39254 INFO   Using work dir "/tmp/pgcopydb"
07:45:10.626 39254 INFO   Restoring database from existing files at "/tmp/pgcopydb"
07:45:10.720 39254 INFO   Found 2 indexes (supporting 2 constraints) in the target database
07:45:10.723 39254 INFO   Using pg_restore for Postgres "16.2" at "/usr/bin/pg_restore"
07:45:10.723 39254 INFO   [TARGET] Restoring database into "postgres://[email protected]:5435/demo?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60"
07:45:10.737 39254 INFO   Drop tables on the target database, per --drop-if-exists
07:45:10.750 39254 INFO    /usr/bin/pg_restore --dbname 'postgres://[email protected]:5435/demo?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60' --section pre-data --jobs 4 --clean --if-exists --use-list /tmp/pgcopydb/schema/pre-filtered.list /tmp/pgcopydb/schema/schema.dump
07:45:10.803 39254 INFO    /usr/bin/pg_restore --dbname 'postgres://[email protected]:5435/demo?keepalives=1&keepalives_idle=10&keepalives_interval=10&keepalives_count=60' --section post-data --jobs 4 --clean --if-exists --use-list /tmp/pgcopydb/schema/post-filtered.list /tmp/pgcopydb/schema/schema.dump

Тогда pgcopydb restore pre-data и pgcopydb restore post-data будут выглядеть одинаково с одним вызовом pg_restore вместо обоих.

Используя pgcopydb restore parse-list, можно просмотреть параметры фильтрации и увидеть, как записи каталога pg_restore комментируются.

$ 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

pgcopydb list - Список объектов базы данных из экземпляра Postgres

Эта команда добавляет префикс к следующим подкомандам:

pgcopydb list: List database objects from a Postgres instance

Available commands:
  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 list базы данных

pgcopydb list databases - Список баз данных

Команда pgcopydb list databases подключается к исходной базе данных и выполняет SQL-запрос, используя каталоги Postgres, чтобы получить список всех баз данных.

pgcopydb list databases: List databases
usage: pgcopydb list databases  --source ...

  --source            Postgres URI to the source database

pgcopydb list расширения

pgcopydb list extensions - Список всех расширений источника для копирования

Команда pgcopydb list extensions подключается к исходной базе данных и выполняет SQL-запрос, используя каталоги Postgres, чтобы получить список всех расширений для КОПИРОВАНИЯ в целевую базу данных.

pgcopydb list extensions: List all the source extensions to copy
usage: pgcopydb list extensions  --source ...

  --source              Postgres URI to the source database
  --json                Format the output using JSON
  --available-versions  List available extension versions
  --requirements        List extensions requirements

Команда pgcopydb list extensions --available-versions обычно используется с целевой базой данных. Если вы используете переменные окружения строки подключения, это выглядит следующим образом:

$ pgcopydb list extensions --available-versions --source ${PGCOPYDB_TARGET_PGURI}

pgcopydb list collations

pgcopydb list collations - Перечислить все исходные локали для копирования

Команда pgcopydb list collations подключается к исходной базе данных и выполняет SQL-запрос, используя каталоги Postgres, чтобы получить список всех локалей для копирования в целевую базу данных.

pgcopydb list collations: List all the source collations to copy
usage: pgcopydb list collations  --source ...

  --source            Postgres URI to the source database

SQL-запрос, который используется, перечисляет сортировку базы данных, а затем любую нестандартную сортировку, используемую в пользовательском столбце или пользовательском индексе.

pgcopydb list tables

pgcopydb list tables - Список всех исходных таблиц для копирования данных

Команда pgcopydb list tables подключается к исходной базе данных и выполняет SQL-запрос, используя каталоги Postgres, чтобы получить список всех таблиц, из которых нужно скопировать данные.

pgcopydb list tables: List all the source tables to copy data from
usage: pgcopydb list tables  --source ...

  --source            Postgres URI to the source database
  --filter <filename> Use the filters defined in <filename>
  --force             Force fetching catalogs again
  --list-skipped      List only tables that are setup to be skipped
  --without-pkey      List only tables that have no primary key

pgcopydb list table-parts

pgcopydb list table-parts - Список разделов копирования исходной таблицы

Команда pgcopydb list table-parts подключается к исходной базе данных и выполняет SQL-запрос, используя каталоги Postgres для получения подробной информации о данной исходной таблице, а затем другой SQL-запрос для вычисления, как разделить эту исходную таблицу, учитывая аргумент порога размера.

pgcopydb list table-parts: List a source table copy partitions
usage: pgcopydb list table-parts  --source ...

  --source                    Postgres URI to the source database
  --force                     Force fetching catalogs again
  --schema-name               Name of the schema where to find the table
  --table-name                Name of the target table
  --split-tables-larger-than  Size threshold to consider partitioning
  --split-max-parts           Maximum number of jobs for Same-table concurrency
  --skip-split-by-ctid        Skip the ctid split
  --estimate-table-sizes      Allow using estimates for relation sizes

pgcopydb list sequences

pgcopydb list sequences - Список всех исходных последовательностей для копирования данных

Команда pgcopydb list sequences подключается к исходной базе данных и выполняет SQL-запрос, используя каталоги Postgres, чтобы получить список всех последовательностей для копирования данных.

pgcopydb list sequences: List all the source sequences to copy data from
usage: pgcopydb list sequences  --source ...

  --source            Postgres URI to the source database
  --force             Force fetching catalogs again
  --filter <filename> Use the filters defined in <filename>
  --list-skipped      List only tables that are setup to be skipped

pgcopydb list indexes

pgcopydb list indexes - Список всех индексов для повторного создания после копирования данных

Команда pgcopydb list indexes подключается к исходной базе данных и выполняет SQL-запрос, используя каталоги Postgres, чтобы получить список всех индексов для копирования данных.

pgcopydb list indexes: List all the indexes to create again after copying the data
usage: pgcopydb list indexes  --source ... [ --schema-name [ --table-name ] ]

  --source            Postgres URI to the source database
  --force             Force fetching catalogs again
  --schema-name       Name of the schema where to find the table
  --table-name        Name of the target table
  --filter <filename> Use the filters defined in <filename>
  --list-skipped      List only tables that are setup to be skipped

pgcopydb list зависит

pgcopydb list depends - Список всех зависимостей для фильтрации

Команда pgcopydb list depends подключается к исходной базе данных и выполняет SQL-запрос, используя каталоги Postgres, чтобы получить список всех объектов, которые зависят от исключенных объектов из правил фильтрации.

pgcopydb list depends: List all the dependencies to filter-out
usage: pgcopydb list depends  --source ... [ --schema-name [ --table-name ] ]

  --source            Postgres URI to the source database
  --force             Force fetching catalogs again
  --schema-name       Name of the schema where to find the table
  --table-name        Name of the target table
  --filter <filename> Use the filters defined in <filename>
  --list-skipped      List only tables that are setup to be skipped

pgcopydb list schema

pgcopydb list schema - Список схем для миграции, форматированный в JSON

Команда pgcopydb list schema подключается к исходной базе данных и выполняет SQL-запросы, используя каталоги Postgres, чтобы получить список таблиц, индексов и последовательностей для миграции. Затем команда выводит строку в формате JSON, которая содержит подробную информацию обо всех этих объектах.

pgcopydb list schema: List the schema to migrate, formatted in JSON
usage: pgcopydb list schema  --source ...

  --source            Postgres URI to the source database
  --force             Force fetching catalogs again
  --filter <filename> Use the filters defined in <filename>

pgcopydb list progress

pgcopydb list progress - Список прогресса

Команда pgcopydb list progress читает внутренние каталоги SQLite в рабочем каталоге, анализирует их и затем вычисляет, сколько таблиц и индексов планируется скопировать и создать в целевой базе данных, сколько уже выполнено и сколько находится в процессе выполнения.

Опция --summary отображает сводку верхнего уровня и может быть использована во время выполнения команды или после её завершения.

При использовании опции --json вывод в формате JSON также включает список всех таблиц и индексов, которые в данный момент обрабатываются.

pgcopydb list progress: List the progress
usage: pgcopydb list progress  --source ...

  --source  Postgres URI to the source database
  --summary List the summary, requires --json
  --json    Format the output using JSON
  --dir     Work directory to use

Опции

Следующие параметры доступны для pgcopydb dump schema:

--source

Строка подключения к исходному экземпляру Postgres. См. документацию Postgres для строк подключения для подробностей. Вкратце, поддерживаются как форма в кавычках "host=... dbname=...", так и форма URI postgres://user@host:5432/dbname.

--schema-name

Фильтровать индексы только из заданной схемы.

--table-name

Фильтруйте индексы только из заданной таблицы (используйте --schema-name, чтобы полностью квалифицировать таблицу).

--without-pkey

Перечислить только таблицы из исходной базы данных, если у них нет первичного ключа, прикрепленного к их схеме.

--filter <filename>

Эта опция позволяет пропускать объекты в операциях со списком. См. Фильтрация для получения подробной информации о ожидаемом формате файла и доступных вариантах фильтрации.

--list-skipped

Вместо перечисления объектов, которые выбраны для копирования фильтрами, установленными с помощью опции --filter, перечислите объекты, которые будут пропущены при использовании фильтров.

--summary

Вместо отображения текущего прогресса, когда команда все еще выполняется, отображайте сводку с деталями времени для каждого шага и для всех таблиц, индексов и ограничений.

Эта опция также требует опции --json: в данный момент поддерживается только этот формат вывода.

--json

Вывод команды форматируется в JSON, если поддерживается. В противном случае игнорируется.

--verbose

Увеличьте текущий уровень подробности. Уровень подробности по умолчанию - INFO. В порядке возрастания pgcopydb знает о следующих уровнях подробности: FATAL, ERROR, WARN, INFO, NOTICE, DEBUG, TRACE.

--debug

Установить текущий уровень подробности на уровень DEBUG.

--trace

Установить текущий уровень подробности на уровень TRACE.

--quiet

Установить текущий уровень подробности на уровень ERROR.

Окружение

PGCOPYDB_SOURCE_PGURI

Строка подключения к исходному экземпляру Postgres. Когда --source опущен в командной строке, используется эта переменная окружения.

Примеры

Перечисление таблиц:

$ 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

Список таблиц разделов COPY:

$ 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

Перечисление индексов:

$ 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)

Перечисление схемы в формате JSON:

$ pgcopydb list schema --split-at 200kB

Это дает следующий JSON-вывод:

{
    "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 stomer_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 stomer_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 stomer_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 stomer_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 stomer_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 tomer_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 e (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"
        }
    ]
}

Список текущего прогресса (строки журнала удалены):

$ pgcopydb list progress 2>/dev/null
             |  Total Count |  In Progress |         Done
-------------+--------------+--------------+-------------
      Tables |           21 |            4 |            7
     Indexes |           48 |           14 |            7

Перечисление текущего прогресса в формате JSON:

$ 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 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 для подробного примера использования pgcopydb stream sentinel set endpos.

Также команды pgcopydb stream setup и pgcopydb stream cleanup могут использоваться напрямую в обычных операциях. См. Пример захвата изменений данных 2 для подробного примера.

Эта команда добавляет префикс к следующим подкомандам:

pgcopydb stream: Stream changes from the source database

Available commands:
  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
    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: Maintain a sentinel table

Available commands:
  pgcopydb stream sentinel
    setup  Setup the sentinel table
    get    Get the sentinel table values
  + set    Set the sentinel table values
pgcopydb stream sentinel set: Set the sentinel table values

Available commands:
  pgcopydb stream sentinel set
    startpos  Set the sentinel start position LSN
    endpos    Set the sentinel end position LSN
    apply     Set the sentinel apply mode
    prefetch  Set the sentinel prefetch mode
pgcopydb stream sentinel setup: Setup the sentinel table
usage: pgcopydb stream sentinel setup <start lsn> <end lsn>

Эти команды реализуют часть всей операции воспроизведения базы данных, как подробно описано в разделе pgcopydb follow. Используйте эти команды только для отладки конкретной части или потому что вы знаете, что хотите реализовать только этот шаг.

Примечание

Подкоманды stream setup, затем stream prefetch и stream catchup являются командами более высокого уровня, которые используют внутреннюю информацию для определения, какие файлы обрабатывать. Эти команды также отслеживают свой прогресс.

Подкоманды stream receive, stream transform и stream apply являются интерфейсом более низкого уровня, который работает с заданными файлами. Эти команды все еще отслеживают свой прогресс, но им нужно предоставить больше информации для работы.

pgcopydb stream настройка

pgcopydb stream setup - Настроить исходные и целевые системы для логического декодирования

Команда pgcopydb stream setup подключается к целевой базе данных и создает источник репликации, расположенный на позиции LSN слота логической декодирующей репликации, который должен быть уже создан. См. pgcopydb snapshot, чтобы создать слот репликации и экспортировать снимок.

pgcopydb stream setup: Setup source and target systems for logical decoding
usage: pgcopydb stream setup

  --source                      Postgres URI to the source database
  --target                      Postgres URI to the target database
  --dir                         Work directory to use
  --restart                     Allow restarting when temp files exist already
  --resume                      Allow resuming operations after a failure
  --not-consistent              Allow taking a new snapshot on the source database
  --snapshot                    Use snapshot obtained with pg_export_snapshot
  --plugin                      Output plugin to use (test_decoding, wal2json)
  --wal2json-numeric-as-string  Print numeric data type as string when using wal2json output plugin
  --slot-name                   Stream changes recorded by this slot
  --origin                      Name of the Postgres replication origin

pgcopydb stream очистка

pgcopydb stream cleanup - очистка исходных и целевых систем для логического декодирования

Команда pgcopydb stream cleanup подключается к исходной и целевой базам данных для удаления объектов, созданных на этапе pgcopydb stream setup.

pgcopydb stream cleanup: Cleanup source and target systems for logical decoding
usage: pgcopydb stream cleanup

  --source         Postgres URI to the source database
  --target         Postgres URI to the target database
  --restart        Allow restarting when temp files exist already
  --resume         Allow resuming operations after a failure
  --not-consistent Allow taking a new snapshot on the source database
  --snapshot       Use snapshot obtained with pg_export_snapshot
  --slot-name      Stream changes recorded by this slot
  --origin         Name of the Postgres replication origin

pgcopydb stream предварительная выборка

pgcopydb stream prefetch - Потоковая передача изменений JSON из исходной базы данных и их преобразование в SQL

Команда pgcopydb stream prefetch подключается к исходной базе данных, используя протокол логической репликации и указанный слот репликации.

Команда предварительной выборки получает изменения из исходной базы данных в потоковом режиме и записывает их в серию JSON-файлов, названных так же, как их исходное имя файла WAL (с расширением .json). Каждый раз, когда JSON-файл закрывается, запускается подпроцесс для преобразования JSON в SQL-файл.

pgcopydb stream prefetch: Stream JSON changes from the source database and transform them to SQL
usage: pgcopydb stream prefetch

  --source         Postgres URI to the source database
  --dir            Work directory to use
  --restart        Allow restarting when temp files exist already
  --resume         Allow resuming operations after a failure
  --not-consistent Allow taking a new snapshot on the source database
  --slot-name      Stream changes recorded by this slot
  --endpos         LSN position where to stop receiving changes

pgcopydb stream догнать

pgcopydb stream catchup - Применить предварительно загруженные изменения из SQL файлов к целевой базе данных

Команда pgcopydb stream catchup подключается к целевой базе данных и применяет изменения из SQL файлов, которые были подготовлены с помощью команды pgcopydb stream prefetch.

pgcopydb stream catchup: Apply prefetched changes from SQL files to the target database
usage: pgcopydb stream catchup

  --source         Postgres URI to the source database
  --target         Postgres URI to the target database
  --dir            Work directory to use
  --restart        Allow restarting when temp files exist already
  --resume         Allow resuming operations after a failure
  --not-consistent Allow taking a new snapshot on the source database
  --slot-name      Stream changes recorded by this slot
  --endpos         LSN position where to stop receiving changes
  --origin         Name of the Postgres replication origin

pgcopydb stream replay

pgcopydb stream replay - Воспроизведение изменений из исходной базы данных в целевую базу данных в реальном времени

Команда pgcopydb stream replay подключается к исходной базе данных и передает изменения, используя протокол логического декодирования, и внутренне передает эти изменения в процесс преобразования, а затем в процесс воспроизведения, который подключается к целевой базе данных и применяет изменения SQL.

pgcopydb stream replay: Replay changes from the source to the target database, live
usage: pgcopydb stream replay

  --source         Postgres URI to the source database
  --target         Postgres URI to the target database
  --dir            Work directory to use
  --restart        Allow restarting when temp files exist already
  --resume         Allow resuming operations after a failure
  --not-consistent Allow taking a new snapshot on the source database
  --slot-name      Stream changes recorded by this slot
  --endpos         LSN position where to stop receiving changes
  --origin         Name of the Postgres replication origin

Эта команда эквивалентна выполнению следующего скрипта:

pgcopydb stream receive --to-stdout
| pgcopydb stream transform - -
| pgcopydb stream apply -

pgcopydb stream sentinel get

pgcopydb stream sentinel get - Получить значения таблицы sentinel

pgcopydb stream sentinel get: Get the sentinel table values
usage: pgcopydb stream sentinel get

  --json           Format the output using JSON
  --startpos       Get only the startpos value
  --endpos         Get only the endpos value
  --apply          Get only the apply value
  --write-lsn      Get only the write LSN value
  --flush-lsn      Get only the flush LSN value
  --replay-lsn     Get only the replay LSN value

pgcopydb stream sentinel set startpos

pgcopydb stream sentinel set startpos - Установить начальную позицию LSN для sentinel

pgcopydb stream sentinel set startpos: Set the sentinel start position LSN
usage: pgcopydb stream sentinel set startpos <start lsn>

Это продвинутый API, используемый для модульного тестирования и отладки, операция автоматически охвачена в обычных операциях pgcopydb.

Целевая система логической репликации регистрирует прогресс, присваивая текущий LSN узлу с именем --origin. При создании источника в целевой системе баз данных необходимо предоставить текущий LSN из исходной системы баз данных, чтобы правильно инициализировать логическое декодирование pgcopydb.

pgcopydb stream sentinel set endpos

pgcopydb stream sentinel set endpos - Установить конечную позицию LSN для sentinel

pgcopydb stream sentinel set endpos: Set the sentinel end position LSN
usage: pgcopydb stream sentinel set endpos [ --source ... ] [ <end lsn> | --current ]

  --source      Postgres URI to the source database
  --current     Use pg_current_wal_flush_lsn() as the endpos

Целевой LSN для логической репликации. Автоматически остановить репликацию и выйти с нормальным статусом выхода 0, когда получение достигнет указанного LSN. Если существует запись с LSN, точно равным lsn, запись будет выведена.

The --endpos опция не учитывает границы транзакций и может обрезать вывод на полпути через транзакцию. Любая частично выведенная транзакция не будет потреблена и будет воспроизведена снова при следующем чтении слота. Отдельные сообщения никогда не обрезаются.

См. также документацию для pg_recvlogical.

pgcopydb stream sentinel set apply

pgcopydb stream sentinel set apply - Установить режим применения sentinel

pgcopydb stream sentinel set apply: Set the sentinel apply mode
usage: pgcopydb stream sentinel set apply

pgcopydb stream sentinel set предварительная выборка

pgcopydb stream sentinel set prefetch - Установить режим предварительной выборки sentinel

pgcopydb stream sentinel set prefetch: Set the sentinel prefetch mode
usage: pgcopydb stream sentinel set prefetch

pgcopydb stream receive

pgcopydb stream receive - Потоковая передача изменений из исходной базы данных

Команда pgcopydb stream receive подключается к исходной базе данных, используя протокол логической репликации и указанный слот репликации.

Команда receive получает изменения из исходной базы данных в потоковом режиме и записывает их в серию JSON файлов, названных так же, как их исходное имя WAL файла (с .json расширением).

pgcopydb stream receive: Stream changes from the source database
usage: pgcopydb stream receive

  --source         Postgres URI to the source database
  --dir            Work directory to use
  --to-stdout      Stream logical decoding messages to stdout
  --restart        Allow restarting when temp files exist already
  --resume         Allow resuming operations after a failure
  --not-consistent Allow taking a new snapshot on the source database
  --slot-name      Stream changes recorded by this slot
  --endpos         LSN position where to stop receiving changes

pgcopydb stream transform

pgcopydb stream transform - Преобразование изменений из исходной базы данных в SQL команды

Команда pgcopydb stream transform преобразует JSON файл, полученный командой pgcopydb stream receive, в SQL файл с одним запросом на строку.

pgcopydb stream transform: Transform changes from the source database into SQL commands
usage: pgcopydb stream transform  <json filename> <sql filename>

  --target         Postgres URI to the target database
  --dir            Work directory to use
  --restart        Allow restarting when temp files exist already
  --resume         Allow resuming operations after a failure
  --not-consistent Allow taking a new snapshot on the source database

Команда поддерживает использование - в качестве имени файла для ввода JSON или вывода SQL, или для обоих. В этом случае чтение из стандартного ввода и/или запись в стандартный вывод осуществляется в потоковом режиме. Классический случай использования - это использование Unix Pipes, см. pgcopydb stream replay тоже.

pgcopydb stream применить

pgcopydb stream apply - Применить изменения из исходной базы данных в целевую базу данных

Команда pgcopydb stream apply применяет SQL файл, подготовленный командой pgcopydb stream transform в целевой базе данных. Процесс применения отслеживает прогресс благодаря API Postgres для Отслеживания Прогресса Репликации.

pgcopydb stream apply: Apply changes from the source database into the target database
usage: pgcopydb stream apply  <sql filename>

  --target         Postgres URI to the target database
  --dir            Work directory to use
  --restart        Allow restarting when temp files exist already
  --resume         Allow resuming operations after a failure
  --not-consistent Allow taking a new snapshot on the source database
  --origin         Name of the Postgres replication origin

Эта команда поддерживает использование - в качестве имени файла для чтения, и в этом случае читает из стандартного ввода в потоковом режиме.

Опции

Следующие параметры доступны для pgcopydb stream подкоманд:

--source

Строка подключения к исходному экземпляру Postgres. См. документацию Postgres для строк подключения для подробностей. Вкратце, поддерживаются как форма в кавычках "host=... dbname=...", так и форма URI postgres://user@host:5432/dbname.

--target

Строка подключения к целевому экземпляру Postgres.

--dir

Во время своей нормальной работы pgcopydb создает много временных файлов для отслеживания прогресса подпроцессов. Временные файлы создаются в каталоге, указанном в этой опции, или по умолчанию в ${TMPDIR}/pgcopydb, если установлена переменная окружения, или иначе в /tmp/pgcopydb.

Файлы захвата изменений данных хранятся в cdc подкаталоге опции --dir, если она указана, в противном случае см. переменную окружения XDG_DATA_HOME ниже.

--restart

При повторном запуске команды pgcopydb, если рабочий каталог уже содержит информацию от предыдущего запуска, то команда отказывается продолжать и удалять информацию, которая может быть использована для диагностики и криминалистики.

В этом случае можно использовать опцию --restart, чтобы позволить pgcopydb удалить следы от предыдущего запуска.

--resume

Когда команда pgcopydb была завершена до завершения, либо из-за сигнала прерывания (например, C-c или SIGTERM), либо из-за сбоя, возможно возобновить миграцию базы данных.

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

--plugin

Плагин вывода логического декодирования для использования. По умолчанию это test_decoding, который поставляется с самим ядром Postgres, поэтому, вероятно, уже доступен на вашем исходном сервере.

Возможно использовать 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

Имя слота логического декодирования для использования.

--origin

Целевой системе логической репликации необходимо отслеживать транзакции, которые уже были применены, чтобы в случае разрыва соединения или необходимости возобновления операций мы могли пропустить уже воспроизведенные транзакции.

Postgres использует понятие имени исходного узла, как описано в Отслеживание прогресса репликации. Эта опция позволяет выбрать собственное имя узла и по умолчанию устанавливается в “pgcopydb”. Выбор другого имени полезен в некоторых сложных сценариях, таких как миграция нескольких источников в одну и ту же цель, где каждый источник должен иметь свое уникальное имя исходного узла.

--verbose

Увеличьте текущий уровень подробности. Уровень подробности по умолчанию - INFO. В порядке возрастания pgcopydb знает о следующих уровнях подробности: FATAL, ERROR, WARN, INFO, NOTICE, DEBUG, TRACE.

--debug

Установить текущий уровень подробности на уровень DEBUG.

--trace

Установить текущий уровень подробности на уровень TRACE.

--quiet

Установить текущий уровень подробности на уровень ERROR.

Окружение

PGCOPYDB_SOURCE_PGURI

Строка подключения к исходному экземпляру Postgres. Когда --source опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_TARGET_PGURI

Строка подключения к целевому экземпляру Postgres. Когда --target опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_OUTPUT_PLUGIN

Плагин вывода логического декодирования для использования. Когда --plugin опущен в командной строке, используется эта переменная окружения.

PGCOPYDB_WAL2JSON_NUMERIC_AS_STRING

Когда true (или yes, или on, или 1, тот же ввод, что и у Postgres boolean), тогда pgcopydb использует опцию wal2json --numeric-data-types-as-string при использовании плагина вывода wal2json.

Когда --wal2json-numeric-as-string опущен в командной строке, используется эта переменная окружения.

TMPDIR

Команда pgcopydb создает все свои рабочие файлы и каталоги в ${TMPDIR}/pgcopydb, и по умолчанию в /tmp/pgcopydb.

XDG_DATA_HOME

Команда pgcopydb создает файлы Change Data Capture в стандартном месте XDG_DATA_HOME, которое по умолчанию ~/.local/share. См. Спецификация базового каталога XDG.

Примеры

В качестве примера здесь приведен вывод, сгенерированный при запуске тестового случая cdc, где слот репликации создается до начального копирования данных, а затем выполняется следующий оператор INSERT:

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 был извлечен вызовом pg_current_wal_lsn() 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, потому что каждый запуск создает разные, и захваты не все сделаны из одного и того же запуска.

$ 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

А полученный 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 configuration

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

Фильтрация

Фильтрация позволяет пропускать некоторые определения объектов и данные при копировании из исходной базы данных в целевую. Команды pgcopydb, которые принимают опцию --filter (или --filters), ожидают существующее имя файла в качестве аргумента опции. Указанное имя файла читается в формате INI файла, но используются только секции и ключи опций. Значения опций не используются.

Вот пример конфигурации фильтра на основе включения:

[include-only-table]
public.allcols
public.csv
public.serial
public.xzero

[exclude-index]
public.foo_gin_tsvector

[exclude-table-data]
public.csv

Вот пример конфигурации фильтра на основе исключений:

[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

Фильтрация может быть выполнена с помощью pgcopydb, используя следующие правила, которые также являются названиями разделов файла INI.

include-only-table

Этот раздел позволяет перечислить исключительный список исходных таблиц для копирования в целевую базу данных. Никакие другие таблицы не будут обрабатываться pgcopydb.

Каждая строка в этом разделе должна быть именем таблицы с указанием схемы. Правила экранирования идентификаторов Postgres могут быть использованы для избежания неоднозначности.

Когда используется секция include-only-table в конфигурации фильтрации, секции exclude-schema и exclude-table запрещены. Мы не будем знать, как обрабатывать таблицы, которые существуют в исходной базе данных и не являются частью какого-либо фильтра.

NOTE: Материализованные представления также считаются таблицами при фильтрации.

exclude-schema

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

Этот раздел не разрешен, когда используется раздел include-only-table.

include-only-schema

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

Несмотря на название, этот раздел является фильтром исключения.

Этот раздел не разрешен, когда используется раздел exclude-schema.

exclude-table

Этот раздел позволяет добавить список квалифицированных имен таблиц в фильтры исключения. Все таблицы, которые перечислены в разделе exclude-table, будут игнорироваться командой pgcopydb.

Этот раздел не разрешен, когда используется раздел include-only-table.

NOTE: Материализованные представления также считаются таблицами при фильтрации.

exclude-index

Этот раздел позволяет добавить список квалифицированных имен индексов в фильтры исключения. Это позволяет pgcopydb работать с таблицей и пропускать одно определение индекса, которое принадлежит таблице, которая все еще обрабатывается.

exclude-table-data

Этот раздел позволяет пропустить копирование данных из списка квалифицированных имен таблиц. Схема, индекс, ограничения и т.д. таблицы все равно копируются.

NOTE: Материализованные представления также считаются таблицами при фильтрации.

Рецензирование и отладка фильтров

Фильтрация архивного файла pg_restore осуществляется путем переписывания каталога архива, полученного с помощью pg_restore --list. Это иногда немного хакерский метод, и нам также приходится иметь дело с зависимостями в самом pgcopydb.

Следующие команды можно использовать для изучения набора правил фильтрации: