SlideShare a Scribd company logo
MySQLerの七つ道具
2016/11/26
yoku0825
第18回 中国地⽅DB勉強会 in 広島
\こんにちは/
yoku0825@GMOメディア株式会社
オラクれない-
ポスグれない-
マイエスキューエる-
⽣息域
Twitter: @yoku0825-
Blog: ⽇々の覚書-
MyNA ML: ⽇本MySQLユーザ会-
MySQL Casualʼs Slack: MySQL Casual-
1/79
MySQLer七つ道具
pt-query-digest1.
EXPLAIN2.
PMP for Cacti3.
innotop4.
SHOW PROFILE5.
performance̲schema & sys6.
???7.
2/79
MySQLer七つ道具
pt-query-digest1.
EXPLAIN2.
PMP for Cacti3.
innotop4.
SHOW PROFILE5.
performance̲schema & sys6.
???7.
3/79
pt-query-digest
みんなだいすきPercona Toolkitの⼈気No.1
スローログをまとめて⾒やすくしてくれる
⼤⽂字⼩⽂字、⽂字列定数と数値定数をノーマライズして「ダイジェ
スト」ごとに集約
-
4/79
先頭のセクション
$ pt-query-digest /path/to/slowlog
..
# Time range: 2016-03-16 17:29:32 to 2016-11-22 11:37:24
# Attribute total min max avg 95% stddev medi
an
# ============ ======= ======= ======= ======= ======= ======= =====
==
# Exec time 45155s 500ms 117s 3s 7s 9s 640
ms
# Lock time 2s 29us 14ms 110us 176us 136us 93
us
# Rows sent 156.96M 0 5.85M 10.33k 54.03k 74.89k 0.
99
# Rows examine 36.18G 0 26.40M 2.38M 22.38M 5.41M 298.0
6k
# Rows affecte 0 0 0 0 0
0 0
# Bytes sent 9.86G 0 362.91M 664.55k 4.26M 4.87M 1.0
9k
# Query size 3.29M 25 24.47k 221.80 346.17 425.46 136.
99
..
5/79
先頭のセクション
まああんま⾒ない
6/79
ダイジェスト⼀覧
# Profile
# Rank Query ID Response time Calls R/Call V/M It
em
# ==== ================== ================ ===== ======= ===== ==
=========
# 1 0x15E7E7E2F486896A 16739.1308 37.1% 382 43.8197 0.76 SE
LECT table1 table2 table3
# 2 0x223A9E1EC454F977 10883.7272 24.1% 270 40.3101 5.94 SE
LECT table1 table3
# 3 0xAF335DE1A49E8218 2909.3875 6.4% 5542 0.5250 0.00 SE
LECT table4
# 4 0x180720D51CB2E890 2044.8649 4.5% 1451 1.4093 0.07 SE
LECT table5
..
7/79
ダイジェスト⼀覧
デフォルトでは「トータルでかかった時間」の降順
--order-by で変えられるデフォルトは “Query̲time:sum”
書き⽅にちょっとクセがある
Query̲time:max
Query̲time:sum
Rows̲examined:max
bytes:sum とか
-
8/79
ダイジェストごと、前半
Query 1: 0.00 QPS, 0.01x concurrency, ID 0x15E7E7E2F486896A at byte 6304792
# This item is included in the report because it matches --limit.
# Scores: V/M = 0.76
# Time range: 2016-11-01 14:02:59 to 2016-11-22 11:37:24
# Attribute pct total min max avg 95% stddev median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count 2 382
# Exec time 37 16739s 37s 100s 44s 52s 6s 40s
# Lock time 2 50ms 70us 395us 131us 152us 25us 125us
# Rows sent 0 1.87k 5 5 5 5 0 5
# Rows examine 27 9.78G 26.05M 26.40M 26.22M 25.91M 0 25.91M
# Rows affecte 0 0 0 0 0 0 0 0
# Bytes sent 0 311.36k 825 840 834.63 833.10 7.50 833.10
# Query size 6 228.65k 611 614 612.93 592.07 0 592.07
9/79
ダイジェストごと、前半
1⾏目に ID 0x.. があるので、ダイジェスト⼀覧から検索で
⾶んでくるとよし
Time range を⾒ないと、実は半年前に撲滅されたクエリー
を⼀⽣懸命EXPLAINする⽻目に遭ったり
単発のクエリーが⼤きくて累計 Exec time が⼤きくなってる
のか、満遍なく出続けているのか
anemo eat erも便利だよ-
Rows examine / Rows_sent
GROUP BYを除くと、⽐率が1に近く低いほど理想-
Lock time はInnoDBではアテにならないので注意
10/79
ダイジェストごと、後半
# Query_time distribution
# 1us
# 10us
# 100us
# 1ms
# 10ms
# 100ms
# 1s
# 10s+ ########################################################
########
# Tables
..
# EXPLAIN /*!50100 PARTITIONS*/
SELECT ..
11/79
ダイジェストごと、後半
クエリーごとにバラつきがあるか︖
バラついているなら、カーディナリティーの悪戯か、それともキャッ
シュの具合か
特にInnoDB圧縮を使ってる場合、バッファプールミスヒットやテーブルキャッシュミ
スヒットのコストは⼤きい
-
均等に遅いなら、それはクソクエリーかな-
ただし pt-query-digest がそもそも、スローログに載っているヤーツ
しか⾒られない以上、まともな速度で応答を返しているヤーツは検出
されない
-
最後の⾏はEXPLAIN⽤に1⾏、集約してないやつを引っこ抜
いてくれるだけ
オプションによっては⾃動でEXPLAINまでかけてくれる-
12/79
pt-query-digestと上⼿く付き合うコツ
--since オプションはほぼ必須
--since オプションでもログは舐めてしまうので、⼤きなログを⾷わ
すのであれば tail -50000 slow.log | pt-query-digest とパイプで
⾷わせるのも⼿
-
「膨⼤で⾒にくいスローログの塊を、認識しやすいチャンク
にまとめる」
--group-by=tables からの --group-by=fingerprint --
filter='$events->{fingerprint} =~ /sテーブル名s/' とか
-
13/79
with Anemometer
pt-query-digest の出⼒結果を可視化するツール
pt-query-digest の結果をMySQLに⼊れる機能(--history,
--review)をそのまま使ってる
box/Anemometer: Box SQL Slow Query Monitor
14/79
Anemometerの弱点
テーブル上UNIQUE KEY (hostname_max, checksum, ts_min,
ts_max)で、Anemometerはts_minでプロットするため、そ
のクエリーがts_minに集中したことになってしまう。
mysql> SELECT * FROM global_query_review_history LIMIT 1G
*************************** 1. row ***************************
hostname_max: xxx
db_max: xxx
checksum: 1233945238822708500
sample: xxx
ts_min: 2015-09-14 11:32:12
ts_max: 2015-10-28 15:51:01
ts_cnt: 31
Query_time_sum: 651.778
Query_time_min: 2.07993
Query_time_max: 197.678
15/79
Anemometerの弱点
⽇次で pt-query-digest を回している程度だと、⽇単位までし
か分解できない
16/79
anemo eat er
スローログをスプリットして pt-query-digest を呼びまくる
1分ぶんずつ pt-query-digest に⾷わせれば、ts_min と ts_max の差
は最⼤でも1分
-
AnemometerをDockerコンテナーとして起動する-
既存のAnemometerがあれば単にスローログを分割して⾷わせる pt-
query-digest のラッパーとして呼べる
-
17/79
with anemo eat er
1分単位でプロットできる
18/79
anemo eat er
リアルタイムでなくてもいい
スロークエリーのリアルタイム通知は別の⽅法でしてる-
グラフで⾒られれば数分前の情報であっても全然構わない-
リアルタイムを捨てて
保存期間を考えない
スローログが残っている限りの情報を、最初から、最後まで⾒られる
-
⾒るかどうかもわからないグラフのために常時リソースを割かなくて
いい
⾒たく / ⾒せたく なったら起動、⾒終わったら停⽌
-
19/79
anemo eat er
現在のところ docker と pt-query-digest はホストにインス
トールしておかないとダメ
$ git clone https://github.com/yoku0825/anemoeater
$ cd anemoeater
$ ./anemoeater slow_log_file
Docker container starts with 172.17.0.43.
URL will be http://xxxx:32780/anemometer
20/79
pt-query-digest
だいたいこんな感じでDailyの動きをメールで⾶ばしてる
気になったら anemo eat erで⾒る
$ pt-query-digest --since=$(date -d yesterday "+%Y-%m-%d") /pat
h/to/slowlog | awk '/^# Overall:/{print $3, $5}'
822 4
21/79
MySQLer七つ道具
pt-query-digest1.
EXPLAIN2.
PMP for Cacti3.
innotop4.
SHOW PROFILE5.
performance̲schema & sys6.
???7.
22/79
EXPLAIN
今更なのでEXTENDEDの話しかしないよ
23/79
目XPLAIN
出来る⼈︖
24/79
Please 目XPLAIN Me
SELECT DISTINCT
T.c_month,
T.unique_id
FROM
(SELECT A.a_id, DATE_FORMAT(C.datetime, '%Y%m') AS c_month, C.u
nique_id
FROM table_2 AS C
LEFT OUTER JOIN table_1 AS A
ON (CAST(C.session_id AS CHAR) = A.another_id AND C.unique_id
= A.unique_id)
WHERE C.unique_id = 0x333132 AND C.unique_id <= 260006385 AND
C.datetime < TIMESTAMPADD(DAY, -180, CURDATE())
) AS T
WHERE
T.another_id IS NULL
25/79
実はこれ、5.6
と5.7で実⾏計
画が違う
26/79
5.6
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: <derived2>
type: ref
possible_keys: <auto_key0>
key: <auto_key0>
key_len: 35
ref: const
rows: 10
Extra: Using where; Using temporary
*************************** 2. row ***************************
id: 2
select_type: DERIVED
table: C
type: range
possible_keys: PRIMARY,idx_xxx,idx_yyy_zzz
key: PRIMARY
key_len: 8
ref: NULL
rows: 12130512
Extra: Using where
*************************** 3. row ***************************
id: 2
select_type: DERIVED
table: A
type: eq_ref
possible_keys: PRIMARY,idx_xxx_yyy,idx_xxx_aaa_ccc,idx_xxx_ddd
key: PRIMARY
key_len: 68
ref: func,const
rows: 1
Extra: Using where; Using index
27/79
5.7
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: C
partitions: NULL
type: range
possible_keys: PRIMARY,idx_xxx,idx_yyy_zzz
key: PRIMARY
key_len: 8
ref: NULL
rows: 12675660
filtered: 5.97
Extra: Using where; Using temporary
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: A
partitions: NULL
type: eq_ref
possible_keys: PRIMARY,idx_xxx_yyy,idx_xxx_aaa_ccc,idx_xxx_ddd
key: PRIMARY
key_len: 68
ref: func,const
rows: 1
filtered: 100.00
Extra: Using where; Not exists; Using index
28/79
5.6
mysql> SHOW WARNINGSG
*************************** 1. row ***************************
Level: Note
Code: 1003
Message: /* select#1 */ select distinct `t`.`c_month` AS `c_month
`,`t`.`unique_id` AS `unique_id` from (/* select#2 */ select `sch
ema`.`a`.`another_id` AS `another_id`,date_format(`schema`.`c`.`d
atetime`,'%Y%m') AS `c_month`,`schema`.`c`.`unique_id` AS `unique
_id` from `schema`.`table_2` `c` left join `schema`.`table_1` `a
` on(((`schema`.`a`.`unique_id` = 0x333132) and (cast(`schema`.`c
`.`SESSION_ID` as char charset sjis) = `schema`.`a`.`another_id`)
)) where ((`schema`.`c`.`unique_id` = 0x333132) and (`schema`.`c
`.`UNIQUE_ID` <= 260006385) and (`schema`.`c`.`datetime` < <cache
>((curdate() + interval -(180) day))))) `t` where isnull(`t`.`ano
ther_id`)
1 row in set (0.00 sec)
29/79
5.7
> SHOW WARNINGSG
*************************** 1. row ***************************
Level: Note
Code: 1003
Message: /* select#1 */ select distinct date_format(`schema`.`c`.
`OCCUR_DATE`,'%Y%m') AS `c_month`,`schema`.`c`.`unique_id` AS `un
ique_id` from `schema`.`table_2` `c` left join `schema`.`table_1
` `a` on(((`schema`.`a`.`unique_id` = 0x333132) and (cast(`schema
`.`c`.`SESSION_ID` as char charset sjis) = `schema`.`a`.`another_
id`))) where ((`schema`.`c`.`unique_id` = 0x333132) and isnull(`s
chema`.`a`.`another_id`) and (`schema`.`c`.`UNIQUE_ID` <= 2600063
85) and (`schema`.`c`.`OCCUR_DATE` < <cache>((curdate() + interva
l -(180) day))))
30/79
EXPLAIN EXTENDED
5.7からはデフォルトでEXTENDEDがついてくる
EXPLAIN直後に SHOW WARNINGS でオプティマイザーが最適化した後
のクエリーが⾒える
-
想像したのと違う遅くなり⽅ をしたらEXTENDED⾒た⽅が
良い
特に5.6の蝉ジョインとか蝉ジョインとか蝉ジョインとか-
MySQL :: MySQL 5.6 リファレンスマニュアル :: 8.8.3
EXPLAIN EXTENDED 出⼒フォーマット
31/79
MySQLer七つ道具
pt-query-digest1.
EXPLAIN2.
PMP for Cacti3.
innotop4.
SHOW PROFILE5.
performance̲schema & sys6.
???7.
32/79
PMP(Percona Monitoring Plugins) for Cacti
別に for Zabbixでもいいと思う
単にウチはもともとCactiを使っていたからというだけ
33/79
PMP for Cacti
rrdtoolだから容量効率は素晴らしい
rrdtoolだから丸め誤差は厳しい
CactiそのものがWEBからポチポチするインターフェースな
のつらい
ss̲get̲mysql̲stats.php ⾃体はPHPで、頑張って⾊々パー
スしてるので、ホゲろうと思えばホゲれる
けど、それならPerlで書きたい-
34/79
Data Input Methodのデフォルトを⼀気にSQLで書き換
えるとか
mysql> UPDATE data_input_fields JOIN data_input_data ON data_input_fields.id
= data_input_data.data_input_field_id JOIN data_input ON data_input_fields.d
ata_input_id = data_input.id
-> SET data_input_data.value = 'pmp' WHERE data_input.name LIKE 'Percon
a %' AND data_input_fields.name = 'Username';
mysql> UPDATE data_input_fields JOIN data_input_data ON data_input_fields.id
= data_input_data.data_input_field_id JOIN data_input ON data_input_fields.d
ata_input_id = data_input.id
-> SET data_input_data.value = 'pmp_pass' WHERE data_input.name LIKE 'Pe
rcona %' AND data_input_fields.name = 'Password';
mysql> UPDATE data_input_fields JOIN data_input_data ON data_input_fields.id
= data_input_data.data_input_field_id JOIN data_input ON data_input_fields.d
ata_input_id = data_input.id
-> SET data_input_data.value = '3306', data_input_data.t_value = 'on' WH
ERE data_input.name LIKE 'Percona %' AND data_input_fields.name = 'Port';
35/79
Device追加する時にポートを⼀⻫に変えるブックマーク
レットだとか
javascript:void((function(elems,port){for(var p in elems){elems[p
].value=port}})(document.querySelectorAll('input[type=text]'),pro
mpt('port','3306')))
(c) irok
36/79
みんなどうし
てるんだろう
37/79
PMP for Cacti
やっぱり視認性だいじ
絶対値に惑わされない
問題が起きていなくてもたまには⾒る
たまには⻑い期間で⾒る
使いづらいものはユーティリティー作っちゃえばいいと思う
38/79
MySQLer七つ道具
pt-query-digest1.
EXPLAIN2.
PMP for Cacti3.
innotop4.
SHOW PROFILE5.
performance̲schema & sys6.
???7.
39/79
innotop
みんな⼤好き、topライクに SHOW PROCESSLIST を表⽰して
くれるinnotop
地味に “M” (Replication Status) も便利
なんとMSR対応してるんだぜ
-
“L” (InnoDB Locks) とか-
“T” (InnoDB Transaction) とか-
pt-osc してる間だと “D” (InnoDB Deadlocks) を眺めることもある-
tmuxでばっちんばっちんターミナル割って、 dstat とか流
しながら⾒るのが好き
40/79
innotop
41/79
innotop
地味に機能は多いけど今のバージョンだと表⽰されない項目
がたまにある
旧バージョンのサポート切れば楽なんだけど…と思ったり思わなかっ
たり
-
ALTER TABLE や percona-toolkit で重いことやる時のおとも
に最適
“d” で表⽰間隔の変更。0.1とかやるとたのしい-
ただし万能感を期待しない-
“Q” => “K” => “T” => “k” (killステートメント) のコンボで詰まっ
てるのを殺すくらい
-
42/79
innotop
中⾝は結構スパゲティ
最近メンテナンス遅め
ちょっと⾊々事情が-
⽇々の覚書: innotopのその後 2016年6⽉-
43/79
MySQLer七つ道具
pt-query-digest1.
EXPLAIN2.
PMP for Cacti3.
innotop4.
SHOW PROFILE5.
performance̲schema & sys6.
???7.
44/79
SHOW PROFILE
MySQLの組み込みプロファイラー
「そのクエリーが実⾏されていた期間、どのStatus(SHOW
PROCESSLIST で “State” と表⽰されているもの)にどのくら
いの時間かかったか
使うのが超簡単
45/79
SHOW PROFILE
mysql> SET @@profiling= 1;
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> ..;
mysql> SHOW PROFILE;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000206 |
| checking permissions | 0.000024 |
| Opening tables | 0.000039 |
| init | 0.000089 |
| System lock | 0.000027 |
| optimizing | 0.000037 |
| statistics | 0.000245 |
| preparing | 0.000058 |
| Creating tmp table | 0.000119 |
| Sorting result | 0.000023 |
| executing | 0.000019 |
| Sending data | 2.619037 |
| Creating sort index | 0.000821 |
| end | 0.000014 |
| removing tmp table | 0.000017 |
| end | 0.000013 |
| query end | 0.000015 |
| closing tables | 0.000022 |
| freeing items | 0.000028 |
| logging slow query | 0.000109 |
| cleaning up | 0.000013 |
+----------------------+----------+
21 rows in set (0.00 sec)
46/79
SHOW PROFILE
組み込みだから使うのは超簡単
プロファイルを「どう解析するか」はまた別の問題
ざっと⾒てわかりやすいところに時間がかかってたらつぶせ
る…くらいのノリ
再現性がないとつらい
47/79
SHOW PROFILE S
mysql> SHOW PROFILES;
+----------+-------------+-------------------------------------------------------------------------------+
| Query_ID | Duration | Query |
+----------+-------------+-------------------------------------------------------------------------------+
| 1 | 7.56061200 | SELECT * FROM t1 WHERE val IN (SELECT val FROM t2 WHERE num BETWEEN 1 AND 10) |
| 2 | 8.00373925 | DELETE FROM t1 WHERE num > 1000 |
| 3 | 1.05841250 | DELETE FROM t1 WHERE num > 100 |
| 4 | 33.97938100 | DELETE FROM t2 WHERE num > 100 |
| 5 | 1.09654200 | DELETE FROM t2 WHERE num > 40 |
| 6 | 0.03032175 | DELETE FROM t1 WHERE num > 40 |
| 7 | 0.00410725 | explain SELECT * FROM t2 JOIN t1 USING(val) WHERE t2.num = 1 |
| 8 | 0.01773500 | SELECT * FROM t1 WHERE val IN (SELECT val FROM t2 WHERE num BETWEEN 1 AND 10) |
| 9 | 0.02148750 | DELETE FROM t1 WHERE num > 30 |
| 10 | 0.27967925 | DELETE FROM t2 WHERE num > 30 |
| 11 | 0.00826075 | SELECT * FROM t1 WHERE val IN (SELECT val FROM t2 WHERE num BETWEEN 1 AND 10) |
+----------+-------------+-------------------------------------------------------------------------------+
11 rows in set (0.01 sec)
48/79
SHOW PROFILE FOR QUERY ..
mysql> SHOW PROFILE FOR QUERY 4;
+------------------------------+-----------+
| Status | Duration |
+------------------------------+-----------+
| starting | 0.007228 |
| checking permissions | 0.000302 |
| Opening tables | 0.001042 |
| System lock | 0.000030 |
| init | 0.006702 |
| updating | 33.930371 |
| end | 0.000923 |
| Waiting for query cache lock | 0.000013 |
| end | 0.002784 |
| query end | 0.024151 |
| closing tables | 0.000430 |
| freeing items | 0.000809 |
| logging slow query | 0.000006 |
| logging slow query | 0.004583 |
| cleaning up | 0.000009 |
+------------------------------+-----------+
15 rows in set (0.01 sec)
49/79
SHOW PROFILE
MySQL 5.6でdeprecated
代替として performance_schema.events_stages_* と
events_statements_* が案内されている…けど
-
@@profiling はセッション単位に対して、p̲sはセッション単位の調
整がちょっと難しい
-
⼀応、MySQL 8.0.0現在でもまだ使える
50/79
MySQLer七つ道具
pt-query-digest1.
EXPLAIN2.
PMP for Cacti3.
innotop4.
SHOW PROFILE5.
performance̲schema & sys6.
???7.
51/79
performance̲schema(p̲s)
パフォーマンスモニタリング専⽤のストレージエンジン
MySQL 5.6から真っ当に使えるようになってる
吊るしのデフォルトではONになってる-
計測する項目も「だいたい必要になりそうなところ」だけがONになっ
てるので、必要になるまではそのまま使えばOK
-
メモリーを⾷うのは相変わらず
デフォルトがautosizeなので、気になる場合は固定値を決め打つ-
しかも5.7のデフォルトが auto re size になりやがった。。-
52/79
p_s.setup_*
mysql> SHOW TABLES FROM performance_schema LIKE 'setup_%';
+-----------------------------------------+
| Tables_in_performance_schema (setup_%) |
+-----------------------------------------+
| setup_actors |
| setup_consumers |
| setup_instruments |
| setup_objects |
| setup_timers |
+-----------------------------------------+
5 rows in set (0.00 sec)
53/79
p_s.setup_consumers
mysql> SELECT * FROM setup_consumers;
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| events_stages_current | NO |
| events_stages_history | NO |
| events_stages_history_long | NO |
| events_statements_current | YES |
| events_statements_history | YES |
| events_statements_history_long | NO |
| events_transactions_current | NO |
| events_transactions_history | NO |
| events_transactions_history_long | NO |
| events_waits_current | NO |
| events_waits_history | NO |
| events_waits_history_long | NO |
| global_instrumentation | YES |
| thread_instrumentation | YES |
| statements_digest | YES |
+----------------------------------+---------+
15 rows in set (0.00 sec)
54/79
p_s.setup_instruments
mysql> SELECT SUBSTRING_INDEX(`name`, '/', 2) AS short_name, ANY_VALUE(name) AS example, SUM(ENABLED = 'YES') AS enabled, SUM(ENABLED
= 'NO') AS disabled FROM setup_instruments GROUP BY short_name;
+---------------------------+-----------------------------------------------------+---------+----------+
| short_name | example | enabled | disabled |
+---------------------------+-----------------------------------------------------+---------+----------+
| idle | idle | 1 | 0 |
| memory/archive | memory/archive/FRM | 0 | 2 |
| memory/blackhole | memory/blackhole/blackhole_share | 0 | 1 |
| memory/client | memory/client/mysql_options | 0 | 7 |
| memory/csv | memory/csv/TINA_SHARE | 0 | 5 |
| memory/federated | memory/federated/FEDERATED_SHARE | 0 | 1 |
| memory/innodb | memory/innodb/adaptive hash index | 0 | 85 |
| memory/keyring | memory/keyring/KEYRING | 0 | 1 |
| memory/memory | memory/memory/HP_SHARE | 0 | 4 |
| memory/myisam | memory/myisam/MYISAM_SHARE | 0 | 21 |
| memory/myisammrg | memory/myisammrg/MYRG_INFO | 0 | 2 |
| memory/mysys | memory/mysys/max_alloca | 0 | 21 |
| memory/partition | memory/partition/ha_partition::file | 0 | 3 |
| memory/performance_schema | memory/performance_schema/mutex_instances | 70 | 0 |
| memory/sql | memory/sql/Locked_tables_list::m_locked_tables_root | 0 | 152 |
| memory/vio | memory/vio/ssl_fd | 0 | 3 |
| stage/innodb | stage/innodb/alter table (end) | 8 | 0 |
| stage/mysys | stage/mysys/Waiting for table level lock | 0 | 1 |
| stage/sql | stage/sql/After create | 1 | 119 |
| statement/abstract | statement/abstract/Query | 3 | 0 |
| statement/com | statement/com/Sleep | 32 | 0 |
| statement/scheduler | statement/scheduler/event | 1 | 0 |
| statement/sp | statement/sp/stmt | 16 | 0 |
| statement/sql | statement/sql/select | 141 | 0 |
| transaction | transaction | 0 | 1 |
| wait/io | wait/io/file/sql/map | 55 | 3 |
| wait/lock | wait/lock/table/sql/handler | 1 | 1 |
| wait/synch | wait/synch/mutex/sql/TC_LOG_MMAP::LOCK_tc | 0 | 257 |
+---------------------------+-----------------------------------------------------+---------+----------+
28 rows in set (0.01 sec)
55/79
統計情報へのアクセス
mysql> SHOW TABLES;
..
| events_stages_summary_by_account_by_event_name |
| events_stages_summary_by_host_by_event_name |
..
| memory_summary_by_thread_by_event_name |
| memory_summary_by_user_by_event_name |
| memory_summary_global_by_event_name |
..
| replication_applier_configuration |
| replication_applier_status |
..
56/79
p̲s⾃体のモニタリング
mysql> SHOW ENGINE PERFORMANCE_SCHEMA STATUS;
+--------------------+----------------------------------------------------------
---+----------+
| Type | Nam
e | Status |
+--------------------+----------------------------------------------------------
---+----------+
| performance_schema | events_waits_current.siz
e | 176 |
| performance_schema | events_waits_current.coun
t | 1536 |
| performance_schema | events_waits_history.siz
e | 176 |
| performance_schema | events_waits_history.coun
t | 2560 |
| performance_schema | events_waits_history.memor
y | 450560 |
..
| performance_schema | performance_schema.memor
y | 94739320 |
+--------------------+----------------------------------------------------------
---+----------+
229 rows in set (0.00 sec)
57/79
sys
p̲sの情報を⾒やすくするためのビューやストアドファンク
ション、ストアドプロシージャ
名前空間として sys スキーマを使うのでそう呼ぶことも
performance_schema = OFF の状態ではほとんどからっぽ
MySQL 5.7では最初から導⼊済み
MySQL 5.6にも対応
GitHubのmysql-sysリポジトリー からインストール-
58/79
sysのインストール(5.6向け)
$ git clone https://github.com/mysql/mysql-sys.git
Initialized empty Git repository in /root/mysql-sys/.git/
remote: Counting objects: 3009, done.
remote: Total 3009 (delta 0), reused 0 (delta 0), pack-reused 3008
Receiving objects: 100% (3009/3009), 1.17 MiB | 466 KiB/s, done.
Resolving deltas: 100% (1768/1768), done.
$ cd mysql-sys
$ mysql -uroot -p < sys_56.sql
$ mysql -uroot -p
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.01 sec)
59/79
sys.statement_analysis
p_s.events_statements_summary_by_digest のビュー
超⾒やすい
これのためだけに p̲s有効にする価値がある
60/79
sys.statement_analysis
mysql> SELECT * FROM statement_analysisG
..
*************************** 2. row ***************************
query: SELECT `c` FROM `sbtest1` WHERE `id` = ?
db: sbtest
full_scan:
exec_count: 23890
err_count: 0
warn_count: 0
total_latency: 2.36 s
max_latency: 521.15 us
avg_latency: 98.74 us
lock_latency: 778.65 ms
rows_sent: 23890
rows_sent_avg: 1
rows_examined: 23890
rows_examined_avg: 1
rows_affected: 0
rows_affected_avg: 0
tmp_tables: 0
tmp_disk_tables: 0
rows_sorted: 0
sort_merge_passes: 0
digest: 80295d1d2720d4515b05d648e8caa82f
first_seen: 2016-07-12 17:04:40
last_seen: 2016-07-12 17:04:53
..
61/79
sys.innodb_lock_waits
いわゆるSH2さんの アレ とほぼ同等の機能
これは i̲s のビューなので、p̲sが無効でもフツーに⾒られ
る
バンドルされて便利になったという感じ
62/79
sys.innodb_lock_waits
mysql57> SELECT * FROM innodb_lock_waitsG
*************************** 1. row ***************************
wait_started: 2016-07-12 17:49:06
wait_age: 00:00:13
wait_age_secs: 13
locked_table: `d1`.`user`
locked_index: PRIMARY
locked_type: RECORD
waiting_trx_id: 8063
waiting_trx_started: 2016-07-12 17:49:06
waiting_trx_age: 00:00:13
waiting_trx_rows_locked: 1
waiting_trx_rows_modified: 0
waiting_pid: 320
waiting_query: SELECT * FROM user LIMIT 3 FOR UPDATE
waiting_lock_id: 8063:146:3:2
waiting_lock_mode: X
blocking_trx_id: 8062
blocking_pid: 321
blocking_query: NULL
blocking_lock_id: 8062:146:3:2
blocking_lock_mode: X
blocking_trx_started: 2016-07-12 17:49:06
blocking_trx_age: 00:00:13
blocking_trx_rows_locked: 3
blocking_trx_rows_modified: 0
sql_kill_blocking_query: KILL QUERY 321
sql_kill_blocking_connection: KILL 321
1 row in set (0.01 sec)
63/79
sys.ps_truncate_all_tables
ストアド
p̲s は起動時から統計情報を累積するが、それをリセットす
るにはp̲sの各テーブルに対してTRUNCATEが必要
それを全部まとめてやってくれる、ただそれだけなんだけど
便利なストアド
mysql> CALL sys.ps_truncate_all_tables(0);
+---------------------+
| summary |
+---------------------+
| Truncated 44 tables |
+---------------------+
1 row in set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
64/79
sys.x$*
x$ で始まるビューは、 x$ のない他のビューと対になってい
る
フツーの⽅は、[kMG]B をまとめたり [num]s をまとめた
りしてくれるが、そうすると⽂字列になっちゃうのでソート
に不便
そんな時、 x$ のビューは何の整形もしないので…ってこと
だと思う
でもナノ秒単位とか正直つらいので、ソートだけ x$ でやって digest
カラムとかでフツーのビューとJOINした⽅がいいと思う
-
65/79
MySQLer七つ道具
pt-query-digest1.
EXPLAIN2.
PMP for Cacti3.
innotop4.
SHOW PROFILE5.
performance̲schema & sys6.
???7.
66/79
Do you
know
“Dimitri”?
67/79
Dimitri KRAVTCHUK
68/79
Dimitriおじさん says
69/79
Dimitriおじさん says
70/79
Dimitriおじさん says
71/79
エコシステム
たとえば MariaDB, Percona Server
たとえば MHA for MySQL, HandlerSocket
たとえば ⽇本MySQLユーザ会, MySQL Casual
たとえば Oracle
72/79
USE YOUR
BRAIN
73/79
but/and
74/79
YOU are
not alone.
75/79
2年前
76/79
みなさんのご参加をお待ちしております :)
MyNA ML: ⽇本MySQLユーザ会
MySQL Casualʼs Slack: MySQL Casual
77/79
Advent Calendarのおさそい
まだまだお席に余裕がございます
具体的には 20 名様ほどお⼊りいただけます-
@soudai1025-
@kkkida̲twtr-
@kamipo-
MySQL Casual Advent Calendar 2016 - Qiita
78/79
Questions
and/or
Suggestions?
79/79

