Skip to content

ADR 0014: индексы страниц каталога без длительной блокировки записи ​

Статус: accepted. Дата: 2026-09-23.

Контекст ​

После ADR 0013 запрос ограничивает выдачу, но без индекса вычисляет SemVer-ключ и сортирует все подходящие строки. На отдельной PostgreSQL 18.4 в Docker, с 100 000 синтетических UPack-версий, прогретым кешем и одним клиентом первая страница из 50 строк занимала около 150–160 мс для каждого из шести вариантов сортировки. EXPLAIN ANALYZE показывал полный просмотр и Sort. Это локальный замер, а не обещание времени ответа под рабочей нагрузкой.

Решение ​

  • Миграция 8 создаёт шесть B-tree индексов по точному порядку group|name|version × asc|desc, включая равные ключи. Обратный проход по одному индексу не сохраняет нужный порядок всех вторичных полей и может снова сортировать большую группу.
  • Индексы создаются через CREATE INDEX CONCURRENTLY вне транзакции. Отдельное соединение миграции имеет лимит SQL-команды 10 минут, в отличие от короткого лимита обычных запросов. Сеансы миграции сериализуются через pg_try_advisory_lock с ограниченным ожиданием вне SQL-транзакции: блокирующее ожидание advisory lock может образовать взаимную блокировку с concurrent index build. После обрыва повтор использует уже годные индексы, удаляет негодный частичный индекс и продолжает. Версия 8 записывается только после завершения всех шести индексов.
  • Существующий код не требует новых столбцов. Перед выпуском нового кода запускается npm run migrate; обычный порядок резервного копирования и остановки процессов сохраняется. Команда может потребовать свободного места для индексов, WAL и временных файлов и ждать длительные транзакции. При превышении лимита её можно запустить повторно после проверки причины.

Измерение и последствия ​

На том же тестовом наборе после индексации первые страницы занимали около 1–4 мс, а планы использовали Index Scan. Шесть индексов занимали около 60 МБ, таблица пакетов — около 13 МБ; это плата диском и работой при регистрации версии за предсказуемое чтение. Замер не охватывает параллельную запись, холодный кеш, глубокие страницы и рабочее распределение пакетов. Перед промышленным выпуском нужны замеры на репрезентативной копии каталога и наблюдение за размером индексов, временем миграции и WAL.

Уточнение по аудиту 2026-09-24: координация index build использует отдельный session advisory lock 18471/9. Исходный ключ 18471/2 пересекался с reservation-транзакциями uploads и мог останавливать новые загрузки на время построения индекса.

Arkvory · ProAnimaStudio