MySQLでTPC-Hベンチマークを実行する
DSS (Decision Support System) のベンチマークであるTPC-HをMySQLで実行してみます。
HammerDB というTPC-Hを実行できるベンチマークツールも存在するのですが、今回は公式に配布されるデータロードプログラムのDBGENとクエリ作成プログラムのQGENを使用します。
環境
前提
- MySQLがインストールされていること
mysqld
が動いてること
手順
TPC-H用のデータベースとユーザの作成
TPC-H用のデータベースtpch
とクエリを実行するユーザーtpch
を作成します。
わかりやすさのためtpch
としていますが、別に何でもいいと思います。
ユーザーtpch
にはデータベースtpch
の権限を与えておきます。
$ mysql -u root -p mysql> CREATE DATABASE tpch; Query OK, 1 row affected (0.00 sec) mysql> CREATE USER 'tpch'@'localhost'; Query OK, 0 rows affected (0.00 sec) mysql> GRANT ALL ON tpch.* to 'tpch'@'localhost'; Query OK, 0 rows affected (0.00 sec)
DBGEN, QGENのセットアップ
DBGENとQGENは公式ページ TPC-H - Homepage の右のリンクからダウンロードできますが、MySQLで実行するには何点かの修正パッチが必要です。
ダウンロードとパッチの適用などをしてくれるスクリプトinstall-dbgen.sh
を書いたので、それを用います。
install-dbgen.sh
が行うことは以下の通りです。
DBGENのダンロード先とラッパースクリプトの設置先はそれぞれシェル変数SRC_DIR
とBIN_DIR
で指定します。
今回はSRC_DIR
に~/src
、BIN_DIR
に~/bin
を指定します。
$ cd ~/src $ git clone git://github.com/itiut/tpch-mysql $ BIN_DIR=~/bin SRC_DIR=~/src ./tpch-mysql/install-dbgen.sh
install-dbgen.sh
のソースはこちらから。itiut/tpch-mysql
修正点は以下の通りです。
- データベース名とテーブル名を大文字から小文字に変更 (
dss.ddl
,dss.ri
) - コメントの文法を修正 (
dss.ri
) - 外部キー作成クエリに参照先のカラム名を追加 (
dss.ri
) - MySQL用のヘッダ定義を追加 (
tpcd.h
) - クエリのテンプレートをMySQLの文法に修正 (
queries/*.sql
)
通常dbgen
とqgen
を実行するときには辞書ファイルやクエリテンプレートを指定しなければいけないのですが、ラッパースクリプトではその辺の指定をしなくても済むようにしています。
tpch-mysql/queries
にあるクエリテンプレートとSRC_DIR
にダウンロードしたDBGENをそのまま使うので、変更や削除はしないで下さい。
テーブルの作成
dbgen
と同じディレクトリにある、テーブル作成用のクエリdss.ddl
を実行してテーブルを作成します。
$ cd ~/src/tpch_2_17_0/dbgen $ mysql -u tpch -D tpch < dss.ddl
dbgen
を用いてデータを作成
BIN_DIR
に指定したディレクトリが環境変数PATH
中にあれば、dbgen
が使えます。
dbgen
の基本的な使い方としては、-s
オプションでScale Factorというデータのサイズの指標を変更します。Scale Factorが大きいときには、データを分割して作成することもできます。
データは拡張子が.tbl
のファイルとして作成されます。
$ dbgen -s 1 $ ls *.tbl customer.tbl lineitem.tbl nation.tbl orders.tbl partsupp.tbl part.tbl region.tbl supplier.tbl
データベースにデータをロード
作成したデータのファイル名から拡張子を除いたものが同じ名前のテーブルに対応しているので、対応するテーブルにデータをロードします。
$ for tbl_file in *.tbl; do mysql -u tpch -D tpch -e "LOAD DATA LOCAL INFILE '$tbl_file' INTO TABLE $(basename $tbl_file .tbl) FIELDS TERMINATED by '|' LINES TERMINATED BY '\n';"; done
インデックスを作成
dbgen
と同じディレクトリにある、インデックス作成用のクエリdss.ri
を実行してインデックスを作成します。
$ mysql -u tpch -D tpch < dss.ri
qgen
を用いてクエリを作成
qgen
も-s
オプションでScale Factorを指定します。
1~22のクエリ番号を指定してクエリを個別に作成できます。
$ for i in $(seq 1 22); do qgen -s 1 $i > $i.sql; done $ ls *.sql 10.sql 11.sql 12.sql 13.sql 14.sql 15.sql 16.sql 17.sql 18.sql 19.sql 1.sql 20.sql 21.sql 22.sql 2.sql 3.sql 4.sql 5.sql 6.sql 7.sql 8.sql 9.sql
後はこれらのクエリを
$ mysql -u tpch -D tpch < 1.sql
などで実行するだけです。
平成26年度データベーススペシャリスト試験に合格した
やったぜ。
とはいえ準備不足だったためあまり点数は高くないので、これからもっと精進します。
研究室の同期向けにターミナルの勉強会を開いた
4月から新しい研究室に変わってリモートで作業する機会が増えたので、自分自身の復習も兼ねてターミナルにあまり慣れてないであろう研究室の同期向けにターミナルの勉強会を開きました。
参加者は私を含めてM1とM2合わせて9人で、内容はbashとtmuxの基本操作・設定をデモを交えつつやり、最後に~/.ssh/config
を使うとsshコマンドが楽になるということを説明しました。
スライドはこちら。
黒い画面入門
勉強会中の質問とか感想とか
- 意外とbashの行頭・行末移動の
C-a
・C-e
のコマンドが覚えられない- キーボード上で
a
が左、e
が右にあるのを行頭・行末と対応させると覚えやすい
- キーボード上で
whatis emacs
は哲学- コマンドの実行回数ランキングの上位が1文字になっててウケる
rm -i
にしてても結局確認せずにy
押してEnter
しちゃう- ファイルの内容確認して重要そうだったら警告してくれるコマンドがあったら幸せになれそう
- tmuxの
|
でペイン縦に分割、-
でペインを横に分割は直感的でわかりやすい - 多段sshは全然知られてなかった
- tmuxの発音は「ティーマックス」だった?
- 今までずっと「ティーミュックス」と呼んでた
スライドの作成環境
PowerPointを窓から投げ捨てたいのですが、良さそうな移行先が見つかってません。
前に使ったglide.soというgist上のmarkdownをスライドショーにしてくれるサービスがダウンしてて使えなかったので、今回のスライドはRemarkを使って作ったのですが、結構使いやすかったです。
$ python -m SimpleHTTPServer
すればローカル環境だけでプレビューできてとても楽です。
ただしテンプレートらしきものはないのでcssを少しカスタマイズしないといけないし、htmlの<textarea>
にmarkdownを直書きするのは少しキモいです。
しばらくはRemarkを使ってみようと思います。
InnoDBの共有テーブルスペースにrawデバイスを使う
すごくハマったのでメモ。 公式ドキュメントに手順が載っているが、これだけではできなかった。
MySQL :: MySQL 5.6 Reference Manual :: 14.5.8 Using Raw Disk Partitions for the Shared Tablespace
環境
手順
1. innodb_file_per_table
を無効に
5.6.6 以降はデフォルトでinnodb_file_per_table
が有効になっていて、テーブルごとにファイルを作ってしまう。
/etc/my.cnf
を開いて[mysqld]
セクションに無効にする設定を追加しておく。
またこの時点ではinnodb_data_file_path
はデフォルト値に設定しておく。
rawデバイス用の設定にするとmysql_install_db
でデータディレクトリを初期化したときにエラーが生じ、rootパスワードが勝手に設定されてmysqlにログインできなかった。
[mysqld] innodb_file_per_table=OFF innodb_data_file_path=ibdata1:12M:autoextend
2. mysql_install_db
でデータディレクトリの初期化
$ sudo /opt/mysql/scripts/mysql_install_db --user=mysql --datadir=/var/lib/mysql
必要に応じて--datadir
オプションを付けてデータディレクトリを指定する。
3. mysql
データベース中のテーブルのダンプと削除
ibdata1
中にはmysql
データベース中のいくつかのテーブルが含まれている。5.6 以前ではibdata1
が削除されるとそれらのテーブルは再び作られるが、5.6 では再び作られないらしい。
innodb - Cannot open table mysql/innodb_index_stats - Database Administrators Stack Exchange
なのでこれらのテーブルをダンプしておいて、後でリストアする。
これらのテーブルを復元しないでおくとInnoDB: Error: Table "mysql"."innodb_table_stats" not found.
というようなエラーが大量に出ていた。
mysqld
を起動してテーブルをダンプして削除。その後mysqld
を停止。
$ sudo service mysql.server start $ mysqldump -u root mysql \ innodb_index_stats \ innodb_table_stats \ slave_master_info \ slave_relay_log_info \ slave_worker_info \ > mysql_innodb_tables.sql $ mysql -u root -D mysql -e "DROP TABLE innodb_index_stats, innodb_table_stats, slave_master_info, slave_relay_log_info, slave_worker_info" $ sudo service mysql.server stop
4. ログファイルの削除
ドキュメントには書かれていなかったが、ib_logfile0
などのログファイルが存在するとログが書き込めないというエラーが生じた。
$ sudo rm /var/lib/mysql/ib_logfile*
5. rawデバイスの初期化のための設定
ここからやっとドキュメントの手順開始。
/etc/my.cnf
を開いてinnodb_data_home_dir
とinnodb_data_file_path
を設定する。
[mysqld] innodb_data_home_dir= innodb_data_file_path=/dev/sdb1:300Gnewraw
使うデバイスの所有者がmysqld
を動かすユーザーと同じでないとデバイスを開けないので、所有者を変更しておく。
$ sudo chown mysql:mysql /dev/sdb1
6. rawデバイスの初期化
mysqld
を起動するとrawデバイスの初期化が始まる。大きい容量を指定していると長い時間がかかる。
初期化が終わったら何もせずにmysql
を停止させる。
$ sudo service mysql.server start && sudo service mysql.server stop
7. rawデバイス用の設定
/etc/my.cnf
を開いてinnodb_data_file_path
の値がnewraw
であったところをraw
に変更する。
[mysqld] innodb_data_home_dir= innodb_data_file_path=/dev/sdb1:300Graw
8. ダンプしたテーブルのリストア
mysqld
を起動してさっきダンプしたテーブルをリストアする。
$ sudo service mysql.server start $ mysql -u root -D mysql < mysql_innodb_tables.sql
以上で完了。
KVM上のVirtIOを使うWindowsでディスクアクセス速度を測定してみた
前回に引き続きKVMの準仮想ドライバVirtIOを使って、KVM上のWindowsでディスクアクセス速度を測定しました。 比較対象としては網羅性は無いですが、KVM上でVirtIOを使わずデフォルトのドライバを使った場合と、VirtualBox上のWindowsと、ローカルのUbuntuとで速度を測定して比較しました。
環境
ホスト環境
ハードウェア
- CPU
- RAM
- DDR3 1067MHz 4GB x 2
- HDD
- Hitachi HTS547550A9E384 500GB 5400RPM
ソフトウェア
- ホストOS
- Ubuntu 14.04 64bit
- カーネル
- 3.13.0-27-generic
- ハイパーバイザ
- qemu-kvm 2.0.0
- VirtualBox 4.3.10 + Guest Additions 4.3.10
- 測定ソフト
- CrystalDiskMark 3.0.3 x64 (ゲスト)
- fio 2.1.3 + fioでCrystalDiskMarkと同様の測定を実現するシナリオファイル (ローカル)
ゲスト環境
共通
- 割り当てCPUコア数
- 2
- 割り当てメモリサイズ
- 4096MB
- 割り当てストレージサイズ
- 96GB
- ゲストOS
- Windows 7 Professional SP1 64bit
比較対象
- VBox-dynamic
- VirtualBox上で、ストレージは動的割り当て
- AHCIタイプのストレージコントローラを使用 (デフォルト仕様)
- ホストI/Oキャッシュは使用しない (デフォルト仕様)
- VBox-fixed
- VirtualBox上で、ストレージは固定割り当て
- それ以外はVBox-dynamicと同じ
- KVM-IDE
- KVM-VirtIO
- Local
- ホストのローカルで測定
測定結果
KVM-VirtIOの値が非常に大きくなったので、他の値を見やすくするためKVM-VirtIOがグラフの右端で見切れるようにしてます。
考察
まずKVM-IDEもKVM-VirtIOも明らかにおかしい大きな値が出ています。ローカルとゲストとで測定方法が厳密には同じではないので正確な比較ではないですが、ローカルよりもKVM-IDEやKVM-VirtIOの方が大きな値を取るのは普通考えられないことです。 あまり確証はないですが、考えられる理由は2点あります。
一方VirtualBoxでの値はローカルの値とほぼ同等で、個人的見解としては仮想化した時のディスクアクセスのオーバーヘッドは実用上無視できると思います。
今回の測定は、デスクトップやノートPCでホストOSのWindowsを使うときにハイパーバイザとしてKVMを使うかどうかの調査も兼ねてたのですが、VirtualBoxのディスクアクセスは遅いのではないかという疑念は晴れて、VirtualBoxの使用をやめる消極的な理由はなくなりました。
KVMを使ってみた感想
- ゲストの解像度をウィンドウサイズに合わせて変更できなかった (やり方を知らないだけかも)
- ホストでは
xmodmap
を使ってCapsLockを左Ctrlに変更していたのに、ゲストには反映されなかった
ディスクアクセス速度よりも使いにくさが目立ったので、KVMでWindowsを仮想化するのはやめておきます。
結論
- KVMのディスクアクセス速度はなんか悪さされて正確に測れなかった
- VirtualBoxのディスクアクセスのオーバーヘッドは実用上無視できる (個人的見解)
- 引き続きVirtualBoxでWindowsを仮想化して使う
KVM上にVirtIOドライバを使うWindows 7をインストールする
準仮想化ドライバであるVirtIOを使うことでWindows仮想マシンのIOが速くなるか試してみたかったので、KVM上にVirtIOドライバを使うWindows 7をインストールしてみました。
凖仮想化とは、全ての命令をソフトウェアエミュレーションする完全仮想化に対して、ゲストOSなどにある程度修正を加えて、物理ハードウェア上で動かすのに近い形で動作させる仮想化のことです。Windowsの場合はカーネル自体には修正を加えれられないので、準仮想化ドライバであるVirtIOを使うことで準仮想化を実現できます。
環境
- ホストOS: Ubuntu 14.04 64bit
- ゲストOS: Windows 7 64bit
- ハイパーバイザ: qemu-kvm 2.0.0
- ドライバ: virtio-win-0.1-74.iso
インストール
kvmとvirt-managerのインストール
$ sudo apt-get install qemu-kvm qemu-system libvert-bin virt-manager
libvirtd
グループに入っていないと仮想マシンの操作ができないみたいですが、上のコマンドを実行するだけで現在のユーザーをlibvirtd
グループに追加してくれるので、ログインし直してグループの設定を反映させます。
Windows用のVirtIOドライバをダウンロード
Vistaより新しい64bit版Windowsでは通常デジタル署名されたドライバしかインストールできません。
幸いFedoraプロジェクトでデジタル署名されたドライバを公開してくれているので、それを使います。
公式ページ WindowsGuestDrivers/Download Drivers - KVM の Latest VirtIO drivers for Windows from Fedora からドライバが入ったisoファイルをダウンロードできます。
仮想マシンの作成
virt-manager
を起動して、通常と同じように仮想マシンを作成します。
最後の画面でCustomize configuration before install
にチェックを入れておきます。
設定画面が開くので、ディスクの設定でDisk bus
をVirtio
に、NICの設定でDevice model
をvirtio
に設定してインストールを開始します。
Windowsのインストール
インストールを進めると、初めはドライバが無いためディスクが認識されません。
Load driver
を押すと次のような画面になります。
仮想マシンの設定画面からCDROMの設定を開き、Windowsのインストールisoファイルをダウンロードしておいたドライバのisoファイルに変更した後、仮想マシンの画面に戻ります。
Browse
を押すとドライバを探す画面になるので、CDROMの中からインストールするWindowsにあったバージョンとアーキテクチャのディレクトリを選択します。
ドライバが見つかったので、全て選択してNext
を押してインストールします。
ドライバのインストールが終わるとディスクが認識されます。
ここではWindows cannot be installed to this disk.
と出てきて先に進めなくなっていますが、CDROMをWindowsのインストーラisoファイルに変更し直せば先に進むことができます。
後は普通にインストールするだけです。
インストールして少し使ってみて思ったのですが、KVMにはVMwareやVirtualBoxにはあるディスプレイの解像度の自動調整機能とかは無いんでしょうか。ググってもよくわかりませんでした。
卒論提出にあたって私はどう生きようと思うか
近況報告
本日2月7日、私は卒業論文を提出し、無事に受理されました。 発表や学位審査をまだ控えていますが、とりあえず一段落といった感じです。
昨年の10月下旬から3ヶ月少々メールやLINEなど軒並み連絡を絶っており、関係者各位におかれましては心配した方もしなかった方もいるかもしれませんが、私は生きています。
物理的に何かあったというわけではなく精神的な問題を抱え、自分の人生をどう生きるかという悩みに答えを出せずに、何も手を付けることができないという状態でした。
3ヶ月間何をしていたか
11月末までは、読書50%ゲーム50%ぐらいの時間配分で過ごしていました。 悩みの答えを求めて読書をして、読むのに疲れたらゲームで現実逃避をする、というパターンを繰り返していました。
12月に入ってからは、このままでは卒業が危ういという危機感から研究室には復帰し、卒論を進めていました。
しかし、悩みに対してある程度明確な答えを出せたのは12月の中旬になってからでした。 また、絶っていた連絡を再び取り戻そうするのにもしばらく時間がかかりました。
人生をどう生きるかという悩み
私の頭の中のどこかに必ず潜んでいる悩みが、人生をどう生きるかという悩みです。 なぜこのことについて悩むようになったかはよくわかりませんが、初めに悩むようになったのは高校2年の頃です。 普段は悩みについてほんの薄っすら考えている程度でしかありませんが、ふとした拍子に思考の中に悩みの占める割合が大きくなると、 悩みのせいで何も手を付けられず身動きが取れなくなってしまうことがあります。
何も手を付けられないほど思い悩んだことは、今回を含めると3回あります。
1回目は、高校2年の時です。 高校2年の終わりが近づくに連れて、1年後に迫る大学受験の危機感から、「偏差値の高い大学に行けばなんとかなるだろし、そうしなければならない」と思考を停止させて受験勉強に逃げ込み、悩みを先送りにするというその場しのぎの対処しかできませんでした。
2回目は、大学入学の1年後くらいです。 受験という悩みの先送り要因がなくなってしまったため、当然その悩みは立ち現れました。 入学直後は新たな大学生活に目を奪われていたため、悩みは大きくなかったものの、半年もするとしだいに悩みが大きくなり、1年後には大学生活に支障をきたすまで思い悩むようになっていました。 一人で思い悩むだけでは解決しないと思い、いろいろなことに手を出してはみたものの中途半端に終わったり失敗したりする、ということを繰り返したことを覚えています。
その過程で、自分が楽しめることをして生きる、という生き方が私にとっては一番良いのではないかと思い至りました。 自分が楽しめないことをしていても、いずれ耐えられなくなり精神的に病んでしまうということを、経験則として学んだからです。
いずれ考えを改める可能性もあるかもしれないが、ひとまずは「楽しめることをして生きる」という生き方を暫定的に掲げて生きていこうと思いました。 いろいろ手を出した中でプログラミングは楽しめたので、将来的にIT技術者として生計を立てることを念頭に置き、情報系の学科に進学したり、プログラマのアルバイトをしたりと、自分で進路を決めてきました。
プログラミングは本当に楽しかったのか
進学した学科では、電気の講義には苦しめられたものの、情報の講義はとても楽しく、概ね満足していたのだが、ここに来て3回目の悩みが生まれました。
プログラミングは確かに楽しい。しかし、プログラミングが楽しいと、他人に向かって言える自信を持てなくなってきていたのです。
なぜかというと、プログラミングが上達するにつれて、すごい人のすごさを実感できる機会がしだいに増えていき、プログラミングの実力やプログラミングに対する情熱を自分と比較して勝手に落ち込んでしまうのです。 実力という点では、ネットを見ていると、働いている年上の人はもちろん、同世代や下の世代の人でも、いろいろなプロダクトやサービスを作っているという人がたくさん見受けられます。 情熱という意味でも、寝食を除いて起きている時間は呼吸をするようにプログラミングをしている人もいるらしいし、そういう人たちに対して私もプログラミングが楽しいと胸を張って言えるかというと、言える自信はないとどうしても思ってしまうのです。
それに加えて、プログラミングの対象に、時間を忘れて熱中できるという意味での「楽しさ」を持てていなかったことに気づきました。 中間発表までの卒論にしろ、この前参加したハッカソンにしろ、これは自分が本当にやり遂げるべき仕事ではないという感覚をどこかで抱いていました。
プログラミングが楽しいと自信を持って言えなくなりつつあり、プログラミングの対象も楽しめていないのならば、「楽しめることをして生きる」という方針だと、プログラミングで生計を立てようとすることにいずれ無理が生じるだろうと思うようになり、苦悩が生じました。
私にとってのプログラミングの楽しさとは
プログラミングの楽しさがどこから来ていたのかを振り返ってみました。 するとプログラミング自体よりも、プログラミングを通して問題を解決することに楽しさを見出していたのではないか、と思うようになりました。
プログラミングを楽しいと感じたきっかけとしては、PC1台さえあれば自分の好きなモノが作れるということもさることながら、独学したての頃に競技プログラミングにハマったことも挙げられます。
また4年弱のプログラミング経験を振り返ると、自分の創造力を働かせてユニークなものを作るよりも、身の回りの不便なことを解決するものであったり、チャレンジングな課題に挑戦することの方により楽しんで取り組んでいたように思います。
その時点ではできなかったことを、プログラミングによってできるようにするという、問題解決プロセスにこそ私は楽しさを感じていたのでしょう。
どう生きようと思うか
自分が楽しいと感じることは「プログラミングによる問題解決」だとわかった今、次なる問題は、解決すべき問題は何かということです。 今回の悩みの原因になった、プログラミングの対象に情熱を持てていないということとも直接関係してくる問題です。
妥当な考えとしては、自分が解決することに情熱を持てて、かつ、それによって生計を立てるためには、社会的にも解決することに価値があるような問題なのでしょう。
「楽しいことをして生きる」という生き方の下、自分が情熱を持てる問題をプログラミングによって解決すること。 それが現時点で私が考える人生の生き方です。