Миграция PostgreSQL под ОС AstraLinux c использованием pgcopydb с PG11 на PG15

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

Многие в настоящее время сталкиваются с необходимостью миграции с AstraLinux 1.7 на AstraLinux 1.8.

Для тех, кто пользуется штатной PostgreSQL 11 из поставки AstraLinux 1.7, встает во весь рост вопрос, как перетащить существующие базы на новую версию. Если базы маленькие, особых проблем нет. А вот если базу под 1ТБ, то проблемы встают в полный рост.

Для штатной pg_upgrade требуются обе версии (PostgreSQL-11 и PostgreSQL-15). Но в поставке AstraLinux 1.8 нет PostgreSQL 11! При этом, так как Astra PostgreSQL не совместим бинарно с "Ванилью", то и не получится собрать самому нужную версию для Astra 1.8.

"Вкорячить" его из поставки Astra 1.7 можно, но не гарантирует работоспособность. (Напишу заметку об этом позже).

Штатный pg_dump | pg_restore в одну нитку, для базы 1.1 Тб у нас на стенде работал аж 27 часов. Максимальный размер технологического окна при этом установлен 24 часа.

Поиск решения (помимо логической репликации), навел на утилиту pgcopydb

Для начала засады:

1) в Astra1.8 в PostgreSQL уменьшили длину типа name с 255 байт до 63.

https://docs.astralinux.ru/latest/guide/application/devfeature/

Поэтому, при использовании длинных идентификаторов (имен) возникают ошибки при pg_dump15/pg_restore15 при работе с PostgreSQL-11. При этом утилиты pg11 без проблем работают с PostgreSQL-15.

Из-за этого, для миграции с использованием pgcopydb его нужно собирать именно на astra1.7.

2)  pgcopydb не понимает MAC LABEL SECURITY

3) PG12+: больше не поддерживается созданием таблиц с кляузой "WITH OIDS"

Ранее в таблицу можно было добавить столбец oid (невидимый в обычных запросах), создавая её с указанием WITH OIDS; теперь такой возможности нет. При этом по-прежнему возможно создавать столбцы с типом oid. С учётом этого изменения порядок использования таблиц, созданных с указанием WITH OIDS, потребуется скорректировать.

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

Сборка pgcopydb

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

apt-get install -y --no-install-recommends \
  git \
  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

git clone https://github.com/dimitri/pgcopydb

cd pgcopydb
make

Инсталляция pgcopydb на другую машину

Для инсталляции нужен только сам исполняемый файл pgcopydb и библиотека libgc.so.1

## Скопировать полученный файл на нужную машину
scp src/bin/pgcopydb/pgcopydb targethost:bin/ 

## разрешить установку права запуска для файлов
sudo astra-nochmodx-lock disable

## добавляем возможность запуска
chmod 0755 pgcopydb

## доставить библиотеку libgc.so.1
apt install libgc1c2

Так, как pgcopydb не понимает MAC LABEL SECURITY, ставим обертку для pg_dump, pg_restore, pg_dumpall

cd /usr/lib/postgresql/11/bin

mv pg_dump pg_dump.bin
mv pg_dumpall pg_dumpall.bin
mv pg_restore pg_restore.bin

## добавляем опции отключающие MAC LABEL
echo "/usr/lib/postgresql/11/bin/pg_dump.bin --no-security-labels --disable-macs $@" > pg_dump
echo "/usr/lib/postgresql/11/bin/pg_dumpbin.bin --no-security-labels $@" > pg_dumpall
echo "/usr/lib/postgresql/11/bin/pg_restore.bin --no-security-labels $@" > pg_restore
chmod 0755 pg_dump pg_dumpall pg_restore

Подготовка исходной базы

Правим длинные имена

получить список объектов для поля типа name > 63 bytes

Для этого тупо генерируем запросы select ... from object where length(name) > 63 для всех объектов где есть поле name, и выполняем полученный tmp.sql в отдельном шаге.

Готовим файл запроса полей name и формирования запросов к каждой такой таблице (файл q1.sql):

select
  'SELECT '''||table_schema||'.'||table_name||'.'||column_name||': ''||'|| column_name || 

  ' FROM "'||table_schema||'"."'||table_name||'" WHERE '||'length("'||column_name||'") > 63;' 
from information_schema.columns
where
data_type = 'name'
;

Выполняем следующую команду:

## для каждой базы, формируем tmp.sql и потом выполняем его для получения списка объектов
psql -AXtc "select datname from pg_database"|while read db 
 do echo "==== $db =====";
 psql -AXt -d $db -f q1.sql > tmp.sql
 psql -d $db -AtX -f tmp.sql > $db.txt
done

Передаем полученный список разработчикам, чтобы убрали длинные имена.

Правим "WITH OIDS" у таблиц

Получаем команды для правки таблиц

-- генерация команд для правки таблиц
 
SELECT 'ALTER TABLE "' || n.nspname || '"."' || c.relname || '" SET WITHOUT OIDS;'
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE 1=1
  AND c.relkind = 'r'
  AND c.relhasoids = true
  AND n.nspname <> 'pg_catalog'
order by n.nspname, c.relname;
 
-- выполняем полученные команды, например
test=# ALTER TABLE "abc"."recipients_m11" SET WITHOUT OIDS;
ALTER TABLE
test=#  ALTER TABLE "abc"."config_m11" SET WITHOUT OIDS;
ALTER TABLE
test=#  ALTER TABLE "abc"."data_m11" SET WITHOUT OIDS;

Подготовка целевой базы

Тут все просто, шаги те же что и для обычного pg_dump/pg_restore

например:

создаем базу с нужным owner

переносим роли и extension

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

Можно запускать pgcopydb для миграции

export PGCOPYDB_SOURCE_PGURI="postgres://user@source.host.dev/dbname"
export PGCOPYDB_TARGET_PGURI="postgres://role@target.host.dev/dbname"

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

Источник: https://habr.com/ru/articles/882192/


Интересные статьи

Интересные статьи

В современных непростых условиях на фоне существующих внешних вызовов процесс импортозамещения в России приобретает особую важность. Предлагаем вам познакомиться с опытом по импортозамещению АО ...
В данной пошаговой инструкции мы подробно опишем весь процесс получения доступа к WhatsApp Business API через официального партнера Facebook — сервис Gupshup и подключени...
Всем привет! Не так давно на работе в рамках тестирования нового бизнес-процесса мне понадобилась возможность авторизации под разными пользователями. Переход в соответствующий р...