CockroachDB壊れちゃった話
概要
社内で使っていたツールのDatabaseに実験用途でCockroachDB(v20.1.3)を使っていた。構成は以下となる。
「AWS EKS1.6上にStatefuleSetで3Podで運用。StorageClassはEBS gp2(kube masterのin treeの中にある実装)のPVでデータを保存」
実はこの構成はそこそこ問題があって、Nodeの入れ替えなどでPodの再配置が起きた際に過去のPVと新しく配置されたPodのAZが一致しないとStatusがPendingになりコンテナが作られない。
これはAWSのEBSがAZを跨げないためであるが、 kube1.7以降の環境でVolume Binding Modeを WaitForFirstConsumer
にして、CSI Driverがいい感じであればうまく行くという説がある(参照:Storage Classes | Kubernetes)
これは、あんまり興味がない点だったので認識が間違っていて嘘の可能性もある。
そんなこんなで、PendingになったPodを動かすためには以下の2通りのオペをする必要がある。
- Podを削除して、過去のPVと同じAZに配置されることを祈る
- PVかPVCを消すなりして、新しいPodに新しいPVが作られるようにする。
ただ、2のオペレーションをした場合はデータが消えるので、CockroachDBの新規のNodeとしてClusterにJoinすることになる。
経緯
実は詳細な原因が特定できていないので、省かせてもらうがNodeの入れ替え作業中に """いろいろあって"""Clusterが起動しなくなってしまった
以下は現在わかっていること
X日の15:00(JST)ごろに入れ替え作業をして一旦は動いていた
16:00ごろまで以下のログが出始める。
W210126 07:17:43.388615 906 server/node.go:830 [n2,summaries] health alerts detected: {Alerts:[{StoreID:2 Category:METRICS Description:ranges.underreplicated Value:11}]}
上記のWarningが出ている状態でなんらかの原因で再起動がかかり、
server drained and shutdown completed
おそらく正常に終了はしたが、他のPodも以下の状態になってしまう
W210126 07:18:57.177231 201 kv/kvserver/node_liveness.go:488 [n2,liveness-hb] failed node liveness heartbeat: operation "node liveness heartbeat" timed out after 4.5s
17:00(JST)ごろアプリケーションが動いていないことで気づく
エラー内容はこれに近いように感じた。
色々と修正しようと頑張っている内に以下のエラーを吐くようになった。
W210126 13:32:11.928294 156 kv/kvserver/store.go:1631 [n2,s2,r6/3:/Table/{SystemCon…-11}] could not gossip system config: [NotLeaseHolderError] r6: replica (n2,s2):3 not lease holder; lease holder unknown W210126 13:32:12.743191 127 kv/kvserver/replica_range_lease.go:554 can't determine lease status due to node liveness error: node not in the liveness table
現在振り返って考えると17:00ごろはなんとかなったかもしれないが、21:00ごろから上のエラーがで始めた時点で厳しい感じがする。(=よくない操作をした)
データ復旧に関して
CockroachDBは様々な方法でバックアップやデータのdumpができるようになっているが、Clusterが起動している状態でないできない。
上のVersionでは内部のストレージ部分にRocksDBを使っているので(最近のVersionはPebbleになっている)RocksDBと向き合いながら頑張ればデータを復旧できるという説がある。自分の認識では理屈上2Nodeのデータがあればいいはず
今回はデータは捨てる判断にしたが、大事なデータを保存していてバックアップもとっていない人はチャレンジするための資料を置いておく
Goを使ってRocksDBから復旧を試みる
データ構造に関しては、以下のスライドが参考になる
以下のソースコードのコメントもデータ構造に関してわかるかもしれない
余談
ちなみにcockroach debug rocksdb
でデータを直接操作することができる。
cockroach debug rocksdb scan
でK/Vっぽいものを取得できるが、cockroach debug rocksdb get KEY_NAME
にscanした結果のkeyを使うことができない。
あまり理解していないが、cockroach debug rocksdb scan
は CockroachDBの内部でてくるKey (例:/Local/Store/gossipBootstrap
) で、RocksDB側で使われているKeyは別のbinary表現のkeyに変換しているようだ。RocksDBの私が理解していない機能を使っている気がする。
なので、 cockroach debug rocksdb scan
と cockroach debug rocksdb scan --hex
のvalueを比較することで、同一のkeyを取得することができ、cockroach debug rocksdb get --hex HEX_KEY_NAME
でCLIから値を操作することができる。
cockroach debug rocksdb scan
はほとんどデータがないはずのDBから数GBのファイルを生成してくるので、地獄みたいな作業になる。
RocksDBの操作はかのブログで雰囲気を察することをお勧めする