> For the complete documentation index, see [llms.txt](https://docs.iexexchanger.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.iexexchanger.com/server-i-dannye/sozdanie-rezervnoi-kopii.md).

# Создание резервной копии

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

Для создания резервных копий PostgreSQL в iEXExchanger используется инструмент `iEX DB Backup`. Он экспортирует основную базу приложения, базу Laravel Pulse и дополнительные базы PostgreSQL.

Каждая новая резервная копия проверяется перед сохранением и получает manifest с контрольной суммой SHA-256. Это позволяет убедиться, что файл не повреждён и относится к нужному профилю.

## Где находится инструмент

Основная команда:

{% content-ref url="/spaces/uyjsNtEAtO6Sby8CHWyD/pages/cCEoFDjTDIufy3NUEakd" %}
[Подключение к серверу по SSH](/help-center/upravlenie-serverom/podklyuchenie-k-serveru-po-ssh.md)
{% endcontent-ref %}

```
tools/db-backup/iex-db-backup
```

Пример конфигурации:

```
tools/db-backup/db-backup.example.json
```

Рабочая конфигурация:

```
tools/db-backup/db-backup.json
```

Стандартный каталог резервных копий:

```
storage/app/backups/database/
```

Логи:

```
storage/logs/db-backup/
```

Все команды рекомендуется выполнять из корня Backend-проекта.

Для FASTPANEL путь обычно выглядит так:

{% content-ref url="/spaces/uyjsNtEAtO6Sby8CHWyD/pages/MDuqJRjp8L1cHG9i4sRB" %}
[Файлы сайта в FastPanel](/help-center/upravlenie-serverom/panel-fastpanel/faily-saita-v-fastpanel.md)
{% endcontent-ref %}

```
/var/www/SITE_OWNER/data/www/app.example.com
```

## Для чего нужен iEX DB Backup

Через инструмент можно:

* создать резервную копию основной базы приложения;
* отдельно сохранить базу Laravel Pulse;
* подключить дополнительные базы PostgreSQL;
* создать сжатый `.sql.gz`;
* получить обычный `.sql`;
* добавить метку к имени файла;
* сохранить копию в стандартный или отдельный каталог;
* проверить SQL-файл без подключения к рабочей базе;
* сверить SQL-файл с manifest;
* проверить контрольную сумму SHA-256;
* выполнить контрольное восстановление в пустую базу;
* настроить автоматическое копирование через CRON.

Инструмент не выполняет:

* изменение Laravel `.env`;
* Product Updates;
* Laravel migrations;
* очистку рабочей базы;
* включение режима обслуживания;
* удаление старых копий;
* перезапись существующих backup-файлов.

{% hint style="danger" %}
`iEX DB Backup` сохраняет только базу данных.

Файлы Backend и Frontend, `.env`, изображения, пользовательские загрузки и содержимое каталога `storage` необходимо резервировать отдельно.
{% endhint %}

## Как работает резервное копирование

После запуска инструмент:

1. загружает конфигурацию;
2. получает реквизиты выбранного профиля;
3. проверяет подключение к PostgreSQL;
4. запускает `pg_dump`;
5. создаёт временный SQL-файл;
6. проверяет содержимое SQL;
7. вычисляет SHA-256;
8. создаёт manifest;
9. публикует готовую резервную копию.

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

Если проверка не пройдена, файл не считается готовой резервной копией.

Существующие файлы не перезаписываются.

## Что создаётся

Для каждого профиля создаются два файла:

| Файл                         | Назначение                               |
| ---------------------------- | ---------------------------------------- |
| `<имя>.sql.gz`               | Сжатая SQL-копия PostgreSQL              |
| `<имя>.sql.gz.manifest.json` | Manifest с информацией о резервной копии |

По умолчанию файлы сохраняются в отдельный UTC-каталог:

```
storage/app/backups/database/YYYYMMDDTHHMMSSZ/
```

Пример:

```
storage/app/backups/database/20260719T030000Z/
├── main-postgresql-app_example_com_pg-before-update.sql.gz
├── main-postgresql-app_example_com_pg-before-update.sql.gz.manifest.json
├── pulse-postgresql-pulse_pg-before-update.sql.gz
└── pulse-postgresql-pulse_pg-before-update.sql.gz.manifest.json
```

Каталог создаётся с правами:

```
0700
```

SQL-файлы и manifest создаются с правами:

```
0600
```

Manifest содержит:

* имя профиля;
* название профиля;
* метку запуска;
* тип базы данных;
* тип сжатия;
* размер файла;
* SHA-256;
* количество таблиц;
* количество индексов;
* первичные ключи;
* уникальные ограничения;
* внешние ключи;
* количество строк.

## Перед началом

Убедитесь, что:

* PostgreSQL 18 установлен и работает;
* Backend iEXExchanger подключён к PostgreSQL;
* вы знаете пользователя Backend-сайта;
* в корне проекта находятся `.env` и `artisan`;
* каталог `tools/db-backup/` присутствует;
* в `.env` указаны рабочие реквизиты PostgreSQL;
* на сервере установлен `pg_dump`;
* на диске достаточно свободного места.

Go на сервер устанавливать не требуется. Launcher автоматически выбирает бинарный файл для архитектуры сервера.

Поддерживаются:

* Linux amd64;
* Linux arm64;
* macOS arm64.

Проверьте версию инструмента:

```bash
./tools/db-backup/iex-db-backup --version
```

Проверьте `pg_dump`:

```bash
pg_dump --version
```

Для PostgreSQL 18 рекомендуется использовать:

```
pg_dump 18
```

Проверка точного файла:

```bash
/usr/lib/postgresql/18/bin/pg_dump --version
```

Инструкция по установке PostgreSQL 18:

{% content-ref url="/pages/nTV8YubEHpIQWlwePofG" %}
[Подключение PostgreSQL](/server-i-dannye/rabota-s-postgresql/podklyuchenie-postgresql.md)
{% endcontent-ref %}

{% hint style="warning" %}
Запускайте `iEX DB Backup` от пользователя Backend-сайта, а не от `root`.

Так резервные копии, временные файлы и логи получат правильного владельца.
{% endhint %}

***

## Какие базы сохраняются

Для каждой базы используется отдельный профиль.

{% stepper %}
{% step %}

### Основная база приложения

Профиль `main` сохраняет основную базу iEXExchanger:

```json
"main": {
  "enabled": true,
  "optional": false,
  "label": "Основная база приложения",
  "env": "main"
}
```

Реквизиты берутся из стандартных параметров Laravel:

```dotenv
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=app_example_com_pg
DB_USERNAME=app_example_com_pg
DB_PASSWORD=CHANGE_ME
DB_SSLMODE=disable
```

{% endstep %}

{% step %}

### База Laravel Pulse

Профиль `pulse` сохраняет базу Laravel Pulse:

```json
"pulse": {
  "enabled": true,
  "optional": true,
  "label": "База Laravel Pulse",
  "env": "pulse"
}
```

Реквизиты берутся из:

```dotenv
PULSE_DB_CONNECTION=pgsql-pulse
PULSE_DB_HOST=127.0.0.1
PULSE_DB_PORT=5432
PULSE_DB_DATABASE=pulse_pg
PULSE_DB_USERNAME=pulse_pg
PULSE_DB_PASSWORD=CHANGE_ME
PULSE_DB_SSLMODE=disable
```

Параметр:

```json
"optional": true
```

позволяет пропустить недоступный Pulse при выполнении общей команды:

```bash
./tools/db-backup/iex-db-backup export \
  --profile all
```

Пропуск профиля будет показан в результате команды.

Если отдельно запустить:

```bash
./tools/db-backup/iex-db-backup export \
  --profile pulse
```

при недоступной базе Pulse команда завершится ошибкой.
{% endstep %}
{% endstepper %}

### Если Laravel Pulse не используется

Отключите профиль:

```json
"pulse": {
  "enabled": false,
  "optional": true,
  "label": "База Laravel Pulse",
  "env": "pulse"
}
```

После этого команда с `--profile all` обработает только остальные включённые профили.

***

## Пошаговое создание резервной копии

{% stepper %}
{% step %}

### Перейдите в Backend-проект

Для FASTPANEL:

{% content-ref url="/spaces/uyjsNtEAtO6Sby8CHWyD/pages/MDuqJRjp8L1cHG9i4sRB" %}
[Файлы сайта в FastPanel](/help-center/upravlenie-serverom/panel-fastpanel/faily-saita-v-fastpanel.md)
{% endcontent-ref %}

```bash
cd /var/www/имя_пользователя_backend/data/www/app.ваш_домен
```

Пример:

```bash
cd /var/www/example_usr/data/www/app.example.com
```

Проверьте текущий каталог:

```bash
pwd
```

Проверьте обязательные файлы:

```bash
ls -la artisan .env tools/db-backup
```

Проверьте права на запуск:

```bash
ls -la tools/db-backup/iex-db-backup*
```

Если право на запуск потерялось после загрузки или распаковки архива:

```bash
chmod 755 tools/db-backup/iex-db-backup*
```

{% endstep %}

{% step %}

### Создайте конфигурацию

Если `db-backup.json` ещё не существует:

```bash
cp tools/db-backup/db-backup.example.json \
  tools/db-backup/db-backup.json
```

Установите приватные права:

```bash
chmod 600 tools/db-backup/db-backup.json
```

Для стандартного проекта используйте:

```json
{
  "version": 1,
  "profiles": {
    "main": {
      "enabled": true,
      "optional": false,
      "label": "Основная база приложения",
      "env": "main"
    },
    "pulse": {
      "enabled": true,
      "optional": true,
      "label": "База Laravel Pulse",
      "env": "pulse"
    }
  }
}
```

Проверьте права:

```bash
ls -la tools/db-backup/db-backup.json
```

Ожидаемый результат:

```
-rw-------
```

{% hint style="danger" %}
`db-backup.json` может содержать пароли.

Не добавляйте его в Git, не размещайте в публичном каталоге и не используйте символическую ссылку.
{% endhint %}

Если конфигурация уже существует, не перезаписывайте её. Сначала проверьте текущие профили и сохраните защищённую копию.
{% endstep %}

{% step %}

### Проверьте конфигурацию

Выполните:

```bash
./tools/db-backup/iex-db-backup config-check \
  --profile all
```

Команда проверит:

* структуру `db-backup.json`;
* права конфигурационного файла;
* параметры из `.env`;
* подключения к PostgreSQL;
* доступность профилей;
* количество найденных объектов.

Успешный результат заканчивается сообщением:

```
All selected profiles completed successfully.
```

`config-check` не создаёт резервную копию и не изменяет данные.
{% endstep %}

{% step %}

### Создайте резервную копию

Для основной базы и Laravel Pulse:

```bash
./tools/db-backup/iex-db-backup export \
  --profile all \
  --tag before-update
```

Только для основной базы:

```bash
./tools/db-backup/iex-db-backup export \
  --profile main \
  --tag manual
```

Только для Laravel Pulse:

```bash
./tools/db-backup/iex-db-backup export \
  --profile pulse \
  --tag manual
```

Для всех выбранных профилей используется один UTC-каталог и одна метка запуска.
{% endstep %}

{% step %}

### Проверьте результат

После успешного экспорта должно появиться:

```
All selected profiles completed successfully.
```

Проверьте код завершения:

```bash
echo $?
```

Успешный код:

```
0
```

Возьмите фактический путь к созданному файлу из результата команды и выполните:

```bash
./tools/db-backup/iex-db-backup inspect \
  --file storage/app/backups/database/<UTC>/<BACKUP>.sql.gz \
  --require-manifest
```

Пример:

```bash
./tools/db-backup/iex-db-backup inspect \
  --file storage/app/backups/database/20260719T030000Z/main-postgresql-app_example_com_pg-before-update.sql.gz \
  --require-manifest
```

При необходимости укажите ожидаемый профиль:

```bash
./tools/db-backup/iex-db-backup inspect \
  --profile main \
  --file /secure/backups/main-postgresql-app_example_com_pg-before-update.sql.gz \
  --require-manifest
```

{% endstep %}

{% step %}

### Сохраните копию вне сервера

Для каждого профиля сохраните оба файла:

```
*.sql.gz
*.sql.gz.manifest.json
```

Подходящие места хранения:

* отдельный backup-сервер;
* защищённое объектное хранилище;
* локальный защищённый компьютер;
* другой физический диск.

{% hint style="warning" %}
Не храните единственную резервную копию на сервере с проектом.

При повреждении диска или потере доступа к серверу копия может быть утрачена вместе с рабочей базой.
{% endhint %}
{% endstep %}
{% endstepper %}

***

## Проверка резервной копии

Команда `inspect` не подключается к рабочей базе и ничего в ней не изменяет.

Она проверяет:

* файл является обычным файлом;
* файл не является символической ссылкой;
* gzip-поток не повреждён;
* SQL относится к PostgreSQL;
* размер файла;
* SHA-256;
* соответствие manifest;
* имя файла;
* профиль;
* количество таблиц;
* индексы;
* первичные ключи;
* уникальные ограничения;
* внешние ключи;
* команды `COPY`;
* количество строк;
* отсутствие запрещённых управляющих SQL-команд.

Пример успешного результата:

```
SQL artifact valid: ...
Manifest: profile=main, label="Основная база приложения"
Engine=postgresql, compression=gzip, bytes=...
Inventory: tables=..., indexes=..., PK=..., UNIQUE=..., FK=..., rows=...
```

Наличие `.sql.gz` ещё не подтверждает успешное создание копии.

Должны выполняться все условия:

* экспорт завершился кодом `0`;
* показано `All selected profiles completed successfully`;
* рядом создан manifest;
* `inspect` завершился успешно.

## Хранение SQL и manifest

SQL и manifest необходимо хранить вместе:

```
main.sql.gz
main.sql.gz.manifest.json
```

Не переименовывайте только один файл.

Неправильно:

```
backup.sql.gz
main.sql.gz.manifest.json
```

Manifest содержит исходное имя SQL-файла. Если переименовать только один файл, проверка завершится ошибкой.

Оба файла можно переместить в другой каталог, сохранив их имена.

### Проверка старого SQL без manifest

Старый доверенный SQL-файл можно проверить без manifest:

```bash
./tools/db-backup/iex-db-backup inspect \
  --file database/legacy_dump.sql
```

В результате будет показано:

```
Manifest: absent
```

Для такого файла нельзя использовать:

```
--require-manifest
```

Для новых резервных копий всегда сохраняйте manifest.

## Метки резервных копий

Параметр `--tag` добавляет понятную метку в имя SQL-файла и manifest:

```bash
./tools/db-backup/iex-db-backup export \
  --profile all \
  --tag before-product-update
```

Примеры:

```
before-product-update
before-migration
before-release-11.3.0
manual
scheduled
incident-copy
```

Допускаются:

* латинские буквы;
* цифры;
* точка;
* дефис;
* подчёркивание.

Максимальная длина — 64 байта.

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

## Форматы резервных копий

{% stepper %}
{% step %}

### Сжатая резервная копия

По умолчанию используется gzip:

```bash
./tools/db-backup/iex-db-backup export \
  --profile main \
  --compression gzip \
  --tag manual
```

Результат:

```
*.sql.gz
*.sql.gz.manifest.json
```

Для большинства проектов рекомендуется использовать этот формат.
{% endstep %}

{% step %}

### Обычный SQL-файл

Чтобы получить несжатый `.sql`:

```bash
./tools/db-backup/iex-db-backup export \
  --profile main \
  --compression none \
  --tag manual \
  --output storage/app/backups/manual/main.sql
```

При `--compression gzip` имя должно заканчиваться на `.gz`.

При `--compression none` окончание `.gz` использовать нельзя.

{% hint style="danger" %}
Не сохраняйте рабочую базу с клиентскими данными в каталоге `database/` и не добавляйте её в Git.

Каталог `database/` можно использовать только для очищенного установочного snapshot.
{% endhint %}
{% endstep %}
{% endstepper %}

***

## Выбор каталога

{% stepper %}
{% step %}

### Стандартный каталог

Если `--output` не указан, файлы сохраняются в:

```
storage/app/backups/database/<UTC>/
```

Для большинства проектов рекомендуется использовать стандартный каталог.
{% endstep %}

{% step %}

### Отдельный каталог

Чтобы сохранить копии в другом каталоге:

```bash
./tools/db-backup/iex-db-backup export \
  --profile all \
  --tag before-update \
  --output /secure/backups/iexexchanger/
```

При `--profile all` значение `--output` всегда считается каталогом.

Каталог должен:

* находиться вне `public`;
* быть доступен пользователю сайта;
* иметь приватные права;
* не быть символической ссылкой.

Создайте каталог:

```bash
mkdir -p /secure/backups/iexexchanger
```

Установите права:

```bash
chmod 700 /secure/backups/iexexchanger
```

Убедитесь, что пользователь Backend-сайта может записывать в этот каталог.
{% endstep %}

{% step %}

### Точное имя файла

Точное имя можно указать только для одного профиля:

```bash
./tools/db-backup/iex-db-backup export \
  --profile main \
  --tag before-update \
  --output storage/app/backups/manual/main-before-update.sql.gz
```

Чтобы указать каталог для одного профиля, завершите путь символом `/`:

```bash
./tools/db-backup/iex-db-backup export \
  --profile main \
  --output storage/app/backups/manual/
```

Если файл уже существует, команда остановится:

```
refusing to overwrite existing backup
```

{% endstep %}
{% endstepper %}

***

## Прямое подключение к PostgreSQL

Если Laravel подключается через pooler, а `pg_dump` должен обращаться напрямую к PostgreSQL, добавьте в `.env`:

{% content-ref url="/spaces/uyjsNtEAtO6Sby8CHWyD/pages/MDuqJRjp8L1cHG9i4sRB" %}
[Файлы сайта в FastPanel](/help-center/upravlenie-serverom/panel-fastpanel/faily-saita-v-fastpanel.md)
{% endcontent-ref %}

```dotenv
DB_DIRECT_HOST=127.0.0.1
DB_DIRECT_PORT=5432
DB_DIRECT_DATABASE=app_example_com_pg
DB_DIRECT_USERNAME=app_example_com_pg
DB_DIRECT_PASSWORD=CHANGE_ME
DB_DIRECT_SSLMODE=disable
```

Если параметры `DB_DIRECT_*` заполнены, инструмент использует их для экспорта основной базы.

Рабочее подключение Laravel при этом не изменяется.

## Автоматическое резервное копирование

Автоматический запуск настраивается через CRON пользователя Backend-сайта.

{% content-ref url="/pages/VQTz35uLnAox2blCwlqe" %}
[Планировщик задач](/server-i-dannye/planirovshik-zadach.md)
{% endcontent-ref %}

Подготовьте каталог логов:

```bash
mkdir -p storage/logs/db-backup
```

```bash
chmod 700 storage/logs/db-backup
```

Откройте планировщик:

```bash
crontab -e
```

Для PostgreSQL 18 укажите путь к `pg_dump`:

```cron
IEX_DB_TOOL_PG_DUMP=/usr/lib/postgresql/18/bin/pg_dump
```

Пример ежедневного запуска в 03:15:

```cron
15 3 * * * cd /var/www/имя_пользователя_backend/data/www/app.example.com && umask 077 && /usr/bin/flock -n storage/framework/iex-db-backup.lock ./tools/db-backup/iex-db-backup export --profile all --tag scheduled >> storage/logs/db-backup/cron.log 2>&1
```

`flock` запрещает запуск второго процесса, если предыдущий ещё работает.

Для каждого запуска создаётся новый UTC-каталог. Существующие файлы не перезаписываются.

{% hint style="warning" %}
`iEX DB Backup` не удаляет старые копии автоматически.

Следите за свободным местом и настройте собственную политику хранения.
{% endhint %}

## Где находятся логи

Логи сохраняются в:

{% content-ref url="/spaces/uyjsNtEAtO6Sby8CHWyD/pages/MDuqJRjp8L1cHG9i4sRB" %}
[Файлы сайта в FastPanel](/help-center/upravlenie-serverom/panel-fastpanel/faily-saita-v-fastpanel.md)
{% endcontent-ref %}

```
storage/logs/db-backup/
```

Пример:

```
storage/logs/db-backup/20260719T030000.000000000Z-export-all.log
```

Лог содержит:

* выполненную команду;
* выбранные профили;
* путь к конфигурации;
* путь к `.env`;
* путь к результату;
* прогресс;
* размер файла;
* SHA-256;
* итоговый статус.

Пароли в лог не записываются.

Каталог логов должен иметь права:

```
0700
```

Установите их при необходимости:

```bash
chmod 700 storage/logs/db-backup
```

Логи создаются с правами:

```
0600
```

## Контрольное восстановление

Команда `inspect` проверяет SQL и manifest, но наиболее надёжная проверка — восстановление в отдельную пустую базу.

{% hint style="danger" %}
Не проверяйте восстановление на рабочей базе.

Создайте отдельную пустую базу, которая не используется приложением.
{% endhint %}

Создайте в FASTPANEL пустую PostgreSQL-базу:

```
app_example_com_restore_test
```

Добавьте в `db-backup.json` профиль:

```json
"restore_test": {
  "enabled": true,
  "optional": false,
  "label": "Тестовое восстановление основной базы",
  "connection": {
    "driver": "pgsql",
    "host": "127.0.0.1",
    "port": 5432,
    "database": "app_example_com_restore_test",
    "username": "app_example_com_restore_test",
    "password": "CHANGE_ME",
    "socket": "",
    "tls": "",
    "sslmode": "disable",
    "admin": null
  }
}
```

Проверьте подключение:

```bash
./tools/db-backup/iex-db-backup config-check \
  --profile restore_test
```

Выполните восстановление:

```bash
./tools/db-backup/iex-db-backup import \
  --profile restore_test \
  --from-profile main \
  --expect-tag before-update \
  --file /secure/backups/main-postgresql-app_example_com_pg-before-update.sql.gz \
  --require-manifest \
  --yes
```

Параметры:

<table><thead><tr><th width="374">Параметр</th><th>Назначение</th></tr></thead><tbody><tr><td><code>--profile restore_test</code></td><td>Пустая тестовая база</td></tr><tr><td><code>--from-profile main</code></td><td>Ожидаемый профиль исходной копии</td></tr><tr><td><code>--expect-tag before-update</code></td><td>Ожидаемая метка</td></tr><tr><td><code>--file</code></td><td>Путь к SQL-файлу</td></tr><tr><td><code>--require-manifest</code></td><td>Обязательная проверка manifest</td></tr><tr><td><code>--yes</code></td><td>Подтверждение восстановления</td></tr></tbody></table>

Если база содержит пользовательские объекты, команда остановится:

```
refusing to import into non-empty PostgreSQL backup profile
```

Инструмент не очищает базу автоматически.

## Дополнительные базы PostgreSQL

Для дополнительной базы создайте отдельный профиль:

```json
"archive_pg": {
  "enabled": true,
  "optional": false,
  "label": "Архивная PostgreSQL-база",
  "connection": {
    "driver": "pgsql",
    "host": "127.0.0.1",
    "port": 5432,
    "database": "archive_database",
    "username": "archive_user",
    "password": "CHANGE_ME",
    "socket": "",
    "tls": "",
    "sslmode": "disable",
    "admin": null
  }
}
```

Каждый профиль должен использовать только один источник реквизитов:

* `"env": "main"`;
* `"env": "pulse"`;
* `"connection": {...}`.

Одновременно указывать `env` и `connection` нельзя.

***

## Запуск из другого каталога

Если команда запускается не из корня Backend, передайте абсолютные пути:

```bash
/var/www/имя_пользователя_backend/data/www/app.example.com/tools/db-backup/iex-db-backup export \
  --env /var/www/имя_пользователя_backend/data/www/app.example.com/.env \
  --config /var/www/имя_пользователя_backend/data/www/app.example.com/tools/db-backup/db-backup.json \
  --profile all \
  --tag manual
```

Для команды `inspect` Laravel-проект не требуется:

```bash
/absolute/path/iex-db-backup inspect \
  --file /secure/backups/main.sql.gz \
  --require-manifest
```

## Хранение резервных копий

Пример базовой политики:

| Тип копии          | Срок хранения                       |
| ------------------ | ----------------------------------- |
| Ежедневная         | 7–14 последних копий                |
| Еженедельная       | 4–8 последних копий                 |
| Перед обновлением  | До подтверждения стабильной работы  |
| Внешняя копия      | Минимум одна актуальная проверенная |
| Критическая версия | По внутренней политике проекта      |

Не удаляйте предыдущую копию, пока:

* новая копия не завершилась успешно;
* рядом не создан manifest;
* не выполнен `inspect`;
* файлы не сохранены вне основного сервера.

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

## Частые вопросы

<details>

<summary>Нужно ли останавливать сайт?</summary>

Нет. `pg_dump` создаёт транзакционно согласованный снимок PostgreSQL. Приложение может продолжать работу во время экспорта.

</details>

<details>

<summary>Можно ли запускать инструмент от root?</summary>

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

</details>

<details>

<summary>Что делать, если Laravel Pulse не используется?</summary>

Отключите профиль:

```json
"pulse": {
  "enabled": false
}
```

</details>

<details>

<summary>Достаточно ли наличия файла .sql.gz?</summary>

Нет. Рядом должен находиться manifest, экспорт должен завершиться кодом `0`, а `inspect` — без ошибок.

</details>

<details>

<summary>Можно ли переименовать резервную копию?</summary>

SQL и manifest связаны именем файла. Не переименовывайте только один из них.

</details>

<details>

<summary>Можно ли хранить копию только на сервере?</summary>

Не рекомендуется. Минимум одна актуальная проверенная копия должна находиться вне основного сервера.

</details>

<details>

<summary>Можно ли проверить восстановление на рабочей базе?</summary>

Нет. Для проверки создайте отдельную пустую базу PostgreSQL.

</details>

<details>

<summary>Нужно ли создавать копию Laravel Pulse?</summary>

Если Pulse используется, рекомендуется сохранять его вместе с основной базой через:

```bash
--profile all
```

Если данные Pulse не нужны для восстановления проекта, профиль можно отключить.

</details>

<details>

<summary>Можно ли создать копию без сжатия?</summary>

Да. Используйте:

```bash
--compression none
```

Для обычного хранения рекомендуется gzip.

</details>

## Частые ошибки

<details>

<summary>Конфигурация требует права 0600</summary>

Сообщение:

```
require 0600 or stricter
```

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

Исправьте права:

```bash
chmod 600 tools/db-backup/db-backup.json
```

Также проверьте, что файл не является символической ссылкой.

</details>

<details>

<summary>Не найден Laravel-проект</summary>

Сообщение:

```
could not locate Laravel project
```

Перейдите в корень Backend:

```bash
cd /var/www/SITE_OWNER/data/www/app.example.com
```

Либо передайте точные пути через `--env` и `--config`.

</details>

<details>

<summary>Профиль отключён или не существует</summary>

Сообщение:

```
profile ... is not defined or is disabled
```

Проверьте имя профиля и настройку:

</details>

<details>

<summary>Laravel Pulse недоступен</summary>

Сообщение:

```
profile pulse is unavailable
```

Проверьте:

```dotenv
PULSE_DB_CONNECTION=
PULSE_DB_HOST=
PULSE_DB_PORT=
PULSE_DB_DATABASE=
PULSE_DB_USERNAME=
PULSE_DB_PASSWORD=
```

Если Pulse не используется, отключите профиль.

</details>

<details>

<summary>Не найден pg_dump</summary>

Сообщение:

```
required native tool "pg_dump" was not found
```

Для PostgreSQL 18 выполните:

```bash
IEX_DB_TOOL_PG_DUMP=/usr/lib/postgresql/18/bin/pg_dump \
  ./tools/db-backup/iex-db-backup export \
  --profile main \
  --tag manual
```

Для CRON укажите:

```cron
IEX_DB_TOOL_PG_DUMP=/usr/lib/postgresql/18/bin/pg_dump
```

</details>

<details>

<summary>Версия pg_dump не соответствует PostgreSQL</summary>

Сообщение:

```
server version mismatch
```

Проверьте версию:

```bash
/usr/lib/postgresql/18/bin/pg_dump --version
```

Используйте бинарный файл PostgreSQL 18:

```bash
IEX_DB_TOOL_PG_DUMP=/usr/lib/postgresql/18/bin/pg_dump
```

</details>

<details>

<summary>Резервная копия уже существует</summary>

Сообщение:

```
refusing to overwrite existing backup
```

Используйте другую метку:

```bash
./tools/db-backup/iex-db-backup export \
  --profile main \
  --tag manual-2
```

Не удаляйте старую копию до успешного создания и проверки новой.

</details>

<details>

<summary>Manifest не соответствует SQL</summary>

Сообщение:

```
backup manifest does not match SQL artifact
```

Возможные причины:

* SQL и manifest относятся к разным запускам;
* один из файлов повреждён;
* переименован только один файл;
* SQL был изменён после экспорта.

Используйте исходную пару файлов.

</details>

<details>

<summary>Неправильные права каталога логов</summary>

Сообщение:

```
backup log directory ... require 0700
```

Исправьте права:

```bash
chmod 700 storage/logs/db-backup
```

</details>

<details>

<summary>Недостаточно свободного места</summary>

Проверьте диск:

```bash
df -h
```

Проверьте размер резервных копий:

```bash
du -sh storage/app/backups/database
```

При необходимости сохраните копию на другом диске:

```bash
./tools/db-backup/iex-db-backup export \
  --profile all \
  --tag manual \
  --output /secure/backups/iexexchanger/
```

</details>

***

## Доступные команды

<table><thead><tr><th width="212.0234375">Команда</th><th>Назначение</th></tr></thead><tbody><tr><td><code>config-check</code></td><td>Проверить конфигурацию и подключения</td></tr><tr><td><code>export</code></td><td>Создать резервную копию</td></tr><tr><td><code>backup</code></td><td>Синоним <code>export</code></td></tr><tr><td><code>inspect</code></td><td>Проверить SQL и manifest</td></tr><tr><td><code>import</code></td><td>Восстановить резервную копию</td></tr><tr><td><code>restore</code></td><td>Синоним <code>import</code></td></tr></tbody></table>

## Доступные параметры

<table><thead><tr><th width="204.59375">Команда</th><th>Параметры</th></tr></thead><tbody><tr><td><code>config-check</code></td><td><code>--profile</code>, <code>--env</code>, <code>--config</code>, <code>--version</code></td></tr><tr><td><code>export</code> / <code>backup</code></td><td><code>--profile</code>, <code>--env</code>, <code>--config</code>, <code>--output</code>, <code>--compression</code>, <code>--tag</code>, <code>--version</code></td></tr><tr><td><code>inspect</code></td><td><code>--file</code>, <code>--profile</code>, <code>--require-manifest</code>, <code>--version</code></td></tr><tr><td><code>import</code> / <code>restore</code></td><td><code>--profile</code>, <code>--from-profile</code>, <code>--expect-tag</code>, <code>--file</code>, <code>--require-manifest</code>, <code>--yes</code>, <code>--version</code></td></tr></tbody></table>

Параметры одной операции нельзя передавать другой.

Например, `--file` нельзя использовать с командой `export`.

## Рекомендации

Для большинства проектов рекомендуется:

* использовать профили `main` и `pulse`;
* получать реквизиты из Laravel `.env`;
* использовать `pg_dump` версии 18;
* создавать копии в формате `.sql.gz`;
* добавлять понятные метки через `--tag`;
* проверять каждый SQL-файл через `inspect`;
* хранить SQL и manifest вместе;
* сохранять минимум одну копию вне сервера;
* настроить ежедневный запуск через CRON;
* периодически проверять восстановление;
* контролировать свободное место на диске.

Перед Product Updates используйте метку:

```
before-product-update
```

***

## Коротко

`iEX DB Backup` создаёт резервные копии основной базы PostgreSQL, Laravel Pulse и дополнительных баз.

Стандартный порядок:

1. перейдите в Backend-проект;
2. создайте `db-backup.json`;
3. выполните `config-check`;
4. запустите `export`;
5. проверьте каждый файл через `inspect`;
6. сохраните SQL и manifest вне сервера.

Основные команды:

```bash
./tools/db-backup/iex-db-backup config-check --profile all
```

```bash
./tools/db-backup/iex-db-backup export \
  --profile all \
  --tag before-update
```

```bash
./tools/db-backup/iex-db-backup inspect \
  --file <ПУТЬ_К_BACKUP.sql.gz> \
  --require-manifest
```

Резервная копия считается готовой только после успешного `inspect` и сохранения файлов за пределами основного сервера.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.iexexchanger.com/server-i-dannye/sozdanie-rezervnoi-kopii.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
