CentOS 6.6 に Systemtap をインストールして動かす

CentOS 6.6 に Systemtap をインストールして動かすのにハマった話です。

インストール方法

最終的に以下のコマンドでインストールして再起動すると Systemtap を動かせました。

$ sudo yum install systemtap
$ sudo yum --enablerepo=centosplus install kernel kernel-devel
$ sudo yum --enablerepo=base-debuginfo install kernel-debuginfo

ハマった話

ビギナーズガイドによると systemtap を動かすには以下のパッケージが必要です*1

これらのうち systemtap, systemtap-runtime, kernel-devel は CentOS 公式の Base リポジトリから提供されていて、kernel-debuginfo, kernel-debuginfo-common は Debuginfo リポジトリから提供されています。Debuginfo リポジトリはデフォルトでは有効になっていないので、yumコマンド実行時にオプション--enablerepo=base-debuginfoを付けて有効にする必要があります。

これらをインストールします。ただし、これでは動きません。

$ sudo yum install systemtap systemtap-runtime kernel-devel
$ sudo yum --enablerepo=base-debuginfo install kernel-debuginfo kernel-debuginfo-common

インストール後に、ビギナーズガイドにあるテスト用のコマンド*2を実行してみます。

$ sudo stap -v -e 'probe vfs.read {printf("read performed\n"); exit()}'
Pass 1: parsed user script and 103 library script(s) using 201640virt/29512res/3148shr/26860data kb, in 120usr/60sys/257real ms.
semantic error: while resolving probe point: identifier 'kernel' at /usr/share/systemtap/tapset/linux/vfs.stp:768:18
        source: probe vfs.read = kernel.function("vfs_read")
                                 ^

semantic error: missing x86_64 kernel/module debuginfo [man warning::debuginfo] under '/lib/modules/2.6.32-504.12.2.el6.x86_64/build'
semantic error: while resolving probe point: identifier 'vfs' at <input>:1:7
        source: probe vfs.read {printf("read performed\n"); exit()}
                      ^

semantic error: no match
Pass 2: analyzed script: 0 probe(s), 0 function(s), 0 embed(s), 0 global(s) using 211904virt/39740res/5172shr/35020data kb, in 60usr/480sys/1967real ms.
Pass 2: analysis failed.  [man error::pass2]

何やら debuginfo が無いと言われます。

原因

ググったりしてもよく分からなかったのですが、kernel-debuginfo の info を見ると原因がわかりました。

$ yum --enablerepo=base-debuginfo info kernel-debuginfo
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.nara.wide.ad.jp
 * extras: ftp.nara.wide.ad.jp
 * updates: ftp.nara.wide.ad.jp
Installed Packages
Name        : kernel-debuginfo
Arch        : x86_64
Version     : 2.6.32
Release     : 504.12.2.el6.centos.plus
Size        : 1.6 G
Repo        : installed
From repo   : base-debuginfo
Summary     : Debug information for package kernel
URL         : http://www.kernel.org/
License     : GPLv2
Description : This package provides debug information for package kernel.
            : This is required to use SystemTap with kernel-2.6.32-504.12.2.el6.centos.plus.x86_64.

Description の部分に

This is required to use SystemTap with kernel-2.6.32-504.12.2.el6.centos.plus.x86_64.

とあるように、カーネルのリリース名に見慣れぬ centos.plus という文字があります。 これは現在のカーネルとは違っていました。

$ uname -r
2.6.32-504.12.2.el6.x86_64

調べてみると CentOSPlus というリポジトリでも kernel と kernel-devel が提供されています。リリース名も kernel-2.6.32-504.12.2.el6.centos.plus.x86_64 に一致します。

というわけで CentOSPlus リポジトリから kernel とkernel-devel をインストール。

$ sudo yum --enablerepo=centosplus install kernel kernel-devel

そして再起動した後再びテスト用コマンドを実行すると、うまく動きました。

$ sudo stap -v -e 'probe vfs.read {printf("read performed\n"); exit()}'
Pass 1: parsed user script and 103 library script(s) using 201672virt/29544res/3148shr/26892data kb, in 110usr/20sys/128real ms.
Pass 2: analyzed script: 1 probe(s), 1 function(s), 3 embed(s), 0 global(s) using 296424virt/125164res/4124shr/121644data kb, in 990usr/200sys/1195real ms.
Pass 3: translated to C into "/tmp/stap53301G/stap_2a362e40998232e8986eb51a4ebd96d9_1543_src.c" using 296424virt/125496res/4456shr/121644data kb, in 0usr/70sys/59real ms.
Pass 4: compiled C into "stap_2a362e40998232e8986eb51a4ebd96d9_1543.ko" in 3670usr/1850sys/5836real ms.
Pass 5: starting run.
read performed
Pass 5: run completed in 10usr/10sys/359real ms.

OProfile / Bugs / #263 Using operf with multiple events, samples may be attributed to wrong event

OProfile / Bugs / #263 Using operf with multiple events, samples may be attributed to wrong event

oprofile v0.9.9 でとあるバグに遭遇しました。operf複数のイベントを同時に取得した場合、opreportの出力結果においてイベント名とその値が正しく関連付けられていないというものです。 このバグは oprofile v1.0.0 にて修正されています。

バグに遭遇した環境は CentOS 6.6, oprofile 0.9.9-6.el6_6 です。チケットで報告されているのと同じく、複数のイベントをそれぞれ単独に取得した場合と比較したとき、イベント名とその値の対応が正しくありませんでした。

2015/04/17 現在ではパッケージマネージャで提供される oprofile は v1.0.0 以前のものが多いかと思うので、注意が必要かもしれません。
以上、IPCを計測しようとしたらCPIになってしまったという結構深刻なバグでした。

