Железо и софт • 06.06.2026
CockroachDB выдает ошибку Range lease holder unavailable и блокирует шарды как исправить
Развернул распределенный отказоустойчивый кластер CockroachDB из пяти нод на серверах Linux для обработки финансовых транзакций. Во время планового теста на изоляцию сети и принудительное отключение одной из нод, СУБД полностью заблокировала запись в связанные таблицы, а в консоли бэкенда вылетел критический лог сбоя: «retryable error: Range lease holder unavailable» или «context deadline exceeded: range lease acquisition timeout». В этот момент pgAdmin и клиентские приложения уходят в глухой ступор ожидания ответа сокетов. При этом оставшиеся четыре ноды видят друг друга, но кворум Raft для пострадавших диапазонов данных (ranges) завис. Подскажите, из-за каких внутренних лимитов синхронизации времени или параметров таймаутов распределенного консенсуса падает СУБД и как оперативно разблокировать шарды?
Ответы (5)
Артем СУБД
Здорово! Ты столкнулся с фундаментальной особенностью архитектуры NewSQL баз данных. Ошибка "Range lease holder unavailable" означает, что конкретный диапазон данных (range) потерял своего держателя аренды (leaseholder) — ноду, которая единолично отвечает за чтение и запись в этот шард. По спецификации CockroachDB, аренда выдается узлу на жестко ограниченный срок и постоянно продлевается через протокол Raft. Если одна нода внезапно падает, кластер обязан переизбрать нового держателя аренды на живых узлах. Но если у тебя на серверах разъехалось системное время (clock skew) хотя бы на 100-200 миллисекунд, распределенный консенсус блокируется намертво, так как узлы не могут согласовать валидность временных меток.
Марина Девопс
Чтобы принудительно восстановить стабильный запуск распределенного консенсуса и убрать мертвые блокировки шардов, необходимо выстроить строгое единое время на всех серверах по шагам:
1. Подключитесь по SSH к каждой из пяти нод вашего распределенного кластера от имени root.
2. Установите продвинутый демон синхронизации времени, выполнив команду: `sudo apt install chrony` (или `yum install chrony` для RHEL).
3. Откройте файл глобальной конфигурации `sudo nano /etc/chrony/chrony.conf` и убедитесь, что на всех серверах прописаны одни и те же надежные NTP-пулы с низким пингом, например: `pool ://ubuntu.com iburst maxpoll 6`.
4. Сохраните документ, закройте nano и принудительно перезапустите службу синхронизации: `sudo systemctl restart chrony`.
5. Проверить текущий статус расхождения часов можно системной командой `chronyc tracking`. Убедитесь, что строка `Last offset` упала до значений в пределах микросекунд. Ноды мгновенно согласуют Raft-аренду, и ступор сокетов СУБД снимется.
Дмитрий Сис
Ребята, если системные часы на серверах идут идеально ровно, а acquisition timeout продолжает намертво вешать транзакции, проверяйте параметры ваших конфигураций зон репликации (zone configurations). Сбой переизбрания leaseholder-а наступает лавинообразно, если вы жестко зажали размещение реплик по конкретным гео-зонам с помощью ограничений `constraints`. Если вы отключили одну ноду, которая была единственным легальным держателем аренды в определенном дата-центре согласно вашим правилам yaml, выжившие ноды из других регионов просто откажутся забирать этот шард себе, уходя в бесконечный цикл ожидания.
Никита Облако
Если ваш кластер развернут в условиях нестабильных сетевых мостов между серверами (высокий network latency), увеличьте внутренние лимиты ожидания консенсуса без остановки СУБД по инструкции:
1. Запустите встроенный интерактивный SQL-клиент СУБД на любом живом узле: `cockroach sql --insecure --host=localhost:26257`.
2. Введите административную команду расширения допустимого порога расхождения часов, чтобы база не паниковала при мелких сетевых лагах: `SET CLUSTER SETTING server.clock.max_offset = '500ms';`.
3. Следом увеличьте время ожидания ответа от Raft-групп перед тем, как шард признается потерянным, прописав команду: `SET CLUSTER SETTING kv.raft_allocator.lease_rebalance_aggression = 'relaxed';`.
4. Дополнительно поднимите таймаут сетевых gRPC-запросов между нодами: `SET CLUSTER SETTING kv.transaction.max_intents_bytes = 10485760;`.
5. Введите `q` для выхода из консоли. Кластер адаптируется к сетевым пакетам с задержками и автоматически распределит аренду шардов.
Роман Кьюб
Если одна из ваших нод сгорела аппаратно и больше никогда не вернется в строй, а кластер продолжает бесконечно пытаться достучаться до её сокетов и блокирует часть диапазонов, исключите её принудительно. Вызовите встроенную консольную утилиту администрирования нод: `cockroach node decommission ID_НОДЫ --insecure --host=localhost:26257` (узнать точный ID можно через `node ls`). Этот шаг заставит менеджер репликации немедленно переписать Raft-карты, запустить миграцию потерянных осколков на четыре живых сервера и полностью снять ошибку lease holder.