NetBox 4.7: подготовка PostgreSQL перед апгрейдом
АйТи Фреш
Linux, Docker и DevOps

Что проверить в PostgreSQL перед апгрейдом NetBox 4.7 и почему обновлению нужно длинное окно простоя

Автор: , директор ООО «АйТи-Фреш» · · ~15 мин чтения
PostgreSQL база данных NetBox переходит с древовидной структуры django-mptt на расширение ltree с временной блокировкой
Замена django-mptt на ltree — не косметика: это блокирующая миграция, которую нельзя по-настоящему откатить.

Если вы планируете обновить NetBox до 4.7 тем же коротким окном, что и обычно, — не планируйте: релиз требует PostgreSQL 15 и расширение ltree, а миграция, которая заменяет django-mptt на ltree, держит блокировку ACCESS EXCLUSIVE на иерархических таблицах и не откатывается по-настоящему. Разбираю, что проверить в PostgreSQL заранее, чтобы обновление не встало посреди рабочего дня.

Что именно меняется в 4.7 и почему это не рядовой минорный апгрейд

NetBox 4.7.0 вышел 2 сентября 2026 года, и в списке breaking changes есть два пункта, которые касаются напрямую PostgreSQL, а не только кода приложения. Первый: «PostgreSQL 14 is no longer supported. NetBox now requires PostgreSQL 15 or later: The upgrade script will abort when connected to an earlier release». Это отличие от предыдущего релиза — в 4.6 то же самое несоответствие версии просто выводило предупреждение, апгрейд с PostgreSQL 14 хоть и не рекомендовался, но проходил. В 4.7 скрипт обновления прерывается сразу, если база на 14-й версии или старше.

Второй пункт — совсем новое требование, которое в документации по обновлению сформулировано так: «NetBox v4.7 and later require the PostgreSQL ltree extension». Это модуль иерархических данных из стандартного набора contrib-модулей PostgreSQL, который должен быть включён в конкретной базе данных. В пакетах Debian/Ubuntu он входит в основной пакет сервера, а на RHEL-подобных системах с пакетами PGDG живёт в отдельном postgresqlNN-contrib — если его нет, CREATE EXTENSION упадёт с ошибкой об отсутствии control-файла. До 4.7 NetBox хранил иерархии (регионы, группы сайтов, локации, роли устройств и ещё несколько моделей) через django-mptt — стороннюю Python-библиотеку. В 4.7 это заменено на нативный тип PostgreSQL ltree, и без включённого расширения миграция просто не сможет создать нужные колонки. Подготовку базы под такие релизы я обычно закладываю заранее в план внедрения NetBox — версия СУБД и её расширения реже всего попадают в чек-лист, который сам администратор составляет по памяти.

Третье, менее заметное в заголовках, но не менее важное изменение — минимальная версия Redis поднята до 6.0, релиз 5.x больше не поддерживается. Если вы годами не трогали инфраструктуру вокруг NetBox (сам PostgreSQL, Redis), апгрейд до 4.7 — тот случай, когда обновление приложения тянет за собой ревизию всего стека, а не только pip install новой версии кода.

Сравнение требований к PostgreSQL и Redis между NetBox 4.6 и NetBox 4.7
Главное отличие 4.7 от предыдущих минорных релизов — несовместимые версии больше не предупреждение, а стоп-кран.

Расширение ltree: что это и кто должен его включить

ltree — доверенный (trusted) модуль PostgreSQL для хранения и запроса иерархических меток вида 1.2.3. Он входит в стандартную поставку PostgreSQL и, будучи модулем trusted, не требует прав суперпользователя для активации — это прямо отмечено в предупреждении релиз-нот: «This trusted module ships with PostgreSQL and does not require superuser permission to activate». Формально включить его может обычный владелец базы данных, если у него есть привилегия CREATE на этой базе.

NetBox постарается сделать это сам: «NetBox will install it automatically during the upgrade if it is not already present. This requires the NetBox database user to hold the CREATE privilege on the database». То есть в большинстве случаев ничего вручную делать не придётся — миграция сама выполнит CREATE EXTENSION ltree, если у пользователя, от имени которого подключается NetBox, есть на это право. Официальная документация по установке PostgreSQL для NetBox изначально делает пользователя NetBox владельцем базы данных, а владелец базы по умолчанию обладает правом CREATE — так что для инсталляций, разворачивавшихся по стандартной инструкции, отдельно ничего готовить не нужно.

