Недавно один из наших клиентов обратился к нам с одной интересной задачей: ему нужно было перенести весь свой кластер PostgreSQL с DBaaS (Database as a Service) на дроплет в рамках DigitalOcean. Причиной их перехода с DBaaS на дроплеты была их более низкая стоимость. Эта задача оказалась довольно сложной, поскольку в документации DigitalOcean четко сказано, что “в настоящее время мы не поддерживаем миграцию баз данных из одних кластеров DigitalOcean в другие кластеры в рамках DigitalOcean”.
Короче говоря, нам нужно было переносить базу данных своими силами, и мы предоставили клиенту два варианта решения этой задачи:
-
pg_dump
-
Логическая репликация
Метод с pg_dump предполагает определенный период простоя, так как мы должны создать дамп, а затем восстановить его на новом сервере. Логическая репликация же оставляет исходную базу данных в рабочем состоянии пока данные копируются в новую базу данных. Как только мы достигнем желаемого состояния, мы можем переключиться на новую базу данных.
Для миграции с помощью логической репликации все таблицы, которые необходимо реплицировать, должны иметь первичный или уникальный ключ.
Предварительные требования для миграции
Чтобы перенести существующую базу данных в кластер базы данных DigitalOcean, нам необходимо убедиться, что в исходной базе данных включена логическая репликация, получить учетные данные для подключения к исходной базы данных и отключить или обновить любые файрволы между базами данных.
Получить Root-права: Для подготовки базы данных к миграции и для проведения самой миграции нам нужны root-права в исходной базе данных.
Сделать базу данных общедоступной: Для миграции базы данных имя хоста или IP-адрес исходной базы данных должны быть доступны из публичного интернета. Информация о публичном подключении к базам данных DigitalOcean находится в разделе “Connection Details” на панели управления базой данных.
Разрешить удаленные подключения: Во-первых, убедитесь, что база данных разрешает все удаленные подключения. Это определяется переменной базы данных listen_addresses, которая разрешает все удаленные подключения, если ее значение равно. Чтобы проверить ее текущее значение, выполните в терминале PostgreSQL (psql) следующий запрос:
SHOW listen_addresses; If enabled, the command line returns: listen_addresses ----------- * (1 row)
Если ваш результат будет другим, вы можете разрешить удаленные подключения в вашей базе данных, выполнив следующий запрос:
ALTER SYSTEM SET listen_addresses = '*';
Мы также должны изменить ваше локальное IPv4-соединение, чтобы разрешить все входящие IP-адреса. Для этого вам нужно найти файл конфигурации pg_hba.conf с помощью следующего запросом:
SHOW hba_file;
Откройте pg_hba.conf в текстовом редакторе по вашему выбору, например, nano: nano pg_hba.conf
В разделе “IPv4 local connections” найдите и замените IP-адрес на 0.0.0.0/0, что разрешат все IPv4-адреса:
# TYPE DATABASE USER ADDRESS METHOD # IPv4 local connections: host all all 0.0.0.0/0 md5 # IPv6 local connections: host all all ::/0 md5
Включение логической репликации
У большинства поставщиков облачных баз данных логическая репликация включена по умолчанию. Логическая репликация может быть не включена, если вы переносите базу данных с локального сервера. Если ваша база данных не подготовлена для логической репликации, то процесс миграции не будет работать, поскольку база данных может перемещать только ваши схемы, а не сами данные.
Чтобы убедиться, что логическая репликация включена, выполните следующий запрос в терминале PostgreSQL (psql):
show wal_level; If enabled, the output returns: wal_level ----------- logical (1 row) If the output is different, enable logical replication in your database by setting wal_level to logical: ALTER SYSTEM SET wal_level = logical;
Изменение максимального количества слотов репликации
После включения логической репликации нам нужно убедиться, что значение max_replication_slots вашей базы данных равно или превышает количество баз данных на вашем PostgreSQL сервере. Чтобы проверить текущее значение, выполните следующий запрос в терминале PostgreSQL (psql):
show max_replication_slots;
Вывод будет выглядеть следующим образом:
max_replication_slots ----------- (1 row)
Если это значение меньше, чем количество баз данных на нашем PostgreSQL сервере, измените его, выполнив следующий запрос, где use_your_number — это количество баз данных на нашем сервере:
ALTER SYSTEM SET max_replication_slots = use_your_number;
И перезагрузите сервер.
Проблемы, с которыми мы можем столкнуться во время миграции
Когда мы реализуем логическую репликацию без первичного ключа, мы можем столкнуться с некоторыми проблемами. Существует два разных метода реализации логической репликации без столбца с первичным ключом, один из которых — с использованием уникального ключа.
Этот метод реализуется с помощью того же самого набора шагов, который мы собираемся здесь выполнить. Его технические аспекты также аналогичны. Просто вместо первичного ключа обновления будут происходить по уникальному ключу.
Предостережения
-
Он не поддерживает DELETE/UPDATE без репликационного идентификатора.
-
Уникальный индекс нельзя использовать с репликационным идентификатором, если разрешены NULL-значения.
-
Используется REPLICA IDENTITY FULL.
-
Если для репликационного идентификатора не найден подходящий индекс, мы можем установить для него значение FULL. В этом случае все столбцы таблицы коллективно выступают в роли первичного ключа.
-
Из-за дополнительного логирования создается огромное количество WAL.
-
Этот метод может быть медленнее, чем традиционный.
Что следует учитывать
И так, нам нужно установить репликационный идентификатор FULL для таблиц, которые переносятся логически только по UNIQUE ключу, иначе DELETE/UPDATE не будет поддерживаться.
После того, как данные из форка DBaaS будут синхронизированы на новую виртуальную машину на дроплете, нам нужно выполнить методы pg_dump и pg_restore для последовательностей. У вас может возникнуть вопрос: зачем нам дамп последовательности и почему мы не можем реплицировать ее с помощью логической репликации?
Логическая репликация предназначена отслеживания изменений WAL и информирования подписчиков о текущих состояниях и значениях. Было бы довольно противоречиво реплицировать последовательность, потому что текущее значение последовательности не равно значению, хранящемуся в WAL. Чтобы компенсировать это, документация PostgreSQL предлагает вручную скопировать значения последовательности или использовать для копирования такую утилиту, как pg_dump.
-
Сделайте дамп последовательностей из форка БД DBaaS
-
Остановите форк БД DBaaS
-
Восстановите последовательности на новом дроплете
-
Отключите логические подписки
Ниже приведен краткий обзор того, что было сделано для миграции среды:
Исходный кластер: DBasS Digital Ocean
Место назначения: дроплеты Digital Ocean
Процесс:
-
Клиент выбрал миграцию посредством логической репликации, чтобы сократить время простоя.
-
На целевой виртуальной машине мы установили дистрибутив Percona для PostgreSQL 13.7.
-
Перенесли в место назначения роли из исходного кластера, т.е. DBasS.
-
Сформировали список таблиц, у которых нет первичного ключа, и проинформировал их.
-
Для некоторых таблиц клиент добавил первичный ключ, а для остальных таблиц сформировал уникальный ключ.
-
Установили на виртуальную машину расширения, которые были в исходном кластере.
-
Сформировали дамп схемы из исходного кластера, т.е. DBasS.
-
Восстановили схему на месте назначения, т.е. на дроплетых.
-
Скорректировали в исходном кластере и месте назначения параметры, связанные с логической репликацией, такие как max_replication_slots, max_logical_replication_workers и max_wal_senders.
-
Настроили логическую репликацию, создав публикацию и подписку между исходным кластером и местом назначения.
-
Как только место назначения было синхронизировано, отключили подписчиков.
-
Сформировали дамп последовательностей из исходного кластера и восстановили их в месте назначения.
-
Скорректировали файлы listen_address, pg_hba на месте назначения.
-
Сбросили подписчиков на месте назначения.
Заключение
Как мы все знаем, PostgreSQL — это объектно-реляционная система управления базами данных с открытым исходным кодом, созданная с упором на расширяемость, скорость и целостность данных. Ее поддержка параллелизма делает ее полностью совместимой с ACID. Мы смогли реализовать миграцию данных клиентов с DBasS на дроплеты, используя одну из замечательных фич PostgreSQL, то есть логическую репликацию. Мы также смогли сформировать дамп последовательностей из исходного кластера и восстановить их на месте назначения.
В заключение статьи приглашаем всех желающих на открытое занятие «Автоматизация развертывания на кластера PostgreSQL на базе Patroni в Kubernetes», которое пройдет в рамках онлайн-курса «PostgreSQL Cloud Solutions».
На этом открытом уроке будет разыграна книга руководителя курса Евгения Аристова — «PostgreSQL 14. Оптимизация, Kubernetes, кластера, облака».
ссылка на оригинал статьи https://habr.com/ru/articles/725606/
Добавить комментарий