← блог

Как лимит подключений к базе данных чуть не перезагрузил Mac моих клиентов

20 сентября 2026 г. · 7 мин чтения

Мы держим небольшой парк Mac mini для клиентов. Демон на хабе опрашивает каждую машину по SSH, отправляет телеметрию в control plane и эскалирует, когда машина замолкает. Сначала он ждёт. Потом перезапускает питание машины через умную розетку. Потом зовёт человека.

На прошлой неделе control plane начал отвечать ошибками 500. Через тринадцать минут демон решил, что все четыре Mac мертвы, и записал перезапуск питания для каждого. Два принадлежали платящим клиентам. Третий был продан тем же утром.

Что на самом деле сломалось

Пул подключений к базе данных. Control plane работает на serverless функциях с пулером Postgres, у которого лимит на весь проект пятнадцать подключений. Несколько тёплых функций заняли их все, и каждый маршрут API, работающий с базой, начал падать. Подробности в отдельном посте.

С Mac всё было в порядке. SSH работал. Все графические сессии были подняты. Клиент, который собирал проект на одном из них, ничего не заметил. Сломана была только система, чья работа знать, сломаны ли Mac.

Как здоровый парк стал выглядеть мёртвым

Демон хранил одну метку времени на машину: когда опрос в последний раз прошёл успешно. Логика эскалации сравнивала её с текущим временем. Опрос вполне разумно начинался с получения списка машин из control plane. Если получить его не удавалось, опрос завершался досрочно.

Поэтому во время сбоя ни один опрос не выполнялся, ни одна метка не сдвигалась, и все разрывы росли одновременно. Логика эскалации не знала, что демон даже не пытался. Она видела тринадцать минут тишины от четырёх машин и сделала то, для чего её построили.

ladder: Unit 02 unreachable 12m51s → power cycle
ladder: Unit 03 unreachable 12m51s → power cycle
ladder: Unit 04 unreachable 12m51s → power cycle
ladder: Unit 05 unreachable 12m43s → power cycle

Почему ничего не перезагрузилось

Умная розетка не была настроена. Шаг перезапуска питания проверил наличие розетки, не нашёл её и пошёл дальше. Потом у четырёх машин был аптайм шесть дней, шесть дней, один день и около часа. Их никто не трогал.

Это везение, а не замысел. Умные розетки входят в план для следующей партии машин. Будь они установлены, проблема с подключениями к базе отключила бы питание трём клиентским Mac. Один из них, возможно, был посреди сборки. Ни один из них ничего плохого не сделал.

Исправление

Теперь демон записывает, когда ему в последний раз удалось получить список машин и реально попробовать связаться с ними. Логика эскалации отказывается действовать, если это было давно. И пишет в лог причину: сбой в control plane, а не в машинах.

ladder: skipped, no successful unit poll in 14m02s (control plane, not the units)

Эта строка точно говорит, что она отказывается делать и почему. Именно это старая версия должна была сказать с самого начала.

Правило под этим простое. Восстановление должно требовать доказательства, что проверка выполнилась. "Мы пытались связаться и не смогли" это доказательство. "Мы о нём ничего не слышали" нет. Ведь ровно так же выглядит сбой того, кто слушает.

Что проверить в своей автоматизации

Мы проверяли, что происходит, когда умирает Mac. Мы ни разу не проверяли, что происходит, когда умирает то, что следит за Mac. Это разные проверки, и именно вторая тянется к выключателю питания.

Вопросы

Должны ли действия восстановления вроде перезапуска питания быть автоматическими?
Да, но только при положительном доказательстве, что отказала сама цель. Действие, которое срабатывает на отсутствие информации, сработает при любом сбое того, что эту информацию собирает.
Как проверить это, не сломав продакшен?
Отключайте наблюдателя, а не узлы. Закройте демону доступ к его control plane и посмотрите, что решит автоматика восстановления. Если она эскалирует, она делает выводы из тишины.
Каким должен быть порог недоступности?
Дольше любого ожидаемого кратковременного сбоя control plane. И отсчёт должен начинаться только после неудачной попытки достучаться до узла, а не с того момента, когда узел случайно видели в последний раз.

Посчитайте свои цифры в калькуляторе или арендуйте раннер.