Проблема возникает там, где базу разворачивали не по этой инструкции: например, DBA завёл отдельную учётную запись для NetBox без роли владельца, или база живёт в управляемом облачном PostgreSQL (RDS, Cloud SQL и аналоги), где владение базой и права на расширения разграничены отдельно от прав на данные. В этих сценариях апгрейд может упасть на этапе миграции с ошибкой прав, и разбираться с этим в разгар обслуживания — заведомо хуже, чем проверить права до начала работ. У меня похожая история с правами регулярно всплывает и на серверах 1С на Linux с PostgreSQL: роль базы отдельно от роли владельца — удобно с точки зрения ИБ, но требует отдельного шага перед любым апгрейдом, который меняет схему.

Как проверить и выдать право CREATE заранее

Официальная документация по обновлению отдельным разделом «Verify Database Permissions» описывает, что делать, если расширение не установлено, а прав недостаточно. Заходите в psql от системного пользователя postgres:

sudo -u postgres psql

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

GRANT CREATE ON DATABASE netbox TO netbox;

После этого при следующем запуске миграций NetBox 4.7 сможет создать расширение самостоятельно.

Альтернативный путь — не давать NetBox это право вообще, а поставить расширение заранее силами администратора базы данных:

CREATE EXTENSION IF NOT EXISTS ltree;

Эту команду выполняет пользователь с более широкими правами (например, суперпользователь или владелец базы), подключившись именно к базе NetBox (sudo -u postgres psql -d netbox) — расширение ставится в конкретную базу, а не на весь сервер. Один раз, заранее — до дня апгрейда. Я предпочитаю именно этот вариант для клиентов с управляемым PostgreSQL или строгой моделью прав: расширение появляется в базе спокойно, без спешки в окне обслуживания, и сама миграция NetBox уже просто находит его на месте и ничего не создаёт.

Проверить, установлено ли расширение уже сейчас, можно одной командой на самой базе:

SELECT extname, extversion FROM pg_extension WHERE extname = 'ltree';

Если запрос вернул строку — расширение уже активно, и этот пункт подготовки можно вычеркнуть. Если пусто — самое время решить, кто и когда выдаёт право CREATE или ставит расширение вручную, до, а не во время апгрейда.

Четыре шага апгрейда NetBox до 4.7 с указанием, где возникает блокировка ACCESS EXCLUSIVE
Два шага из четырёх масштабируются с размером базы — именно они превращают обычный апгрейд в длинное окно.

Почему миграция держит блокировку и сколько это реально длится

В релиз-нотах этому посвящено отдельное предупреждение «Extended Upgrade Duration», и формулировка там жёсткая: «Two steps in this upgrade scale with the size of the database, and may take considerably longer than a typical NetBox upgrade». Первый шаг — сама замена django-mptt на ltree: миграция добавляет и изменяет колонки на каждой иерархической таблице, а затем заполняет таблицу одним оператором («adds and alters columns on each hierarchical table before backfilling it in a single statement»). Изменение схемы держит блокировку ACCESS EXCLUSIVE, которая блокирует не только запись, но и чтение на затронутых таблицах на всё время своей работы; последующий backfill блокирует уже конкретные строки, которые обновляет, до своего коммита. Оценка в релиз-нотах — «on a large deployment this can last several minutes»: минуты, а не часы, но именно на крупной базе.

Список моделей, которые это затрагивает, в релиз-нотах прямой (с пометкой «etc.» для групп): Region, SiteGroup, Location, DeviceRole, Platform, TenantGroup, ContactGroup, WirelessLANGroup, а также ModuleBay, InventoryItem и InventoryItemTemplate. Если у вас скромная база — десятки регионов, сотни локаций — миграция пройдёт незаметно. Если счёт идёт на многие тысячи объектов инвентаря (InventoryItem — обычно самая объёмная из этого списка модель, туда попадают все компоненты внутри устройств), блокировка на чтение всей таблицы на несколько минут — это уже ощутимый простой для любого сервиса, который читает NetBox через API в реальном времени (генераторы конфигов, дашборды, интеграции с системами мониторинга).

Второй шаг — отдельная команда rebuild_config_context_cache, которая исполняется прямо в скрипте апгрейда и делает по одному UPDATE на каждое устройство и каждую виртуальную машину в базе. У инфраструктуры с несколькими тысячами устройств это тысячи отдельных операций записи — не одна тяжёлая транзакция, как в случае с ltree, но по совокупному времени тоже заметно длиннее, чем обычные миграции NetBox, к которым все привыкли за прошлые релизы. Хорошая новость из тех же релиз-нот: команда пропускает объекты с уже заполненным кешем, её безопасно прервать и перезапустить, а при нехватке окна — отложить до момента, когда NetBox уже снова в строю (объект с пустым кешем просто рендерит config context на лету). Похожий эффект «много мелких операций дают долгий общий апгрейд» я разбирал на примере обновления конфигураций 1С без аварий — регламент там тоже строится вокруг оценки реального объёма данных, а не вокруг привычной длительности из прошлого раза.

