Восстановление после потери PHP-сессий
Как новое поколение PHP начинается после утраты временного состояния — автоматически после перезагрузки сервера или вручную — и как проверить итог без повтора старых форм.
Временное состояние PHP может исчезнуть при перезапуске VPS, Docker или PHP-контейнера. Micator закрывает небезопасное исполнение. После подтверждённой перезагрузки сервера новое поколение PHP-сессий начинается автоматически, в остальных случаях владелец начинает его вручную. Потерянное содержимое сессий этот порядок не восстанавливает.
Ручной порядок относится к контракту PHP format2. Автовосстановление доступно с выпуска 20261101.1, контроллер 20261101, и требует обновления установки. Наличие статьи не обновляет сервер; ручной recovery требует явного согласия владельца на потерю сессий.
Что происходит при потере состояния
Новое приложение проверяет поколение PHP и служебные метки до обработчика. При потере, повреждении или неготовности состояния обработчик не вызывается и POST автоматически не повторяется. Ошибка проверки пула в PHP даёт 503; запрос со старым или недействительным защищённым доступом может получить 404. В прежнем контракте новое поколение запускается вручную. В выпуске 20261101.1 подтверждённая перезагрузка ОС обрабатывается по правилам автоматического восстановления; перезапуск отдельной службы или повтор обновления не запускают автоматическое восстановление. Если PHP-состояние потеряно, нужны ручная проверка и recovery.
При первом закреплении работающих legacy-пулов служба сначала сохраняет устойчивый барьер входящего трафика, затем меняет их runtime restart policy на no без остановки и пересоздания и только потом записывает состояние сохранения PHP. Барьер переживает прерывание или перезапуск ОС между этими шагами: старое приложение не должно получить пустой legacy-пул. Если обновление отклонено или прервано уже после записи состояния, но до начала резервной копии, служба сама снимает барьер (при прерывании — при следующем запуске), пока оба пула ограждены и совпадают с записью: прежнее приложение продолжает обслуживать те же закреплённые пулы. Иначе барьер остаётся, а php-status показывает lost. Если снять барьер при запуске не удалось (например, Docker не ответил), служба не повторяет попытку: барьер остаётся, пока обновление не продолжено командой из раздела ниже, а php-status показывает requires_compatible_release. Не возвращайте прежнюю restart policy и не удаляйте барьер вручную; продолжайте исходную операцию после проверки причины.
Это отказ выполнения PHP с неизвестным состоянием. Он не является причиной самостоятельно выключать приём постбеков или обычные внешние редиректы. Во время самого recovery служба может оградить и перезапустить процессы приложения, чтобы завершить запросы и проверить совместимый код; непрерывность всего трафика этим порядком не обещается.
Пока восстановление держит приложения остановленными, трекер ставит трафик на паузу так же, как при создании копии: ссылки кампаний, локальные лендинги и офферы, приём постбеков и лидов отвечают кодом 503 с текстом Tracker maintenance in progress. Клики и постбеки, пришедшие за это время, не сохраняются. Исходящие постбеки не отправляются и ждут в очереди, разделы панели не загружают данные. Пауза снимается сама, когда совместимые приложения снова запущены, а при старом приложении — когда завершено обновление до совместимого выпуска. PHP остаётся закрытым до завершения восстановления.
Автоматическое восстановление после перезагрузки
С выпуска 20261101.1, контроллер 20261101. Новый контракт автоматически начинает новое поколение PHP после подтверждённой перезагрузки самого сервера. Потерянные сессии и заполненные формы не возвращаются. Старый POST не повторяется; посетитель должен заново открыть ссылку кампании и новую форму. На часть восстановления приложения останавливаются: до их повторного запуска трафик получает ответ 503 об обслуживании, как описано выше.
Служба ждёт запуска приложений и проверяет прежнее состояние, текущий выпуск, PHP-пулы и настройки. Она не вмешивается в установку, обновление, восстановление копии или перенос истории. Изменение файлов, подмена контейнера либо потеря служебной записи требуют проверки администратора. Один перезапуск службы обновлений или отдельного PHP-контейнера сам по себе не разрешает сброс сессий.
Если при перезагрузке Redis остановился раньше сервера обработки, в Redis остаётся запись прежнего процесса. Следующий запуск того же контейнера удаляет её, как только с последнего отклика проходит больше 30 секунд, поэтому такая запись не мешает ни автоматическому, ни ручному восстановлению. Запись пересозданного контейнера так не удаляется, а запись другого сервера обработки удаляет следующий запуск его собственного контейнера. Пока такая запись есть, восстановление отклоняется; она исчезает сама через 24 часа после последнего отклика. Если этот сервер выведен из работы, убедитесь, что он действительно остановлен и не принимает трафик.
Прерванное автоматическое восстановление продолжается с тем же поколением; повторный запуск контроллера не создаёт ещё одно. После успешной проверки служба прекращает повторные обращения к Docker до изменения состояния. Успех или устойчивый отказ появляется в уведомлениях владельца, ход операции сохраняется в журнале службы обновлений.
Проверьте sudo micatorctl php-status: команда печатает одну строку JSON, успешный результат содержит "state":"ready" и "ready":true. Если автоматическое восстановление не завершилось, сохраните журналы и выполните проверки ниже. Ручной php-recover с прежними пятью подтверждениями остаётся доступен; он также позволяет продолжить незавершённую операцию после потери локального ключа. Копия с другого сервера не даёт разрешения автоматически сбросить сессии на этой установке.
Что проверить владельцу
Команду выполняет владелец установки с правами root на сервере управляемой клиентской установки. Перед ней:
- Проверьте фактические процессы, слоты, PHP-пулы, ноды и балансировщик. Старый процесс не должен обойти закрытый PHP-контур.
- Проверьте HTTPS, CDN и обход кеша для кампаний, hosted-путей и переходов; уберите старые кешированные ответы.
- Подтвердите границу отката и восстановления. После recovery нельзя возвращать старое приложение или снимок состояния, который снимает этот барьер.
- Проверьте PHP-обработчики и внешнего получателя на тестовой форме.
- Примите потерю всех текущих PHP-сессий, а не только одного сломанного пула. Заявки, уже принятые внешним получателем, не нужно повторять.
Старые sess_* не копируются между страницами или поколениями. Cookie PHPSESSID не служит источником восстановления или доказательством владельца файла.
Проверить состояние
До любых действий выполните на сервере:
sudo micatorctl php-statusЭто проверка через локальный root-контроллер. Команда печатает одну строку JSON с полями format, state, ready, private_ready, legacy_preserved, legacy_retired, php_epoch, controller_min_version, witness_sha256, а при наличии плана — plan_sha256, start, legacy_until и arm_plan. Она показывает текущее поколение и готовность PHP, в том числе потерю состояния или незавершённую операцию; не создаёт новый epoch и не запускает или продолжает recovery.
"state":"ready"и"ready":true— PHP подтверждён; новое восстановление не требуется.lost— прежнее временное состояние больше не подтверждается: пул перезапущен, метка или ограждение потеряны.recovering— готовность ещё не подтверждена. Причиной может быть незавершённый recovery или промежуточная публикация root-плана после arm. Если прерван arm при здоровых пулах, используйте подтверждённый повтор того же arm, а не сброс сессий.requires_compatible_release— для продолжения нужен совместимый подписанный выпуск. Так же отображается прерванное или отклонённое первое обновление с сохранением PHP: работающие legacy-пулы те же, что были закреплены, сессии не потеряны. Подтверждённыйphp-recoverв этом состоянии не создаёт новое поколение и не сбрасывает сессии; с--target-versionэтого выпуска он продолжает то же обновление (см. ниже).php_epochиlegacy_retired— поколение сессий и выведены ли legacy-пулы из обслуживания. Если присутствуетarm_plan, это исходный закреплённый план с ID и датамиstart/legacy_until. Сверяйте их без продления или создания новых дат.
При здоровом PHP повтор php-recover не создаёт ещё одно поколение и не теряет здоровые сессии. Без незавершённого задания обычный вызов или --target-version с уже установленной версией только возвращает статус. Явный другой target может запустить установку ранее принятого и закреплённого совместимого кандидата, сохранив текущий epoch; этот узкий случай описан ниже. Если уже есть незавершённое recovery-обновление в фазе переключения или фиксации, исходное задание имеет приоритет: повторяйте его target, другое значение не подменяет pending job. Команду нельзя добавлять в автоматику. ready не означает завершённое обновление или открытый трафик.
Ручная команда
Для установки с действующим совместимым приложением:
sudo micatorctl php-recover \
--inventory-confirmed \
--cache-confirmed \
--restore-confirmed \
--php-confirmed \
--accept-session-lossВсе пять флагов обязательны. Последний явно принимает потерю сессий. Их нельзя добавлять в автоматический boot-скрипт, cron или обычную команду обновления. Первое фактическое восстановление после потери состояния создаёт durable intent; что делать, если команда прервалась, описано ниже.
Если при запуске восстановления идёт другая операция с паузой трафика — обновление, создание или восстановление копии либо перенос из Keitaro, — php-recover отказывает, ничего не останавливая, и печатает «Local controller refused the operation; the PHP recovery journal is preserved.» Завершите эту операцию и повторите ту же команду.
Служба проверяет приложение и подписанный PHP-runtime, закрывает прежнее исполнение, ждёт завершения обработчиков и создаёт новые private-пулы. Новый PHP epoch относится к сессиям и доступу, а не к версии HTML/PHP-файлов страницы.
Если работает старое приложение
После разрешённого до активации отката могут остаться несовместимые Go-процессы. Recovery в этом случае остаётся закрытым и сообщает requires_compatible_release. Если php-recover уже остановил старое приложение, оно остаётся остановленным до установки совместимого выпуска: служба его снова не запускает, а трафик получает ответ 503 об обслуживании. Нужен проверенный совместимый подписанный выпуск через штатный контроллер:
То же состояние и та же команда применимы, если первое обновление с сохранением PHP было отклонено или прервано до переключения приложения. Подтверждения команды обязательны, но здесь сессии не сбрасываются: обновление продолжается по ранее принятому подписанному комплекту.
sudo micatorctl php-recover \
--inventory-confirmed \
--cache-confirmed \
--restore-confirmed \
--php-confirmed \
--accept-session-loss \
--target-version 0.1.0-beta.20261101.1Тот же явный вызов с --target-version применим и после отката к старому приложению, когда php-status уже показывает здоровый PHP. Если target отличается от установленной версии, контроллер может запустить только ранее принятый и закреплённый точный подписанный комплект. В этой ветке новое recovery не запускается, epoch и здоровые сессии не сбрасываются, публичный latest-каталог не используется как запасной вариант. Если такого сохранённого кандидата нет, команда отказывает без перехода на другую версию. Это обычное обновление с остановкой: на время переключения возможна пауза трафика приложения, даже если PHP-сессии сохранены. Это не произвольный выбор версии или обход нижней границы отката. compatible_update_job означает запущенное или продолженное задание, а не его завершение.
После первоначального принятия подписанного комплекта контроллер сохраняет и закрепляет его точные байты: архив, подписанный каталог и манифест. Повтор с тем же --target-version может продолжить работу по этому ранее принятому комплекту, даже если в публичном каталоге уже другая версия или прежний каталог истёк. Подписи, хеши и совместимость проверяются снова. Это узкое исключение для тех же закреплённых байтов, а не разрешение использовать любой старый каталог, одноимённый архив или другой источник.
Если сохранённые файлы отсутствуют, изменены или не соответствуют закреплённому кандидату, продолжение закрывается. Не удаляйте кеш, журнал или root-запись и не подменяйте версию ради обхода: сохраните состояние и обратитесь в поддержку.
Какие формы больше не работают
Потеря одного пула требует смены общего PHP epoch. После фактического создания нового поколения из-за потери состояния все прежние защищённые посещения и формы теряют доступ. Установка только сохранённого кандидата при здоровом PHP сама по себе не меняет epoch и не инвалидирует формы этим механизмом. После восстановления из-за потери состояния старые legacy-пулы выведены из обслуживания навсегда; raw POST к прежнему пути, в том числе к ссылке кампании или /clk, не превращается в новый POST и не получает пустую новую сессию.
Чтобы начать новую работу, откройте заново ссылку кампании обычным GET. Она выдаёт новое ограниченное посещение и использует private-сессии, даже если отдельный переход защиты ещё находится в compat. Это явное recovery-исключение к прежнему режиму. Прямой GET на старый PHP-путь не обновляет доступ автоматически.
Сохранённые даты start и legacy_until плана защиты остаются прежними. Recovery не начинает новое 48-часовое окно и не продлевает открытые формы. Ограничение старого отката и in-place restore после нового epoch сохраняется независимо от часов.
Сбой во время recovery
При прерывании повторите ту же подтверждённую команду после проверки причины. Продолжение использует исходный intent, epoch и nonce; новый срок защиты не создаётся. Пока приложение или PHP не готовы, исполнение остаётся закрытым. Не удаляйте журналы операции, метки и файлы состояния и не пересоздавайте контейнеры вручную.
Ручной php-recover, прерванный перезапуском контроллера или перезагрузкой сервера, сам не продолжается: повторите ту же команду. До этого трекер может отвечать 503 (обслуживание), а PHP остаётся закрытым. Исключение — обновление до совместимого выпуска, которое уже дошло до этапа «Создание резервной копии»: его служба обновлений продолжает сама; итог проверяйте в истории операций обновления.
Состояния recovering, lost и requires_compatible_release не означают завершения. ready означает готовность поколения PHP, но не завершение recovery-обновления: оно ещё может переключать приложение или фиксировать итог. Повторяйте ту же подтверждённую команду, чтобы продолжить то же задание и поколение PHP. Значение compatible_update_job — ID запущенного или продолжаемого задания; проверяйте его итог в истории операций обновления. При непонятном состоянии обратитесь в поддержку.
Проверка результата
- Дождитесь успешного итога исходного задания обновления, готовности совместимого приложения и private-пулов. Один
compatible_update_jobилиreadyэтого не подтверждает. - Повторите
sudo micatorctl php-status: нужны"state":"ready"и"ready":true. После восстановления из-за потери состояния нужны"legacy_retired":trueи новыйphp_epoch; при установке сохранённого кандидата со здоровым PHP поколение и значениеlegacy_retiredдолжны остаться прежними. Старое сообщение терминала не является свежей проверкой. - В отдельном браузерном профиле откройте ссылку тестовой кампании, загрузите ресурсы и отправьте новую тестовую форму. Проверьте внешнего получателя.
- После смены поколения старое защищённое посещение и старый raw POST должны получить отказ без повторного вызова обработчика. При обновлении со здоровым PHP проверьте сохранение открытой тестовой формы без повторной отправки реальной заявки.
- Сверьте исходные даты плана защиты, открытый трафик, статусы редиректов и приёма событий. Не отправляйте реальные заявки повторно ради проверки.
Восстановление после фактической потери состояния возобновляет работу с новыми сессиями. Оно не возвращает содержимое старых форм, корзин, CSRF-состояния или уже утраченных временных файлов.