More Related Content

PDF
なかったらINSERTしたいし、あるならロック取りたいやん?
PDF
MySQL 5.7にやられないためにおぼえておいてほしいこと
PDF
Dockerfileを改善するためのBest Practice 2019年版
PDF
雑なMySQLパフォーマンスチューニング
PDF
ヤフー社内でやってるMySQLチューニングセミナー大公開
PPTX
押さえておきたい、PostgreSQL 13 の新機能!!(Open Source Conference 2021 Online/Hokkaido 発表資料)
PDF
基本に戻ってInnoDBの話をします
PDF
What's New in MySQL 5.7 Optimizer @MySQL User Conference Tokyo 2015
なかったらINSERTしたいし、あるならロック取りたいやん?
MySQL 5.7にやられないためにおぼえておいてほしいこと
Dockerfileを改善するためのBest Practice 2019年版
雑なMySQLパフォーマンスチューニング
ヤフー社内でやってるMySQLチューニングセミナー大公開
押さえておきたい、PostgreSQL 13 の新機能!!(Open Source Conference 2021 Online/Hokkaido 発表資料)
基本に戻ってInnoDBの話をします
What's New in MySQL 5.7 Optimizer @MySQL User Conference Tokyo 2015

What's hot (20)

PPTX
iostat await svctm の 見かた、考え方
PDF
MySQLテーブル設計入門
PDF
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
PDF
MySQLレプリケーションあれやこれや
PPTX
Metaspace
PDF
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
PDF
A24 SQL Server におけるパフォーマンスチューニング手法 - 注目すべきポイントを簡単に by 多田典史
PDF
Doma SQLテンプレートのしくみ
PPTX
MongoDBが遅いときの切り分け方法
PPTX
x86x64 SSE4.2 POPCNT
PDF
MySQL Index勉強会外部公開用
PDF
イミュータブルデータモデル(世代編)
PDF
SQLアンチパターン(インデックスショットガン)
PDF
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
PDF
コンテナの作り方「Dockerは裏方で何をしているのか?」
PDF
SSH力をつけよう
PDF
DBスキーマもバージョン管理したい!
PDF
YugabyteDBを使ってみよう - part2 -(NewSQL/分散SQLデータベースよろず勉強会 #2 発表資料)
PDF
MySQLステータスモニタリング
PDF
アーキテクチャから理解するPostgreSQLのレプリケーション
iostat await svctm の 見かた、考え方
MySQLテーブル設計入門
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
MySQLレプリケーションあれやこれや
Metaspace
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
A24 SQL Server におけるパフォーマンスチューニング手法 - 注目すべきポイントを簡単に by 多田典史
Doma SQLテンプレートのしくみ
MongoDBが遅いときの切り分け方法
x86x64 SSE4.2 POPCNT
MySQL Index勉強会外部公開用
イミュータブルデータモデル(世代編)
SQLアンチパターン(インデックスショットガン)
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
コンテナの作り方「Dockerは裏方で何をしているのか?」
SSH力をつけよう
DBスキーマもバージョン管理したい!
YugabyteDBを使ってみよう - part2 -(NewSQL/分散SQLデータベースよろず勉強会 #2 発表資料)
MySQLステータスモニタリング
アーキテクチャから理解するPostgreSQLのレプリケーション
Ad

Similar to MySQLerの7つ道具 (20)

PPT
Maatkit で MySQL チューニング
PDF
MySQLerの7つ道具 plus
KEY
道具を磨くことのススメ
PDF
MySQL 5.7が魅せる新しい運用の形
PDF
紹介 of Anemometer
PDF
[data analytics showcase] B12: サーバー1,000台を監視するということ by 株式会社インサイトテクノロジー 小幡 一郎
PDF
MySQL 5.7 トラブルシューティング 性能解析入門編
PDF
MySQL 5.5 Update #denatech
PDF
Devsの常識、DBAは非常識
PDF
MySQL 開発最新動向
PDF
ペパボ de MySQL
PPT
20090107 Postgre Sqlチューニング(Sql編)
PPTX
[OSC 2017 Tokyo/Fall] OSSコンソーシアム DB部会 MySQL 8.0
PPTX
PostgreSQL使いのエンジニアから見たMySQL
PPTX
押さえておきたい、PostgreSQL 13 の新機能!! (PostgreSQL Conference Japan 2020講演資料)
PDF
MySQLとPostgreSQLの基本的な実行プラン比較
PPTX
【基礎編】社内向けMySQL勉強会
PPTX
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PDF
Maatkitの紹介
PDF
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版
Maatkit で MySQL チューニング
MySQLerの7つ道具 plus
道具を磨くことのススメ
MySQL 5.7が魅せる新しい運用の形
紹介 of Anemometer
[data analytics showcase] B12: サーバー1,000台を監視するということ by 株式会社インサイトテクノロジー 小幡 一郎
MySQL 5.7 トラブルシューティング 性能解析入門編
MySQL 5.5 Update #denatech
Devsの常識、DBAは非常識
MySQL 開発最新動向
ペパボ de MySQL
20090107 Postgre Sqlチューニング(Sql編)
[OSC 2017 Tokyo/Fall] OSSコンソーシアム DB部会 MySQL 8.0
PostgreSQL使いのエンジニアから見たMySQL
押さえておきたい、PostgreSQL 13 の新機能!! (PostgreSQL Conference Japan 2020講演資料)
MySQLとPostgreSQLの基本的な実行プラン比較
【基礎編】社内向けMySQL勉強会
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
Maatkitの紹介
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版
Ad

More from yoku0825 (20)

PDF
逝くぞ最新版、罠の貯蔵は十分か
PDF
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
PDF
MySQL 8.0で憶えておいてほしいこと
PDF
片手間MySQLチューニング戦略
PDF
MySQLを割と一人で300台管理する技術
PDF
わかった気になるMySQL
PDF
わたしを支える技術
PDF
MySQL 5.7の次のMySQL 8.0はどんなものになるだろう
PDF
Dockerイメージで誰でも気軽にMroonga体験
PDF
MySQLアンチパターン
PDF
MySQL 5.7の次のMySQLは
PDF
MHAの次を目指す mikasafabric for MySQL
PDF
5.7の次のMySQL
PDF
mikasafabric for MySQL
PDF
とあるイルカの近況報告
PDF
MySQL Fabricでぼっこぼこにされたはなし
PDF
MySQLと正規形のはなし
PDF
MySQLおじさんの逆襲
PDF
地雷職人の朝は早い
PDF
イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション
逝くぞ最新版、罠の貯蔵は十分か
サーバーが完膚なきまでに死んでもMySQLのデータを失わないための表技
MySQL 8.0で憶えておいてほしいこと
片手間MySQLチューニング戦略
MySQLを割と一人で300台管理する技術
わかった気になるMySQL
わたしを支える技術
MySQL 5.7の次のMySQL 8.0はどんなものになるだろう
Dockerイメージで誰でも気軽にMroonga体験
MySQLアンチパターン
MySQL 5.7の次のMySQLは
MHAの次を目指す mikasafabric for MySQL
5.7の次のMySQL
mikasafabric for MySQL
とあるイルカの近況報告
MySQL Fabricでぼっこぼこにされたはなし
MySQLと正規形のはなし
MySQLおじさんの逆襲
地雷職人の朝は早い
イルカさんチームからゾウさんチームに教えたいMySQLレプリケーション

MySQLerの7つ道具