Миграция PostgreSQL 16.14 и TimescaleDB 2.27.1

Процедура обновления базы данных PostgreSQL с версии 16.3 до 16.14 и расширения TimescaleDB с 2.15.2 до 2.27.1 в контейнеризированной среде Docker. Миграция разделена на два этапа:

  1. Обновление компонентов внутри работающего контейнера PostgreSQL до целевых версий (16.14 и 2.27.1) без удаления данных.

  2. Полная миграция данных в новый контейнер на базе образа с требуемыми версиями.

Подготовка

  • Контейнер PostgreSQL: unidata-dg-deploy-postgres-dg-1.

  • Том данных: unidata-dg-deploy_dg-postgres-data.

  • Целевой образ: docker.universe-data.ru/mirror/postgres16.14-tsdb2.27.1.

  • На первом этапе действующий контейнер обновляется до версий PostgreSQL 16.14 и TimescaleDB 2.27.1 - это необходимый шаг перед заменой контейнера.

  • В зависимости от версии Docker Compose могут использоваться команды docker-compose или docker compose - скорректируйте скрипты под ваше окружение.

  • Для загрузки пакетов TimescaleDB необходим доступ к ресурсу packagecloud.io. При ограниченном прямом доступе используйте сетевые инструменты, доступные в вашей инфраструктуре.

Этап 1: Обновление PostgreSQL и TimescaleDB внутри существующего контейнера

На этом этапе версии пакетов повышаются без удаления контейнера и тома данных.

Автоматический способ (скрипт up_pgts.sh):

 #!/bin/bash

CONTAINER=unidata-dg-deploy-postgres-dg-1

echo "== Upgrade PostgreSQL packages =="

docker exec -i $CONTAINER bash -c "
set -e

apt-get update
apt-get install -y \
postgresql-16=16.14-1.pgdg12+1 \
postgresql-client-16=16.14-1.pgdg12+1 \
libpq5=16.14-1.pgdg12+1 \
libllvm19

echo '== Download TimescaleDB 2.27.1 =='

wget -q https://packagecloud.io/timescale/timescaledb/packages/debian/bookworm/timescaledb-2-postgresql-16_2.27.1~debian12-1614_amd64.deb/download.deb -O /tmp/ts.deb
wget -q https://packagecloud.io/timescale/timescaledb/packages/debian/bookworm/timescaledb-2-loader-postgresql-16_2.27.1~debian12-1614_amd64.deb/download.deb -O /tmp/ts-loader.deb

echo '== Install TimescaleDB =='

apt-get install -y /tmp/ts-loader.deb /tmp/ts.deb
"

echo "== Restart container =="
docker restart $CONTAINER

sleep 15

echo "== Run extension upgrade =="
docker exec -i $CONTAINER \
  psql -U postgres -d postgres -X \
  -c "ALTER EXTENSION timescaledb UPDATE;"

echo "== Final restart =="
docker restart $CONTAINER

sleep 15

echo "== CHECK VERSIONS =="

docker exec -i $CONTAINER \
  psql -U postgres -d postgres -c "SELECT version();"

docker exec -i $CONTAINER \
  psql -U postgres -d postgres -c "SELECT extversion FROM pg_extension WHERE extname='timescaledb';"

echo "== DONE =="

Ручной способ:

  1. Подключитесь к контейнеру PostgreSQL:

    docker exec -it unidata-dg-deploy-postgres-dg-1 bash
    
  2. Выполните обновление пакетов:

    apt-get update
    apt-get install -y \
    postgresql-16=16.14-1.pgdg12+1 \
    postgresql-client-16=16.14-1.pgdg12+1 \
    libpq5=16.14-1.pgdg12+1 \
    libllvm19
    
    wget -q https://packagecloud.io/timescale/timescaledb/packages/debian/bookworm/timescaledb-2-postgresql-16_2.27.1~debian12-1614_amd64.deb/download.deb -O /tmp/ts.deb
    wget -q https://packagecloud.io/timescale/timescaledb/packages/debian/bookworm/timescaledb-2-loader-postgresql-16_2.27.1~debian12-1614_amd64.deb/download.deb -O /tmp/ts-loader.deb
    
    apt-get install -y /tmp/ts-loader.deb /tmp/ts.deb
    
  3. Выйдите из контейнера (exit) и перезапустите его:

    docker restart unidata-dg-deploy-postgres-dg-1
    
  4. Обновите расширение TimescaleDB:

    docker exec -i unidata-dg-deploy-postgres-dg-1 \
      psql -U postgres -d postgres -X \
      -c "ALTER EXTENSION timescaledb UPDATE;"
    
  5. Повторно перезапустите контейнер:

    docker restart unidata-dg-deploy-postgres-dg-1
    
  6. Проверьте итоговые версии:

    docker exec -it unidata-dg-deploy-postgres-dg-1 psql -U postgres -d postgres -c "SELECT version();"
    docker exec -it unidata-dg-deploy-postgres-dg-1 psql -U postgres -d postgres -c "SELECT extversion FROM pg_extension WHERE extname='timescaledb';"
    

    Ожидаемый результат: PostgreSQL 16.14 и TimescaleDB 2.27.1.

