Groonga周辺を便利にするツールもいろいろと作っている須藤です。
Groongaはクラッシュセーフではないので、クラッシュするタイミングによってはデータベースが壊れてしまうことがあります。データベースが壊れていそうかどうかはログを解析することで判断できます。この記事ではクラッシュ時のログを解析するためのスクリプトを紹介します。
インストール
クラッシュ時のログを解析するスクリプトはgroonga-query-log gemの中に入っています。このスクリプトを使うと以下のことがわかります。
-
いつクラッシュしたか
-
クラッシュしたときに実行していたクエリーはなにか
-
未
flush
の変更コマンド(load
やtable_create
など)(これらがあるとデータベースが壊れている可能性が高い) -
解析対象のログ中にある重要度が高いメッセージ
-
(クラッシュ時ではなく)正常終了時にメモリーリークしていたか
事前にRubyをインストールします。Rubyをインストールしたら以下のコマンドでインストールできます。
% gem install groonga-query-log
使い方
インストールするとgroonga-query-log-check-crash
というコマンドが使えるようになります。これでクラッシュ時のログを解析すると前述のこと(いつクラッシュしたかなど)がわかります。
使う時は次のように通常のログ(--log-path ...
を指定すると出力されるログ)とクエリーログ(--query-log-path ...
を指定すると出力されるログ)を「すべて」指定します。結果が多くなることがあるので、標準出力をリダイレクトして結果をファイルに保存しておくと便利です。
% groonga-query-log-check-crash groonga.log* groonga-query-log* > analyze.log
指定する順番は気にしなくてよいです。ファイル名に含まれているタイムスタンプ情報を元にコマンド内部で自動で並び替えるからです。なお、タイムスタンプ情報のフォーマットはstrftime(3)で言うと%Y-%m-%d-%H-%M-%S-%6N
(%6N
はstrftime(3)
にはないけど、6桁のミリ秒のつもり)です。このフォーマットは--log-rotate-threshold-size
、--query-log-rotate-threshold-size
を使ったときに使われているフォーマットなので、これらのオプションを使ってログローテーションしている場合はとくに気にする必要はありません。
(違うタイムスタンプ情報のフォーマットもサポートして欲しい場合は https://github.com/groonga/groonga-query-log/issues で相談してください。)
また、gzip・ZIPで圧縮されていても構いません。自動で伸張して解析します。
改めてまとめると、持っている通常のログ・クエリーログをすべて渡してください、ということです。
結果
コマンドを実行するとログを解析し、クラッシュを検出すると随時解析結果を出力します。ログが大きいほど時間がかかります。ログはストリームで解析しているので大量のログを解析してもメモリー使用量が比例して大きくなることはありません。
出力結果は特に決まったフォーマットになっているわけではなく(たとえばMarkdownでマークアップされているわけではない)、解析結果が1つずつ表示されるだけです。フォーマットは今後も変わっていきます。(改良していきます。)そのため、ここで現時点のフォーマットの説明はしません。
以下の情報がわかるような出力になっています。
-
いつクラッシュしたか
-
クラッシュしたときに実行していたクエリーはなにか
-
未
flush
の変更コマンド(load
やtable_create
など)(これらがあるとデータベースが壊れている可能性が高い) -
解析対象のログ中にある重要度が高いメッセージ
-
(クラッシュ時ではなく)正常終了時にメモリーリークしていたか
また、より詳しく知りたい場合はどのログファイルを確認すればよいかもわかるようになっています。
まとめ
Groongaがクラッシュしたときのログ解析を支援するツールがあることを紹介しました。Groongaを運用している人はぜひ活用してください。
ログの解析ロジックは私が手動で解析するときのロジックです。そのため、未対応なパターンも十分にありえます。未対応のパターンがあった場合は https://github.com/groonga/groonga-query-log/issues で教えてください。