Восстановление работы кластера ClickHouse
Содержание
Восстановление после потери кворума
Если координаторы теряют кворум, то в журналах сервера ClickHouse можно наблюдать ошибки Code: 999. Coordination::Exception: Session expired. (KEEPER_EXCEPTION) следующего вида:
2024.07.10 15:01:53.419106 [ 223559 ] {} <Error> redqueen.billing (db561f37-c0c1-4cd6-8c95-4411ce927181): void DB::StorageReplicatedMergeTree::queueUpdatingTask(): Code: 999. Coordination::Exception: Session expired. (KEEPER_EXCEPTION), Stack trace (when copying this message, always include the lines below):
Если проверить состояние реплицируемых таблиц с помощью следующего запроса:
SELECT is_readonly, last_queue_update_exception
FROM system.replicas\G
То можно увидеть, что таблицы находятся в состоянии "только чтение" с ошибкой вида Code: 999. Coordination::Exception: Session expired. (KEEPER_EXCEPTION).
Для восстановления работы сервиса координации нужно выбрать один из них, остановить остальные и выполнить на выбранном команду восстановления следующим образом:
$ echo rcvr | nc localhost 9181
Далее нужно по очереди запускать остальных координаторов. Когда количество работающих узлов координатора достигнет кворума, один из узлов сервиса координации возьмёт на себя роль leader, а другие возьмут на себя роли follower. Чтобы проверить текущую роль узла координации, можно воспользоваться такой командой:
$ echo mntr | nc localhost 9181 | awk '$1 == "zk_server_state" { print $2; }'
Следующим шагом будет восстановление информации о таблицах в координаторах. Для этого на исправном сервере ClickHouse, содержащем все данные, нужно выполнить запрос:
SYSTEM RESTORE REPLICA ON CLUSTER core;
Восстановление работы реплики
Если сервис координации исправен, но реплика долгое время отсутствовала в сети, то журналы изменений в сервисе координации могли уйти далеко от состояния, которое помнит реплика. В таком случае реплика не сможет проследить изменения по журналам координатора и синхронизировать своё состояние с исправными актуальными репликами. Для восстановления работы реплики в таких случаях необходимо сравнить собственное состояние с состоянием в координаторе и определить, какие фрагменты данных нуждаются в синхронизации. Сделать это можно с помощью такой команды:
SYSTEM RESTART REPLICAS;
Восстановление синхронности таблиц
По каким-то непонятным причинам может сложиться такая ситуация, что реплицируемая таблица есть на одном узле, но отсутствует на другом узле. В таком случае для восстановления таблицы можно прибегнуть к помощи скрипта schema_for_replica.sh, описанного на странице Добавление и удаление реплик в кластер ClickHouse. Для этого в его выводе нужно найти выражение CREATE TABLE для интересующей нас таблицы.
Далее нужно подключиться с помощью clickhouse-client к узлу кластера, на котором отсутствует реплицируемая таблица, чтобы создать её.
Прежде чем пытаться создать отсутствующую таблицу, нужно сначала разрешить явное указание UUID реплицируемой таблицы. Обычно действует защита, запрещающая создавать новые таблицы с UUID, уже используемым в кластере. В данном случае нам нужно сделать именно это - создать таблицу, которая уже есть на другом узле кластера, но по каким-то причинам отсутствует на текущем узле. Отключим защиту:
SET database_replicated_allow_explicit_uuid = 1;
Узнать текущее значение этой опции, действующей в рамках текущего сеанса, можно с помощью такого запроса:
SELECT value FROM system.settings WHERE name = 'database_replicated_allow_explicit_uuid';
Далее нужно выполнить сам запрос на создание недостающей таблицы. И запустить синхронизацию узлов кластера:
SYSTEM RESTART REPLICAS;
Синхронизация таблиц будет выполняться в фоновом режиме. Изменённое значение опции database_replicated_allow_explicit_uuid действует только в рамках текущего подключения, поэтому возвращать прежнее значение не обязательно - достаточно просто выйти из clickhouse-client.
За активностью фоновой синхронизации таблиц можно наблюдать с помощью команды:
# watch "clickhouse-client -d system -q 'SELECT database, table, progress FROM replicated_fetches;'"