高見 直輝
takam****@orega*****
2015年 8月 24日 (月) 11:06:59 JST
高見です。 > > PGROONGAのVer.0.6.0環境にて、PostgreSQLのイベントログとして以下のものが出力されていました。 > > LOG: pgroonga: 2015-08-21 14:26:16.684000|n| io(base/16384/pgrn.0000154) collisions(1000/163): lock failed 1000 times > > これってどういった理由で出力されているのでしょうか? > > これは、ロックを獲得できなかったときに出力されます。 > > Groongaはマルチスレッド・マルチプロセスをサポートしており、 > 複数の処理から同時にデータを書き込まれる可能性があります。 > そのため、データを書き込むときはロックを獲得し、書き込みが競 > 合しないようにしています。 > > そして、↑はそのためのロックを獲得できないときに出力されます。 > > > 実は現在、『Insert文を実行したら、いつまで経っても終了しない(エラーにもならず、固まった状態になる)』 > > という問題が発生しており、ほぼ同じタイミングで上記のログが > > 出力されていることから関連を疑っています。 > > INSERT文ではデータを書き込むためにロックを獲得する必要があり > ます。ロックを獲得できない場合はロックを獲得できるまで(デフォ > ルトでは結構長い時間)がんばります。その間は処理が止まるので > いつまでも終了しません。 “デフォルトでは”ということは、設定の変更が可能なのでしょうか? 当方としては、ある程度待って駄目ならPostgresのエラーとして検知できるのが望ましいのですが、 このような設定は可能でしょうか? > ロックが獲得できない状況は次のようなケースがあります。 > > 1. 他のスレッド・プロセスがロックを獲得して書き込んでいる > 2. ロック獲得中になんらかの理由で異常終了し、ロックが残留 > している(ロックを解放せずに終了した) > > 1.は同時に書き込むスレッド数・プロセス数を減らすことにより解 > 消します。 > > 2.は異常終了した原因を解決し、その後、該当テーブル・カラムを > 再構築すると解決します。 > > 該当テーブル・カラムを再構築すると一時的に解決はしますが、再 > 発する恐れがあります。 > > なお、該当テーブル・カラムの再構築はインデックスを作りなおす > ことで実現できます。元データはPostgreSQLが持っているので元デー > タを再度投入する必要はありません。 > > > ・OSを再起動しても回復しなかった。ログの内容も冒頭のものと同じ。 > > ということから、1.ではなく2.と考えられます。 > > Groongaのログを出力するようにしてなにかエラーがでていないか > 確認する必要があります。 > > もし、クラッシュしているのなら、PostgreSQLのログあるいはクラ > イアント側のログにもなにかでているかもしれません。なにかとい > うのは、例えば、接続がいきなり切れた、とかです。 発生時点のログは流れてしまっていたので調査できていません。 インデックスの再構築によってInsert文を実行できるようになったので、再発するのを待とうと思います。 > > 念のため、問題の発生状況について記載しておきます。 > > ありがとうございます。 > > > 作業内容:負荷テストの準備のため、1000万件以上のレコードが登録されているテーブルを複数作成する。 > > 状況: > > ・約1200万件のテーブルが一つ、約3000万件のテーブルを二つ、計三つ作成完了。 > > ・四つ目のテーブルを作成し、約730万件のレコードを登録したところ、上記問題が発生。 > > まずは、4つ目のテーブルを操作しているときのログに注目して異 > 常がなかったか確認するのがよさそうです。 > > > ・レコードの追加だけでなく、削除、変更でも同様の状況。 > > 削除はデータの更新が発生しないこともありますが、変更はデータ > の更新が発生するのでロックを獲得する必要があります。よって、 > 追加と同様の挙動になったとしてもそれは同じ原因の可能性が高い > です。 > > > ・問題が発生しているのは四つ目のテーブルのみ。他のテーブルに対してレコードの操作を実行しても問題なかった。 > > 4つ目のテーブルに張ったPGroongaのインデックスのみロックが残 > 留している可能性が高そうです。 > > > ・問題が発生しているテーブルに対する検索の実行は問題無し。 > > Groongaは並列性を高めるためにデータを参照するときはロックを > 獲得しなくても壊れたデータを参照しないような作りになっていま > す。そのため、ロックが残留していても動作に支障はありません。 検索処理ではロックを取得しない(エラーの発生原因にはならない)という認識で良いですか? 現在、対象のテーブルに対して実行している操作は、検索・追加以外では以下の3つのみです。 ・テーブルダンプ ・VACUUM(AUTOVACUUM) ・ANALYZE この中にロックを取得する処理は有りますでしょうか? ----------------------------- 高見 直輝 <takam****@orega*****> 株式会社オレガ TEL:03-3267-0150 FAX:03-3267-0180