2014年4月23日水曜日

EC2のインスタンスでおもむろにGithubからcloneできなくなった

いつもテキトーにインスタンスを立てては、Githubのリポジトリーに突っ込んであったシェルスクリプトを落としてきてセットアップしているんだけれど。

# yum install -y git
..

# git clone https://github.com/yoku0825/my_setup
Cloning into 'my_setup'...

# echo $?
128

あれ?;
よくわからないけど、

# curl https://github.com/yoku0825/my_setup
Illegal instruction

# curl https://www.google.co.jp/
Illegal instruction

# curl http://www.google.co.jp/
..

なので、curlが悪そう。

# yum install -y curl
..

# git clone http://github.com/yoku0825/my_setup
Cloning into 'my_setup'...
remote: Reusing existing pack: 117, done.
remote: Total 117 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (117/117), 16.05 KiB | 0 bytes/s, done.
Resolving deltas: 100% (68/68), done.

できた。なんだったんだ。

2014年4月18日金曜日

MySQL 5.5.36+ TokuDB 7.1.5のパラメーター斜め読み

TokuDB v7.1.5 with Fractal Tree Indexing for MySQL v5.5.36 User's Guide for linux の4章斜め読みメモ。
  • tokudb_commit_sync
    • InnoDBでいうinnodb-flush-log-at-trx-commitに相当する セッション変数
    • ON, OFFだけで2に相当するようなものは(この変数には)ない
  • tokudb_read_block_size
    • 1回の読み込みブロックのサイズ(解凍後のサイズ) セッション変数。
    • 値を小さくすると、狭いレンジスキャンのreadの性能が上がる(I/Oが減らせる)けど、広いレンジスキャンのread性能は落ちるよ、だそう。
    • 暗黙のデフォルトは64KB
  • tokudb_loader_memory_size
    • バルクロード(LOAD DATA INFILE)の時に使うらしい。サーバー変数。
    • 暗黙のデフォルトは100MB
    • バルクロード時に tokudb_cache_size から切り出されるから注意してね、らしい
  • tokudb_fsync_log_period
    • tokudb_commit_syncと関係なく、一定時間ごとにTokuDBログをfsyncするためのサーバー変数。
    • 暗黙のデフォルトは0。単位はミリ秒。
    • tokudb_commit_sync= 0 && tokudb_fsync_log_period= 1000でinnodb-flush-log-at-trx-commit= 2っぽい感じになるか。
  • tokudb_cache_size
    • InnoDBでいうinnodb-buffer-pool-sizeに相当。サーバー変数。
    • 暗黙のデフォルトは 物理メモリーの50%
    • tokudb_directioを使うならメモリーの80%くらい振るのがオススメ って書いてある
  • tokudb_directio
    • InnoDBでいうinnodb_flush_method= O_DIRECT
    • 暗黙のデフォルトはOFF
  • tokudb_lock_timeout
    • innodb_lock_wait_timeoutに相当するセッション変数。
    • 暗黙のデフォルトは4000(ms)。単位がmsなので注意。
  • tokudb_checkpointing_period
    • チェックポイント(TokuDBログファイルからTokuDBデータファイル(という呼び方で良いのかどうかは知らない)へのマージ)間隔
    • 暗黙のデフォルトは60で単位は秒。
    • いじらない方がいいよって書いてある。
  • tokudb_fs_reserve_percent
    • ファイルシステムにn%以上の空きがない場合、INSERTを許可しない…みたいに読める。
    • 暗黙のデフォルトは5、単位はパーセント。
    • この設定を使って、少なくとも物理メモリーの半分はリザーブしとけよ、って書いてある。

ちなみにtokudb_fs_reserve_percentを割り込んだ空き容量(75を設定して、利用率30%くらい)で何か操作をすると、

mysql> CREATE TABLE t2 (num serial) Engine= TokuDB;
ERROR 1030 (HY000): Got error 28 from storage engine

$ perror 28
OS error code  28:  No space left on device

ほほぅ。なるほど。

2014年4月15日火曜日

Percona Server 5.6 with TokuDB Betaのインストール

社内で検証する人がいるらしいのでメモ書き風に。

MySQL Performance Blogでのリリースはここ。
Percona Server 5.6.16-64.2 with TokuDB engine Beta is now available


バイナリー(.tar.gz版)を落としてくる。サーバー本体(Percona Server)とプラグイン(TokuDB Storage Engine Plugin)でそれぞれDLする。

