web-dev-qa-db-ja.com

Keycacheで修復を回避する方法

My.cnfファイルの最適化の経験はありましたが、データベースには約400万のレコード(MyISAM)があります。私はmysqldumpから復元しようとしていますが、実行するたびに、恐ろしい「キーキャッシュによる修復」が行われるため、数日かかる場合があります。これを乗り越えて「Resort By Sorting」としてローリングさせる方法はありますか?

2GB RAM、デュアルコア、たくさんの追加のハードドライブスペースがあります。

My.cnfから切り取ります。

set-variable = max_connections=650
set-variable = key_buffer=256M
set-variable = myisam_sort_buffer_size=64M
set-variable = join_buffer=1M
set-variable = record_buffer=1M
set-variable = sort_buffer_size=2M
set-variable = read_buffer_size=2M
set-variable = query_cache_size=32M
set-variable = table_cache=1024
set-variable = thread_cache_size=256
set-variable = wait_timeout=7200
set-variable = connect_timeout=10
set-variable = max_allowed_packet=16M
set-variable = max_connect_errors=10
set-variable = thread_concurrency=8
32
dvancouver

「並べ替えによる修復」では、filesortルーチンを使用します。これにより、tmpdirに(通常は)いくつかの一時ファイルが作成されます。

Tmpdirにそれらのための十分なスペースがない場合、「キーキャッシュによる修復」に戻ります。これは非常に低速であり、最適なインデックスが作成されないため、非常に悪いです。

他にもいくつか条件がありますが、私はそれらを特定していません。

Filesort()に必要なtmpdirのサイズを計算するのは簡単ではありません。 filesortバッファーに保存されるフォーマットデータはMYDファイルと同じではありません。通常、より多くのスペースを使用します。

したがって、tmpdirが小さな/ tmp(またはtmpfs)を指している場合は、それをより大きな/ var/tmpに変更することができます(存在する場合)。

35
MarkR

MySQLは、テーブルインデックスの可能な最大サイズが変数myisam_max_sort_file_sizeの値より大きい場合は常に、MyISAMテーブルに対してキーキャッシュによる修復を使用します。

インデックスの最大サイズを計算するには、すべてのインデックスのすべてのキーのバイトサイズ値を合計し、その値にテーブルの行数を掛けます。

Myisam_max_sort_file_sizeを大きくすると、スローキーキャッシュ方式ではなく、ディスクでのソートを使用してインデックスが再構築されます。

17
Marc Gear

高速登録用に設定していない新しいデータベースで誤って修復テーブルを実行してしまいました。 myisam_max_sort_file_sizeは、.MIDファイル(88279393280のサイズが大きい、約88GB)に比べて小さすぎます。データファイルは85GBです。テーブルは12億のレコードで、ID、2つの日付、tinytext、少数のbigint、およびdoubleで構成されています。私のサーバー(windows7の下のボックスで実行されている2GBの仮想Linux)には、Windowsサーバー上にある4つのコアが1つしかありませんが、3つ以上のGHZを実行しています。私はこの「キーキャッシュによる修復」イベントが永遠にかかることを恐れていました-はるかに小さなテーブルでのホラーストーリーを考えると。

幸い、修理テーブルのクイック操作を完了するのに「1日」、1時間10時間20.72秒しかかかりませんでした。

私が最も見逃しているのは、mysqlがどのくらい遠くまで操作に到達し、どれだけ早く終了するかを知る方法です。これはまだ私には不明です。

My.iniファイルを変更し、これらの大きな一時ファイル用の十分なディスク領域があることをdfで再確認しました。

とにかく..この罠に陥る次の男に非常に役立つ知識かもしれない私の主なポイントは..実際に...慌てる必要はありません!速度は遅いかもしれませんが、かなり標準以下のハードウェアでは、1〜2日間で10億以上のレコードを並べ替えることができます。 3つのインデックスを取得しました。1つは日付フィールド、1つはbigintフィールド、もう1つはIDフィールドです。

私はこれをソリューションの1つへのコメントとして投稿しましたが、ここでユーザーインターフェイスを使用してこれを行う方法を理解できないので、ソリューションとしてそれをドロップします。私に賛成票を投じないでください。これは私がここに置いておきたかったメモです。 "sort by keycache"スレッドを1週間以上かかると思ったため、ほぼ終了させようとしていました。 10億レコードあたり2日は管理可能です。

編集:そして今、同じデータベース上の修復テーブルですが、mysiam_max_sort_file_size設定が十分に大きいため、並べ替えによる修復を使用して10時間20分かかりました。最も使用されたディスクスペースは約250GBでしたが、サーバーで実際に空いているディスクスペースの量を反映して、myisam_max_sort_file_sizeをはるかに大きく設定しました。

進行状況の追跡は困難です。個々のインデックスの作成中にディスク領域が上下しましたが、regが変更されていない1時間の一時停止がありました。ディスクスペースの使用状況(dfによって報告)。

9
John Doe

ありがとうMarkはい、まさにそれが私が最終的に試みた結果であり、ログから「Repair with keycache」に切り替えた理由はスペース不足エラーであることがわかりました。

これは、最大2MBしかなかった/tmp/mysqltmp/を指しているという事実を経由しないので、私のソリューションを導入するために私がしたことです。

だから私はこれをやった:

mkdir /home/mysqltmp

chown mysql:mysql /home/mysqltmp

my.confのtmp dirをに変更tmpdir=/home/mysqltmp/

ここでdf -h /home/mysqltmpを使用すると、dirには285 GBの空き容量があることがわかります。これは、本当にすばらしい光景であり、十分な空き領域があり、さらにmysqlが20 GBを簡単に望んでいることがわかりました。したがって、12時間前に私にかかっていた処理は20分で完了します。つまり、300万を超えるレコードがインデックスに挿入されます。

5
dvancouver

ここでの解決策はどれも私にとってうまくいきませんでした:myisam_sort_buffer_size変数をどこまで増やしたか、またはtmpdir変数をどこにポイントしたかに関係なく、テーブルは常にキーキャッシュで修復されました。

機能したのは、コマンドラインユーティリティmyisamchkを使用することでした。

myisamchk --sort-recover --sort_buffer_size=14G /path/to/table

どこ:

  • /path/to/tableは、拡張子なしのデータベースファイルのパスです(つまり、末尾に.MYIがありません)。デフォルトでは、/var/lib/mysql/your_databaseディレクトリにあります。

  • バッファサイズを14Gから使用可能な空き容量に変更します。

追加のボーナスとして、データをチャーンするときの進行状況も表示されます。

0
Jealie

MySQLリファレンスマニュアルによると、「元のインデックスファイルが置かれているディレクトリを含むファイルシステム内にディスク容量が必要です」( http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_myisam_max_sort_file_size )-これは(少なくとも)v5.0以降に適用されます。これは、tmpディレクトリのディスク領域を増やすと役立つと主張する、上記の回答の一部と矛盾します。

リファレンスマニュアルに記載されている動作を確認できます。テーブルのデータ(*.MYD)&インデックスファイル(*.MYI)は格納されますが、tmpdirには格納されません。

0
twonkeys