連載
» 2008年08月06日 00時00分 公開

DTraceでトラブルシューティングOpenSolarisで始めるブログサーバ構築(最終回)(3/4 ページ)

[原口章司,サン・マイクロシステムズ株式会社]

MySQLサーバのトレース

 続いて、MySQLサーバのトレース方法について説明します。

図2 図3 mysqlのモニタリング

 大域ゾーンから、稼働中のmysql_zoneの中を確認してみます。

solaris# dtrace -n 'syscall:::entry /zonename == "mysql_zone"/ {@[execname]=count(); }'
dtrace: description 'syscall:::entry ' matched 235 probes
^C
   ttymon                                    9
   svc.configd                             154
   nscd                                    294
   java                                    388
   mysqld                                15344
solaris#

 このmysqldプロセスの中を、DTraceでトレースしていきましょう。

 MySQL内でone connection-levelのコマンドの実行に使われるdispatch_command()関数を確認して、SQLsnoopのような「トレーサ」を作ってみます。mysqldは独立したプロセスとして稼働中ですので、DTraceのpidプロバイダを利用して、

pid<mysqld のプロセスID>::dispatch_command:entry

でProbeを指定できそうに見えます。しかしMySQLは、C++言語でコンパイルされているため、オブジェクトファイル内での実際の関数名は符号化(mangle)された名前で存在しています。符号化のルールはコンパイラにより異なりますので、DTraceでC++のコードをトレースするには、ちょっとしたコツが必要になります。

 まず下記の方法で、mysqldのバイナリファイルから符号化された関数名を検索します。

solaris# cd /pool/zones/mysql_zone/root/opt/coolstack/mysql_32bit/bin
solaris# dem `nm ./mysqld | cut -f 8 -d "|" | grep
dispatch_command`
_Z16dispatch_command19enum_server_commandP3THDPcj == dispatch_command(enum_server_command, THD*,
char*, unsigned)
_ZZ16dispatch_command19enum_server_commandP3THDPcjE12
__FUNCTION__ ==
dispatch_command(enum_server_command, THD*, char*, unsigned)::__FUNCTION__

 nm(1)コマンドとdem(1)コマンドにより検索された「_Z16dispatch_command19enum_server_commandP3THDPcj」という文字列が、dispatch_command関数の符号化された関数名であることが分かります。この符号化された関数名を使い、下記のmysql.dというDスクリプトファイルを作成します。

pid$target::_Z16dispatch_command19enum_server_command
P3THDPcj:entry
{
       printf("%s\n",copyinstr(arg2));
}

 大域ゾーンに戻り、mysqldのプロセスIDを取得します。

solaris# pgrep -l mysqld
  1632 mysqld
  1222 mysqld_safe
solaris#

 dtrace(1M)で作成したmysql.dスクリプトを実行します。pidプロバイダに渡す引数として、稼働中のmysqldのプロセスIDを指定します。これで、Rollerの処理と連動してMySQLのトレースが可能になります。

solaris# dtrace -qs mysql.d -p 1632
/* mysql-connector-java-5.1.6 ( Revision: ${svn.Revision} ) */SHOW VARIABLES WHERE Variable_name
='language' OR Variable_name = 'net_write_timeout' OR Variable_name = 'interactive_timeout' OR
Variable_name = 'wait_timeout' OR Variable_name = 'character_se
SHOW COLLATION
SET character_set_results = NULL
SET autocommit=1
SET sql_mode='STRICT_TRANS_TABLES'
SET autocommit=0
SELECT t0.id, t0.client, t0.lastrun, t0.name, t0.timeacquired, t0.timeleased FROM roller_tasklock t0
WHERE (t0.name = 'ScheduledEntriesTask')
rollback
...

 MySQLはスケーラビリティと可用性に優れているため、Rollerだけでなく、さまざまな目的と併用されていることもあるでしょう。MySQLで負荷の高いトランザクション処理中に、極端にRoller側にアクセスが集中したりすると、RollerとMySQLのコネクション部分がボトルネックになる場合があります。ここで紹介したトレースは、このような場合の状況トレースにも有効で、RollerやMySQLのスケーリングやチューンアップのヒントになります。

 このようにDTraceは、稼働中のシステムやアプリケーションの強力なモニタリングツールとして使用できます。今回紹介したものは一例にすぎませんが、実際に何か不具合が起きた際には、DTraceを使ってProbe指定や述語、備え付けのさまざまなアクション関数や統計関数を活用して、あらゆる角度からの解析や計測の絞り込みが可能となり、原因究明のための有効な手段となります。

 特に、従来のデバッガだけでは解析が困難であった本番稼働中のシステムや、再現性の低いシステム不具合のトラブルシュートに有効であるともいえます。またDTraceを使えば、稼働中のシステムからカーネル内部の構造体の情報も参照可能ですので、OpenSolaris上でのオープンソースのコード解析にも活用されています。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。