MySQLパラメータdelay_についてkey_write、myisam_recover_optionsの使用経験

5382 ワード

最近、データベース・インスタンスの移行でいくつかの奇妙な問題に遭遇しました.
  • MyISAMインスタンス正常shutdown後rsyncデータファイルが別のマシンにインスタンスを開始した後、テーブルにアクセスすると、テーブルの自動修復に失敗したことを示すメッセージが表示されます.repair tableが必要です.ヒント:Table'./test/record_03' is marked as crashed and last (automatic?) repair failed
  • テーブルが破損すると、repair tableコマンドを使用してテーブルを修復する際にテーブルに多くのduplicate keyが存在することを示す.

  •      warning  : Duplicate key for record at 129584986 against record at 62008769
         warning  : Duplicate key for record at 104678355 against record at 61426294
         warning  : Duplicate key for record at 297493788 against record at 61697778
         warning  : Duplicate key for record at 209950328 against record at 61548867
         warning  : Duplicate key for record at 105894968 against record at 61866949
    ...
    ...
    当時の環境情報を補足します.
    1.MySQLバージョンは公式版の5.5.12、表エンジンはMyISAM
    2.移行の手順:stop slave->flush tables->通常shutdownインスタンス->rsyncテーブルファイル->新しいマシンでインスタンスを開始します.rsync前後テーブルファイルMD 5の値は同じです.
    3.テーブルの構造は次のようになります.
    create table test (
    id int auto_increment primary key,
    a varchar(100) not null,
    b int not null,
    c int,
    unique key (a,b)
    )

    まず最初の質問を言います.ここでは2点に分けます.なぜ修復が必要なのですか?2.自動修復に失敗した理由
  • 私は正常に閉じた例で、表が修復する必要がある原因が分からないので、宝を洗って丁奇にデータファイルを分析してもらって、ファイルの頭の中で記録して表が閉じられても6つのスレッドがアクセスしています.しかし、rsyncデータファイルの前が正常なshutdownインスタンスであることを確認することができます.これはMyISAM自体の問題かもしれません.あるいは、自分のデータファイルに問題があるかもしれません.つまり、私が移行してテーブルにアクセスするときに修復する必要があるのは合理的です.テーブルが閉じられたときにスレッドがアクセスしているため、MySQLはテーブルが正常に閉じていないと判断し、修復する必要があります.
  • なぜ自動修復に失敗したのか、これは私がパラメータmyisamを構成したからです.recover_options=default、この構成はMyISAMテーブルにアクセスするたびにテーブルが修復する必要があるかどうかを検出し、必要であれば自動的に行います.これは、前に見た情報last(automatic?)です.repair failed.修復に失敗したのは、このパラメータによる修復動作がデフォルトでkey cacheから修復が必要なデータを探していたためです.私はshutdownインスタンスで、rsyncは新しい環境にインスタンスを開始しました.この場合、当時の現場(key cache環境)はありません.defaultを加えると修復は強制されません(インデックスファイルとデータファイルのデータが一致しなければ自動的に削除または行を追加します).(myisam_recover_options=forceの場合、key cacheが存在しなくても強制修復が行われます.この場合、データファイルとインデックスファイルを比較して、データファイルの余分な行を削除するので、データが失われる可能性があります).自動修復時にerror logに表示される情報は、
  • です.
    130410  9:31:23 [ERROR]/usr/local/mysql55/bin/mysqld: Table './image_0/record_00' is marked as crashed and should be repaired
    130410  9:31:23 [Warning] Checking table:   './image_0/record_00'
    130410  9:31:24 [ERROR] Got an error from unknown thread,/export/home/pb2/build/sb_0-3198286-1302530066.93/mysql-
    5.5.12/storage/myisam/ha_myisam.cc:868
    130410  9:31:24 [Warning] Recovering table: './image_0/record_00'
    130410  9:31:28 [Note] Retrying repair of: './image_0/record_00' with keycache
    130410  9:31:37 [ERROR] Couldn't repair table: image_0.record_00
    次に2つ目の質問です.1つ目の質問では、テーブルが破損していることを示すプロンプトが表示されます.手動repair tableが必要ですが、このコマンドを実行すると、テーブルに重複キーデータがたくさん存在することを示します.
    warning  : Duplicate key for record at 129584986 against record at 62008769
    warning  : Duplicate key for record at 104678355 against record at 61426294
    warning  : Duplicate key for record at 297493788 against record at 61697778
    warning  : Duplicate key for record at 209950328 against record at 61548867
    warning  : Duplicate key for record at 105894968 against record at 61866949
    この繰り返しキーは、一意のキー(a,b)を指し、データファイルに重複する行(a,bフィールド)があることを小さなテスト検証します.論理図は大体こうです
    id a b c
    1  1 2 3
    2  1 2 4
    3  2 3 55
    4  2 3 54

    上のリストは私自身がシミュレートしたもので、(a,b)には唯一のキー制約がありますが、データファイルには(a,b)重複する行が存在します.検証方法は簡単です.
    /*強制的に全表スキャン*/select*from test where a=val 1 and b=val 2;
    結果セットは2行あります
    /*強制インデックス*/select*from test where a=val 1 and b=val 2;
    結果セットは1行のみ
    その时、问题が発生した最初の反応は、开発者がデータを导いてデータを导いた时に唯一の规制検査を禁止したのではないかということでしたが、実は开発は自分がやったことがないと言って、MySQLのバグだと开発しました.私はどうしてもMySQLにこのような大きなバグが存在しないと思って、ずっとMySQLの使い方が间违っていると思っていました.そこで移行前後の環境を比較してみたところ、古い環境にdelayが配置されているという疑問点が発見されました.key_write=ALL,myisam_recover_options=OFF(デフォルトはOFF).私の新しい環境ではdelay_key_write=ON,myisam_recover_options=default .
    簡単な説明でdelay_key_writeは、MyISAMテーブルインデックスを更新するたびにflushを物理ディスクに更新しないが、これらの変更はメモリに保持され、このテーブルが閉じられるまでflush、ALLはすべてのテーブルに対してこの動作を使用することを示し、ONはテーブルの作成にdelay_を使用することを示すkey_writeのテーブルはこの機能を使用します.OFFはdelay key writeを行わないことを示します.公式推奨ではdelayを使用していますkey_write時にmyisamを併用recover_optionsはこのようにしてデータの一貫性を保証することができます.そうしないと、最も簡単な例を挙げると、インデックスデータが一致してもflushがディスクになく、突然テーブルが正常に閉じられ、次のテーブルがアクセスされても対応する検出修復を行わないと、データファイルとインデックスが一致しない場合があり、データが一致しません.
    もっと簡単に説明してmyisam_recover_options,defaultはテーブルにアクセスするたびに修復が必要かどうかを判断しますが、強制修復は行われません(key cacheから修復を試みるだけです)、backupは修復時に古いデータファイルを先にバックアップし、forceは強制修復を表します.具体的な使い方は下図を参照してください.
    このとき、MySQLパラメータの不合理な使用によるデータの不一致の問題であると大まかに判断できるので、MyISAMを使用する際にdelay_を構成した場合key_write、myisamを同時に構成することを忘れないでください.recover_optionsは,データの不一致を防止することができる.では、私はどのようにこの問題を解決しましたか?今のところ、移行後のMySQL構成パラメータ環境は古い環境と一致しています.そうしないと、私が今強制的にパラメータmyisamを追加します.recover_optionsでは、すべてのテーブルが破損し、破損した後に回復する唯一の方法はrepair tableです.これはデータが失われます(またはmyisam_recover_options=force、backupを構成します.この効果はrepair tableと同じで、変更するMYDファイルをバックアップします).重複キーの行に対して、repair tableを利用して行うと、私はMySQLが具体的な行を残すことに関与できません.したがって,強制repair tableでは繰返しキーエラーを解決できるが,最終的に残るどの行がユーザが望む行のデータであるとは限らない.もちろん他にも2つの方法があります.1つ目は、業務責任者に相談した後、重複キーに不要な行を手動で削除することです.第二に、repair tableを強制して古いデータをバックアップし、ユーザー側が異常を発見してデータ復旧を行うが、このやり方は望ましくない.そうしないと、ユーザーから致死的な苦情を受けてしまう.
    いずれにしても、21世紀になって、5.6になったので、MyISAMを使わないでください.私は歴史システムですから、仕方がありません.後期のアップグレード改造もしなければなりません.