[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
SlideShare a Scribd company logo
DTrace で MySQL を斬る!
                〜 DTrace による MySQL 解析ことはじめ 〜




奥野 幹也
@nippondanji
mikiya (dot) okuno (at) gmail (dot) com
自己紹介
●
    今日は個人として来ています。
     –   http://nippondanji.blogspot.com/
     –   http://www.google.com/profiles/mikiya.okuno
●
    現職は MySQL サポートエンジニア。
     –   2000 年にサン・マイクロシステムズ入社
     –   2007 年に MySQL KK へ転職
     –   気付くとまたサン・マイクロシステムズに
     –   オラクル・コーポレーションに・・・
MySQL について
●
    オープンソースのリレーショナル・データベー
    ス・マネージメント・システム
●
    MySQL AB => Sun Microsystems => Oracle に
    よって開発。
●
    Web 開発においては圧倒的なシェア
       –   PHP/Perl/Java/Ruby/C/C++/ODBC...
●
    使い易く、安定して、高速に動作するのがウリ
MySQL は永久に不滅です!




                                     © Brian Aker
         http://krow.livejournal.com/687521.html
MySQL の特徴
●
    ANSI SQL 標準に準拠(一部の文法を除               ●   UNION
    く。)                                  ●
                                             ビュー
●
    種々のプラットフォームをサポート                     ●
                                             サブクエリ
    ( Windows 、 Linux 、 Mac 、各種 UNIX 系   ●   INFORMATION_SCHEMA
    OS )                                 ●
                                             SSL による通信
●
    ストレージエンジンによりデータを格納す                  ●
                                             Unicode をはじめとした各種文字コードの
    るレイヤーを仮想化                                サポート
●
    ACID 準拠のトランザクション                     ●
                                             全文検索
●
    XA トランザクション                          ●
                                             タイムゾーンのサポート
●
    非同期 Master/Slave 型レプリケーション           ●
                                             多種多様な開発言語のサポート( C 、 C+
●
    水平パーティショニング                              + 、 Java 、 Perl 、 PHP 、 Python 、 Ruby
    ( Range 、 List 、 Hash 、 Key )            など)
●
    ストアドプロシージャ、ストアドファンク                  ●
                                             ODBC による接続のサポート
    ション、トリガ
MySQL 構造の特徴
●
    モノリシックカーネル
●
    シングルプロセス・マルチスレッド
●
    1 セッション= 1 スレッド
●
    ストレージエンジン API による仮想化
●
    プラグイン API
●
    GNU Bison による Lexical Scanner
●
    ソースコードは C/C++ 混在( 100 万行程度)
MySQL の仕組み
クライアント             クライアント        クライアント
  Java               PHP           ODBC




     コネクション       コネクション      コネクション
      スレッド         スレッド        スレッド
                                          SQL の解析と最
                                            適化は共通
   パーサー・オプティマイザ・アクセス管理 等


            ストレージエンジン API                 データの格納や
  MyISAM           InnoDB       MySQL     アクセス方法は
                                Cluster   ストレージエン
                    テーブル
 table_name.MYI
                    スペース
                                          ジンごとに違う
table_name.MYD                   NDB
                   ログファイル        API

                  MySQL サーバ


                                データノード
                                 データノード
                               データノード
                              データノード
MySQL の構造を知る!
●
    Web ページ
      –   http://forge.mysql.com/wiki/MySQL_Internals
●
    書籍
      –   詳解 MySQL ( Understanding MySQL
           Internals )
      –   Expert MySQL
      –   MySQL データベース構築バイブル
●
    ソースコード!!
ソースコードを入手!
●   http://dev.mysql.com/downloads/
●   bzr branch lp:mysql-server/5.1 mysql-5.1
     ●
       sql/mysqld.cc ... main() 関数があるよ!
     ●
       sql/sql_parse.cc ... リクエストの入り口
     ●
       sql/sql_yacc.yy ... SQL パーサー                       この辺りから
     ●
       sql/handler.cc ... ストレージエンジン API                  覗いてみよう!
     ●
       sql/log.cc ... ログ関係
     ●
       sql/log_event.cc ... バイナリログ
     ●
       sql/sql_show.cc ... SHOW コマンドと I_S
     ●
       sql/slave.cc ... レプリケーションスレーブ
     ●
       sql/item*cc ... データ型と関数
     ●
       sql/sql_base.cc, sql/sql_class.cc ... 基本的なデータ型等
     ●
       storage/innodb ... InnoDB の実装
     ●
       storage/myisam ... MyISAM の実装
     ●mysys/* ... MySQL Core API
DTrace!!
●
    Solaris 10 で搭載された機能。
      –   Solaris/Mac OS X/FreeBSD で利用可能
●
    カーネル / ユーザープロセスをトレース。
●
    プローブと呼ばれる観測点を対象のプログラム
    に動的に埋め込む。
●
    プローブの種類に応じたプロバイダ。
●
    D 言語と呼ばれるプログラムで操作。
      –   参考: D 言語基本文法最速マスター( DTrace のほう)
      –   http://nippondanji.blogspot.com/2010/02/ddtrace.html
DTrace 動作イメージ
                                 プロバイダに指示を出したり
           ユーザープロセス              情報を表示したり
           ( mysqld など)
                                   dtrace コマンド
                 プロ
                 ーブ
ユーザー空間                                   各種情報


カーネル空間                    Fire
           有効化
                                 DTrace モジュール


   プロバイダ          プロ
                  ーブ
                 モジュール
プロバイダの種類
Provider名          Probeの場所        Providerのシンボル
FBT - function     カーネル内における関数の    fbt
boundary tracing   呼び出しとリターン。

Systrace           システムコールの呼び出し    syscall
                   とリターン。
SDT - statically   ソースコードにおいて指定さ sdtまたはコンパイル時に指
defined tracing    れた任意の場所。(カーネ  定
                   ル内)

PID                ユーザープロセスにおける    pid{pid}
                   関数の呼び出しとリターン。   (pid1234のように指定する)

Fasttrap           ソースコードにおいて指定さ コンパイル時に指定
                   れた任意の場所。(ユー
                   ザープロセス内)

dtrace             トレースの開始と終了、およ BEGIN/END/ERROR
                   び例外発生時。
profiling          一定期間ごと。         profile-n/tick-n
                                   (nはインターバル)
D 言語の書式
プローブ記述子
/ 述語 /
{               これを必要な回数
                 列挙するだけ。
   アクション      ループなし、分岐なし。
}
プローブの書式
●
    プロバイダ名 : モジュール名 : 関数名 : プロー
    ブ名
      –   pid プロバイダの場合、 pid{ プロセス ID} とい
            う書式になる。例 ) pid123
      –   C++ の関数名を指定するにはワイルドカード
           ( * )が便利。
mysqld 内に設置可能なプローブ
●   pid
          –   関数の entry         C++ の関数名に注意
                                   It's mangled!!
          –   関数の return
          –   関数オフセット
          –   書式 ) pid123
●   Fasttrap
          –   MySQL 5.4 で追加!!
          –   書式 ) mysql123
述語の書式
●
    評価出来る式なら何でも OK
      –   例 ) execname == "mysqld"
●
    条件分岐がない代わりに述語で Fire するかどう
    かをコントロール。
アクション
●
    情報の出力や変数への代入。
●
    セミコロン区切りで必要な数を列挙。
●
    情報の出力例。
     –   trace( 式 )
     –   tracemem(address, size);
     –   printf(" フォーマット ", arg1, arg2, ...);
     –   ustack(); jstack(); stack();
         etc
変数の種類
●
    スカラー変数… argname
      –   グローバルなスコープを持つ
●
    スレッドローカル変数… self->argname
      –   同一スレッドだけからアクセス可能
●
    節固有変数… this->argname
      –   プローブが Fire している間だけ利用可能
●
    組み込み変数…後述              ユーザープロセス
●
    外部変数… `argname          には使えない。
組み込み変数
●
    arg0 ... arg9 ・・・プローブに対する引数の最初の 10 個(数値型で取得)
●
    cwd ・・・カレントワーキングディレクトリ
●
    errno ・・・直前のシステムコールによって返されたエラーの値
●
    execname ・・・実行プログラム名
●
    uid ・・・実行中のプロセスの実効ユーザー ID
●
    gid ・・・実行中のプロセスの実効グループ ID
●
    pid ・・・実行中のプロセス ID
●
    ppid ・・・実行中のプロセスの親プロセス ID
●
    tid ・・・現在のスレッドのスレッド ID
                                         大切な情報源!!
●
    probeprov ・・・プロバイダ名
●
    probemod ・・・モジュール名
●
    probefunc ・・・関数名
●
    probename ・・・プローブ名
●
    timestamp ・・・タイムスタンプ
●
    walltimestamp ・・・ 1970 年 1 月 1 日 UTC からの経過時間。単位はナノ秒。
MySQL 5.4 で追加されたプローブ
 ●
     include/probes_mysql.d を見よ!                                  Fasttrap!


connection-start(unsigned long conn_id, char *user, char *host);
connection-done(int status, unsigned long conn_id);
command-start(unsigned long conn_id, int command, char *user, char *host);
command-done(int status);
query-start(char *query, unsigned long connid, char *db_name, char *user,
                     char *host, int exec_type);
query-done(int status);
query-parse-start(char *query);
query-parse-done(int status);
query-cache-hit(char *query, unsigned long rows);
query-cache-miss(char *query);
query-exec-start(char *query, unsigned long connid, char *db_name,
                      char *user, char *host, int exec_type);
query-exec-done(int status);
insert-row-start(char *db, char *table);
insert-row-done(int status);
update-row-start(char *db, char *table);
                  :
                  :
プローブを設置し易い関数
●
    DTrace の制約として、外部変数はユーザープ
    ロセスをサポートしていない。
      –   引数が重要な情報源!
      –   mysql_parse() 関数 ... 第 2 引数が SQL 文
●
    エラー発生時に Fire する。
      –   vprint_msg_to_log() ... エラーログへの書
           き込み
      –   my_error() ... クライアントへエラー送信
      –   my_print_error() ... シンタックスエラー
例 1) SQL 文を抽出
pid$target::*mysql_parse*:entry
{
  trace(copyinstr(arg1));
}
例 2) メモリ不足の原因
pid$target::*mysql_parse*:entry
{
  self->q = 1;
  self->qstr = copyinstr(arg1);
}

pid$target::*mysql_parse*:entry
/ self->q /
{
  self->q = 0;
  self->qstr = 0;
}

pid$target::malloc:return
/ errno == ENOMEM /
{
  printf("=== Memory allocation error at %Y ===n", walltimestamp);
  ustack();
}

pid$target::malloc:return
/ errno == ENOMEM && self->q /
{
  printf("QUERY: %sn", self->qstr);
}
例 3) エラーメッセージを追跡
pid$target::*mysql_parse*:entry
{
  self->q = 1;
  self->qstr = copyinstr(arg1);
}

pid$target::*mysql_parse*:return
/ self->q /
{
  self->q = 0;
  self->qstr = copyinstr(arg1);
}

pid$target::*my_error:entry
/ self->q /
{
  printf("Query generated an error (errno = %d): %sn",
    arg0, self->qstr);
  ustack();
}

pid$target::*my_printf_error:entry
/ self->q /
{
  printf("Syntax error: %sn", self->qstr);
}
例 4) クエリキャッシュのヒット率
mysql$target:::query-cache-hit
{
  hit++;
  @qhit["rows per query when qcache hit"] = quantize(arg1);
}

mysql$target:::query-cache-miss
{
  miss++;
  @qmiss[copyinstr(arg0)] = count();
}

tick-5sec
/ hit != 0 || miss != 0 /
{
  printf("ratio: %u (%u / %u)", 100 * hit / (hit+miss), hit, hit+miss);
}

tick-5sec
/ hit == 0 && miss == 0 /
{
  printf("ratio: NULL");
}

tick-5sec
{
  total_hit += hit;
  total_miss += miss;
  hit = miss = 0;
}
例 5) 1000 行以上のソートを検出
#!/usr/sbin/dtrace -s

BEGIN
{
  printf("Hit Ctrl+C to exit.n");
}

mysql$target:::filesort-start
{
  self->sorting = 1;
  self->db = arg0 == 0 ? "NULL" : copyinstr(arg0);
  self->table = copyinstr(arg1);
}

mysql$target:::filesort-done
/self->sorting && arg1 > 1000/
{
  self->sorting=0;
  printf("DB: %s, Table: %s, Rows: %u",
    self->db, self->table, arg1);
}
例 5) 1000 行以上のソートを検出
#!/usr/sbin/dtrace -s

BEGIN
{
  printf("Hit Ctrl+C to exit.n");
}

mysql$target:::filesort-start
{
  self->sorting = 1;
  self->db = arg0 == 0 ? "NULL" : copyinstr(arg0);
  self->table = copyinstr(arg1);
}

mysql$target:::filesort-done
/self->sorting && arg1 > 1000/
{
  self->sorting=0;
  printf("DB: %s, Table: %s, Rows: %u",
    self->db, self->table, arg1);
}
例 6) テーブルごとのソート統計
mysql$target:::filesort-start
{
  self->sorting = 1;
  self->db = arg0 == 0 ? "NULL" :
    copyinstr(arg0);
  self->table = copyinstr(arg1);
}

mysql$target:::filesort-done
/self->sorting/
{
  self->sorting=0;
  @sorts[self->db, self->table] = sum(arg1);
}
例 7) ソート中断の原因
#!/usr/sbin/dtrace -s

pid$target::*mysql_parse*:entry
{
  self->q = 1;
  self->qstr = copyinstr(arg1);
}

pid$target::*mysql_parse*:return
/ self->q /
{
  self->q = 0;
  self->qstr = 0;
}

mysql$target:::filesort-done
/ self->q && arg0 /
{
  printf("nnABORTED QUERY: %sn", self->qstr);
  ustack();
}
DTrace Toolkit
●
    DTrace を使ったユーティリティ群
      –   http://hub.opensolaris.org/bin/view/Community+
            Group+dtrace/dtracetoolkit
      –   http://nippondanji.blogspot.com/2007/07/dtrace.
            html
●
    DTrace を知らなくても利用可能
●
    Mac OS X ではデフォルトでインストール
      –   grep -I -m 1 dtrace /usr/bin/*
DTrace Toolkit つづき
●
    dappprof ... ユーザープロセスをプロファイリングします。
●
    dapptrace ... ユーザープロセスの関数呼び出しを追跡。
●
    dtruss ... ユーザープロセスのシステムコール呼び出しを追跡。
●
    errinfo ... システムコール呼び出しにおいてエラーの発生を追跡。
●
    execsnoop ... プロセスの実行開始を追跡。意図しないプログラムが実行さ
    れていないかどうかを確認することが可能。
●
    iotop ... システム全体で、 I/O 帯域をたくさん消費しているプロセスをリス
    トアップ。 IO の帯域を消費しているプロセス特定に便利。
●
    kill.d ... プロセスにシグナルが送られた時にその送り主と送り先に関する情
    報を記録。
●
    opensnoop ... ファイルが open された際に情報を出力。
デモで利用したもの
●   Random Query Generator
       –   http://forge.mysql.com/wiki/Random_Query_Ge
             nerator
●   Example DBs
       –   http://dev.mysql.com/doc/index-other.html
●   MySQL Sand Box
       –   http://mysqlsandbox.net/
宣伝!!
●
    著書: MySQL エキスパートトラブルシュー
    ティングガイド(仮)/技術評論社
      –   様々な角度から MySQL のトラブルを解析するのに役立つ書
           籍です。ぜひ安心な DBA 生活のお供に一冊どうぞ。
      –   第一章: MySQL の概要
      –   第二章:開発時における問題
      –   第三章: MySQL の状態を見る。
      –   第四章: DTrace
      –   第五章:運用中に起きる諸問題。
      –   第六章:堅牢な運用を実現するために
      –   第七章:ソースコードのビルド
Q&A

More Related Content

DTraceによるMySQL解析ことはじめ

  • 1. DTrace で MySQL を斬る! 〜 DTrace による MySQL 解析ことはじめ 〜 奥野 幹也 @nippondanji mikiya (dot) okuno (at) gmail (dot) com
  • 2. 自己紹介 ● 今日は個人として来ています。 – http://nippondanji.blogspot.com/ – http://www.google.com/profiles/mikiya.okuno ● 現職は MySQL サポートエンジニア。 – 2000 年にサン・マイクロシステムズ入社 – 2007 年に MySQL KK へ転職 – 気付くとまたサン・マイクロシステムズに – オラクル・コーポレーションに・・・
  • 3. MySQL について ● オープンソースのリレーショナル・データベー ス・マネージメント・システム ● MySQL AB => Sun Microsystems => Oracle に よって開発。 ● Web 開発においては圧倒的なシェア – PHP/Perl/Java/Ruby/C/C++/ODBC... ● 使い易く、安定して、高速に動作するのがウリ
  • 4. MySQL は永久に不滅です! © Brian Aker http://krow.livejournal.com/687521.html
  • 5. MySQL の特徴 ● ANSI SQL 標準に準拠(一部の文法を除 ● UNION く。) ● ビュー ● 種々のプラットフォームをサポート ● サブクエリ ( Windows 、 Linux 、 Mac 、各種 UNIX 系 ● INFORMATION_SCHEMA OS ) ● SSL による通信 ● ストレージエンジンによりデータを格納す ● Unicode をはじめとした各種文字コードの るレイヤーを仮想化 サポート ● ACID 準拠のトランザクション ● 全文検索 ● XA トランザクション ● タイムゾーンのサポート ● 非同期 Master/Slave 型レプリケーション ● 多種多様な開発言語のサポート( C 、 C+ ● 水平パーティショニング + 、 Java 、 Perl 、 PHP 、 Python 、 Ruby ( Range 、 List 、 Hash 、 Key ) など) ● ストアドプロシージャ、ストアドファンク ● ODBC による接続のサポート ション、トリガ
  • 6. MySQL 構造の特徴 ● モノリシックカーネル ● シングルプロセス・マルチスレッド ● 1 セッション= 1 スレッド ● ストレージエンジン API による仮想化 ● プラグイン API ● GNU Bison による Lexical Scanner ● ソースコードは C/C++ 混在( 100 万行程度)
  • 7. MySQL の仕組み クライアント クライアント クライアント Java PHP ODBC コネクション コネクション コネクション スレッド スレッド スレッド SQL の解析と最 適化は共通 パーサー・オプティマイザ・アクセス管理 等 ストレージエンジン API データの格納や MyISAM InnoDB MySQL アクセス方法は Cluster ストレージエン テーブル table_name.MYI スペース ジンごとに違う table_name.MYD NDB ログファイル API MySQL サーバ データノード データノード データノード データノード
  • 8. MySQL の構造を知る! ● Web ページ – http://forge.mysql.com/wiki/MySQL_Internals ● 書籍 – 詳解 MySQL ( Understanding MySQL Internals ) – Expert MySQL – MySQL データベース構築バイブル ● ソースコード!!
  • 9. ソースコードを入手! ● http://dev.mysql.com/downloads/ ● bzr branch lp:mysql-server/5.1 mysql-5.1 ● sql/mysqld.cc ... main() 関数があるよ! ● sql/sql_parse.cc ... リクエストの入り口 ● sql/sql_yacc.yy ... SQL パーサー この辺りから ● sql/handler.cc ... ストレージエンジン API 覗いてみよう! ● sql/log.cc ... ログ関係 ● sql/log_event.cc ... バイナリログ ● sql/sql_show.cc ... SHOW コマンドと I_S ● sql/slave.cc ... レプリケーションスレーブ ● sql/item*cc ... データ型と関数 ● sql/sql_base.cc, sql/sql_class.cc ... 基本的なデータ型等 ● storage/innodb ... InnoDB の実装 ● storage/myisam ... MyISAM の実装 ●mysys/* ... MySQL Core API
  • 10. DTrace!! ● Solaris 10 で搭載された機能。 – Solaris/Mac OS X/FreeBSD で利用可能 ● カーネル / ユーザープロセスをトレース。 ● プローブと呼ばれる観測点を対象のプログラム に動的に埋め込む。 ● プローブの種類に応じたプロバイダ。 ● D 言語と呼ばれるプログラムで操作。 – 参考: D 言語基本文法最速マスター( DTrace のほう) – http://nippondanji.blogspot.com/2010/02/ddtrace.html
  • 11. DTrace 動作イメージ プロバイダに指示を出したり ユーザープロセス 情報を表示したり ( mysqld など) dtrace コマンド プロ ーブ ユーザー空間 各種情報 カーネル空間 Fire 有効化 DTrace モジュール プロバイダ プロ ーブ モジュール
  • 12. プロバイダの種類 Provider名 Probeの場所 Providerのシンボル FBT - function カーネル内における関数の fbt boundary tracing 呼び出しとリターン。 Systrace システムコールの呼び出し syscall とリターン。 SDT - statically ソースコードにおいて指定さ sdtまたはコンパイル時に指 defined tracing れた任意の場所。(カーネ 定 ル内) PID ユーザープロセスにおける pid{pid} 関数の呼び出しとリターン。 (pid1234のように指定する) Fasttrap ソースコードにおいて指定さ コンパイル時に指定 れた任意の場所。(ユー ザープロセス内) dtrace トレースの開始と終了、およ BEGIN/END/ERROR び例外発生時。 profiling 一定期間ごと。 profile-n/tick-n (nはインターバル)
  • 13. D 言語の書式 プローブ記述子 / 述語 / { これを必要な回数 列挙するだけ。 アクション ループなし、分岐なし。 }
  • 14. プローブの書式 ● プロバイダ名 : モジュール名 : 関数名 : プロー ブ名 – pid プロバイダの場合、 pid{ プロセス ID} とい う書式になる。例 ) pid123 – C++ の関数名を指定するにはワイルドカード ( * )が便利。
  • 15. mysqld 内に設置可能なプローブ ● pid – 関数の entry C++ の関数名に注意 It's mangled!! – 関数の return – 関数オフセット – 書式 ) pid123 ● Fasttrap – MySQL 5.4 で追加!! – 書式 ) mysql123
  • 16. 述語の書式 ● 評価出来る式なら何でも OK – 例 ) execname == "mysqld" ● 条件分岐がない代わりに述語で Fire するかどう かをコントロール。
  • 17. アクション ● 情報の出力や変数への代入。 ● セミコロン区切りで必要な数を列挙。 ● 情報の出力例。 – trace( 式 ) – tracemem(address, size); – printf(" フォーマット ", arg1, arg2, ...); – ustack(); jstack(); stack(); etc
  • 18. 変数の種類 ● スカラー変数… argname – グローバルなスコープを持つ ● スレッドローカル変数… self->argname – 同一スレッドだけからアクセス可能 ● 節固有変数… this->argname – プローブが Fire している間だけ利用可能 ● 組み込み変数…後述 ユーザープロセス ● 外部変数… `argname には使えない。
  • 19. 組み込み変数 ● arg0 ... arg9 ・・・プローブに対する引数の最初の 10 個(数値型で取得) ● cwd ・・・カレントワーキングディレクトリ ● errno ・・・直前のシステムコールによって返されたエラーの値 ● execname ・・・実行プログラム名 ● uid ・・・実行中のプロセスの実効ユーザー ID ● gid ・・・実行中のプロセスの実効グループ ID ● pid ・・・実行中のプロセス ID ● ppid ・・・実行中のプロセスの親プロセス ID ● tid ・・・現在のスレッドのスレッド ID 大切な情報源!! ● probeprov ・・・プロバイダ名 ● probemod ・・・モジュール名 ● probefunc ・・・関数名 ● probename ・・・プローブ名 ● timestamp ・・・タイムスタンプ ● walltimestamp ・・・ 1970 年 1 月 1 日 UTC からの経過時間。単位はナノ秒。
  • 20. MySQL 5.4 で追加されたプローブ ● include/probes_mysql.d を見よ! Fasttrap! connection-start(unsigned long conn_id, char *user, char *host); connection-done(int status, unsigned long conn_id); command-start(unsigned long conn_id, int command, char *user, char *host); command-done(int status); query-start(char *query, unsigned long connid, char *db_name, char *user, char *host, int exec_type); query-done(int status); query-parse-start(char *query); query-parse-done(int status); query-cache-hit(char *query, unsigned long rows); query-cache-miss(char *query); query-exec-start(char *query, unsigned long connid, char *db_name, char *user, char *host, int exec_type); query-exec-done(int status); insert-row-start(char *db, char *table); insert-row-done(int status); update-row-start(char *db, char *table); : :
  • 21. プローブを設置し易い関数 ● DTrace の制約として、外部変数はユーザープ ロセスをサポートしていない。 – 引数が重要な情報源! – mysql_parse() 関数 ... 第 2 引数が SQL 文 ● エラー発生時に Fire する。 – vprint_msg_to_log() ... エラーログへの書 き込み – my_error() ... クライアントへエラー送信 – my_print_error() ... シンタックスエラー
  • 22. 例 1) SQL 文を抽出 pid$target::*mysql_parse*:entry { trace(copyinstr(arg1)); }
  • 23. 例 2) メモリ不足の原因 pid$target::*mysql_parse*:entry { self->q = 1; self->qstr = copyinstr(arg1); } pid$target::*mysql_parse*:entry / self->q / { self->q = 0; self->qstr = 0; } pid$target::malloc:return / errno == ENOMEM / { printf("=== Memory allocation error at %Y ===n", walltimestamp); ustack(); } pid$target::malloc:return / errno == ENOMEM && self->q / { printf("QUERY: %sn", self->qstr); }
  • 24. 例 3) エラーメッセージを追跡 pid$target::*mysql_parse*:entry { self->q = 1; self->qstr = copyinstr(arg1); } pid$target::*mysql_parse*:return / self->q / { self->q = 0; self->qstr = copyinstr(arg1); } pid$target::*my_error:entry / self->q / { printf("Query generated an error (errno = %d): %sn", arg0, self->qstr); ustack(); } pid$target::*my_printf_error:entry / self->q / { printf("Syntax error: %sn", self->qstr); }
  • 25. 例 4) クエリキャッシュのヒット率 mysql$target:::query-cache-hit { hit++; @qhit["rows per query when qcache hit"] = quantize(arg1); } mysql$target:::query-cache-miss { miss++; @qmiss[copyinstr(arg0)] = count(); } tick-5sec / hit != 0 || miss != 0 / { printf("ratio: %u (%u / %u)", 100 * hit / (hit+miss), hit, hit+miss); } tick-5sec / hit == 0 && miss == 0 / { printf("ratio: NULL"); } tick-5sec { total_hit += hit; total_miss += miss; hit = miss = 0; }
  • 26. 例 5) 1000 行以上のソートを検出 #!/usr/sbin/dtrace -s BEGIN { printf("Hit Ctrl+C to exit.n"); } mysql$target:::filesort-start { self->sorting = 1; self->db = arg0 == 0 ? "NULL" : copyinstr(arg0); self->table = copyinstr(arg1); } mysql$target:::filesort-done /self->sorting && arg1 > 1000/ { self->sorting=0; printf("DB: %s, Table: %s, Rows: %u", self->db, self->table, arg1); }
  • 27. 例 5) 1000 行以上のソートを検出 #!/usr/sbin/dtrace -s BEGIN { printf("Hit Ctrl+C to exit.n"); } mysql$target:::filesort-start { self->sorting = 1; self->db = arg0 == 0 ? "NULL" : copyinstr(arg0); self->table = copyinstr(arg1); } mysql$target:::filesort-done /self->sorting && arg1 > 1000/ { self->sorting=0; printf("DB: %s, Table: %s, Rows: %u", self->db, self->table, arg1); }
  • 28. 例 6) テーブルごとのソート統計 mysql$target:::filesort-start { self->sorting = 1; self->db = arg0 == 0 ? "NULL" : copyinstr(arg0); self->table = copyinstr(arg1); } mysql$target:::filesort-done /self->sorting/ { self->sorting=0; @sorts[self->db, self->table] = sum(arg1); }
  • 29. 例 7) ソート中断の原因 #!/usr/sbin/dtrace -s pid$target::*mysql_parse*:entry { self->q = 1; self->qstr = copyinstr(arg1); } pid$target::*mysql_parse*:return / self->q / { self->q = 0; self->qstr = 0; } mysql$target:::filesort-done / self->q && arg0 / { printf("nnABORTED QUERY: %sn", self->qstr); ustack(); }
  • 30. DTrace Toolkit ● DTrace を使ったユーティリティ群 – http://hub.opensolaris.org/bin/view/Community+ Group+dtrace/dtracetoolkit – http://nippondanji.blogspot.com/2007/07/dtrace. html ● DTrace を知らなくても利用可能 ● Mac OS X ではデフォルトでインストール – grep -I -m 1 dtrace /usr/bin/*
  • 31. DTrace Toolkit つづき ● dappprof ... ユーザープロセスをプロファイリングします。 ● dapptrace ... ユーザープロセスの関数呼び出しを追跡。 ● dtruss ... ユーザープロセスのシステムコール呼び出しを追跡。 ● errinfo ... システムコール呼び出しにおいてエラーの発生を追跡。 ● execsnoop ... プロセスの実行開始を追跡。意図しないプログラムが実行さ れていないかどうかを確認することが可能。 ● iotop ... システム全体で、 I/O 帯域をたくさん消費しているプロセスをリス トアップ。 IO の帯域を消費しているプロセス特定に便利。 ● kill.d ... プロセスにシグナルが送られた時にその送り主と送り先に関する情 報を記録。 ● opensnoop ... ファイルが open された際に情報を出力。
  • 32. デモで利用したもの ● Random Query Generator – http://forge.mysql.com/wiki/Random_Query_Ge nerator ● Example DBs – http://dev.mysql.com/doc/index-other.html ● MySQL Sand Box – http://mysqlsandbox.net/
  • 33. 宣伝!! ● 著書: MySQL エキスパートトラブルシュー ティングガイド(仮)/技術評論社 – 様々な角度から MySQL のトラブルを解析するのに役立つ書 籍です。ぜひ安心な DBA 生活のお供に一冊どうぞ。 – 第一章: MySQL の概要 – 第二章:開発時における問題 – 第三章: MySQL の状態を見る。 – 第四章: DTrace – 第五章:運用中に起きる諸問題。 – 第六章:堅牢な運用を実現するために – 第七章:ソースコードのビルド
  • 34. Q&A