Обновление и восстановление

Обновление и восстановление #

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

Точные версии необходимых справочников указаны в блоке Требования к версиям справочников на странице История изменений

Если справочник выделен жирным шрифтом и над ним указан знак «плюс», это означает, что справочник обновлен для этой версии, в противном случае обновление справочника не требуется.

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

Порядок обновления #

  1. Подготовка - загрузить справочники и образы. Приложение продолжает работать.
  2. Остановка приложения
  3. Обновление базы данных - только если для версии обновлены справочники
  4. Запуск и проверка приложения
  5. Прогрев кэша базы данных

Сервис недоступен с шага 2 по шаг 4. Без обновления справочников это около минуты, с обновлением справочника ru - до полутора часов.

Если ApiDQ установлен на нескольких серверах за балансировщиком нагрузки, обновляйте серверы по одному: выведите сервер из балансировки, обновите, дождитесь успешной проверки и только после этого переходите к следующему. Для проверки доступности сервера в балансировщике используйте GET /health.

Подготовка #

Все действия этого шага выполняются при работающем приложении.

Загрузите обновлённые справочники в папку ~/apidq/dumps на сервере базы данных и проверьте, что файлы не повреждены и загружены полностью. Команда читает архив целиком (для справочника ru - несколько минут) и ничего не меняет в базе данных:

cd ~/apidq/dumps
pg_restore -f /dev/null services_20241030.dump && echo OK
pg_restore -f /dev/null ru_20260907.dump && echo OK
Не удаляйте старый справочник из базы данных, пока новый не загружен и не прошёл проверку.

На сервере приложения в папке apidq укажите новую версию в файле .env

APIDQ_VERSION=1.22.0

и загрузите образы

docker compose pull
Если в вашем docker-compose.yaml у образов указан тег latest, замените его на ${APIDQ_VERSION} - актуальный файл приведён в инструкции Установка ApiDQ приложения. При обновлении сверьте с инструкцией и файлы конфигурации сервисов.

Остановка приложения #

docker compose stop

Сервис address загружает справочники в память при запуске, поэтому на время обновления базы данных приложение должно быть остановлено. Если справочники не обновляются, переходите к шагу Запуск и проверка приложения.

Обновление базы данных #

Временные параметры PostgreSQL #

На время восстановления рекомендуем задать PostgreSQL временные параметры - они ускоряют восстановление и не дают автоочистке (autovacuum) конкурировать с ним.

Создайте файл /etc/postgresql/18/main/conf.d/zz-apidq-restore-window.conf

max_wal_size = 4GB
maintenance_work_mem = 256MB
autovacuum = off

и примените его

sudo systemctl reload postgresql@18-main
maintenance_work_mem выделяется на каждый поток восстановления. Проверьте бюджет памяти: shared_buffers + число потоков -j × maintenance_work_mem + 1,5 ГБ не должны превышать RAM сервера.

Восстановление справочников #

Для каждого обновленного справочника нужно удалить старый SCHEMA и восставновить новый SCHEMA из резервной копии (пример для services и ru). Параметр -j - число параллельных потоков, укажите количество CPU сервера.

Восстанавливайте справочники по одному: выполните команды для одного справочника, убедитесь, что они завершились без ошибок, и только после этого переходите к следующему.

cd ~/apidq/dumps
export PGPASSWORD='p_a_s_s_w_o_r_d'
psql -v ON_ERROR_STOP=1 -U user_apidq -h 127.0.0.1 -d db_apidq -c "DROP SCHEMA IF EXISTS services CASCADE;" && \
pg_restore --no-owner --no-acl -Fc -j 8 -U user_apidq -h 127.0.0.1 -d db_apidq services_20241030.dump && echo OK
psql -v ON_ERROR_STOP=1 -U user_apidq -h 127.0.0.1 -d db_apidq -c "DROP SCHEMA IF EXISTS ru CASCADE;" && \
pg_restore --no-owner --no-acl -Fc -j 8 -U user_apidq -h 127.0.0.1 -d db_apidq ru_20260907.dump && echo OK

Справочник name восстанавливается в схему public, в которой также находятся расширения PostgreSQL (postgis, hstore, pg_trgm, uuid-ossp). Никогда не выполняйте DROP SCHEMA public. Для обновления справочника name используйте параметры --clean --if-exists - pg_restore сам удалит только те объекты, которые есть в резервной копии:

pg_restore --clean --if-exists --no-owner --no-acl -Fc -U user_apidq -h 127.0.0.1 -d db_apidq name_20210801.dump && echo OK

После этого добавьте --schema=public в команду сбора статистики ниже.

Сбор статистики #