$ wget http://www.percona.com/redir/downloads/TESTING/Percona-5.6-TokuDB/beta/538/binary/tarball/release/percona-server-5.6.16-64.2-tokudb-7.1.5.el5.x86_64-server.tar.gz
$ wget http://www.percona.com/redir/downloads/TESTING/Percona-5.6-TokuDB/beta/538/binary/tarball/release/percona-server-5.6.16-64.2-tokudb-7.1.5.el5.x86_64-plugin.tar.gz
$ tar xzf percona-server-5.6.16-64.2-tokudb-7.1.5.el5.x86_64-server.tar.gz
$ tar xzf percona-server-5.6.16-64.2-tokudb-7.1.5.el5.x86_64-plugin.tar.gz

同じディレクトリで解凍すれば、ちゃんと./percona-server-5.6.16-64.2-tokudb-7.1.5.el5.x86_64 のlib/mysql/pluginとか mysql-test とかの下に入ってくれる。

CentOS(RHEL互換)の6.xの場合、transparent_hugepageを無効化する必要がある。

$ echo never > /sys/kernel/mm/transparent_hugepage/enabled
$ echo never > /sys/kernel/mm/transparent_hugepage/defrag

去年ハマってたやつ。 http://yoku0825.blogspot.jp/2013/07/tokudbcentos-63.html

mysql_install_dbで初期化して一度MySQL起動。
INSTALL PLUGIN的なことをやってくれるsqlファイルがあるのでそれを食わせる。

$ bin/mysql mysql < share/tokudb_engine_install.sql

これ、INSTALL PLUGIN叩いてくれるのかと思ったら、なぜかテンポラリーテーブルに一覧を作ってからmysql.pluginにINSERTする作りになっているので、デフォルトデータベースを指定しないと通らない。どうしてこうなった。

手でINSTALL PLUGINを叩くならこちらを参考に。 http://www.percona.com/doc/percona-server/5.6/tokudb/tokudb_installation.html

my.cnfにTokuDB関連の設定を追加。INSTALL PLUGIN(じゃないけど)前にTokuDB関連の値を設定すると、当然Unknown Variableでmysqldが起動してくれないので注意。looseつけとくか。

$ vim ./my.cnf
loose-tokudb_cache_size= 24G

とはいえまだ真面目にベンチマークしてないのでこれくらいしかわからない。
tokudb_cache_sizeはInnoDBでいうinnodb_buffer_pool_sizeのようなもの。本家のクイックスタートガイドでは、"物理メモリーの50%くらい割り当てたまえ"と書いてある。
(PDFです) http://www.tokutek.com/wp-content/uploads/2014/03/QuickStartGuide-7.1.5.pdf

InnoDBと一緒に使うと、コイツらでメモリーの割り当てを奪い合うことになりそうなので、できればTokuDBを使うところはTokuDB一本でいきたいところ。

ここでmysqldを再起動すれば、さっきのスクリプトでINSERTされたmysql.pluginが読み取られるので、次に起動してきたときにはTokuDBが有効になって起動してきます。


7/11のMySQL Casual TalksはTokuDBで行こうかと思っているので、カブる方はご連絡ください :)

MroongaのラッパーモードでInnoDBを使う落とし穴

Mroonga(ストレージモード)はトランザクション非対応だから、ラッパーモードでInnoDBにしてトランザクション…とか考えているとハマる(かもしれない)落とし穴。

Mroongaのラッパーモードは「データは任意のストレージエンジンに」「転置索引はGroonga上に」作るモードであって、飽くまでGroonga上ではトランザクションは利きません。つまり、こういうことが起こる。


mysql56> CREATE TABLE t1 (num int, val varchar(32), primary key(num), fulltext key(val)) Engine= Mroonga COMMENT= 'engine "innodb"';
Query OK, 0 rows affected (0.09 sec)

mysql56> INSERT INTO t1 VALUES (1, 'yoku0825');
Query OK, 1 row affected (0.01 sec)

mysql56> SELECT * FROM t1;
+-----+----------+
| num | val      |
+-----+----------+
|   1 | yoku0825 |
+-----+----------+
1 row in set (0.01 sec)

mysql56> SELECT * FROM t1 WHERE match(val) against('yoku');
+-----+----------+
| num | val      |
+-----+----------+
|   1 | yoku0825 |
+-----+----------+
1 row in set (0.00 sec)

mysql56> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

mysql56> UPDATE t1 SET val= 'updated' WHERE num= 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql56> SELECT * FROM t1;
+-----+---------+
| num | val     |
+-----+---------+
|   1 | updated |
+-----+---------+
1 row in set (0.00 sec)

mysql56> SELECT * FROM t1 WHERE match(val) against('yoku');
Empty set (0.00 sec)

mysql56> SELECT * FROM t1 WHERE match(val) against('update');
+-----+---------+
| num | val     |
+-----+---------+
|   1 | updated |
+-----+---------+
1 row in set (0.00 sec)

