2012年8月31日金曜日

InnoDB buffer pool dumpで遊ぶ

掲題のMySQL5.6の新機能で遊んでみたメモ。

InnoDBバッファプールの内容をファイルに書き出しておくことが出来る機能が追加された。

書き出すタイミングは正常終了時(SET GLOBALまたはmy.cnfでinnodb_buffer_pool_dump_at_shutdown = 1を設定)または
任意のタイミングで即時書き出し(SET GLOBAL innodb_buffer_pool_dump_now = 1;)

読み出すタイミングは起動時(my.cnfにinnodb_buffer_pool_load_at_startup = 1)または
任意のタイミングで即時読み込み(SET GLOBAL innodb_buffer_pool_load_now = 1;)

これで、mysqldを再起動してバッファプールが空っぽになっても
素早くウォームアップできるぞ、ということらしい。



特に何も考えずに5.6をインストールして、テーブルにデータを入れ込む。
リブートしてからテーブルの中身をバッファプールに載せておく。

mysql> SELECT * FROM t1;
10000000 rows in set (1 min 24.12 sec)


mysql> SELECT * FROM t1;
10000000 rows in set (37.42 sec)


mysql> SELECT * FROM t1;
10000000 rows in set (22.63 sec)

mysql> SHOW ENGINE INNODB STATUS\G
..

----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 2747269120; in additional pool allocated 0
Dictionary memory allocated 47230
Buffer pool size   163832
Free buffers       70768
Database pages     85688
Old database pages 31466
Modified db pages  0
Pending reads 0
Pending writes: LRU 0, flush list 0 single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 147, created 85541, written 117235
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 85688, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
..

そういえばバッファプールインスタンスの数も増えたんだっけなぁと出力結果を見て思い出したり。
取り敢えず吐かせてみようそうしよう。



mysql> SET GLOBAL innodb_buffer_pool_dump_now = 1;
Query OK, 0 rows affected (0.07 sec)

$ ls -lh /var/lib/mysql/ib*

-rw-rw---- 1 mysql mysql 649K  8月 31 16:43 2012 /var/lib/mysql/ib_buffer_pool
-rw-rw---- 1 mysql mysql  16M  8月 31 16:25 2012 /var/lib/mysql/ib_logfile0
-rw-rw---- 1 mysql mysql  16M  8月 31 16:25 2012 /var/lib/mysql/ib_logfile1
-rw-rw---- 1 mysql mysql 394M  8月 31 16:25 2012 /var/lib/mysql/ibdata1

おー、吐いてる吐いてる。

しかし…649K? 小さすぎる気がしてならない。。
innodb_buffer_pool_sizeは2560Mで、Database pagesが85688(=1.3GBちょい)なのに。。

というかなんか平文で読めるんだけどこのib_buffer_pool。。

$ head /var/lib/mysql/ib_buffer_pool

0,7
0,1
0,3
0,2
0,4
0,11
0,5
0,6
0,45
0,46

謎。すごい謎。

取り敢えず気を取り直してmysqldを再起動。

mysql> SET GLOBAL innodb_buffer_pool_load_now = 1;
Query OK, 0 rows affected (0.00 sec)



エラーログに↓のエントリがぴょっこり出た。
流石に一瞬じゃ終わらないのね。

my.cnfにinnodb_buffer_pool_load_at_startup = 1でも同じログが出る。
ただしロードが終わる前にReady for connectionsは出て接続も出来るのでOK。


120831 17:52:11 InnoDB: Loading buffer pool(s) from .//ib_buffer_pool
120831 17:53:21 InnoDB: Buffer pool(s) load completed at 120831 17:53:20





mysql> SHOW ENGINE INNODB STATUS\G
..
----------------------


BUFFER POOL AND MEMORY
----------------------
Total memory allocated 2747269120; in additional pool allocated 0
Dictionary memory allocated 59613
Buffer pool size   163840
Free buffers       78123
Database pages     85717
Old database pages 31797
Modified db pages  0
Pending reads 0
Pending writes: LRU 0, flush list 0 single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 85717, created 0, written 1
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 85717, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]

..

数値的にはちゃんと(?)戻ってる。

肝心のウォームアップ具合はというと。


mysql> SELECT * FROM t1;
10000000 rows in set (31.89 sec)


mysql> SELECT * FROM t1;
10000000 rows in set (20.66 sec)



mysql> SELECT * FROM t1;
10000000 rows in set (22.40 sec)



利いてる利いてる。

ファイルサイズとファイル構造が謎なので気が向いたら調べよう。。