Этот шаг обязателен. pg_restore не переносит статистику планировщика: без неё первые же запросы к новому справочнику выполняются полным перебором таблиц и могут полностью загрузить CPU и память сервера.

Выполните VACUUM ANALYZE для всех восстановленных схем до запуска приложения:

vacuumdb --analyze --jobs=8 -U user_apidq -h 127.0.0.1 -d db_apidq --schema=services --schema=ru

Возврат параметров PostgreSQL #

Удалите временный файл и примените настройки. Выполните этот шаг, даже если восстановление завершилось ошибкой или сессия оборвалась, - иначе автоочистка останется выключенной. Если вы не уверены, был ли шаг выполнен, проверьте, что файла zz-apidq-restore-window.conf нет в каталоге /etc/postgresql/18/main/conf.d/.

sudo rm /etc/postgresql/18/main/conf.d/zz-apidq-restore-window.conf
sudo systemctl reload postgresql@18-main

Запуск и проверка приложения #

docker compose up -d --remove-orphans

Команда завершится после того, как сервис address загрузит справочники в память (около минуты).

Проверьте версию и основные сервисы. Параметр -w выводит после ответа код HTTP: каждый запрос должен завершиться строкой HTTP 200 и вернуть непустой результат.

curl -w '\nHTTP %{http_code}\n' 'http://127.0.0.1:8080/api/v1/version'

curl -w '\nHTTP %{http_code}\n' --request POST 'http://127.0.0.1:8080/api/v1/suggest/address' \
--header 'Content-Type: application/json' \
--data-raw '{"query": "москва лазо","countryCode": "RU","count": 2}'

curl -w '\nHTTP %{http_code}\n' --request POST 'http://127.0.0.1:8080/api/v1/clean/address' \
--header 'Content-Type: application/json' \
--data-raw '{"query": "Москва Кравченко 12","countryCode": "RU"}'

curl -w '\nHTTP %{http_code}\n' --request POST 'http://127.0.0.1:8080/api/v1/idsearch/address' \
--header 'Content-Type: application/json' \
--data-raw '{"query": "0c5b2444-70a0-4932-980c-b4dc0d3f02b5","type": "FIAS","countryCode": "RU"}'
Проверяйте все три сервиса, а не только suggest/address: они обращаются к разным таблицам справочника. Если версия приложения новее справочника, suggest/address может отвечать успешно, а clean/address и idsearch/address - возвращать ошибку 500.

Прогрев кэша базы данных #

После восстановления справочника или перезапуска PostgreSQL кэш базы данных пуст, и первые минуты запросы выполняются в несколько раз медленнее. Рекомендуем прогреть наиболее используемые таблицы и индексы адресного справочника (пример для ru)

sudo su postgres
psql db_apidq -c "CREATE EXTENSION IF NOT EXISTS pg_prewarm;"
psql db_apidq -c "SELECT pg_prewarm('ru.pk_ru_addresses_id');"
psql db_apidq -c "SELECT pg_prewarm('ru.pk_ru_houses_id');"
psql db_apidq -c "SELECT pg_prewarm('ru.idx_ru_houses_address_cover');"
psql db_apidq -c "SELECT pg_prewarm('ru.address_fts');"
psql db_apidq -c "SELECT pg_prewarm(indexrelid) FROM pg_index WHERE indrelid = 'ru.address_fts'::regclass;"
exit

Таблица ru.address_fts прогревается последней: при нехватке shared_buffers вытесняются данные, загруженные первыми, а она используется чаще всего.

Индекс ru.idx_ru_houses_address_cover появился в справочнике ru_20260907. Для более ранних справочников пропустите эту команду.

Восстановление #

Возврат на предыдущую версию выполняется в том же порядке, что и обновление: сначала база данных, затем приложение. Если вместе с версией обновлялись справочники, предыдущей версии приложения нужны предыдущие версии справочников - они указаны в блоке Требования к версиям справочников нужной версии на странице История изменений

Не запускайте предыдущую версию приложения на новых справочниках: до восстановления базы данных сервисы могут возвращать ошибку 500.
  1. Подготовка - загрузите и проверьте предыдущие версии справочников (если они обновлялись), укажите предыдущую версию в файле .env, например APIDQ_VERSION=1.21.3, и выполните docker compose pull
  2. Остановка приложения
  3. Обновление базы данных - восстановите предыдущие версии справочников. Если справочники не обновлялись, шаг пропускается
  4. Запуск и проверка приложения
  5. Прогрев кэша базы данных
При возврате на версию ниже 1.21.1 удалите из docker-compose.yaml блок healthcheck у сервиса address и замените у gateway условие service_healthy на service_started - см. Установка ApiDQ приложения.