読者です 読者をやめる 読者になる 読者になる

kenken0807_DBメモ

つば九郎が好きなDBAです。Oracle Standard Editionでの運用やツールとかとかの備忘録。特に記載がない場合はoracle11gR2です。時々MySQL

MyDumperを使ってみた

MySQLのデータインポートツールMyDumperを試したのでメモ。

  • mysqldump・・・データのエクスポート・インポートをシングルスレッドで実行
  • mydumper・・・データのエクスポート・インポートをパラレルスレッドで実行

エクスポートしたファイルごとにパラレルで実行する。デフォルトはテーブル単位でパラレル化。
巨大なテーブルがあればデータをチャンクごとに分けファイルを分散することで高速に実行してくれる。

インストール

  • yumでインストール
yum install https://twindb.com/twindb-release-latest.noarch.rpm
yum install mydumper
  • 確認
$ mydumper --version   
mydumper 0.6.2, built against MySQL 5.6.25

もし、libmysqlclient.so.18がないよ。って言われた場合はyumでMySQL5.6をインストール(5.1ではだめ)。
または、libmysqlclient.so.18がある場所にLD_LIBRARY_PATHで設定。

コマンド

  • mydumper・・・export用コマンド
  • myloader・・・import用コマンド

試す

DB容量:280G(内130Gが1つのテーブル)

  • export DB設定

    • MySQL5.6
    • stop slaveして実行する
  • import DB設定

    • MySQL5.6
    • --skip_innodb_doublewrite
    • innodb_flush_log_at_trx_commit=0
    • slow_query_log=OFF
    • log_bin=OFF
    • innodb_log_buffer_size=128M
    • innodb_log_file_size=1G
    • innodb_log_files_in_group = 3

EXPORT

  • 10スレッドでGZ圧縮してチャンクサイズ10000000行で取得。
    注意:exportはスキーマの指定はフルまたは1つのスキーマになってしまうので複数スキーマを指定することはできない。
    -Tオプションでテーブル単位で指定可能。information_schema.tablesで複数のスキーマから取得する方法を教わったのでそちらで実行。
time mydumper -u root -p 'xxxxxxx' -S /var/lib/mysql/mysql.sock -e                   
     -t 10 -c -o /tmp/dump_dir 
     -r 10000000 
     -s 5000000 
     -T $(mysql  
        -sse"set group_concat_max_len=10240; 
        select aa from  (select 1,group_concat(concat(table_schema,'.',table_name)) as aa
        from information_schema.tables where table_schema in
       ('main','sub1','sub2','sub3','sub4') group by 1) a")

real    43m41.139s
user    220m16.990s
sys     3m0.312s

約44分

  • 1スレッドかつチャンク分けなしでやった場合は約4時間20分かかった。

出力ファイル確認

できたファイルはこんな感じで分かれている。

$ ls -ltr /tmp/dump_dir 
合計 45721788
・
・
-rw-rw-r-- 1 mysql mysql        679  6月  1 16:00 2016 main.table1.sql.gz
-rw-rw-r-- 1 mysql mysql        169  6月  1 16:00 2016 main.table2.sql.gz
-rw-rw-r-- 1 mysql mysql        185  6月  1 16:00 2016 main.table3.sql.gz
-rw-rw-r-- 1 mysql mysql      76932  6月  1 16:00 2016 main.table4.sql.gz
-rw-rw-r-- 1 mysql mysql     208327  6月  1 16:00 2016 main.table5.sql.gz
-rw-rw-r-- 1 mysql mysql    1505960  6月  1 16:00 2016 sub1.subtable1.sql.gz
-rw-rw-r-- 1 mysql mysql  768276450  6月  1 16:06 2016 sub1.subtable2.00000.sql.gz
-rw-rw-r-- 1 mysql mysql  750226866  6月  1 16:06 2016 sub1.subtable2.00001.sql.gz
-rw-rw-r-- 1 mysql mysql  770132442  6月  1 16:07 2016 sub1.subtable2.00002.sql.gz

通常はテーブル単位でのファイルだが、チャンク分けしていると連番でファイルも分かれている。

  • スレーブとして起動したい場合はmetadataファイルを確認するとポジション情報が記載してある
$ vim /tmp/dump_dir/metadata

  1 Started dump at: 2016-06-01 16:00:13
  2 SHOW MASTER STATUS:
  3         Log: mysql-bin.000275
  4         Pos: 120
  5
  6 SHOW SLAVE STATUS:
  7         Host: 192.168.1.2
  8         Log: mysql-bin.000438
  9         Pos: 944084446
 10
 11 Finished dump at: 2016-06-01 16:39:00

IMPORT

  • 16スレッドで実行
$ time myloader -d /tmp/dump_dir  -u root -p 'xxx' -S /var/lib/mysql/mysql.sock -t 16 

real    525m31.015s
user    299m14.828s
sys     3m8.467s

約8時間45分

  • チャンク分けなしのものを16スレッドで実行した場合。 結局全DB量の半分近くを占めているテーブルがシングル実行になるので遅い。
$ time myloader -d /tmp/dump_dir  -u root -p 'xxx' -S /var/lib/mysql/mysql.sock -t 16 

real    1541m14.572s
user    245m43.989s
sys     2m23.104s

約25時間

よって、チャンク分けをうまくすればmydumper結構使える。

注意

  • ibdata1のサイズが大きくなる。
    50%はinsert bufferが占めていた。セカンダリインデックスを後で貼るようにしてくれたらいいのにな。
 *8.1G*  6月  3 01:01 2016 ibdata1   こうなるので注意。
  • export時にテーブル指定でもimport時データベース作成してしてくれる。
    ファイル名の先頭を読んでcreate databaseする。↓のような感じ。
    main.table1.sql.gz → create database main;
    となるとデータベースごとにキャラクタセットが違うと危険かも・・・