続いて、MySQLサーバのトレース方法について説明します。
大域ゾーンから、稼働中のmysql_zoneの中を確認してみます。
solaris# dtrace -n 'syscall:::entry /zonename == "mysql_zone"/ {@[execname]=count(); }' |
この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 |
nm(1)コマンドとdem(1)コマンドにより検索された「_Z16dispatch_command19enum_server_commandP3THDPcj」という文字列が、dispatch_command関数の符号化された関数名であることが分かります。この符号化された関数名を使い、下記のmysql.dというDスクリプトファイルを作成します。
pid$target::_Z16dispatch_command19enum_server_command |
大域ゾーンに戻り、mysqldのプロセスIDを取得します。
solaris# pgrep -l mysqld |
dtrace(1M)で作成したmysql.dスクリプトを実行します。pidプロバイダに渡す引数として、稼働中のmysqldのプロセスIDを指定します。これで、Rollerの処理と連動してMySQLのトレースが可能になります。
solaris# dtrace -qs mysql.d -p 1632 |
MySQLはスケーラビリティと可用性に優れているため、Rollerだけでなく、さまざまな目的と併用されていることもあるでしょう。MySQLで負荷の高いトランザクション処理中に、極端にRoller側にアクセスが集中したりすると、RollerとMySQLのコネクション部分がボトルネックになる場合があります。ここで紹介したトレースは、このような場合の状況トレースにも有効で、RollerやMySQLのスケーリングやチューンアップのヒントになります。
このようにDTraceは、稼働中のシステムやアプリケーションの強力なモニタリングツールとして使用できます。今回紹介したものは一例にすぎませんが、実際に何か不具合が起きた際には、DTraceを使ってProbe指定や述語、備え付けのさまざまなアクション関数や統計関数を活用して、あらゆる角度からの解析や計測の絞り込みが可能となり、原因究明のための有効な手段となります。
特に、従来のデバッガだけでは解析が困難であった本番稼働中のシステムや、再現性の低いシステム不具合のトラブルシュートに有効であるともいえます。またDTraceを使えば、稼働中のシステムからカーネル内部の構造体の情報も参照可能ですので、OpenSolaris上でのオープンソースのコード解析にも活用されています。
Copyright © ITmedia, Inc. All Rights Reserved.