Kouhei Sutou
kou****@clear*****
2015年 10月 1日 (木) 21:11:19 JST
須藤です。 In <20151****@orega*****> "[groonga-dev,03532] Re: PGRNファイルが開けない?" on Thu, 01 Oct 2015 09:31:29 +0900, 高見 直輝 <takam****@orega*****> wrote: > ただ、これはエラーの発生を予防する手段だと思うのですが、上記エラーが発生 > している環境を、既存データを保持したまま修復する手段は有りませんでしょう > か? 少し荒っぽいのですが、base/16384/pgrnから始まる名前のファイ ルをすべて削除し、接続し、インデックスを作りなおしてください。 既存データはPostgreSQLが管理しているので↑で消えることはあり ません。 PGroongaはpgrnから始まるファイルがないと自動で新しくデータベー スを作成するのでPGroongaがエラーを出さなくなります。 > また、コマンド実行時にディスク障害などによってエラーが発生した場合、障害 > が解消した後に何らかの処理を実行する必要がありますでしょうか? > 例)Create Index文が完了し、io_flushでエラー発生 > ⇒エラー原因解消後、インデックス再構築が必要 この場合はインデックス再構築が必要です。 > インデックス作成以外で対応が必要なものはありますでしょうか? > 以下に必要と思われるものを列挙するので、過不足あればご指摘下さい。 > インデックス(テーブル)削除 > インデックス再構築 > VACUUM > PGROONGAの各種設定内容変更 足りないものは「TRUNCATE」です。「TRUNCATE」は内部的には新し い空のテーブル・インデックスを作成するのです。 多いものは「インデックス(テーブル)削除」と 「PGROONGAの各種設定内容変更」です。 前者は削除してもすぐには物理的に削除されないからです。VACUUM のときに物理的に削除されます。 後者は設定内容はPGroongaではなく、PostgreSQL管理となるため io_flushしても意味がないからです。 >> > これに関しては、pgrnファイルを排他ロックで開いた状態でログレベルの変更を行っ >> > たところ、再現できました。 >> >> の具体的なSQLを教えてもらえないでしょうか? >> 試してみたいです。 手順ありがとうございます。 > 1.pgroongaのインデックスを持つテーブルを作成しておく > 2.PostgreSQLのサービスを再起動する(1のテーブルにアクセスしないようにする) > 3.pgrnファイルを排他ロックした状態で開き、この状態を維持する すみません、ここ、どうやりましたか? PostgreSQLを使わないでなにか別のものを使って開いたということ でしょうか? > 4.1のテーブルにレコード追加を実行する > ⇒上記Permission deniedのエラーとなる > 5.以下のSQLを実行する(設定内容は任意) > ALTER DATABASE "【データベース名】" SET pgroonga.log_type='postgresql'; > ALTER DATABASE "【データベース名】" SET pgroonga.log_level ='warning'; > 6.PostgreSQLのサービスを再起動する > 7.3で開いているのを閉じる > 以後、1のテーブルを対象としたSQLを実行すると、必ず57P03のエラーが発生し > ます。 > 復旧方法については、設定済みの項目に対して > ALTER DATABASE 〜 RESET 〜 > を実行し、PostgreSQLのサービスを再起動したら直りました。 > ※その後、再設定しても問題無し PGroonga初期化時に失敗する(データベースを開けないとか)とこ の状況になるということみたいですね。 余談ですが、元のエラーメッセージがどうして発生するのかの説明 を書いた後に、説明する必要はなかったことに気付いたのですが、 せっかくなので書きかけのものを残しておきます。だれかの役に立 つかもしれないので。。。 ---- このエラーメッセージ > > > ERROR: 58030: pgroonga: failed to open database: <base/16384/pgrn>: [db][open] invalid keys table's type: 0 がどういうときに出力されるか説明しないといけないのでそこから 始めます。 ちょっと話が遠いように感じるかもしれませんが、Groongaがテー ブルとカラムをどうやって紐付けているかから説明します。 テーブルは複数のカラムを持つことができます。つまり、このテー ブルとこのカラムは関係がある、という情報を管理する必要があり ます。 Groongaでこの情報を管理しているのがDBです。テーブルが「自分 はこういうカラムを持っている」という情報を持っているわけでは ありません。テーブルは自分がどのカラムと関係があるかを知りま せん。 DBはどうやってテーブルとカラムの関係を管理しているかというと 名前です。 Groongaでは * テーブルは「${テーブル名}」という名前を * カラムは「${テーブル名}.${カラム名}」という名前を つけられます。各テーブル・カラムは自分の名前は知りません。 DBが知っています。DBが「この名前のテーブルはあのテーブル」、 「その名前のカラムはあっちのカラム」ということを管理していま す。 つまり、DBの仕事(の1つ)は「名前」と「テーブル・カラム」を 紐付けることです。 > > > ERROR: 58030: pgroonga: failed to open database: <base/16384/pgrn>: [db][open] invalid keys table's type: 0 のメッセージに「keys table」とあるのですが、それが「名前」と 「テーブル・カラム」を紐付けているデータ(実態は普通の Groongaのテーブル)のことです。この中身がおかしいぞと言って いるのです。 このおかしいと言われているところは初期化したときに最初に設定 する値で、それ以降は書き換えることがない値です。それが、「0」 になっている、つまり、何も設定されていない状態になっています。 つまり、DBを初期化したときに設定した値がディスクに書き込まれ ていないということです。初期化時に設定した値が書き込まれてい ないので、それ以降に設定した値(たとえばインデックス)も書き 込まれていない可能性が高いです。 一度でもio_flushを実行するとDBを初期化したときに設定した値は 確実にディスクに書き込まれているので、このエラーは発生しなく なります。 ---- -- 須藤 功平 <kou****@clear*****> 株式会社クリアコード <http://www.clear-code.com/> Groongaベースの全文検索システムを総合サポート: http://groonga.org/ja/support/ パッチ採用 - プログラミングが楽しい人向けの採用プロセス: http://www.clear-code.com/recruitment/ コードリーダー育成支援 - 自然とリーダブルコードを書くチームへ: http://www.clear-code.com/services/code-reader/