Super-Smack solaris10 x86_32bit インストール
MySQLを含め、PostgreSQL、Oracleで使えるDB負荷テストツール、Super Smackをインストールしてみる。
配布サイト→http://vegan.net/tony/supersmack/さんのところの Solaris10 x86 バイナリがバージョンが古いので1.3をsourceからコンパイル。
MySQL 32bit版のパッケージなどを/usr/local/mysqlに展開
正確に測定するためSuperSmackとMySQLは違うホストに入れます。
ただ、Super-SmackにはMySQLクライアントライブラリが必要なので、手っ取り早くTAR PACKAGE版でも展開しましょう。
今回は、以下の構成を用意。
細かい注意
- bison2.xxを使う
- なんか/usr/sfw/bin以下のbisonを使うとエラーが出ます。
- 他のutilも新しいほうがいいかも・・・
- libmysqlclient.soのディレクトリをRUNPATHに
- LDFLAGSにおまじない"-lsocket -lnsl -lm"
bash-3.00# LDFLAGS="-lsocket -lnsl -lm -R/usr/local/mysql/lib/ -L/usr/local/mysql/lib/ " ./configure --with-mysql
/usr/share/smacks/select-key.smackを参考にsmackファイルを作成
以下の部分を書き換える
user "root"; host "192.168.1.102"; db "test"; pass "xxxxxxxxxxxxx";
テストデータ作成
Super Smackホスト 192.168.1.101側で作業
bash-3.00# /usr/local/bin/gen-data -n 90000 -f %12-12s%n,%25-25s,%n,%d > /var/tmp/words.dat bash-3.00# scp /var/tmp/words.dat 192.168.1.102:/var/tmp/
DBサーバ側にテーブルを作る
MySQLサーバホスト 192.168.1.102側で作業
create table http_auth (username char(25) not null primary key, pass char(25), uid integer not null, gid integer not null )";
データのロード
DBサーバ側でデータをテーブルに取り込む
mysql> LOAD DATA INFILE '/tmp/words.dat' INTO TABLE test.http_auth FIELDS TERMINATED BY ',';
smack!
super-smack <設定ファイル> <同時接続数> <トランザクション数>
※5.1系の上限スレッド数は150がデフォルト
bash-3.00# /usr/local/bin/super-smack /usr/share/smacks/select-key_mosa.smack 150 100 Query Barrel Report for client smacker1 connect: max=45ms min=1ms avg= 9ms from 150 clients Query_type num_queries max_time min_time q_per_s select_index 30000 53 0 22479.87
レプリケーションが"LOAD DATA INFILE"後に再開できない件
Super-Smackをインストール後にレプリケーションが再開できないことに気がついた orz
負荷試験などの前にはレプリケーションをSTOP/STARTすることは良くあると思いますが、今回も試験前に[stop slave]でレプリケーションを止めていたのですが、以下のエラーが出てレプリケーションが再開できません。
bash3.0 # less /usr/local/mysql_64/data/slave.err 〜色々と略〜 080411 15:17:06 [ERROR] Error reading packet from server: error reading log entry ( server_errno=1236) 080411 15:17:06 [ERROR] Got fatal error 1236: 'error reading log entry' from master when reading data fr om binary log
どうやら"max_allowed_packet"の制限に引っかかっている模様。
MySQLのバージョンはmaster、slaveとも5.1.23・・・binlog_formatがMIXEDなせいの問題かな?あとで検証してみよう。※検証した。STATEMENTでも発生。
とりあえず回避方法は以下。
slave > stop slave; master> set global max_allowed_packet = 10484736; ←LOADした量に応じてサイズは変える slave > set global max_allowed_packet = 10484736; slave > start slave;
my.cnfに max_allowed_packet を指定してもいいが、上記の方法なら再起動が要りません。デフォルトは1MBなので、不必要なら元に戻しておきましょう。
レプリケーションの遅延を計るシンプルな方法
MySQLでレプリケーションをするときに、必ず気になるのが master-slave間の遅延だと思います。
そこで、先日のDeNAさんのテクノロジーセミナーで開示していただいたネタをもとに簡単な遅延監視方法を実装してみました。
- MySQLバージョン 5.1.23
- binlog_format=MIXED
まずmasterに以下のようなテーブルを作ります。databaseは適当に作ってください。
CREATE TABLE `replitimes` ( `No` int(10) unsigned NOT NULL AUTO_INCREMENT, `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `ldate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (`No`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
当然slaveにも同じものが作成されたと思います。作成されてない人は遅延監視とか以前の問題ですね^^;
次に、master側で以下のようなSQLを実行してみましょう。
master> INSERT INTO replitimes (ldate) value (sysdate());
次にslaveで以下のようなクエリを投げて見ましょう。
slave > select * from replitimes; +----+---------------------+---------------------+ | No | date | ldate | +----+---------------------+---------------------+ | 1 | 2008-04-11 17:57:12 | 2008-04-11 17:57:12 | +----+---------------------+---------------------+ 1 row in set (0.00 sec)
きちんと反映されたでしょうか?
さて、それでは遅延をわざと発生させてどう変化するか確かめてみましょう。
slave > stop slave; master> INSERT INTO replitimes (ldate) value (sysdate()); 〜数秒待ってください〜 slave > start slave; mysql> select *,ldate - date as delay from replitimes; +----+---------------------+---------------------+-------+ | No | date | ldate | delay | +----+---------------------+---------------------+-------+ | 1 | 2008-04-11 17:57:12 | 2008-04-11 17:57:12 | 0 | | 2 | 2008-04-11 18:02:15 | 2008-04-11 18:02:24 | 9 | +----+---------------------+---------------------+-------+ 2 rows in set (0.00 sec)
[date]にはmasterでnow()を実行したときと同じTIMESTAMP値が、[ldate]にはslaveでsysdate()が実行されたときの時間が記録されたかと思います。
sysdate()を使うのがコツです。理由はbinlogを眺めてもらえれば自明ですね。
bash3.0 # ./bin/mysqlbinlog /usr/local/mysql_64/data/mysql-bin.000018 〜色々と中略〜 # at 4988971 #080411 18:02:15 server id 1 end_log_pos 4989094 Query thread_id=1 exec_time=0 error_code=0 SET TIMESTAMP=1207904535/*!*/; INSERT INTO replitimes (ldate) value (sysdate())/*!*/; DELIMITER ; # End of log file
ここで一つ注意なのが、パラメータ[binlog_format]です。
5.1.23では、以下の3つが選べます。
- MIXED(Default)
- STATEMENT
- ROW
これを ROW にして行ベースレプリケーション(RBR)にしてしまうと、今回の手法は使えません。
MySQL5.1.12以降では、標準で MIXED が設定されているので敢えて変えない限りはこの手法で遅延を検出できます。(STATEMENTでも同じ動作を得ることが可能です)。詳細は・・・まあマニュアルを読んでください。
5.0系はいまのところステートメントベースレプリケーション(SBR)であり、5.1系で言うところの STATEMENT と同じ状況なので、この手法が使えると思います。