Обновление отложено из-за поэтапного распространения в apt
apt upgrade пишет, что обновление отложено? Это не ошибка. Объясняем, как apt выбирает машины по /etc/machine-id и как поставить исправление сразу, если ждать нельзя.
Обновление отложено из-за поэтапного распространения: это не ошибка
Если apt upgrade пишет, что обновление отложено из-за поэтапного распространения, значит, ничего не сломалось. Ubuntu выпускает часть обновлений не для всех сразу. Сначала их получает небольшая доля машин, потом эта доля растёт. Ваш сервер пока не попал в эту долю. Поэтому apt оставил пакет на текущей версии и сообщил об этом.
Сообщение выглядит так. Вместо <пакет> вы увидите имя настоящего пакета:
Обновление следующих пакетов отложено из-за поэтапного распространения:
<пакет>Эта строка взята из файла перевода apt (po/ru.po). В английском оригинале она звучит так:
The following upgrades have been deferred due to phasing:В apt с новым форматом вывода заголовок короче. По-русски он звучит как Обновление отложено из-за поэтапного распространения:, а по-английски Not upgrading yet due to phasing:. Код apt выбирает заголовок по параметру APT::Output-Version: длинный вариант печатается, когда значение меньше 30. В Ubuntu 24.04 стоит apt 2.7, и там вы увидите длинный вариант. Если сервер уже прошёл обновление Ubuntu 24.04 до 26.04 и на нём стоит apt третьей ветки, заголовок может быть коротким. Обе строки значат одно и то же.
Дальше разберём, как apt решает, получит ли машина обновление. Потом посмотрим, при чём здесь /etc/machine-id. В конце покажем, как поставить исправление сразу, если оно нужно вам сегодня. Короткий ответ: в большинстве случаев лучше ничего не делать и подождать.
Что такое поэтапные обновления в Ubuntu
Поэтапные обновления (phased updates) работают так. Новая версия пакета для стабильного выпуска Ubuntu публикуется в репозитории с полем Phased-Update-Percentage. Это целое число от 0 до 100. Оно показывает, для какой доли машин версия уже доступна. Сначала доля маленькая. Потом её увеличивают, пока она не дойдёт до 100.
Зачем это нужно? В обновлении может оказаться регрессия, то есть ошибка, которой не было в прошлой версии. При поэтапном распространении она затронет только часть серверов. Остальные машины ещё не получили эту версию. Поэтому проблему можно заметить и исправить до того, как она дойдёт до всех.
Документация Ubuntu Server говорит прямо: обновления безопасности никогда не распространяются поэтапно. Код apt проверяет это отдельно. Функция PhasingApplied в файле apt-pkg/depcache.cc сразу пропускает версию, если это обновление безопасности. Поэтому, пока вы ждёте, исправления уязвимостей приходят без задержки.
Как apt решает, получит ли ваш сервер обновление
Механизм описан в справке apt_preferences(5), в разделе Phased Updates. Своими словами:
- apt берёт имя исходного пакета, номер новой версии и содержимое
/etc/machine-id. - Из этих значений он получает псевдослучайное число в диапазоне от 0 до 100.
- Если число больше
Phased-Update-Percentage, версия откладывается. Иначе действуют обычные правила apt.
/etc/machine-id хранит уникальный идентификатор установленной системы. В файле одна строка из 32 шестнадцатеричных символов. Обычно systemd записывает её при первой загрузке.
Важное следствие: результат не меняется от запуска к запуску. Число зависит только от имени пакета, версии и machine-id. Поэтому для одной и той же версии ваш сервер каждый раз получает один и тот же ответ. Можно запустить apt update и apt upgrade десять раз подряд, и ответ не изменится. Он меняется в двух случаях. Первый: Ubuntu увеличила процент. Второй: вышла новая версия пакета, и для неё число считается заново.
Справка говорит, что отложенная версия закрепляется с приоритетом 1. В текущем исходном коде apt это поведение включается параметром APT::Get::Phase-Policy, а по умолчанию он выключен. Комментарий в коде объясняет причину: apt временно вернулся к прежней реализации, пока не исправлена ошибка LP: #1929082. В прежней реализации кандидатом на установку остаётся новая версия, а apt upgrade просто не трогает этот пакет. Поэтому apt policy показывает новую версию как кандидата, хотя apt upgrade её не ставит.
В той же функции PhasingApplied есть ещё одно правило: фаза касается только пакетов, которые уже установлены. Если пакета на сервере нет, apt install сразу поставит самую новую версию.
Как узнать процент для конкретного пакета
apt policy <пакет>В таблице версий у отложенной версии будет пометка вида (phased 30%). В русской локали она выглядит как (поэтапно 30%). Число показывает долю машин, для которых версия уже доступна. apt берёт его из локальных списков пакетов. Поэтому новое значение появится только после очередного apt update.
Проверьте /etc/machine-id: пустой и скопированный файл
Поэтапное распространение работает правильно, только когда у каждой машины свой machine-id. Проверьте файл:
ls -l /etc/machine-id
test -s /etc/machine-id && echo "machine-id заполнен" || echo "machine-id пуст или отсутствует"
cat /etc/machine-idtest -s проверяет, что файл существует и не пуст. На обычном VPS вторая команда печатает machine-id заполнен, а cat выводит одну строку из 32 шестнадцатеричных символов. Если файла нет, ls и cat сообщат Нет такого файла или каталога. В английской локали это сообщение звучит как No such file or directory.
Пустой или отсутствующий machine-id
Справка apt_preferences(5) этот случай не описывает. Ответ есть в исходном коде apt. Сначала apt смотрит параметр APT::Machine-ID. Если он не задан, apt читает файл /etc/machine-id. Если прочитать файл не удалось, apt не печатает ошибку. Увидеть её можно только с отладочным параметром -o Debug::Phasing=true.
Дальше в apt-pkg/depcache.cc стоит проверка: если machine-id пустой, фаза не применяется. Такая машина сразу получает все поэтапные обновления, то есть всегда входит в первую группу. Сообщение об отложенном обновлении она не увидит никогда. Это легко принять за норму. На самом деле сервер просто лишён защиты, которую даёт поэтапное распространение.
Та же проверка отключает фазу ещё в двух случаях. Первый случай: apt работает внутри chroot, то есть в окружении, где корневой каталог подменён другим каталогом. apt определяет это программой ischroot -t. Второй случай: задана переменная окружения SOURCE_DATE_EPOCH, которую используют воспроизводимые сборки.
Один machine-id на нескольких серверах
Если серверы созданы из одного образа или снимка диска, у них может оказаться одинаковый /etc/machine-id. Тогда apt на всех этих машинах считает одно и то же число для каждой версии. Все клоны либо получают обновление одновременно, либо не получает ни один. В такой группе поэтапное распространение теряет смысл. Если в версии есть регрессия, она попадёт на все клоны сразу.
Сравните вывод cat /etc/machine-id на своих серверах. Если строки совпадают, создайте новый идентификатор на каждом клоне. Как это сделать, описано в руководстве как пересоздать machine-id после клонирования VPS. Одинаковый machine-id мешает не только apt, поэтому его стоит исправить в любом случае.
Иногда одинаковое решение для группы серверов как раз нужно. Например, вы хотите, чтобы тестовый и рабочий серверы получали один и тот же набор версий. Для этого справка apt_preferences(5) предлагает задать на всех этих машинах одинаковый UUID в параметре APT::Machine-ID. Это осознанная настройка. Случайная копия файла её не заменяет.
Как установить отложенное обновление сейчас
По умолчанию лучше подождать. Но иногда в отложенной версии есть исправление, которое нужно вам сегодня. Для этого есть два способа. Первый затрагивает только один пакет. Второй отключает фазу для всех пакетов на машине.
Способ 1: установить один пакет явно
Этот путь описан в документации Ubuntu Server: нужно назвать пакет в apt install. Сначала запомните, как пакет помечен сейчас. Это пригодится, чтобы потом вернуть пометку.
pkg=имя-пакета
apt-mark showauto "$pkg"
sudo apt install "$pkg"Когда apt-mark showauto получает имя пакета, он печатает это имя, только если пакет установлен автоматически, то есть как зависимость. Пустой вывод значит, что пакет уже помечен как установленный вручную. apt install ставит новую версию и помечает пакет как установленный вручную.
Как отменить. Если apt-mark showauto напечатал имя пакета, верните пометку:
sudo apt-mark auto "$pkg"Без этой пометки apt autoremove никогда не удалит пакет, даже если он больше ничему не нужен. Новая версия при этом остаётся на месте. Вернуть старую версию можно, только если она ещё есть в репозитории. Посмотрите таблицу версий в выводе apt policy "$pkg". Если старая версия там есть, укажите её явно: sudo apt install "$pkg"=<версия>.
Способ 2: файл в /etc/apt/apt.conf.d
Параметр APT::Get::Always-Include-Phased-Updates заставляет apt всегда брать поэтапные обновления. Сначала посмотрите, какие настройки фаз у apt есть сейчас:
apt-config dump | grep -i phased || echo "настроек фаз нет"apt-config dump печатает всю текущую конфигурацию apt. Если в ней нет строк со словом phased, grep ничего не выводит и завершается с кодом 1. Поэтому после него стоит || echo. Вы увидите настроек фаз нет, а не пустой экран с кодом ошибки. Если строки нашлись, значит, кто-то уже настроил фазы на этой машине. Разберитесь с ними, прежде чем добавлять свои.
Создайте файл:
echo 'APT::Get::Always-Include-Phased-Updates "true";' | sudo tee /etc/apt/apt.conf.d/99-phased-updates
apt-config dump | grep -i phasedТеперь apt-config dump должен показать строку:
APT::Get::Always-Include-Phased-Updates "true";Следующий apt upgrade поставит все отложенные версии. Документация Ubuntu предлагает добавить в тот же файл вторую строку, Update-Manager::Always-Include-Phased-Updates true;. Её читает графическая программа Update Manager. Сам apt сначала смотрит параметр APT::Get::Always-Include-Phased-Updates, а ключ Update-Manager использует как запасной. На сервере без графической среды хватит первой строки.
Если обновления нужны один раз и файл оставлять не хочется, передайте тот же параметр в командной строке: sudo apt -o APT::Get::Always-Include-Phased-Updates=true upgrade.
Как отменить. Удалите файл и проверьте, что параметр исчез:
sudo rm /etc/apt/apt.conf.d/99-phased-updates
apt-config dump | grep -i phased || echo "настроек фаз нет"Должно напечататься настроек фаз нет. Учтите: удаление файла не откатывает версии, которые уже установились. Оно только возвращает обычное поведение для будущих обновлений.
Обратный вариант: никогда не брать поэтапные обновления
Есть и противоположный параметр, APT::Get::Never-Include-Phased-Updates. С ним apt откладывает любую версию, которая ещё распространяется поэтапно, и machine-id не учитывается. Это полезно на сервере, где стабильность важнее скорости. Обновления безопасности этот параметр не задерживает, потому что они не распространяются поэтапно.
Почему по умолчанию лучше подождать
Отложенная версия ещё проходит проверку на части машин. Если поставить её раньше времени, ваш сервер добровольно войдёт в эту первую группу. Для тестового сервера это разумно. Для рабочего сервера обычно нет.
При этом вы почти ничего не теряете. Обновления безопасности не распространяются поэтапно, поэтому исправления уязвимостей приходят сразу. Это касается и пакетов, которые ставит автоматическая установка обновлений безопасности через unattended-upgrades. Отложенные версии обычно исправляют ошибки, а не уязвимости. Когда процент дойдёт до 100, apt upgrade поставит их сам.
Брать версию раньше стоит в одном случае: в ней исправлена ошибка, которая мешает вам прямо сейчас. Тогда используйте способ 1 и только для этого пакета. Включать все фазы сразу для этого не нужно.
Чем поэтапная задержка отличается от обычного «kept back»
apt может не обновить пакет и по другим причинам. Обычно это зависимости, которые нельзя выполнить без удаления других пакетов, или пометка apt-mark hold. Такие пакеты apt выводит под другим заголовком:
Следующие пакеты будут оставлены в неизменном виде:В английском оригинале это The following packages have been kept back:. В новом формате вывода заголовок звучит как Пропуск обновления:, по-английски Not upgrading:. Если в одном запуске есть пакеты обоих видов, apt добавляет примечание Some packages may have been kept back due to phasing.
Различать эти случаи важно. Поэтапная задержка пройдёт сама. Задержка из-за зависимостей сама не пройдёт, и её нужно разбирать. Проверьте вывод apt-mark showhold. Если проблемы начались после перехода на новый выпуск, прочитайте руководство как восстановить сервер после неудачного обновления выпуска Ubuntu.
FAQ
Почему apt пишет «обновление отложено из-за поэтапного распространения»?
Ubuntu выпускает часть обновлений постепенно, сначала для небольшой доли машин. apt вычисляет число из имени пакета, версии и /etc/machine-id и сравнивает его с полем Phased-Update-Percentage. Если число больше, версия откладывается. Это штатное поведение, а не ошибка. Когда доля дойдёт до 100, apt upgrade поставит версию сам.
Поможет ли повторный apt update получить обновление быстрее?
Нет. Для одной и той же версии число зависит только от имени пакета, версии и machine-id, поэтому ответ не меняется между запусками. Он изменится, когда Ubuntu увеличит процент или выпустит новую версию. Чтобы поставить версию сразу, назовите пакет явно: sudo apt install имя-пакета.
Откладываются ли обновления безопасности?
Нет. Документация Ubuntu Server говорит, что обновления безопасности никогда не распространяются поэтапно. Код apt (функция PhasingApplied в apt-pkg/depcache.cc) отдельно пропускает их при проверке фазы. Поэтому ожидание не оставляет сервер без исправлений уязвимостей.
Почему мои клонированные серверы получают обновление все сразу или ни один?
Скорее всего, у них одинаковый /etc/machine-id. apt использует его в расчёте, поэтому все клоны получают одинаковый ответ для каждой версии. Сравните вывод cat /etc/machine-id на серверах и создайте новый идентификатор на каждом клоне. Если файл пуст, apt вообще не применяет фазу, и машина сразу получает все поэтапные обновления.
Как отменить APT::Get::Always-Include-Phased-Updates?
Удалите файл, в котором задан параметр, например sudo rm /etc/apt/apt.conf.d/99-phased-updates. Потом выполните apt-config dump | grep -i phased. Пустой вывод значит, что параметра больше нет. Версии, которые уже установились, останутся. Удаление файла меняет только поведение будущих обновлений.