Groongaが予期せぬ理由で落ちた理由を調査中の阿部です。
通常の終了処理で終了すると問題は起きないのですが、突然の停電などでGroongaサーバーが落ちると、Groongaのデータが壊れる場合があります。
壊れた場合は復旧する必要があります。そんなときに役立つツールを紹介します。
はじめに
そのツールは以前の記事でも紹介されているgroonga-query-log gemに含まれるgroonga-query-log-check-crashコマンドです。
実行すると復旧のヒントになる情報が得られます。
復旧のヒントも得られるのですが、このツールが「Groongaが落ちたときに何が起きたのかを把握しやすくする」ことに重きをおいていたため、復旧を目的に使うと少々使いづらいツールでした。 具体的には出力が多くて復旧のヒントになる情報を見つけにくかったのです。
今回リリースした1.7.9では出力の情報を整理しつつ、Groongaに何が起きたのかを検出する精度を向上させたので、改めてgroonga-query-log-check-crashの使い方を説明します。
インストール
インストール方法は以前と同じです。
事前にRubyをインストールします。Rubyをインストールしたら以下のコマンドでインストールできます。
$ gem install groonga-query-log
# ...(略)
$ gem list groonga-query-log
*** LOCAL GEMS ***
groonga-query-log (1.7.9)
1.7.9以降で改良されているので、1.7.9以降がインストールされたことを確認してください。
使い方
使い方も基本的に以前と同じです。
プロセスログ(以前の記事で通常のログと呼ばれているもの)とクエリーログのパスを指定します。(Groongaのログについてはドキュメントでご確認ください。)
すべてのログを指定します。指定する順番は気にしなくて良いです。とりあえずすべて指定すればよいです。
次のようにプロセスログとクエリーログが順番になってなくても良いですし、タイムスタンプ順に並んでいなくても良いです。
実行例:
$ groonga-query-log-check-crash \
path/to/process-log-2000-02-* \
path/to/query-log-2000-01-* \
path/to/process-log-2000-01-* \
path/to/query-log-2000-02*
Summary:
crashed:no, unflushed:no, unfinished:no, leak:no
OK: no problems.
1.7.9以前は大量の出力がありましたが、今回の修正でデフォルトでは復旧に重きをおいた出力のみに変更しました。
このあとは「復旧で活用する」の視点で結果の見方を説明します。
結果の見方
Summary情報の見方
1.7.9からSummary情報を出力するようにしました。この項目を見るとGroongaに何が起きたのかだいたいわかるようになっています。
次の4つの項目が出力され、すべてnoであれば何も問題がなかったということです。
- crashed
yesの場合、Groongaがクラッシュしています。- クラッシュの原因はいろいろなので、ログと共にGroongaコミュニティに報告してもらえるとありがたいです。
- unflushed
yesの場合、メモリー上のデータ(非永続データ)がディスク(永続データ)に書き込まれていない可能性があります。- 復旧が必要です。対象のコマンドを再実行する必要があります。(詳細は後述します。)
- unfinished
yesの場合、正常終了していないコマンドがあり、対象のテーブルやカラム、インデックスが壊れている可能性があります。- 復旧が必要です。対象のテーブルやカラム、インデックスを再構築する必要があります。(詳細は後述します。)
- leak
yesの場合、Groongaがメモリーリークしています。- リークの原因はいろいろなので、ログと共にGroongaコミュニティに報告してもらえるとありがたいです。
復旧で利用するのはunflushedとunfinishedの情報です。
以降で、次の場合の結果の見方や対応方法について記載します。
- 何も問題がなかったとき
unflushedのとき - メモリー上のデータがディスクに書き出されていないときunfinishedのとき - 途中で処理が終わったコマンドがあるときunflushedとunfinished- その他
何も問題がなかったとき
何も問題なかったときは次の出力です。
Summary:
crashed:no, unflushed:no, unfinished:no, leak:no
OK: no problems.
Summaryのみが表示されます。
この場合は何も起きていないのでそのままGroongaを利用し続けてOKです。
メモリー上のデータがディスクに書き出されていないとき
Groongaはメモリー上で処理をします。 メモリー上のデータはOSが任意のタイミングでディスクに書き出します。 メモリー上のデータをディスクに書き出す前にGroongaプロセスが終了すると、そのデータは失われてしまいます。 通常終了時は問題なくディスクに書き出されますが、クラッシュなどで異常終了した場合などは書き出されずデータが失われてしまうことがあります。
そのような失われてしまったかもしれない操作があるときは次のような出力があります。
!!!
!!! [unflushed] Recovery information
!!!
There may be commands that were not flushed between 2000-01-01T00:00:00+09:00 and 2000-01-01T12:00:00+09:00.
These commands may not have been written to the database files, so please re-run them.
===
[unflushed] 2000-01-01T00:00:01+09:00: load --table "Data"
===
Summary:
crashed:yes, unflushed:yes, unfinished:no, leak:no
NG: Please check the display and logs.
注目すべきは[unflushed] ではじまる行で、そのコマンドが失われてしまった可能性がある操作です。
この例では 2000/01/01 00:00:01 データをロードした情報が失われてしまった可能性があります。 データの有無を確認し、失われてしまった場合には同じコマンドを再実行することで復旧できます。
途中で処理が終わったコマンドがあるとき
完了しなかったコマンドがあるとGroongaのデータが壊れている可能性があります。 その可能性があるときは次のような出力があります。
!!!
!!! [unfinished] Recovery information
!!!
Unfinished commands were found due to abnormal termination or other issues.
It is safer to rebuild the target tables, columns, and indexes because the data may be corrupted.
===
[unfinished] 2000-01-01T00:00:01+09:00: load --table "Data"
===
Summary:
crashed:yes, unflushed:no, unfinished:yes, leak:no
NG: Please check the display and logs.
注目すべきは[unfinished] ではじまる行で、それが異常終了などの問題により正常に完了しなかったコマンドです。
この例では 2000/01/01 00:00:01 に実行したloadコマンドが正常終了していない、ということを示しています。
正常終了しなかったことによりDataテーブルやそれに依存するインデックスがあればそれが破損している可能性があり、再構築が必要になります。
再構築方法は状況によって変わるので、方法がわからない場合はログと合わせてGroongaコミュニティに相談していただくか、より手厚いサポートをご希望の場合はお問い合わせよりご相談ください。
その他
上述の「メモリー上のデータがディスクに書き出されていないとき」、「途中で処理が終わったコマンドがあるとき」で示した以外にログの中の重要情報なども出力されます。
例えば次のような出力です。
!!!
!!! Important entries
!!!
It contained logs that require checking.
If you need help, please feel free to contact the community: https://groonga.org/docs/community.html
===
2000-01-01T12:00:00+09:00: 1: 00000000: critical: -- CRASHED!!! --
2000-01-01T12:00:00+09:00: 1: 00000000: critical: ...trace
2000-01-01T12:00:00+09:00: 1: 00000000: critical: ----------------
===
こちらは出力内容によって対応が変わったり、未知のバグの可能性があるので、ログと合わせてGroongaコミュニティに報告してもらえるとありがたいです。
出力を調整するオプション
1.7.9から次の3つのオプションが追加されました。
--command-format--pretty-print--output-level
--command-format
commandとuriが指定できます。デフォルトはcommandです。
このオプションは出力するコマンドのフォーマットを指定します。
「出力するコマンド」とはこれまで見てきた、
===
[unflushed] 2000-01-01T00:00:01+09:00: load --table "Data"
===
の
load --table "Data"
のところです。
GroongaをHTTPサーバーで利用している場合は、この形式よりも普段利用しているURLのパスのほうが便利です。 そのようなときは次のように指定するとURLのパスで出力されます。
実行例:
groonga-query-log-check-crash \
--command-format=uri \
path/to/process-log-2000-01-* \
path/to/query-log-2000-01-*
出力例:
===
[unflushed] 2000-01-01T00:00:01+00:00: /d/load?table=Data
===
--[no-]pretty-print
このオプションもコマンド出力の見た目を調整するオプションです。 デフォルトでは有効になっていて、改行され整形された次のような出力になります。
===
[unflushed] 2000-01-01T00:00:01+09:00:
load \
--table "Data"
===
改行されていて人間は見やすいですが、1行になっていたほうが便利なときもあります。
(この記事でも一行になっていたほうが説明しやすかったので、--no-pretty-printを指定した結果を掲載しました。)
そのときは次のように指定すると1行で出力されます。
実行例:
groonga-query-log-check-crash \
--no-pretty-print \
path/to/process-log-2000-01-* \
path/to/query-log-2000-01-*
出力例:
===
[unflushed] 2000-01-01T00:00:01+00:00: load --table "Data"
===
このオプションは--command-format=commandのときのみ有効です。
--output-level
infoとdebugが指定できます。デフォルトはinfoです。
debugを指定するとより詳細な出力になりますが、復旧目的で利用する場合は出力が多すぎて、復旧情報を確認しづらくなるのでinfoのままでご利用ください。
さらにお役立ち情報
1.7.9では、これまで書いた出力の改良に加えて「メモリー上のデータがディスクに書き出されていないとき」の検出精度が向上しました。 これまでいくつかのケースで検出漏れがあったのですが改良しました。
わかりやすい例でいうとGroongaにはselectした結果を別のテーブルにloadする機能があるのですが、それが検出対象ではありませんでした。 今回の変更でそれも検出されるようになりました。
より復旧で便利に使えるようになったのでぜひご活用ください!
まとめ
Groongaを復旧するときに便利なgroonga-query-log-check-crashコマンドを改良したので紹介しました。
この改良はGroongaのサポートサービスで実施しました。 元々はサポート業務で社内での利用が主なツールでしたが、改良してお客様にも実行していただける形にしました。
クリアコードでは、お客様の課題を解決するためにソフトウェア開発や技術サポートを行うだけでなく、業務を通じて得られた知見やツールを可能な限り公開することを重視しています。 例えば、今回のように改良したスクリプトを自由なソフトウェアとして公開することで、同じ課題を抱えている他のユーザーもその成果を活用できるようになります。 また、スクリプトの公開によって外部からのフィードバックや改善提案を受ける機会も増え、より良質なソフトウェアへと発展させていくことができます。
groonga-query-log-check-crashコマンドを使った復旧のサポートなど、Groongaの運用サポートが必要な方は、お気軽にお問い合わせよりご連絡ください。
参考: groonga-query-logを紹介しているククログ
groonga-query-logにはいくつかツールが含まれています。それらを紹介したククログも合わせてご覧ください。