大きなサイズのデータをmyisamからinnodbに移行する検証をしたメモ
ハマってなんとか解決したことや、現状困ったりしていることを書いてみる。
前置き
ibdata1、大きくなり過ぎ!
- myisamと違ってinnodbのデータファイル(ibdata1)はデフォルトでは一つにまとまっていて、何もしないとこれが際限なく大きくなる。
- db全体で100G程度のサイズ。でもデータの更新などを繰り返すうちに200G以上にサイズが膨れ上がった。つまりibdata1だけで100G以上に。
- これを回避する方法は以下2つ
- innodb_data_file_pathにibdata1の最大サイズを指定する
- innodb_file_per_tableを設定し、テーブルごとにデータファイルを作る。
- 参考にしたエントリ。漢(オトコ)のコンピュータ道: InnoDBのファイルサイズ管理
- 際限のない膨張は回避できたが、既に膨れ上がったibdataのサイズを縮小するのはけっこう大変。
- 参考にしたエントリ。MySQLのInnoDBデータファイル「ibdata1」の最適化
- ただ、dump->drop->restoreだと時間がいくらあっても足りないので、innodbのテーブルのみ一度全部drop->ibdata1をrmで削除->innodbのテーブル再作成、という強引な手を使った。幸いうまくいった。
- 最後もうひとつメモ。innodb_file_per_tableを設定した状態でテーブルのパーティショニングを行うと、パーティション単位でデータファイルができ、だいぶ扱いやすいサイズになった。
innodb_buffer_pool_sizeは欲張るな!
- メモリの7割から8割のサイズを設定すると言われているが、とち狂って32Gに対して28G(約9割!)を設定してしまっていた。
- 22G(7割程度)にしてかなりパフォーマンス改善。バランス大事。
- こちらが参考になった。MySQLでInnoDB、バランスを取り戻せ! | −ゆめログ−
更新処理時のデータのオーバーヘッドが大きい!
- truncateしたあと、データの挿入を行うとデータファイルが500Mに。あれ?テーブルをoptimizeすると、300M程度のサイズまで減少。
- 放っておくとdb全体の容量がどんどん大きくなるので、何らかの対応が必要。
- 今回パーティショニングの単位でデータの入れ替えを行うことにしているので、さしあたり以下の流れ。
- alter table t1 truncate partiton p1;
- flush table t1;
- insert into t1 〜
- alter table t1 rebuild partiton p1
- insertの後、テーブル全体でoptimizeするよりもパーティション単位にrebuildした方が効率がよさそう。
show table statusが遅い!
- これがいまだに原因分からず、苦戦中。とても重い処理をやっているとは思えないshow table statusの実行に何秒もかかる場合がある。
- show table statusに限らず、テーブルを参照するクエリなどを発行すると、プロセスの状態が「Opening tables」となっているのをよく見かける。
- テーブル分割を行った結果、一つのスキーマに数百のテーブルができたが、これが原因かもしれない。
- 引き続き検証必要。
というわけで
主に更新に関するあれこれを書いてみた。実際のところ更新に関しては、課題はある程度クリアできているのかなといった状況。
一方、参照の方のパフォーマンスについても少しづつ検証しているが、思ったようなパフォーマンスが出せず、けっこう前途多難な感じ。
innodbはけっこうじゃじゃ馬ですなぁ。
しかしまぁ良さを引き出してナンボなので、もっと突っ込んでやってみようと思う。楽しみつつ!
進展があればまた書いてみようと思います。