Необратимость: почему «просто откатить» не сработает

Последняя строка предупреждения в релиз-нотах особенно важна для планирования: «these migrations are not reversible in practice: Reversing them restores the MPTT columns but does not repopulate them». Формально команда отката существует — Django-миграции всегда можно откатить командой migrate на более раннюю ревизию, и технически колонки lft, rght, tree_id, level, которые использовал django-mptt, снова появятся в схеме. Но данные в них никто не восстановит: обратная миграция создаёт пустые колонки, а не пересчитывает дерево заново.

На практике это означает, что после успешного перехода на ltree откат версии NetBox назад — это не «нажать одну кнопку», а фактически восстановление базы данных из бэкапа, снятого до апгрейда. Официальная документация по обновлению отдельным предупреждением требует бэкап перед любым апгрейдом: «Always be sure to save a backup of your current NetBox deployment prior to starting the upgrade process» — это общая рекомендация для любой версии, но для перехода на 4.7 она перестаёт быть формальностью и становится единственным реальным планом отхода, если что-то пойдёт не так в процессе или сразу после обновления. Тот же принцип «бэкап — это не формальность, а единственный реальный план Б» я закладываю в любую стратегию резервного копирования баз, которую строю клиентам, независимо от конкретной СУБД под капотом.

Отдельно стоит учитывать, что level — поле, которое раньше можно было использовать в фильтрах и order_by() при работе с иерархией через API или скрипты — после миграции остаётся доступным только как Python-свойство и больше не участвует в запросах к базе. Туда же — методы MPTT, которые NetBox не перенёс: реализация на ltree покрывает только get_ancestors(), get_descendants(), get_children() и add_related_count(), а get_root(), get_family(), is_leaf_node(), move_to() и insert_at() больше недоступны. Если у вас есть кастомные скрипты, репорты, плагины или интеграции, которые сортируют или фильтруют объекты по level или зовут эти методы, они перестанут работать именно в момент этого апгрейда — стоит поискать такие места в коде заранее, а не находить постфактум по упавшей интеграции.

Чек-лист подготовки к окну обслуживания

Порядок действий, который я использую при подготовке клиентов к переходу на 4.7. Сначала — оценка объёма: количество строк в таблицах Region, Location, DeviceRole, Platform и особенно InventoryItem (обычно самая большая), чтобы понять, о каких минутах блокировки реально идёт речь именно на вашей базе, а не полагаться на общую формулировку «may take considerably longer». Затем — версии зависимостей: SELECT version(); в psql на предмет PostgreSQL 15+, и версия Redis-сервера — обе должны быть подняты заранее, отдельным этапом, ещё до попытки апгрейда самого NetBox.

Дальше — права и расширение: проверка pg_extension на ltree, и если его нет — либо выдача GRANT CREATE, либо ручная установка CREATE EXTENSION силами DBA, оба варианта разобраны выше. Отдельным пунктом — полный бэкап базы данных (pg_dump или снапшот тома, в зависимости от вашей инфраструктуры) прямо перед началом работ, и проверка, что все установленные плагины заявляют совместимость с 4.7 — документация по обновлению прямо требует свериться с этим перед апгрейдом любой версии. Ещё два пункта именно из 4.7: дать фоновым очередям RQ опустеть перед остановкой воркеров (вебхуки, поставленные в очередь старой версией, после рестарта упадут с TypeError), а если у вас SSO — проверить вход на тестовом стенде, потому что social-auth-app-django и social-auth-core обновлены до новых мажорных версий.

Последний пункт — коммуникация с командой, которая пользуется интеграциями поверх NetBox. Если у вас есть скрипты, дёргающие REST API или GraphQL в момент планового окна, предупредите их авторов: сама миграция держит ACCESS EXCLUSIVE на части таблиц, поэтому даже чтение через API в эти минуты будет получать таймауты, а не просто медленный ответ. Планируйте окно не на «пару минут по привычке», а на реалистичную оценку по объёму вашей базы плюс запас.

Цифры кейса апгрейда NetBox до версии 4.7 у инкубатора стартапов Бизнес-трамплин
Реалистичная оценка окна по объёму своей базы — единственная защита от простоя посреди рабочего дня.

Кейс: инкубатор стартапов «Бизнес-трамплин», 21 рабочее место

