Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ぼくがかんがえたさいきょうのMySQLの監視スクリプトを読み解く

 ぼくがかんがえたさいきょうのMySQLの監視スクリプトを読み解く

yoku0825
PRO

March 28, 2021
Tweet

More Decks by yoku0825

Other Decks in Technology

Transcript

  1. ぼくがかんがえたさいきょうのMySQLの監視ス
    クリプトを読み解く
    変数に $ がつくPで始まるプログラミング言語
    2021/03/28
    yoku0825
    PHPerKaigi 2021

    View Slide

  2. Chiba.pmの方
    から来ました
    1/59

    View Slide

  3. Chiba.pmの “m”
    はMySQLの “m”
    ※諸説あり
    2/59

    View Slide

  4. *.pm は地方のPerl
    Mongersの集まり
    です
    3/59

    View Slide

  5. ( ゚д゚) あれここ
    PHPerKaigiだ
    4/59

    View Slide

  6. (・∀・)ゞ まあ、変数の
    頭に $ がつくもの同士
    仲良くしましょう…
    5/59

    View Slide

  7. といいながら別に
    Perlの話さえ出て
    きません
    6/59

    View Slide

  8. \こんにちは/
    yoku0825@とある企業のDBA
    オラクれない

    ポスグれない

    マイエスキューエる

    生息域
    Twitter: @yoku0825

    Blog: 日々の覚書

    日本MySQLユーザ会

    MySQL Casual

    今日13:10~のTrack Bのセッションにもちょっとだけゲスト出演しています
    トラブルのない決済システムを作ろうと奮闘したお話 by 千葉

    7/59

    View Slide

  9. みなさんMySQLの
    監視してますか?
    8/59

    View Slide

  10. ぼくがかんがえたさ
    いきょうのMySQL
    監視スクリプト
    9/59

    View Slide

  11. yt-
    healthcheck
    10/59

    View Slide

  12. yt-healthcheck
    ytkit の1スクリプト
    ytkit is Y oku-san no T ool kit

    他にも yt-binlog-groupby, yt-alter-progress, yt-wait-replication あたりがべ
    んり
    11/59

    View Slide

  13. yt-healthcheckの特徴
    Nagiosプラグインコンパチ
    Nagiosプラグインは終了コードで状態が表されるが、それとコンパチ

    なのでNagiosに設定してもそのまま使えるはず(ウチはもう使ってない)

    Mackerelに設定しても動くのは観測している

    Nagiosコンパチなので、「前回との値を比較」みたいなことはしていない
    これは別にNagiosコンパチだからって訳でもないか

    12/59

    View Slide

  14. yt-healthcheckの特徴
    現役DBAらしい監視
    ロールによる監視項目の制御

    障害を踏むたびに監視項目が増える

    監視の閾値はほとんどがオプションで上書き設定可能

    後追いできるように情報を残す

    テスト

    ライセンス

    13/59

    View Slide

  15. 現役DBAらしい監視
    MySQLの監視はそもそも非対称で、監視項目を変えたり変えなかったりしたい
    レプリケーションソース(マスター)/レプリカ(スレーブ)

    カスケードレプリケーション

    グループレプリケーション

    MySQL Fabric

    けれど、ソース/レプリカの切り替え(フェイルオーバー/スイッチオーバー)を行っ
    ても監視の再設定はしたくない
    14/59

    View Slide

  16. ロールの自動識別
    * --role=[auto, master, slave, backup, fabric, none, intermidiate, group_replication] { D
    efault: auto }
    15/59

    View Slide

  17. ロールの自動識別
    デフォルトではmaster, slave, intermidiate(中間マスター), group_replication
    を 自動判別 する
    自動ったって大したことをしているわけではなくて、

    胸に手を当てて思い出してみよう。DBAは知らないMySQLをポンと与えられた時に、それがマ
    スターかレプリカかどうやって判別している?

    16/59

    View Slide

  18. ロールの自動識別
    my $master= my $slave= my $cluster= 0;
    $master= 1 if $self->show_slaves_via_processlist;
    $slave = 1 if ($self->instance->show_slave_status && $self->instance->show_slave_status->[0]);
    $cluster= 1 if defined($self->instance->i_am_group_replication_primary);
    ### Restore param
    $self->instance->{_ignore_unsupport_version}= $saved_ignore;
    ### SHOW SLAVE STATUS condition is advanced more than cluster.
    if ($slave)
    {
    ### Intermidiate-master in a cascaded replication toporogy.
    return "intermidiate" if $master;
    return "slave";
    }
    elsif ($cluster)
    {
    return "group_replication";
    }
    else
    {
    return "master";
    }
    https://github.com/yoku0825/ytkit/blob/0.5.0/lib/Ytkit/
    HealthCheck.pm#L217-L249 17/59

    View Slide

  19. ロールの自動識別
    1. SHOW PROCESSLIST を叩く
    Commandが Binlog Dump か Binlog GTID Dump のやつがいれば、それはたぶんレプリカがつな
    ぎにきている = コイツはレプリケーションソース

    mysql> SHOW PROCESSLIST;
    +-----+-----------------+-----------------+------+-------------+------+------------------
    ---------------------------------------------+------------------+
    | Id | User | Host | db | Command | Time | State
    | Info |
    +-----+-----------------+-----------------+------+-------------+------+------------------
    ---------------------------------------------+------------------+
    | 5 | event_scheduler | localhost | NULL | Daemon | 38 | Waiting on empty
    queue | NULL |
    | 10 | rsandbox | localhost:37548 | NULL | Binlog Dump | 17 | Master has sent a
    ll binlog to slave; waiting for more updates | NULL |
    | 12 | msandbox | localhost | NULL | Query | 0 | init
    | SHOW PROCESSLIST |
    +-----+-----------------+-----------------+------+-------------+------+------------------
    ---------------------------------------------+------------------+
    18/59

    View Slide

  20. ロールの自動識別
    2. SHOW SLAVE STATUS を叩く
    ソースかレプリカかの判定なので、今は中身は気にしない

    「結果セットが空 = レプリカではない」か、「1行以上存在している = レプリカである」かの
    どちらか。

    mysql> SHOW SLAVE STATUS\G
    *************************** 1. row ***************************
    Slave_IO_State: Waiting for master to send event
    Master_Host: 127.0.0.1
    Master_User: rsandbox
    Master_Port: 23631
    ...
    19/59

    View Slide

  21. ロールの自動識別
    3. performance_schema.replication_group_members を叩く
    これも今は中身は気にしない

    「結果セットが空 = グループレプリケーションのメンバーではない」か、「1行以上存在して
    いる = グループレプリケーションを組んでいる」かのどちらか

    割と最近組み込んだ機能

    mysql> SELECT * FROM performance_schema.replication_group_members;
    +---------------------------+--------------------------------------+---------------------
    ---------+-------------+--------------+-------------+----------------+
    | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST
    | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
    +---------------------------+--------------------------------------+---------------------
    ---------+-------------+--------------+-------------+----------------+
    | group_replication_applier | f80bad73-79a0-11eb-afa3-12053f89f52d | ip-172-31-1-141.ec2.
    internal | 3306 | ONLINE | PRIMARY | 8.0.23 |
    +---------------------------+--------------------------------------+---------------------
    ---------+-------------+--------------+-------------+----------------+
    20/59

    View Slide

  22. ロールの自動識別
    4. 1. ~ 3. の辻褄を合わせる
    現状、グループレプリケーションを非同期レプリカにするトポロジーはサポートしていない( --
    role=group_replication と --role=slave で2回実行すればいいだけだと思う)

    role $master $slave $cluster
    master o x *
    slave x o *
    intermidiate o o *
    group_replication x x o
    21/59

    View Slide

  23. 障害を踏むたびに増えてきた監視項目
    ロングクエリー監視
    コネクション数監視
    レプリケーション状況監視
    AUTO_INCREMENT監視
    read_only 設定監視
    デッドロック発生時間監視
    Uptime監視
    history_list_length 監視
    グループレプリケーション状況監視
    22/59

    View Slide

  24. ロングクエリー監視
    「mysqldとしては生きているけどクエリーの結果がなかなか返ってこない」を判
    定するための機構
    サチってる時はわりと綺麗にこれが一番最初に鳴ってくれるようになった

    バッチ用のホスト/アカウント/クエリー(先頭マッチ)は除外するオプションを用意
    している
    オオカミ少年 (・A・)イクナイ!!

    --long_query_exclude_host, --long_query_exclude_user, --long_query_exclude_query

    長いクエリーでも「1本だけならいいや、本当にサチった時は2本以上引っ掛かるは
    ずだし」という閾値も設定可能
    これ普段2(1本だけなら良い、2本以上ならアラート)にしているけれどこっちをデフォルトにし
    ようかってくらいノイズが減った

    --long_query_min_critical_thread, --long_query_min_warning_thread

    23/59

    View Slide

  25. ロングクエリー監視
    やってることは SHOW FULL PROCESSLIST の Time を見ているだけ
    明らかにevent_schedulerとかBinlog Dumpとかは除外している

    +-----+-----------------+-----------+-----------+---------+------+----------------------------+------------
    ------------------------------------------------------------------------------------------+
    | Id | User | Host | db | Command | Time | State | Info
    |
    +-----+-----------------+-----------+-----------+---------+------+----------------------------+------------
    ------------------------------------------------------------------------------------------+
    | 5 | event_scheduler | localhost | NULL | Daemon | 44 | Waiting on empty queue | NULL
    |
    | 21 | root | localhost | mysqlslap | Query | 0 | waiting for handler commit | INSERT INTO
    t1 VALUES (73673339,'BN3152Gza4GW7atxJKACYwJqDbFynLxqc0kh30YTwgz3FktQ43XTrqJ4PQ25frn7kXh |
    | 22 | root | localhost | NULL | Query | 0 | init | show proces
    slist |
    +-----+-----------------+-----------+-----------+---------+------+----------------------------+------------
    ------------------------------------------------------------------------------------------+
    https://github.com/yoku0825/ytkit/blob/0.5.0/lib/Ytkit/
    HealthCheck.pm#L278-L319
    24/59

    View Slide

  26. コネクション数監視
    「mysqldとしては生きているけどアプリケーションから接続できない」を判定す
    るための機構
    「割合」で判定する。オートスケールとかで意図せずコネクションプールの本数が増えた時な
    んかも割とキャッチできる。

    ホントにToo many connectionsに突っ込んだ時はだいたい他の監視も一緒に引っ掛かる

    my $current= $self->instance->show_status->{Threads_connected}->{Value};
    my $setting= $self->instance->show_variables->{max_connections}->{Value};
    my $ratio = ($current / $setting) * 100;
    https://github.com/yoku0825/ytkit/blob/0.5.0/lib/Ytkit/
    HealthCheck.pm#L354-L366
    25/59

    View Slide

  27. コネクション数監視
    mysql> SHOW GLOBAL STATUS LIKE 'Threads_connected';
    +-------------------+-------+
    | Variable_name | Value |
    +-------------------+-------+
    | Threads_connected | 3 |
    +-------------------+-------+
    1 row in set (0.03 sec)
    mysql> SHOW GLOBAL VARIABLES LIKE 'max_connections';
    +-----------------+-------+
    | Variable_name | Value |
    +-----------------+-------+
    | max_connections | 151 |
    +-----------------+-------+
    1 row in set (0.00 sec)
    26/59

    View Slide

  28. レプリケーション状況監視
    Slave_*_Running がYes(=レプリケーションが止まっていない)か
    Seconds_Behind_Master が閾値未満(=レプリケーションが遅れていない)か
    mysql> SHOW SLAVE STATUS\G
    *************************** 1. row ***************************
    Slave_IO_State: Waiting for master to send event
    ..
    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
    ..
    Seconds_Behind_Master: 0
    ..
    https://github.com/yoku0825/ytkit/blob/0.5.0/lib/Ytkit/
    HealthCheck.pm#L438-L474
    27/59

    View Slide

  29. AUTO_INCREMENT監視
    AUTO_INCREMENTなカラムがデータ型の限界値に近づいていないかのチェック
    AUTO_INCREMENTの現在値は information_schema.tables から引ける
    AUTO_INCREMENT属性のカラム名とデータ型は information_schema.columns か
    ら引ける
    AUTO_INCREMENTの値をデータ型の限界値(UNSIGNED INTなら 2^32 -1 とか)
    で割った値でアラートを出し分ける
    my ($type, $unsigned)= $row->{column_type} =~ /^([a-z]+)(?:\(.+\))?(\s+(unsigned))?/;
    my $max= 2 ** (BYTES->{$type} * 8 - ($unsigned ? 0 : 1));
    my $ratio= ($row->{auto_increment} / $max) * 100;
    https://github.com/yoku0825/ytkit/blob/0.5.0/lib/Ytkit/
    HealthCheck.pm#L368-L413
    28/59

    View Slide

  30. AUTO_INCREMENT監視
    mysql> SELECT
    -> table_schema AS table_schema,
    -> table_name AS table_name,
    -> column_name AS column_name,
    -> auto_increment AS auto_increment,
    -> column_type AS column_type
    -> FROM
    -> information_schema.tables
    -> JOIN information_schema.columns USING(table_schema, table_name)
    -> WHERE
    -> table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys') AND
    -> table_type = 'BASE TABLE' AND
    -> auto_increment IS NOT NULL AND
    -> extra = 'auto_increment';
    +--------------+------------+-------------+----------------+-------------+
    | table_schema | table_name | column_name | auto_increment | column_type |
    +--------------+------------+-------------+----------------+-------------+
    | sbtest | sbtest1 | id | 10001 | int |
    | sbtest | sbtest2 | id | 10001 | int |
    | sbtest | sbtest3 | id | 10001 | int |
    | sbtest | sbtest4 | id | 10001 | int |
    | sbtest | sbtest5 | id | 10001 | int |
    | sbtest | sbtest6 | id | 10001 | int |
    | sbtest | sbtest7 | id | 10001 | int |
    | sbtest | sbtest8 | id | 10001 | int |
    | sbtest | sbtest9 | id | 10001 | int |
    | sbtest | sbtest10 | id | 10001 | int |
    +--------------+------------+-------------+----------------+-------------+
    10 rows in set (0.01 sec)
    29/59

    View Slide

  31. AUTO_INCREMENT監視
    あふれると死ぬ割には案外監視されてない
    デフォルトのWARNING閾値が50%、「このワーニングが鳴るまでの間に過ごした
    年月」が「残り時間」
    データ型の変更はブロッキングALTER TABLEなので、今すぐでなくても長期的に「どこかのメ
    ンテに混ぜ込まないといけない」
    gh-ost でやっちゃうのも手だけど、「そもそもAUTO_INCREMENTが4バイト整数型を食い尽くしそうなテーブ
    ル」に対してやるのは結構現実的ではないこともある(先にお掃除バッチを作るところから…とか)

    「最初はすぐ鳴らす、でも狼少年にはしたくない」ので、一度鳴ってバックログに突っ込んだ
    らすぐ閾値を70%くらいに変えちゃう

    30/59

    View Slide

  32. read_only設定監視
    そのまま。 read_only が意図した値になっているかどうか確認する。
    role read_only=ON read_only=OFF
    master 大事故 o
    slave o 接続先を間違えなければ…
    intermidiate 大事故 o
    なんでこんな単純な監視が存在するのかと言うと、「それで痛い目を見たことがあ
    るから」
    31/59

    View Slide

  33. デッドロック発生時間監視
    飽くまで「Nagiosライク」に単発でチェックするので、現在時刻とデッドロック発
    生時刻の差だけをチェック
    ウチでは5分間隔のポーリングなので「5分以内ならワーニング」とか

    正直あんまり需要はないと思う

    =====================================
    190708 11:49:25 INNODB MONITOR OUTPUT
    =====================================
    Per second averages calculated from the last 18 seconds
    ----------
    SEMAPHORES
    ----------
    OS WAIT ARRAY INFO: reservation count 201960, signal count 160833
    Mutex spin waits 0, rounds 24340763, OS waits 81459
    RW-shared spins 152853, OS waits 73723; RW-excl spins 54434, OS waits 30136
    ------------------------
    LATEST DETECTED DEADLOCK
    ------------------------
    190708 11:11:59 <-- ココ
    *** (1) TRANSACTION:
    TRANSACTION 0 29557, ACTIVE 1 sec, process no 4356, OS thread id 140577570899712 inserting
    mysql tables in use 1, locked 1
    LOCK WAIT 11 lock struct(s), heap size 1216, undo log entries 4
    32/59

    View Slide

  34. デッドロック発生時間監視
    自慢(?)したいことはただ1つだけ
    この機能をテストするためだけに、それぞれ少しずつ出力が違うMySQL 5.0, 5.1,
    5.5, 5.6, 5.7, 8.0の SHOW ENGINE INNODB STATUS のテストデータがある
    https://github.com/yoku0825/ytkit/blob/0.5.0/t/data/show_engine_innodb_status.pl

    33/59

    View Slide

  35. Uptime監視
    何のひねりもなく単にUptimeが閾値未満だったらアラートにする
    ウチは5分間隔のポーリングなので300未満ならCriticalにしている

    それ以外の方法(ログ監視とか)で気が付くことがほとんど
    1回だけRDSのフェイルオーバーをこれで拾えたので、そういう環境では有効なんだろうなぁ

    mysql> SHOW GLOBAL STATUS LIKE 'Uptime';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | Uptime | 72615 |
    +---------------+-------+
    1 row in set (0.08 sec)
    34/59

    View Slide

  36. history_list_length監視
    現在溜まっているUNDOログページの総数(長時間継続しているトランザクション
    があるか、UNDOログのパージが更新に追い付いていないか)
    information_schema.innodb_metrics (5.6とそれ以降) がなかった時代は SHOW ENGINE INNODB
    STATUS の中に history_list_length という表示で含まれていた

    今日日 SHOW ENGINE INNODB STATUS をパースしなくても取り出せる

    mysql> SELECT name, count FROM information_schema.innodb_metrics WHERE name = 'trx_rseg_h
    istory_len';
    +----------------------+-------+
    | name | count |
    +----------------------+-------+
    | trx_rseg_history_len | 69 |
    +----------------------+-------+
    1 row in set (0.00 sec)
    35/59

    View Slide

  37. history_list_length監視
    経験的に「大きくなりすぎるとInnoDBのレスポンスが劣化」することが知られて
    いる
    長時間継続しているトランザクションから見ると「ロールバックポインタを何度も辿らなけれ
    ばならない」ためのオーバーヘッド

    それ以外の単発のトランザクションでも何故か性能劣化が見られた…
    普段10ms未満のトランザクションが1s超え
    UNDOページもバッファプールを使うので、それでデータページが押し出されていた?
    history_list_length のやつだなとあたりをつけてKILLしたら解消したので、まあ確かに当たってはいたんですが遅
    くなる理屈がこれで合っているのかは未確定

    日々の覚書: InnoDBのHistory list lengthの監視と原因スレッドの特定と
    36/59

    View Slide

  38. グループレプリケーション状況監視
    MySQL InnoDB Clusterが利用している「グループレプリケーション」は今までの
    レプリケーションと監視方法が明らかに違う
    たとえば SHOW SLAVE STATUS は空っぽ

    performance_schemaを使った監視をしようとしても、グループレプリケーションは
    replication_replication_member_stats あたり、非同期レプリケーションは
    replication_applier_status_by_worker あたり

    performance_schemaを使っていても、カラムの名前とかまだ人口に膾炙しているというほど
    ではない

    mysql> SHOW SLAVE STATUS;
    Empty set, 1 warning (0.00 sec)
    mysql> SELECT * FROM performance_schema.replication_group_members;
    +---------------------------+--------------------------------------+------------------------------+-------------+--------------+-------------+----------------+
    | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
    +---------------------------+--------------------------------------+------------------------------+-------------+--------------+-------------+----------------+
    | group_replication_applier | 39629f0d-8243-11eb-964e-12bfe5404f29 | ip-172-31-1-192.ec2.internal | 3306 | ONLINE | SECONDARY | 8.0.23 |
    | group_replication_applier | 3a80d620-8243-11eb-a852-12b379095b1f | ip-172-31-1-103.ec2.internal | 3306 | ONLINE | PRIMARY | 8.0.23 |
    | group_replication_applier | 3a999d81-8243-11eb-a8f0-12e72ffe935b | ip-172-31-1-73.ec2.internal | 3306 | ONLINE | SECONDARY | 8.0.23 |
    +---------------------------+--------------------------------------+------------------------------+-------------+--------------+-------------+----------------+
    3 rows in set (0.00 sec)
    37/59

    View Slide

  39. グループレプリケーション状況監視
    グループレプリケーションの「台数」を監視
    グループレプリケーションはスプリットブレイン対策で「残り2台の状態で1台が落ちると全
    断」する
    3台から一気に2台死ぬ、4台から一気に2台死ぬ、5台から一気に3台死ぬようなパターンでも全断するけど

    残り2台になったらワーニング
    過半数が生きている状態で1台が死ぬぶんには、安全にグループレプリケーションから追放されるので、3台から1台
    死ぬような時点ではグループレプリケーション全体は動き続けられる
    し、どのみち死んだノードはヘルスチェックでアラートが上がってくるから

    my $count= grep { $_->{member_state} eq "ONLINE" } @{$self->instance->replication_group
    _members};
    my $status= compare_threshold_reverse($count, { warning => 3, critical => 2 });
    https://github.com/yoku0825/ytkit/blob/0.5.0/lib/Ytkit/
    HealthCheck.pm#L757-L771
    38/59

    View Slide

  40. グループレプリケーション状況監視
    グループレプリケーションの「遅延」を監視
    SHOW SLAVE STATUS の Seconds_Behind_Master のようなシンプルな値ではなく(アレは実は
    「算出方法」がシンプルではないけれど)、自分で(SQLで)計算している

    「適用待ちトランザクションキューの数」と「最後にコミットされたトランザクションの時間
    差」を計算

    ### How many commits not yet applied.
    my $trx_lag= $self->instance->replication_group_member_stats->[0]->{count_transactions_re
    mote_in_applier_queue};
    ### How many seconds between "STARTING APPLY" and "COMMITTED ORIGINAL"
    my $applier_time_lag= $self->instance->replication_applier_status->{group_replication_app
    lier}->{_diff} // 0;
    https://github.com/yoku0825/ytkit/blob/0.5.0/lib/Ytkit/
    HealthCheck.pm#L773-L804
    39/59

    View Slide

  41. グループレプリケーション状況監視
    遅延監視ではグループレプリケーションの RECOVERING ステータス(一度グループレ
    プリケーションから弾き出されたあと、差分同期でグループレプリケーションに追
    い付くまでのステータス)も考慮
    落ちて上がったあと、延々鳴り続けるのも嫌ですしおすし

    ### If node is entering RECOVERING state, mysqlrouter is devide node from load-balancing,
    ### Group Replication lag is not matter.
    if ($self->instance->i_am_group_replication_recovering)
    {
    ### Change critical threshold to supernum to fall back as WARNING
    $self->{group_replication_lag_transactions}->{critical}= 2 ** 63 - 1;
    $self->{group_replication_lag_seconds}->{critical}= 2 ** 63 - 1;
    }
    https://github.com/yoku0825/ytkit/blob/0.5.0/lib/Ytkit/
    HealthCheck.pm#L773-L804
    40/59

    View Slide

  42. 障害を踏むたびに増えてきた監視項目
    ロングクエリー監視
    コネクション数監視
    レプリケーション状況監視
    AUTO_INCREMENT監視
    read_only 設定監視
    デッドロック発生時間監視
    Uptime監視
    history_list_length 監視
    グループレプリケーション状況監視
    41/59

    View Slide

  43. yt-healthcheckの特徴
    現役DBAらしい監視
    ロールによる監視項目の制御

    障害を踏むたびに監視項目が増える

    監視の閾値はほとんどがオプションで上書き設定可能

    後追いできるように情報を残す

    テスト

    ライセンス

    42/59

    View Slide

  44. 監視の閾値調整
    $ yt-healthcheck --help | grep Default
    * --autoinc_usage_critical=value { Default: 90 }
    * --autoinc_usage_enable=value { Default: 1 }
    * --autoinc_usage_warning=value { Default: 50 }
    * --connection_count_critical=value { Default: 95 }
    * --connection_count_enable=value { Default: 1 }
    * --connection_count_warning=value { Default: 70 }
    * --deadlock_critical=value { Default: 1 }
    * --deadlock_enable=value { Default: 0 }
    * --deadlock_warning=value { Default: 300 }
    ..
    43/59

    View Slide

  45. 監視の閾値調整
    ほとんどの監視項目はON/OFF, 閾値調整が可能
    グループレプリケーションの台数だけ2台ワーニング1台クリティカルで固定だけど

    対処の要らないアラートで起こされたくもないし、アラートを無視し続ける運用は
    害悪
    監視の閾値をチューニングできるようにするのが最低限

    暗黙のデフォルトは「まあこれくらいから始めて、うるさければ閾値を上げて運用しよう」と
    いうくらいの感覚値
    暗黙のデフォルトでアラートになるのは悪いことじゃない、そのMySQLに対する最適値を見極めるチャンス

    44/59

    View Slide

  46. 後追いできるように情報を残す
    --dump-detail=/path/to/information.txt と指定すると、ワーニングまたはクリ
    ティカルになった時点のいくつかの情報を平文テキストで吐き出す
    $ yt-healthcheck --help
    ..
    * --dump_detail=value
    When result is NOT NAGIOS_OK,
    output results of "SHOW PROCESSLIST", "SHOW SLAVE STATUS" and "SHOW ENGINE INNODB STATU
    S"" into specified file
    ..
    45/59

    View Slide

  47. 後追いできるように情報を残す
    --help にあるよりもっと情報を取ってた
    SHOW FULL PROCESSLIST

    SHOW SLAVE STATUS

    SHOW ENGINE INNODB STATUS

    sys.x$innodb_lock_waits (sysがないバージョンでは似たようなSQLで直接
    information_schemaを叩く)

    information_schema.innodb_trx

    performance_schema.threads

    https://github.com/yoku0825/ytkit/blob/0.5.0/lib/Ytkit/
    MySQLServer.pm#L1138-L1212
    46/59

    View Slide

  48. 後追いできるように情報を残す
    ログインした時には既に解消してた…けど状況が知りたい
    障害の解消に夢中で解析情報を取り忘れた…
    もしかしてこれ、監視スクリプト側のバグ?
    この機能だけを切り出した yt-print-information というスクリプトもある
    47/59

    View Slide

  49. テスト
    ダミーデータを使ったテストの他に
    https://github.com/yoku0825/ytkit/blob/0.5.0/t/yt-healthcheck.t

    mysqldを起動してチェック用のSQLがエラーにならないかどうかのテスト
    https://github.com/yoku0825/ytkit/blob/0.5.0/xt/mysqlserver_allmethods.t

    https://github.com/yoku0825/ytkit/blob/0.5.0/xt/healthcheck_testrun.t

    48/59

    View Slide

  50. テスト
    ロジックに間違いがあると、通知してほしいアラートが通知されない… のは良い
    としても
    (PerlでもSQLでも)シンタックスエラーなんぞ入れ込もうもんなら、監視している
    全台から一斉にアラートが上がる(切実)
    迂闊に非互換な変更を入れるとデプロイのタイミングのズレで yt-healthcheck を
    使っている監視スクリプトが一斉にエラーを吐く(切実)
    ---------------------------- ------ ------ ------ ------ ------ ------ ------
    File stmt bran cond sub pod time total
    ---------------------------- ------ ------ ------ ------ ------ ------ ------
    lib/Ytkit/HealthCheck.pm 77.9 66.3 60.0 97.4 0.0 0.0 72.2
    lib/Ytkit/MySQLServer.pm 96.7 83.0 70.3 98.8 0.0 14.5 86.0
    49/59

    View Slide

  51. テストは人のため
    ならず(真顔)
    50/59

    View Slide

  52. ライセンス
    GPLv2 or later
    コピーレフトが良いかどうかは好みだとして、要は「オープンソース」だというこ

    とても原始的なオープンソースと企業のエコシステム
    会社 は 従業員 に オープンソース開発への参加を業務時間で(職務著作とせず)許可

    会社 は オープンソース成果物 を利用

    従業員=コミッター は優先的に 会社 の要望を開発する

    51/59

    View Slide

  53. オープンソースな監視スクリプト
    監視のロジックを公開できる
    人に説明する時にべんり

    SQLも読める

    自分に縁のないプログラミング言語でも、大体雰囲気はつかめるはず
    ましてや変数の頭に $ ですよ!

    コミットログの積み上げの良い練習になる
    いやーrebaseしすぎると意図を忘れますね

    stashしまくるとつらい

    Issue ⇒ テストケースを追加したブランチでPull-Req ⇒ そのブランチにFix が好みかな

    とかとかとか

    52/59

    View Slide

  54. yt-healthcheckの特徴
    現役DBAらしい監視
    ロールによる監視項目の制御

    障害を踏むたびに監視項目が増える

    監視の閾値はほとんどがオプションで上書き設定可能

    後追いできるように情報を残す

    テスト

    ライセンス

    53/59

    View Slide

  55. yt-healthcheck
    「そのSQLでそういう情報取れるのか」というのはあるかもしれないけれど、それ
    以外は大したSQLをぶん回しているわけでもない
    飽くまでSQLは値を取っているだけで、判断の部分はPerl側でハンドルしているし

    そこそこ良く監視できていると自分では思っているけれど、「素晴らしい何か」が
    あるわけではなくて「地道に、手持ちのカードを一枚ずつ重ねている」だけ
    俺の中では innotop とか正にそれ

    泥臭い処理を如何に誠実に積み上げるかで監視の質は上げられる

    54/59

    View Slide

  56. yt-healthcheck
    ytkitのリポジトリはこちら!
    yoku0825/ytkit: Yoku\-san no Tool KIT

    Issues/Pull-Reqs are welcome :D
    MySQLの状態確認の参考実装としても使えます

    55/59

    View Slide

  57. 以上、
    56/59

    View Slide

  58. ぼくがかんがえたさ
    いきょうのMySQL
    監視スクリプト
    57/59

    View Slide

  59. でした!
    58/59

    View Slide

  60. Any Questions
    and/or
    Suggestions?
    59/59

    View Slide