破損または不正な ClickHouse Keeper スナップショットは、メタデータの不整合、テーブルの読み取り専用状態、リソースの枯渇、バックアップの失敗など、システムに重大な不安定さを引き起こす可能性があります。この記事では、次の内容を扱います。
- スナップショットとは何か、またどこで見つけられるか
- 問題がどのように現れるか
- 考えられる復旧戦略 と、それぞれが何を意味するのか
Keeper スナップショットの概要
スナップショットとは?
スナップショットは、ある時点における Keeper の内部データ (クラスターに関するメタデータ、テーブルの協調に使用されるパス、設定など) をシリアライズした状態です。スナップショットは、クラスター内の Keeper ノードの再同期、障害発生時のメタデータ復旧、そして既知の正常な Keeper の状態に依存する起動・再起動処理において重要です。
スナップショットはどこにありますか?
スナップショットは、Keeper ノードのローカルファイルシステム上にファイルとして保存されます。デフォルトでは /var/lib/clickhouse/coordination/snapshots/ に保存され、keeper_server.xml ファイルの snapshot_storage_path でカスタムパスを指定している場合は、そちらに保存されます。スナップショットには連番の名前 (例: snapshot.23) が付けられ、新しいものほど番号が大きくなります。
マルチノードのクラスターでは、各 Keeper ノードごとに独自のスナップショットディレクトリがあります。
破損した Keeper スナップショットの主な症状と兆候
以下の表は、破損した Keeper スナップショットでよく見られる主な症状と兆候を示しています。
| Category | Issue Type | What to look for |
|---|---|---|
| 運用上の問題 | 読み取り専用モード | テーブルが予期せず 読み取り専用モードに切り替わる |
| クエリ失敗 | Coordination::Exception エラーを伴うクエリ失敗が継続的に発生する |
|
| メタデータ破損 | 古いメタデータ | 削除したテーブルが反映されない、古いメタデータが原因で操作に失敗する |
| リソース過負荷 | システムリソースの枯渇 | Keeper ノードが CPU、メモリ、またはディスク領域を過剰に消費し、ダウンタイムにつながる可能性がある |
| ディスクフル | スナップショット作成中にディスクがいっぱいになる | |
| バックアップと復元 | バックアップ失敗 | Keeper のメタデータの欠落または不整合によりバックアップが失敗する |
| スナップショットの作成/転送 | Keeper のクラッシュ | スナップショット作成の途中で Keeper がクラッシュする (SEGFAULT エラーを確認) |
| スナップショット転送時の破損 | レプリカ間でのスナップショット転送中に破損が発生する | |
| 競合状態 | ログのコンパクション中に競合状態が発生する - バックグラウンドのコミットスレッドが削除済みのログにアクセスする | |
| ネットワーク同期 | リーダーからフォロワーへのスナップショット同期を妨げるネットワークの問題 |
ログ上の指標:
スナップショットの破損を診断する前に、まず Keeper ログ で特定のエラーパターンを確認してください。
| Log Type | What to Look For |
|---|---|
| スナップショット破損エラー | • Aborting because of failure to load from latest snapshot with index• Failure to load from latest snapshot with index {}: {}. Manual intervention is necessary for recovery• Failed to preprocess stored log at index {}, aborting to avoid inconsistent state• 起動時のスナップショットのシリアライゼーションまたは読み込みの失敗 |
| その他の Keeper の問題 | • Coordination::Exception• Zookeeper::Session Timeout• 同期またはリーダー選出の問題 • ログコンパクション時の競合状態 |
破損した Keeper スナップショットからの復旧
ファイルに手を加える前に、必ず次の対応を行ってください:
- さらなる破損を防ぐため、すべての Keeper ノードを停止する
- 協調ディレクトリ全体を安全な場所にコピーし、完全にバックアップを取る
- 少なくとも 1 つのノードに正常なデータがあることを確認するため、クラスターのクォーラムを確認する
1. 既存のバックアップから復元する
次のいずれかに該当する場合は、この手順に従ってください。
- Keeper のメタデータまたはスナップショットの破損により、現在のデータを復旧できない。
- 正常な Keeper の状態を含むバックアップがある。
既存のバックアップから復元するには、以下の手順に従ってください。
- 最新のバックアップを特定し、メタデータの整合性を確認します。
- ClickHouse と Keeper のサービスを停止します。
- 問題のあるスナップショットとログを、バックアップディレクトリ内のものに置き換えます。
- Keeper クラスターを再起動し、メタデータが同期されていることを確認します。
2. 古いスナップショットへのロールバック
次のような場合は、この手順に従ってください。
- 最新のスナップショットは破損しているが、古いスナップショットは引き続き使用できる。
- 整合性のある復旧に必要なインクリメンタルログが無傷で残っている。
古いスナップショットにロールバックするには、以下の手順に従います。
- Keeper ディレクトリから有効な古いスナップショット (例: snapshot.19) を特定して選択します。
- より新しいスナップショットとログを削除します。
- Keeper を再起動し、ログを再生してメタデータの状態を再構築させます。
3. SYSTEM RESTORE REPLICA を使用したメタデータの復元
次のような場合は、この手順に従ってください。
- Keeper のメタデータが失われている、または破損している一方で、テーブルデータは引き続きディスク上に存在している
- ZooKeeper/Keeper のメタデータが欠落しているため、テーブルが読み取り専用モードに切り替わっている
- ローカルで利用可能なデータパーツに基づいて、Keeper 内のメタデータを再作成する必要がある
メタデータを復元するには、以下の手順に従います。
-
テーブルデータが、config の
<path>で設定されたローカルの clickHouse-server データパスに存在することを確認します (デフォルトは/var/lib/clickhouse/data/) 。 -
影響を受ける各テーブルに対して、次を実行します。
SYSTEM RESTART REPLICA [db.]table_name;
SYSTEM RESTORE REPLICA [db.]table_name;- データベースレベルで復旧する場合 (Replicated データベースエンジンを使用している場合) :
SYSTEM RESTORE DATABASE REPLICA db_name;- 同期が完了するまで待ちます:
SYSTEM SYNC REPLICA [db.]table_name;is_readonly = 0になっていることをsystem.replicasで確認し、system.detached_partsを監視して復旧を検証します
4. Keeper 内のレプリカのメタデータを削除して再作成する
次のような場合は、この手順に従ってください。
- エラーがクラスター内の単一のレプリカで発生しており、そのレプリカの Keeper 内のメタデータが破損している、または不整合が生じている
- "Part XXXXX intersects previous part YYYYY" のようなエラーが発生する
- ローカルデータを保持したまま、レプリカの Keeper メタデータを完全にリセットする必要がある
メタデータを削除して再作成するには、以下の手順に従ってください。
- 影響を受けているレプリカで、テーブルをデタッチします。
DETACH TABLE [db.]table_name;- Keeper からレプリカのメタデータを削除します (任意のレプリカで実行) :
SYSTEM DROP REPLICA 'replica_name' FROM ZKPATH '/clickhouse/tables/{shard}/table_name';適切な ZooKeeper パスを見つけるには:
SELECT zookeeper_path, replica_name FROM system.replicas WHERE table = 'table_name';- テーブルを再アタッチします (読み取り専用モードになります) :
ATTACH TABLE [db.]table_name;- レプリカのメタデータを復元します:
SYSTEM RESTORE REPLICA [db.]table_name;- 他のレプリカと同期します:
SYSTEM SYNC REPLICA [db.]table_name;- 復旧後、すべてのレプリカで
system.detached_partsを確認します
代替: force_restore_data フラグを使用する
サーバー起動時にすべてのレプリケートテーブルを自動復旧するには、次の手順を実行します。
- ClickHouseサーバー を停止します
- 復旧フラグを作成します:
sudo -u clickhouse touch /var/lib/clickhouse/flags/force_restore_data- ClickHouseサーバーを起動します
- サーバーは自動的にフラグを削除し、すべてのレプリケートテーブルを復元します
- ログで復旧の進行状況を監視します
この方法は、複数のテーブルを同時に復旧する必要がある場合に有効です。
5. Keeper クラスターを再構築する
次の場合は、この手順に従ってください。
- 復旧に使用できる有効なスナップショット、ログ、またはバックアップがない。
- Keeper クラスター全体とそのメタデータを再作成する必要がある。
Keeper クラスターを再構築するには、以下の手順に従ってください。
- ClickHouse クラスターと Keeper クラスターを完全に停止します。
- スナップショットとログのディレクトリをクリーンアップして、各 Keeper ノードをリセットします。
- 1 つの Keeper ノードをリーダーとして初期化し、他のノードを段階的に追加します。
- 外部の記録が利用できる場合は、メタデータを再インポートします。