> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bedolagam.ru/llms.txt
> Use this file to discover all available pages before exploring further.

# Обновление PostgreSQL 15 → 18

> Перенос базы бота на PostgreSQL 18 одной командой — с резервной копией, сверкой данных и откатом

Бот перешёл с PostgreSQL 15 на PostgreSQL 18. У PostgreSQL 15 поддержка заканчивается в ноябре 2027 года, у 18 — в ноябре 2030-го.

Данные PostgreSQL 15 нельзя просто открыть в PostgreSQL 18 — их нужно перенести. Для этого в боте есть команда `make pg-upgrade`: она делает всё сама и ничего не удаляет.

<Info>
  **Новая установка?** Ничего делать не нужно: `docker compose up -d` сразу поднимет PostgreSQL 18.
</Info>

## Как понять, что вам нужно обновление

Обновление нужно, если бот уже работал у вас на PostgreSQL 15, а в `docker-compose.yml` после `git pull` стоит `image: postgres:18-alpine`.

Если после обновления бот не запускается, а в логах базы (`docker compose logs postgres`) такое сообщение:

```text theme={null}
PostgreSQL не запущен: база ещё на PostgreSQL 15.
...
    make pg-upgrade
```

— это защита, а не поломка. Без неё PostgreSQL 18 молча создал бы пустую базу, и выглядело бы так, будто пропали все пользователи и подписки. Ваши данные целы в старом томе — выполните перенос.

## Перенос

<Steps>
  <Step title="Обновите бота">
    ```bash theme={null}
    cd /opt/remnawave-bedolaga-telegram-bot   # папка, где лежит бот
    git pull
    ```
  </Step>

  <Step title="Запустите перенос">
    ```bash theme={null}
    make pg-upgrade
    ```

    Если `make` не установлен: `bash scripts/pg-upgrade.sh`.

    Скрипт покажет, что собирается сделать — какие тома, какая база, сколько данных, — и попросит подтверждения. Ответьте `y`.
  </Step>

  <Step title="Дождитесь «✅ Готово»">
    Бот будет остановлен на время переноса — обычно минута-другая, на больших базах дольше. В конце скрипт сам соберёт и запустит бота и напечатает, где лежит резервная копия и как откатиться.
  </Step>
</Steps>

<Tip>
  Бота заранее останавливать не нужно — скрипт сделает это сам. Для запуска без вопросов (например, из автоматизации): `make pg-upgrade ARGS=--yes`.
</Tip>

### Что делает `make pg-upgrade`

1. Проверяет, что места на диске хватит на резервную копию и новую базу.
2. Останавливает бота и базу, чтобы во время переноса никто не писал в базу.
3. Снимает полную резервную копию в `backups/postgres-upgrade-<дата>/` и проверяет, что она читается.
4. Запоминает, сколько строк в каждой таблице и какие значения у счётчиков.
5. Разворачивает PostgreSQL 18 в **новом** томе и восстанавливает туда копию.
6. Сверяет строки и счётчики один в один. Если хоть что-то не сошлось — новый том удаляется, и всё остаётся как было.
7. Запускает базу на PostgreSQL 18, ещё раз сверяет данные, затем собирает и запускает бота.

Старый том с PostgreSQL 15 (`<проект>_postgres_data`) **не удаляется и не меняется** — это ваш откат.

Запускать повторно безопасно: если перенос уже сделан, скрипт напишет «Перенос уже выполнен» и ничего не тронет.

### Параметры

| Параметр | Что делает |
| - | - |
| `--yes` | Не спрашивать подтверждение |
| `--no-bot` | После переноса запустить только базу, без бота. Бота потом: `docker compose up -d --build` |

Через `make` параметры передаются так: `make pg-upgrade ARGS="--yes --no-bot"`.

## Откат на PostgreSQL 15

Если после перехода что-то не так:

```bash theme={null}
docker compose down
git checkout <прошлая версия бота> -- docker-compose.yml
docker compose up -d
```

Бот вернётся на старую базу в том виде, в каком она была в момент переноса.

<Warning>
  Всё, что изменилось после переноса (новые пользователи, платежи), при откате на старый том не сохранится.
</Warning>

## Когда всё работает

Через неделю-другую, убедившись, что всё в порядке, можно освободить место на диске:

```bash theme={null}
docker volume rm <проект>_postgres_data      # старая база PostgreSQL 15
rm -rf backups/postgres-upgrade-*            # резервные копии перед переносом
```

Точные имена тома и папки с копией скрипт печатает в конце работы.

<Warning>
  В папке `backups/` лежат дампы базы с хэшами паролей. Она доступна только владельцу — не выкладывайте её никуда и не копируйте на общедоступные ресурсы.
</Warning>

## Если что-то пошло не так

<AccordionGroup>
  <Accordion title="«Мало места для Docker» или «Мало места для резервной копии»">
    Скрипт проверяет место до начала переноса и ничего не меняет, если его не хватает. Освободите диск (например, `docker system prune` удаляет неиспользуемые образы) и запустите `make pg-upgrade` ещё раз.
  </Accordion>

  <Accordion title="«Пользователь ... не найден в старой базе»">
    Значит, `POSTGRES_USER` в `.env` изменили после установки бота. Верните в `.env` значение, с которым база создавалась, и запустите перенос ещё раз.
  </Accordion>

  <Accordion title="«После восстановления база не совпадает с исходной»">
    Перенос остановлен, новый том удалён, старая база не тронута. Подробности расхождения — в файле `*.diff.txt` в папке резервной копии. Пришлите его в чат поддержки.
  </Accordion>

  <Accordion title="Перенос прервался (обрыв SSH, перезагрузка сервера)">
    Старая база не тронута. Недоделанный новый том скрипт удаляет сам; если прерывание было жёстким, просто запустите `make pg-upgrade` ещё раз.
  </Accordion>

  <Accordion title="Бот не запустился после «✅ Готово»">
    База перенесена и сверена. Посмотрите логи бота: `docker compose logs bot`. Запустить вручную: `docker compose up -d --build`.
  </Accordion>
</AccordionGroup>

## Свои установки

* **Свой `docker-compose.yml` или `docker-compose.override.yml`.** Образ `postgres:18` хранит данные в `/var/lib/postgresql/18/docker`, поэтому том монтируется в `/var/lib/postgresql`, а не в `/var/lib/postgresql/data`, как раньше. Со старым путём данные окажутся вне тома и пропадут при пересоздании контейнера. Актуальный пример — в разделе [Docker развёртывание](/getting-started/docker-deployment).
* **Внешняя база** (не из compose бота). Скрипт вам не нужен: переносите её привычным для вашего хостинга способом. Бот работает и с PostgreSQL 15, и с 18.
