Восстановление работы кластера 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;
Решение проблемы Suspiciously many broken parts
Один из узлов кластера потребовалось выключить для выполнения работ, связанных с электроснабжением стойки. После включения сервера узел кластера ClickHouse перестал запускаться, а в журнале сервера можно было найти ошибку такого вида:
2026.08.28 14:40:50.889391 [ 11913 ] {} <Error> void DB::AsyncLoader::worker(Pool &): Code: 231. DB::Exception: Suspiciously many (159 parts, 0.00 B in total) broken parts to remove while maximum allowed broken parts count is 100. You can change the maximum value with merge tree setting 'max_suspicious_broken_parts' in <merge_tree> configuration section or in table settings in .sql file (don't forget to return setting back to default value): Cannot attach table `redqueen`.`billing` from metadata file /srv/clickhouse/store/ea2/ea2d29c4-447f-4144-bfb1-f64bc04f0ea7/billing.sql from query ATTACH TABLE redqueen.billing UUID 'e3d2bbc2-1263-431d-94eb-5a54cd4d01fc' (`severity` Int32, `facility` Int32, `timestamp` DateTime, `hostname` String, `tag` String, `message` String) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{uuid}/{shard}', '{replica}') PARTITION BY toStartOfInterval(timestamp, toIntervalHour(1)) ORDER BY (timestamp, hostname) TTL timestamp + toIntervalHour(8) SETTINGS index_granularity = 8192, ttl_only_drop_parts = 1. (TOO_MANY_UNEXPECTED_DATA_PARTS), Stack trace (when copying this message, always include the lines below):
Для решения проблемы понадобилось увеличить лимит max_suspicious_broken_parts до 1024, создав файл /etc/clickhouse-server/config.d/max_suspicions_borken_parts.xml со следующим содержимым:
<clickhouse>
<merge_tree>
<max_suspicious_broken_parts>1024</max_suspicious_broken_parts>
</merge_tree>
<replicated_merge_tree>
<max_suspicious_broken_parts>1024</max_suspicious_broken_parts>
</replicated_merge_tree>
</clickhouse>
И выставив его владельцем пользователя clickhouse:
# chown clickhouse:clickhouse /etc/clickhouse-server/config.d/max_suspicions_borken_parts.xml
После чего удалось запустить узел кластера ClickHouse. Для надёжности стоит также запустить принудительное восстановление синхронности реплики с помощью команды, описанной в следующем разделе этого документа.
Восстановление работы реплики
Если сервис координации исправен, но реплика долгое время отсутствовала в сети, то журналы изменений в сервисе координации могли уйти далеко от состояния, которое помнит реплика. В таком случае реплика не сможет проследить изменения по журналам координатора и синхронизировать своё состояние с исправными актуальными репликами. Для восстановления работы реплики в таких случаях необходимо сравнить собственное состояние с состоянием в координаторе и определить, какие фрагменты данных нуждаются в синхронизации. Сделать это можно с помощью такой команды:
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;'"