各務 洋
kagam****@outwa*****
2015年 10月 1日 (木) 16:50:11 JST
お世話になります、各務です。
>> ↑が全て実行中なのを確認しながら、mysqld を 何回も killする
>> # kill -9 `ps ax|egrep -i "/usr/sbin/mysqld --basedir"|egrep -v "grep"|awk '{print $1}'`
>
> おぉ。。。
> mysqldがクラッシュするケースだったんですね。。。
> それなら壊れてもおかしくないです。。。
状況の再現が難しいのでクラッシュさせていますが、io の collisions の際
もあやしいのかなぁと思っているのです。
> もし、キーを追加した直後にクラッシュしたらキーだけが残ってレ
> コードが作られていない状態になります。この状態でもGroonga的
> には壊れていない(ロックが残留していない)状態ですが、
> Mroonga的には壊れている状態になります。
これが大多数だと思います。Index と レコードが合っていない状態ですね。
私の方では数値と日付系の型で上記が発生していて、FULL TEXT の方では経験
は無いのです。
(SELECT できなければ代替の検索条件を用意していないので分からない可能
性もあるのですが、指摘を受けた事もないので)
いずれにせよ、Index とレコードが合っていれば、後はなんとか出来る気が
するのです、値の 0 や Null で残っていても消せるので。
ちなみに 0 も Index を使わなければ掴んで削除できますが、Index は直って
くれませんでした。
> たとえば、UNIQUE KEYの場合は、最初にUNIQUE KEYを管理する
> Groongaのテーブルにキーを追加しようと試みて、追加できたらレ
> コードの中身を保存していく、という処理で実現しています。
回数は少ないのですが、Groonga 上でもまったく同じものが2行入っている
レコードを確認できました。
> select --table tbl_test_pat_0005
[[0,1443683784.70987,0.0669431686401367],[[[2],[["_id","UInt32"],["_key","Int64"],["a_id","Int64"],["id","Int64"],["t1_date","Time"],["t2_date","Time"],["t_text","LongText"]]
,[1,3918,10002,3918,1443598148.0,0.0,"t10002"],[1,3918,10002,3918,1443598148.0,0.0,"t10002"]]]]
> UNIQUE KEY以外ならALTER TABLE DISABLE KEYSしてからALTER
> TABLE ENABLE KEYSすればよいのですが、UNIQUE KEYはその技を使
> えないんですよねぇ。
ありがとうございます、確かにこれはダメでした。
> UNIQUE KEYを1つずつALTER TABLE DROP INDEXしてALTER TABLE ADD
> UNIQUE INDEXしなおしていけば直って、全コピーよりは速いのです
> が、面倒ではあります。
ふむふむ、schema 情報から読めば可能だと思いますが、既に Unique 制約を
満たさない値が入っているものの削除をしないといけないのと、Drop して
Add が終わるまでの間は INSERT 等の処理を開始されたくないとも思いました。
あと、Unique ではない Index も破損している事が多いので、
(日付とか日付とか日付とか)
理想としては mysqld の起動前にこれらの処理が終わっているのが良いかな
と思いましたが、どうでしょうか?
私の手元の環境では mysqld_safe から grndb recover を行って、障害検知を
行えたDB名で mysqld 起動後に、ALTER TABLE ENGINE Mroongaを行う処理を入
れてみたのですが、 肝心の検知がほぼ行えないのでした。(>_<)/
> 後者は(Groongaレベルではなく)Mroongaレベルで処理の途中でク
> ラッシュしていたらインデックスを作り直す、というのはできそう
> です。
>
> Groongaが「ロックが残留しているか」で処理途中かどうかを判断
> できるみたいに、Mroongaでも処理のはじめに印を残して、処理が
> 終わったら印を消す、起動時に印が残っていたら途中でクラッシュ
> したはず、という仕組みを入れれば壊れていそうかどうかを検出で
> きそうです。
これ、良いと思います。
> ロックをするのは性能が落ちそうなのでやりたくないので、内部に
> 管理用のGroongaのテーブルを用意して、処理を始めるときにレコー
> ドを追加、処理が終わったら作ったレコードを削除、起動時にその
> テーブルが空じゃなかったら壊れていそう、とすればいけそうな気
> がします。
もっと贅沢をいうと、試みて失敗して滞留した内容と、Groonga 上の最後の処
理がトランザクションIDのようなもので突合せ可能であれば、レコード単位で
影響を処理できて、クラッシュリカバリ時のコストが減らせるような気がしま
した。
で、対象が分からない際は、テーブル単位でざっくりとですねぇ。
(これは Replication の Slave 側はどのようになるのでしょうか?)
> 壊れていそうだったら勝手にインデックスを再構築する処理が走る
> (データが多いと多少時間がかかりそう)のってアリですか?
個人的にはこれしかないと思います。
フラグで制御できればなお良いとは思いますが、デフォルトで機能する形だと
思います!
----
各務
kagam****@outwa*****