mysql56> ROLLBACK;
Query OK, 0 rows affected (0.01 sec)

mysql56> SELECT * FROM t1;
+-----+----------+
| num | val      |
+-----+----------+
|   1 | yoku0825 |
+-----+----------+
1 row in set (0.00 sec)

mysql56> SELECT * FROM t1 WHERE match(val) against('yoku');
Empty set (0.00 sec)

mysql56> SELECT * FROM t1 WHERE match(val) against('update');
+-----+----------+
| num | val      |
+-----+----------+
|   1 | yoku0825 |
+-----+----------+
1 row in set (0.00 sec)

飽くまで転置索引は既に更新されていて、ROLLBACKが利くのは「データの格納されているInnoDB部分」だけ。この状態を解消するには、転置索引を作り直してやるしかない(と思う)

mysql56> ALTER TABLE t1 DISABLE KEYS;
Query OK, 0 rows affected (0.00 sec)

mysql56> ALTER TABLE t1 ENABLE KEYS;
Query OK, 0 rows affected (0.06 sec)

mysql56> SELECT * FROM t1 WHERE match(val) against('yoku');
+-----+----------+
| num | val      |
+-----+----------+
|   1 | yoku0825 |
+-----+----------+
1 row in set (0.01 sec)

mysql56> SELECT * FROM t1 WHERE match(val) against('update');
Empty set (0.00 sec)

飽くまで「こういうもの」として考えておかないと、ヒットする/しないがシビアなところだと失敗するかも知れません。基本的に俺はストレージモード推しです。

なお、「(パラメーターによるけど)InnoDBのトランザクション機能でデータ部分は保護される」のは事実なので、クラッシュしてGroonga部分が壊れても(ストレージモードだとここでバックアップからリストアコース)データ部分はリストアする必要がなく、転置索引さえ再作成すればOK、というのはありますね。転置索引に比べてデータ部分が十分大きい場合には、リカバリーの時間短縮と考えられるかも知れません(ちゃんと計ってない)

誰か計ったら教えてください :)


【2014/04/16 10:16】
中の人が教えてくだれました :)



ありがとうございます。

MySQLをプロファイる(仮) at MyNA(日本MySQLユーザ会)会 2014年4月

過日のMyNA会でしゃべってきました。



本人の中では、前回のOSC 2014 Tokyo/Springのネタが導入編、今回がじゃあ実際にどんなの使ってやってるよ? という入門編なイメージです。
 ⇒ 日々の覚書: MySQLのパラメーターチューニング at OSC 2014 Tokyo/Spring

誰も手を挙げてはいただけなかったですけど、大なり小なりスクリプトとか色々書いてる人はいるだろうなぁと想像してます。俺もへなちょこPerlでちまちま書いてたりしますし(innotopでステータス変数の差分取るカスタマイズを調べるのが面倒だったので、自分でスクラッチしたとか)


さて、話は変わってポエミーな感じ。

ATNDのページにもでかでかと書いていただきましたが、先月、Oracle ACEに認定いただくことができました。今回のMyNA会は「yokuさんお祝いに勉強会やろう! でもRonaldの都合があるからこの日かこの日ね。yokuさんの都合は別に聞いてない」という某氏の掛け声で開催していただきました。

会場を提供いただいた LINE株式会社 さん、会場提供に全面的にご協力いただいた @studio3104 さん、月曜日の夕刻にも関わらず足を運んでくれたみなさま、本当にありがとうございました。あんなに祝福の言葉をいただいて写真を撮っていただいたのは結婚式以来です。本当に幸せでした(とか書くと死にそう)

○racle様の認定プロセスを通れるくらいモノ(Slideshareのスライド、ブログの記事)が色々残せたのは本当に、中の人のMySQLチームのみなさまと 日本MySQLユーザ会 のみなさまとのご縁が大きいと本当に本当に思っています。

名前を挙げたらきりがないくらい(というか、本当にきりがなかったので途中まで書いて消した)のたくさんの人にお世話になっていますし、細かいことはさておいて色々いじって遊んで人と話せるMySQLが大好きです。

不束者ですが、これからもよろしくお願いいたします。


と、コレだけじゃアレなので、最後にOracle ACE認定のアレな話をおいていきますね :)



2014年4月7日月曜日

MySQL 5.6.17のinnodb_metricsを有効にしてみる

MySQL 5.6から加わった INFORMATION_SCHEMA.INNODB_METRICS のテスト。