sysstatコマンド群の時間表示をUNIX時間にする

やりたいこと

sysstat に含まれるコマンド (sar, iostat, mpstat, pidstat など) の時刻表示を、HH:mm:ssのような表示ではなくUNIX時間にしたい。

理由

  • 機械的に処理しやすくしてデータの加工やプロットを自動化したい
  • pidstat で特定のプロセスの情報を取得して、他のコマンドでシステム全体の情報を取得して別々のファイルに出力したとき、時間をキーとしてマージしようと思ったら表記ゆれがあると割りと面倒

調査

sysstat v11.1.3 について少し調べてみた。

  • pidstat
    • オプション-hで出力を1行にまとめた場合、デフォルトでUNIX時間になる *1
    • オプション-hなしの場合、strftimeのフォーマットが%Xなので *2 、できない 。
  • sar
    • sar単体ではできないと思われるが、sadfと組み合わせることでできる。
    • sar -o path/to/fileでバイナリファイルに出力して、sadf -U path/to/fileUNIX時間で出力される *3
  • mpstat
    • strftimeのフォーマットが%Xなので *4 、できない。
    • ただし mpstat の機能は sar で代用できると思われる。
  • iostat
    • strftimeのフォーマットが%z%Xなので *5 、できない。
    • ただし iostat の機能は sar で代用できると思われる。
  • cifsiostat, nfsiostat-sysstat
    • 使う予定がないので詳しく見てないが、ぱっと見では iostat と同じく無理っぽい *6 *7

まとめ

pidstat はオプション-hを使うと、sar はオプション-oでバイナリを出力して sadf でオプション-Uを使うと、時間表示をUNIX時間にできる。
mpstat や iostat は今のところできないが、sar で代用すればいいと思う。

APUE 3rd Editionの写経の準備メモ

Advanced Programming in the UNIX Environment, 3rd Editionの写経のための準備メモ。

環境

OS X

$ gcc -v
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix

Ubuntu

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.9.1-16ubuntu6' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.9.1 (Ubuntu 4.9.1-16ubuntu6)

ソースコード

http://www.apuebook.com/code3e.html からダウンロード

コンパイル

OS X

makeコンパイルエラーを抜粋。

gcc -R. -o t4 t4.o -L../lib -L. -lapue_db -lapue
clang: error: unknown argument: '-R.'
make[1]: *** [t4] Error 1
make: *** [all] Error 1

-R.のRの後のドットを取れば解決できるっぽい*1

--- db/Makefile.orig 2015-03-08 05:45:46.000000000 +0900
+++ db/Makefile   2015-03-08 05:46:00.000000000 +0900
@@ -15,7 +15,7 @@
   EXTRALD=-Wl,-rpath=.
 endif
 ifeq "$(PLATFORM)" "freebsd"
-  EXTRALD=-R.
+  EXTRALD=-R
 endif
 ifeq "$(PLATFORM)" "macos"
   EXTRALD=-R

Ubuntu

makeコンパイルエラーを抜粋。

gcc -ansi -I../include -Wall -DLINUX -D_GNU_SOURCE  badexit2.c -o badexit2  -L../lib -lapue -pthread -lrt -lbsd
/usr/bin/ld: cannot find -lbsd
collect2: error: ld returned 1 exit status
Makefile:31: recipe for target 'badexit2' failed
make[1]: *** [badexit2] Error 1

libbsdをインストールすればコンパイルできる*2

$ sudo apt-get install libbsd-dev

ヘッダとライブラリ

makeした後にヘッダとライブラリをコピー*3

$ sudo cp include/apue.h /usr/local/include
$ sudo cp lib/libapue.a /usr/local/lib

コンパイル時にオプションでライブラリを指定する。

$ gcc ls.c -lapue

サイボウズのLT大会で発表してきた

サイボウズが社内で開いているLT大会「技術Bar」に参加してLTしてきました。
「まだ黒い画面で消耗してるの?」というタイトルで、主にlsコマンドの出力を色付きにして見やすくする方法について話しました。

スライドを作ってから気がついたのですが、スライド作成時のkコマンドは少しバージョンが古いもので、現在ではオプションがついたりと少しバージョンアップしていました。

技術Barについて

技術Barについては以下の記事で解説されています。

月に1回やっていて学生なら無料で参加できるようなので、学生の人は是非参加すると良いと思います!(ステマ
働いているエンジニアと話せたり、社内の雰囲気を知れたりする良い機会になりました。
facebookページなどで開催のお知らせがあると思います。

サイボウズはもう16卒の新卒採用の選考が始まってますね。早くエントリーしなきゃ。

MySQLでTPC-Hベンチマークを実行する

DSS (Decision Support System) のベンチマークであるTPC-HMySQLで実行してみます。

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のダウンロードと展開
  • dss.ddl, dss.ri, tpcd.hに対してパッチを適用し、その後dbgen, qgenコンパイル
  • dbgen, qgenのラッパースクリプトの設置

DBGENのダンロード先とラッパースクリプトの設置先はそれぞれシェル変数SRC_DIRBIN_DIRで指定します。
今回はSRC_DIR~/srcBIN_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)

通常dbgenqgenを実行するときには辞書ファイルやクエリテンプレートを指定しなければいけないのですが、ラッパースクリプトではその辺の指定をしなくても済むようにしています。 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年度データベーススペシャリスト試験に合格した

やったぜ。

f:id:itiut:20140620125007p:plain

とはいえ準備不足だったためあまり点数は高くないので、これからもっと精進します。