Этап 2: Полная миграция с заменой контейнера

На этом этапе создается резервная копия данных, старый контейнер заменяется на новый с целевым образом, и данные восстанавливаются.

Автоматический способ (скрипт up_pgts_2.sh):

#!/bin/bash
set -e

CONTAINER=unidata-dg-deploy-postgres-dg-1
DUMP_FILE=backup.dump
VOLUME=unidata-dg-deploy_dg-postgres-data
COMPOSE_FILE=docker-compose.yml

echo "== 0. Проверка окружения =="
docker ps >/dev/null

echo "== 1. Делаем бекап БД =="

docker exec -t $CONTAINER \
  pg_dump -U postgres -d postgres \
  -Fc -b -v -f /$DUMP_FILE

echo "== 2. Копируем бекап на хост =="

docker cp $CONTAINER:/$DUMP_FILE ./$DUMP_FILE

if [ ! -f "$DUMP_FILE" ]; then
  echo "Бекап не найден!"
  exit 1
fi

echo "== 3. Останавливаем контейнеры =="

docker-compose down

echo "== 4. Удаляем volume =="

docker volume rm $VOLUME || true

echo "== 4.1 Правим docker-compose.yml =="

cp $COMPOSE_FILE ${COMPOSE_FILE}.bak

# Меняем образ
sed -i \
  "s|postgres16.3-tsdb2.15.2|postgres16.14-tsdb2.27.1|g" \
  $COMPOSE_FILE

echo "== docker-compose.yml обновлен =="

echo "== 5. Поднимаем только PostgreSQL =="

docker-compose up -d postgres-dg

echo "== Ждем запуск PostgreSQL =="
sleep 10

echo "== 6. Создаем extension =="

docker exec -i $CONTAINER \
  psql -U postgres -d postgres \
  -c "CREATE EXTENSION IF NOT EXISTS timescaledb;"

echo "== 7. Копируем дамп в контейнер =="

docker cp ./$DUMP_FILE $CONTAINER:/$DUMP_FILE

echo "== 8. Восстанавливаем БД =="

docker exec -i $CONTAINER \
  pg_restore -U postgres -d postgres \
  --no-owner --no-privileges \
  --disable-triggers \
  -v /$DUMP_FILE

echo "== 9. Проверка PostgreSQL =="

docker exec -i $CONTAINER \
  psql -U postgres -d postgres \
  -c "SELECT version();"

echo "== 10. Проверка TimescaleDB =="

docker exec -i $CONTAINER \
  psql -U postgres -d postgres \
  -c "SELECT extversion FROM pg_extension WHERE extname='timescaledb';"

echo "== Миграция завершена успешно =="

Ручной способ:

  1. Остановите все сервисы, кроме PostgreSQL.

  2. Создайте резервную копию базы данных:

    docker exec -t unidata-dg-deploy-postgres-dg-1 pg_dump -U postgres -d postgres -Fc -b -v -f /backup.dump
    
  3. Скопируйте файл дампа на хост:

    docker cp unidata-dg-deploy-postgres-dg-1:/backup.dump ./backup.dump
    
  4. Остановите все контейнеры и удалите старый том данных:

    docker-compose down
    docker volume rm unidata-dg-deploy_dg-postgres-data
    
  5. В файле docker-compose.yml замените образ PostgreSQL на новый:

    image: docker.universe-data.ru/mirror/postgres16.14-tsdb2.27.1
    
  6. Запустите только контейнер PostgreSQL:

    docker-compose up -d postgres-dg
    
  7. Создайте расширение timescaledb в новой базе:

    docker exec -it unidata-dg-deploy-postgres-dg-1 psql -U postgres -d postgres -c "CREATE EXTENSION IF NOT EXISTS timescaledb;"
    
  8. Скопируйте дамп внутрь контейнера:

    docker cp ./backup.dump unidata-dg-deploy-postgres-dg-1:/backup.dump
    
  9. Восстановите базу из дампа:

    docker exec -i unidata-dg-deploy-postgres-dg-1 pg_restore -U postgres -d postgres --no-owner --no-privileges --disable-triggers -v /backup.dump
    
  10. Убедитесь, что в логах восстановления нет ошибок, и проверьте версии:

    docker exec -it unidata-dg-deploy-postgres-dg-1 psql -U postgres -d postgres -c "SELECT version();"
    docker exec -it unidata-dg-deploy-postgres-dg-1 psql -U postgres -d postgres -c "SELECT extversion FROM pg_extension WHERE extname='timescaledb';"
    
  11. Проверьте работоспособность платформы.