У клиента NetBox используется два года для учёта сетевой инфраструктуры коворкинга — стойки, свитчи, точки доступа по этажам, плюс детальный инвентарь компонентов серверных стоек резидентов (карты расширения, диски, модули памяти заведены как InventoryItem, потому что оборудование резидентов меняется часто и клиенту важно видеть историю). За два года таблица InventoryItem накопила около 6 тысяч записей — немного по меркам крупного дата-центра, но заметно больше, чем в среднем малом офисе.

Перед обновлением до 4.7 мы сначала проверили версию PostgreSQL — на сервере клиента стояла 14-я ветка, унаследованная ещё с первоначальной установки NetBox 4.1 два года назад, апгрейды PostgreSQL параллельно с NetBox всё это время не делали. Пришлось сначала поднять PostgreSQL до 15-й ветки отдельным этапом (со своим планом бэкапа и проверкой совместимости), и только после этого — обновлять сам NetBox. Расширение ltree на новой версии PostgreSQL включили заранее вручную, командой CREATE EXTENSION IF NOT EXISTS ltree, от имени администратора базы, не полагаясь на автоматическое создание в момент миграции.

Окно под само обновление NetBox мы заложили в 40 минут — против обычных 5–10 минут для минорных апгрейдов у этого же клиента в прошлом — и заранее предупредили резидентов коворкинга о плановой недоступности панели самообслуживания, которая читает NetBox через API. Фактически на базе такого размера шаг django-mptt → ltree вместе с блокировкой занял меньше минуты, rebuild_config_context_cache по примерно 150 устройствам и ВМ — около минуты, а весь upgrade.sh с пересборкой виртуального окружения и collectstatic — около 12 минут; остальное время ушло на свежий pg_dump, проверку интерфейса и прогон интеграций. Запас оказался с избытком, и я считаю это правильным исходом: оценку надо делать по своей базе, а «several minutes» из релиз-нот — это про инсталляции с сотнями тысяч объектов, а не про 6 тысяч.

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

Обязательно ли поднимать PostgreSQL до 15 перед апгрейдом NetBox до 4.7?

Да, это жёсткое требование. Скрипт обновления NetBox 4.7 прерывается при подключении к PostgreSQL 14 или старше — в отличие от версии 4.6, которая только предупреждала. PostgreSQL нужно обновить отдельным этапом до апгрейда самого NetBox.

Нужно ли устанавливать расширение ltree вручную?

Не обязательно — NetBox создаст его сам во время миграции, если у пользователя базы есть право CREATE (при стандартной установке пользователь NetBox — владелец базы, и право уже есть). Если у вас управляемый PostgreSQL или строгая модель прав, надёжнее заранее выполнить CREATE EXTENSION IF NOT EXISTS ltree в базе NetBox силами администратора СУБД.

Сколько реально длится блокировка при миграции на ltree?

Зависит от объёма иерархических таблиц — прежде всего InventoryItem, Location, ModuleBay и похожих моделей. Релиз-ноты говорят о нескольких минутах на крупной инсталляции; на базе с ~6 тысячами InventoryItem этот шаг проходит меньше чем за минуту. Оценивайте по числу строк в своих таблицах и закладывайте запас.

Можно ли откатить NetBox с 4.7 назад после обновления?

Технически откат миграции восстанавливает старые колонки django-mptt, но данные в них не заполняются заново — по факту функциональность иерархии будет сломана. Единственный надёжный план отката — восстановление из бэкапа базы данных, снятого перед апгрейдом.

Что делать, если в моих скриптах есть сортировка по полю level?

После миграции на ltree поле level остаётся доступным только как Python-свойство и больше не работает в фильтрах или order_by() на уровне базы данных. Такие места в коде нужно найти и переписать до обновления, иначе они начнут падать сразу после апгрейда.

Требования по Redis тоже обязательны?

Да, NetBox 4.7 прекращает поддержку Redis 5.x и требует версию 6.0 или новее. Проверьте версию Redis вместе с PostgreSQL в рамках той же подготовки, до начала апгрейда.

Столкнулись с похожей задачей? Обращайтесь — решим

Если у вас происходит что-то из описанного в этой статье — или любая другая проблема с ИТ-инфраструктурой, — обращайтесь в любое время. Мои специалисты и я лично разберём ситуацию, найдём настоящую причину и доведём до решения.

Возьмёмся и за разовую задачу, и за постоянное обслуживание. Первичная консультация — бесплатно и без обязательств.

📞 +7 903 729-62-41 ✈ Telegram @ITfresh_Boss

С уважением, Семёнов Евгений Сергеевич, директор «АйТи Фреш» — IT-аутсорсинг для компаний до 50 рабочих мест, 15+ лет практики

Источники

© ООО «АйТи-Фреш» · Москва · Все статьи