【2012/08/31 23:42追記】
ib_buffer_poolの右側カラムがPrimary Keyそのものなんじゃないかと勝手に思ってたんですが、
Primary Keyそのものではありませんでした(´・ω・`)

夕方書いたやつはPrimary Keyがint型だったので区別が付かなかったのですが、
varchar型で日本語入れても出てきたのは数字の羅列。

あと、strace取りながらinnodb_buffer_pool_load_nowさせたところ、
*.ibdファイルをopenしてpread64やってるのが確認できました。
さすがSH2さん大当たりです。。


【2012/09/01 00:16追記】
ib_buffer_poolの書式は、<tablespace id>,<page no>\n でした。

2012年8月24日金曜日

シェルスクリプトにtar-ballを埋め込む発想は無かった

あるプログラムのインストール用のシェルが俺にとっては斬新すぎた。

なんか上手く行ってなかったので中身を覗いてみると、こんな感じ。
(引数とかはちょこちょこ変えてあるけれど)

..
        sed '1,100 d' < "$0" | tar xz
..


…えーと、自分自身を標準入力から読み込んで、1~100行目を削除して、
つまり101行目から最後までをtarに渡す…?

101行目を見てみると。

..
^_<8b>^H^@3<89>XO^@^Ci[k<8c>]×UT<8e>^]'<9e>|I3AE@Oi¶<8e>McI~?<92>AM^TJjU|ichQ^]<9c>yo\|^_A}<8c>i^R$<82><90>¨DAu^@^D<84>^BD´@Qu£ByG^?T<82>^_^U^?^@Qo^G?D$T^HZ!^Uoi{I<8c>gAa<97>^Ta^B>×gIYg ̄?oUk}eqg<8e>§qu<^^aEo0^OAA÷GE2G<97>^Y5|C$^X\^VW^\; ̄<8b>{A^L×<8c>J-^E!L
..

Σ(゚д゚lll) わーい圧縮したtar-ballがそのまま埋め込んであるぞ!?


ちなみにこのtar-ballを展開するとrpmファイルが複数出来上がった。
敢えてシェルスクリプトに組み込んだところがすごい。

道理でスクリプトのくせに300MByteもある訳だよ。。。

2012年8月15日水曜日

vdiファイルのサイズを後から変更する

VBoxManageのmodifyhdコマンドでいける。
vdiファイルをつかんでいるVMを止めてから、

cmd> VBoxManage.exe <vdi filename> --resize <変更後のサイズ[MB]>

VBoxManage極めたいんだけど時間が取れないなぁ。。


http://www.virtualbox.org/manual/ch08.html#vboxmanage-modifyvdi



【2012/08/19】
vdiファイルを拡張しても、その上に作られたパーティションは自動で大きくなったりはしないので、
fdiskだったりlvextendだったりresizefsだったりは必要。

2012年8月9日木曜日

CentOS6.2 minimalでVirtualBox共有フォルダを使う

昔とことんハマったのでメモ。

VBoxGuestAdditionsのCDを入れて起動。
(VirtualBoxのインストールフォルダにVBoxGuestAdditions.isoがあったと思う)


rootでログインして、適当なところにマウントする。

# mount -t iso9660 -r /dev/cdrom /mnt


ゲストOSの現在のkernel sourceを求められるので、yumでkernel-develを突っ込んでおく。
ちゃんと使ってるkernelのバージョンと合わせないとGuestAdditionが突っ込めないので
uname -rで今のバージョンと合わせる。

# yum install kernel-devel-`uname -r`
..
No package kernel-devel-2.6.32-220.el6.x86_64 available.

あれ、無い。6月くらいまではあったと思うんだけど。
`kernel-devel-2.6.32-220.el6.x86_64'でぐぐると出てきたのでそれをインストール。
(バージョン番号はよしなに変える)


その他GuestAdditionのコンパイルに必要なmake,gcc,perlのパッケージを入れる。

# yum install make gcc perl


インストールはシェルスクリプト一発でやってくれる。

# /mnt/VBoxLinuxAdditions.run
..
Starting the VirtualBox Guest Additions                    [  OK  ]
..

このメッセージが出てればOK。
X Windowを入れていない環境だと
Installing the Window System drivers                       [失敗]
(Could not find the X.Org or XFree86 Window System.)
が出る。気にしない。


リブートすれば下準備は完了。
GUIなりVBoxManageから共有フォルダを設定してやる。
`フォルダ名'はマウントする時に使うので、判りやすいアルファベットで。

# mount -t vboxsf <フォルダ名> <マウントポイント>

俺はいつもホストOSのデスクトップを/root/deskにマウントしているので、
/etc/fstabにも
Desktop                 /root/desk              vboxsf  defaults        0 0
って書いてある。

vboxfsじゃなくて、vboxsf。ここが一番ハマった。。

2012年8月3日金曜日

sudoをスクリプトの中で使うとき

sudoはデフォルトではtty(制御端末)を持っていないプロセスから呼び出されると
`sudo: sorry, you must have a tty to run sudo'というエラーを吐く。

普通にログインしてシェルからスクリプトを起動する分にはttyがあるから何もないけど、
これをcronなりinitなりdisownしてdaemonぽくしたシェルにしたりすると大問題。

標準エラー出力には出されるから、cronならメールで飛んでくるかな?
お手製スクリプトをdisownするなら、標準エラー出力をログしておくこと必須。
initスクリプトには是非使わないで欲しい。


ちなみに回避策は"sudo tty"で検索すればさっくり見付かります。