mysql56> SELECT name, subsystem, count, status FROM information_schema.innodb_metrics;
+------------------------------------------+---------------------+-----------+----------+
| name                                     | subsystem           | count     | status   |
+------------------------------------------+---------------------+-----------+----------+
| metadata_table_handles_opened            | metadata            |         0 | disabled |
| metadata_table_handles_closed            | metadata            |         0 | disabled |
| metadata_table_reference_count           | metadata            |         0 | disabled |
| metadata_mem_pool_size                   | metadata            |   8388608 | enabled  |
| lock_deadlocks                           | lock                |         0 | enabled  |
| lock_timeouts                            | lock                |         0 | enabled  |
..
| icp_no_match                             | icp                 |         0 | disabled |
| icp_out_of_range                         | icp                 |         0 | disabled |
| icp_match                                | icp                 |         0 | disabled |
+------------------------------------------+---------------------+-----------+----------+
214 rows in set (0.32 sec)

全部で214もの項目があり、17のサブシステムに分けられていて、それぞれdisabled, enabledが指定できる。
今までSHOW ENGINE INNODB STATUS(InnoDB Monitor)でしか取れなかったような情報や、載っていない情報もぽちぽち取れたりするので、可能なら全enabledにしておきたい所存。

enableの仕方はSET GLOBAL innodb_monitor_enable= で設定する。INFORMATION_SCHEMAなので、performance_schemaみたいに UPDATE information_schema.innodb_metrics SET status= 'enabled'というわけには *いかない*。

mysql56> UPDATE information_schema.innodb_metrics SET status= 'enabled' WHERE subsystem= 'metadata';
ERROR 1044 (42000): Access denied for user 'root'@'localhost' to database 'information_schema'

mysql56> SET GLOBAL innodb_monitor_enable= icp_out_of_range;
Query OK, 0 rows affected (0.00 sec)

mysql56> SET GLOBAL innodb_monitor_enable= module_metadata;
Query OK, 0 rows affected (0.13 sec)

mysql56> SELECT name, subsystem, count, status FROM information_schema.innodb_metrics;
+------------------------------------------+---------------------+-----------+----------+
| name                                     | subsystem           | count     | status   |
+------------------------------------------+---------------------+-----------+----------+
| metadata_table_handles_opened            | metadata            |         0 | enabled  |
| metadata_table_handles_closed            | metadata            |         0 | enabled  |
| metadata_table_reference_count           | metadata            |         0 | enabled  |
| metadata_mem_pool_size                   | metadata            |   8388608 | enabled  |
| lock_deadlocks                           | lock                |         0 | enabled  |
| lock_timeouts                            | lock                |         0 | enabled  |
..
| icp_no_match                             | icp                 |         0 | disabled |
| icp_out_of_range                         | icp                 |         0 | enabled  |
| icp_match                                | icp                 |         0 | disabled |
+------------------------------------------+---------------------+-----------+----------+
214 rows in set (0.19 sec)

イメージ的な"WHERE subsystem= 'xx'"にあたるのがinnodb_monitor_enable= module_xx で、イメージ的な"WHERE name= 'yy'"にあたるのがinnodb_monitor_enable= yyになる。全部いっぺんにenabledにするにはinnodb_monitor_enable= allだし、%記号を使ってワイルドカード指定もできる様子。
無効化するには、SET GLOBAL innodb_monitor_disable= ..で、指定の仕方はenableの時といっしょ。

で、問題はこれがどれくらい性能劣化を引き起こすか。

取りあえずざっくりtpcc_load WH= 1(INSERTのみのワークロードで、1スレッドしかなく、データはすべてバッファプールに収まるサイズ)で試してみる。


$ time ./tpcc_load localhost tpcc root "" 1 > /dev/null

【innodb_monitor何もいじらない】
real    1m22.414s
user    0m9.885s
sys     0m4.890s

real    1m23.739s
user    0m9.927s
sys     0m5.046s

real    1m23.227s
user    0m10.031s
sys     0m4.877s


【SET GLOBAL innodb_monitor_enable= all】
real    1m21.462s
user    0m9.690s
sys     0m4.939s

real    1m21.057s
user    0m9.781s
sys     0m4.803s<

real    1m22.970s
user    0m9.939s
sys     0m5.069s


【SET GLOBAL innodb_monitor_disable= all】
real    1m23.818s
user    0m9.949s
sys     0m4.990s

real    1m19.556s
user    0m9.386s
sys     0m4.844s

real    1m21.829s
user    0m9.824s
sys     0m4.904s

よさげ。 ちゃんとtpcc_startでもオーバーヘッドはからないとだけど、取りあえずmy.cnfにinnodb_monitor_enable= allで全部ONにしちゃおうかなと思いつつ(オンラインで変えられるし)