Slide 1

Slide 1 text

RDBのトラブルの現場を追え!
 
 そーだいなる DBRE Night

Slide 2

Slide 2 text

What is it?
 RDBMSの死はサービスの死


Slide 3

Slide 3 text

What is it?
 ● DBが突然遅くなった…
 ● コネクションが溢れてサービス停止…
 ● INDEXを貼ろうとしたらエラー…
 現場の声


Slide 4

Slide 4 text

What is it?
 現場の 悲鳴 声のお届けします


Slide 5

Slide 5 text

What is it?
 大前提!!
 今日は全部PostgreSQLの話


Slide 6

Slide 6 text

あじぇんだ
 1. 自己紹介
 2. 初級編:スロークエリを追え!
 3. 中級編:エラーログを追え!
 4. 上級編:未知のエラーを追え!
 5. 番外編:何もしてないのにDBが壊れた
 6. まとめ


Slide 7

Slide 7 text

あじぇんだ
 1. 自己紹介
 2. 初級編:スロークエリを追え!
 3. 中級編:エラーログを追え!
 4. 上級編:未知のエラーを追え!
 5. 番外編:何もしてないのにDBが壊れた
 6. まとめ


Slide 8

Slide 8 text

自己紹介
 曽根 壮大(34歳)
 株式会社 オミカレ 副社長 CTO
 
 そ  ね   たけ とも
 ● 日本PostgreSQLユーザ会 勉強会分科会 担当
 ● 3人の子供がいます(長女、次女、長男)
 ● 技術的にはWeb/LL言語/RDBMSが好きです
 ● コミュニティが好き

Slide 9

Slide 9 text

婚活といえばオミカレ
 https://party-calendar.net/

Slide 10

Slide 10 text

本書きました


Slide 11

Slide 11 text

あじぇんだ
 1. 自己紹介
 2. 初級編:スロークエリを追え!
 3. 中級編:エラーログを追え!
 4. 上級編:未知のエラーを追え!
 5. 番外編:何もしてないのにDBが壊れた
 6. まとめ


Slide 12

Slide 12 text

初級編:スロークエリを追え!
 サービスを殺すには刃物は要らぬ。
 スロークエリがあれば良い。


Slide 13

Slide 13 text

初級編:スロークエリを追え!
 スロークエリの見つけ方


Slide 14

Slide 14 text

初級編:スロークエリを追え!
 
 ● スロークエリログ
 ● 実行計画
 ● モニタリング
 ● 職人の勘
 スロークエリログの主な見つけ方


Slide 15

Slide 15 text

初級編:スロークエリを追え!
 
 ● スロークエリログ
 ● 実行計画
 ● モニタリング
 ● 職人の勘
 スロークエリログの主な見つけ方


Slide 16

Slide 16 text

初級編:スロークエリを追え!
 スロークエリログを使う


Slide 17

Slide 17 text

初級編:スロークエリを追え!
 スロークエリログを使う
 ↓
 指定秒以上の実行したSQLをログに出力


Slide 18

Slide 18 text

初級編:スロークエリを追え!
 しかしデフォルトは無効になってる


Slide 19

Slide 19 text

初級編:スロークエリを追え!
 # MySQL
 slow_query_log=0(OFF) or 1(ON)
 slow_query_log_file=出力ファイル名
 long_query_time=許容できないレスポンス時間(秒)
 
 #PostgreSQL
 logging_collector=on or off
 log_min_duration_statement=許容できないレスポンス時間(ミリ秒)
 


Slide 20

Slide 20 text

初級編:スロークエリを追え!
 スロークエリログの見方


Slide 21

Slide 21 text

初級編:スロークエリを追え!
 生ログを見るのは辛い


Slide 22

Slide 22 text

初級編:スロークエリを追え!
 生ログを見るのは辛い
 ↓
 ちょっとした工夫をする


Slide 23

Slide 23 text

初級編:スロークエリを追え!
 Let's Postgres 「スロークエリの分析」
 
 https://lets.postgresql.jp/documents/technical/query_analysis/1 


Slide 24

Slide 24 text

初級編:スロークエリを追え!
 #PostgreSQL
 logging_collector=on or off
 # CSVでログを出力する
 log_destination = 'csvlog'
 log_min_duration_statement=許容できないレスポンス時間(ミリ秒)
 


Slide 25

Slide 25 text

初級編:スロークエリを追え!
 CSVにすると?


Slide 26

Slide 26 text

初級編:スロークエリを追え!
 CSVにすると?
 ↓
 Excelでもプログラムでも集計が楽


Slide 27

Slide 27 text

初級編:スロークエリを追え!
 もちろんテーブルにインポートも楽
 


Slide 28

Slide 28 text

初級編:スロークエリを追え!
 もちろんテーブルにインポートも楽
 ↓
 SQLで検索出来る


Slide 29

Slide 29 text

初級編:スロークエリを追え!
 CSVlogを使わない場合でも
 集計してくれるツールは結構ある


Slide 30

Slide 30 text

初級編:スロークエリを追え!
 そもそも最初から集計してくれる機能がある
 


Slide 31

Slide 31 text

初級編:スロークエリを追え!
 そもそも最初から集計してくれる機能がある
 ↓
 pg_stat_statements
 


Slide 32

Slide 32 text

初級編:スロークエリを追え!
 DBaaSを使ってるからfileに吐けない時
 


Slide 33

Slide 33 text

初級編:スロークエリを追え!
 DBaaSを使ってるからfileに吐けない時
 ↓
 こうやってテーブル(統計情報)の
 選択肢もちゃんとある


Slide 34

Slide 34 text

初級編:スロークエリを追え!
 スロークエリを見つけたら?
 


Slide 35

Slide 35 text

初級編:スロークエリを追え!
 スロークエリを見つけたら?
 ↓
 まずは実行計画を見よう


Slide 36

Slide 36 text

初級編:スロークエリを追え!
 実行計画を見る
 ↓
 EXPLAINを使う


Slide 37

Slide 37 text

初級編:スロークエリを追え!
 
 
 
 
 https://speakerdeck.com/soudai/shi-xing-ji-hua-falsehua 


Slide 38

Slide 38 text

初級編:スロークエリを追え!
 
 ● スロークエリログ
 ● 実行計画
 ● モニタリング
 ● 職人の勘
 スロークエリログの主な見つけ方


Slide 39

Slide 39 text

初級編:スロークエリを追え!
 実行計画を集める


Slide 40

Slide 40 text

初級編:スロークエリを追え!
 実行計画を集める
 ↓
 auto_explain


Slide 41

Slide 41 text

初級編:スロークエリを追え!
 session_preload_libraries = 'auto_explain'
 # 100ms以上かかっているクエリを自動でEXPLAINする
 auto_explain.log_min_duration = 許容できないレスポンス時間(ミリ秒)
 auto_explain.log_analyze = on
 auto_explain.log_nested_statements = on
 auto_explain.log_triggers = on
 


Slide 42

Slide 42 text

初級編:スロークエリを追え!
 トリガーや外部キー制約経由の参照なども
 ログに吐ける


Slide 43

Slide 43 text

初級編:スロークエリを追え!
 
 ● スロークエリログ
 ● 実行計画
 ● モニタリング
 ● 職人の勘
 スロークエリログの主な見つけ方


Slide 44

Slide 44 text

初級編:スロークエリを追え!
 スロークエリを事前に察知する


Slide 45

Slide 45 text

初級編:スロークエリを追え!
 スロークエリを事前に察知する
 ↓
 インフラから知る


Slide 46

Slide 46 text

初級編:スロークエリを追え!
 
 ● メモリが足りずtemp落ち
 ● ロック待ち
 ● 様々な理由で実行計画が変わる
 …etc
 突然SQLが遅くなるとき


Slide 47

Slide 47 text

初級編:スロークエリを追え!
 
 ● メモリが足りずtemp落ち
 ● ロック待ち
 ● 様々な理由で実行計画が変わる
 …etc
 突然SQLが遅くなるとき


Slide 48

Slide 48 text

初級編:スロークエリを追え!
 
 https://gihyo.jp/dev/feature/01/dex_postgresql/0002 


Slide 49

Slide 49 text

初級編:スロークエリを追え!
 


Slide 50

Slide 50 text

初級編:スロークエリを追え!
 


Slide 51

Slide 51 text

初級編:スロークエリを追え!
 
 ● メモリが足りずtemp落ち
 ● ロック待ち
 ● 様々な理由で実行計画が変わる
 …etc
 突然SQLが遅くなるとき


Slide 52

Slide 52 text

初級編:スロークエリを追え!
 スロークエリログには
 ロックの待ち時間は含まれない


Slide 53

Slide 53 text

初級編:スロークエリを追え!
 スロークエリログには
 ロックの待ち時間は含まれない
 ↓
 pg_locks+pg_stat_activity 


Slide 54

Slide 54 text

初級編:スロークエリを追え!
 Let's Postgres「稼動統計情報を活用しよう」
 
 https://lets.postgresql.jp/documents/technical/statistics
 


Slide 55

Slide 55 text

初級編:スロークエリを追え!
 =# SELECT l.locktype, c.relname, l.pid, l.mode,
 substring(a.current_query, 1, 6) AS query,
 (current_timestamp - xact_start)::interval(3) AS duration
 FROM pg_locks l LEFT OUTER JOIN pg_stat_activity a
 ON l.pid = a. procpid
 LEFT OUTER JOIN pg_class c ON l.relation = c.oid
 WHERE NOT l.granted ORDER BY l.pid;


Slide 56

Slide 56 text

初級編:スロークエリを追え!
 locktype | relname | pid | mode | query | duration ---------------+----------+------+---------------+--------+-------------- tuple | tellers | 2700 | ExclusiveLock | UPDATE | 00:00:00.013 transactionid | | 2701 | ShareLock | INSERT | 00:00:00.004 transactionid | | 2702 | ShareLock | UPDATE | 00:00:00.014 tuple | tellers | 2703 | ExclusiveLock | UPDATE | 00:00:00.004 tuple | tellers | 2704 | ExclusiveLock | UPDATE | 00:00:00.009 tuple | branches | 2705 | ExclusiveLock | UPDATE | 00:00:00.001 transactionid | | 2706 | ShareLock | UPDATE | 00:00:00.001 transactionid | | 2707 | ShareLock | UPDATE | 00:00:00.017 transactionid | | 2708 | ShareLock | UPDATE | 00:00:00.007 (9 rows)

Slide 57

Slide 57 text

初級編:スロークエリを追え!
 ツールを使って可視化する


Slide 58

Slide 58 text

初級編:スロークエリを追え!
 
 ● Mackerel + plugin
 ● Zabbix + pg_monz
 ● pg_statsinfo + pg_stats_reporter 
 …etc
 メジャーなモニタリングツール


Slide 59

Slide 59 text

初級編:スロークエリを追え!
 
 
 
 
 
 https://speakerdeck.com/soudai/postgresql-architecture-and-performance-monitoring 


Slide 60

Slide 60 text

初級編:スロークエリを追え!
 
 ● スロークエリログ
 ● 実行計画
 ● モニタリング
 ● 職人の勘
 スロークエリログの主な見つけ方


Slide 61

Slide 61 text

初級編:スロークエリを追え!
 プロはsshで入る瞬間にわかる(ときがある)


Slide 62

Slide 62 text

初級編:スロークエリを追え!
 topでもわかる(ときがある)


Slide 63

Slide 63 text

初級編:スロークエリを追え!
 職人の勘→DBAの仕事
 職人の勘を仕組みにする→DBREの仕事


Slide 64

Slide 64 text

初級編:スロークエリを追え!
 日本PostgreSQLユーザ会の動画を活用
 
 


Slide 65

Slide 65 text

初級編:スロークエリを追え!
 
 
 
 https://www.youtube.com/channel/UCeenIljXnSwrwYEU-YBE2qA/feed


Slide 66

Slide 66 text

あじぇんだ
 1. 自己紹介
 2. 初級編:スロークエリを追え!
 3. 中級編:エラーログを追え!
 4. 上級編:未知のエラーを追え!
 5. 番外編:何もしてないのにDBが壊れた
 6. まとめ


Slide 67

Slide 67 text

中級編:エラーログを追え!
 エラーログ
 「実を言うとDBはもうだめです。
 突然こんなこと言ってごめんね。
 でも本当です。」


Slide 68

Slide 68 text

中級編:エラーログを追え!
 エラーログは答えを教えてくれてる
 


Slide 69

Slide 69 text

中級編:エラーログを追え!


Slide 70

Slide 70 text

中級編:エラーログを追え!
 
 # postgresql
 logging_collector=on # logの有効化
 # logの出力時のフォーマットの指定
 log_line_prefix='[%t]%u %d %p[%l] %h[%i]' 
 log_min_duration_statement=<許容できないレスポンス時間(ミリ秒)>
 # 出力したい深刻度レベル
 # 指定された深刻度レベルよりも重要なレベルが出力される
 # この場合、ERROR LOG FATAL PANIC
 log_min_error_statement=error 


Slide 71

Slide 71 text

中級編:エラーログを追え!
 
 # mysql
 log_syslog=1
 log_syslog_include_pid=1
 log_error_verbosity=3
 slow_query_log = 1 # slow queryログの有効化
 slow_query_log_file=/usr/local/mysql/data/slow.log # ファイルパス
 long_query_time=<許容できないレスポンス時間(秒)>
 # インデックスが使用されていないクエリをログに出力
 log_queries_not_using_indexes = 1 


Slide 72

Slide 72 text

中級編:エラーログを追え!
 まずはググる
 


Slide 73

Slide 73 text

中級編:エラーログを追え!
 まずはググる
 ↓
 エラーログは英語の方が良い


Slide 74

Slide 74 text

中級編:エラーログを追え!
 最初に公式ドキュメントを信じる
 


Slide 75

Slide 75 text

中級編:エラーログを追え!
 最初に公式ドキュメントを信じる
 ↓
 スタックオーバーフローやQiitaで満足しない


Slide 76

Slide 76 text

中級編:エラーログを追え!
 ???「エラーログで調べると
 自分のblogしか出てこないんですけど」
 


Slide 77

Slide 77 text

中級編:エラーログを追え!
 ???「わかるぅ〜〜〜」
 (CV:そーだい)


Slide 78

Slide 78 text

中級編:エラーログを追え!
 そうなったら上級者


Slide 79

Slide 79 text

あじぇんだ
 1. 自己紹介
 2. 初級編:スロークエリを追え!
 3. 中級編:エラーログを追え!
 4. 上級編:未知のエラーを追え!
 5. 番外編:何もしてないのにDBが壊れた
 6. まとめ


Slide 80

Slide 80 text

上級者編:未知のエラーを追え!
 突然の謎のエラーログ
 


Slide 81

Slide 81 text

上級者編:未知のエラーを追え!
 突然の謎のエラーログ
 ↓
 ググっても謎


Slide 82

Slide 82 text

上級者編:未知のエラーを追え!
 日本語コミュニティのSlackを活用する
 


Slide 83

Slide 83 text

上級者編:未知のエラーを追え!
 日本語コミュニティのSlackを活用する
 ↓
 mysql-casualとpostgresql-jp


Slide 84

Slide 84 text

上級者編:未知のエラーを追え!
 Slackで有識者に聞く
 


Slide 85

Slide 85 text

上級者編:未知のエラーを追え!
 Slackで有識者に聞く
 ↓
 バグだったりすることもある


Slide 86

Slide 86 text

上級者編:未知のエラーを追え!
 それでもわからない


Slide 87

Slide 87 text

上級者編:未知のエラーを追え!
 広大なインターネットにも
 無いものは無い


Slide 88

Slide 88 text

上級者編:未知のエラーを追え!
 誰も知らないことは
 自分が言葉にするしか無い


Slide 89

Slide 89 text

上級者編:未知のエラーを追え!
 振る舞いを知る


Slide 90

Slide 90 text

上級者編:未知のエラーを追え!
 Source Code Reading
 http://higepon.hatenablog.com/entry/19700110/1233646390 
 https://lets.postgresql.jp/node/10 
 


Slide 91

Slide 91 text

上級者編:未知のエラーを追え!
 まぁソースコード、言うほど読む必要ない


Slide 92

Slide 92 text

上級者編:未知のエラーを追え!
 まぁソースコード、言うほど読む必要ない
 ↓
 試して挙動を理解する方が大事


Slide 93

Slide 93 text

上級者編:未知のエラーを追え!


Slide 94

Slide 94 text

上級者編:未知のエラーを追え!
 しっかりと動作を知ることができたら?
 


Slide 95

Slide 95 text

上級者編:未知のエラーを追え!
 しっかりと動作を知ることができたら?
 ↓
 アウトプットしていこう


Slide 96

Slide 96 text

上級者編:未知のエラーを追え!
 あなたが検索して出てこなかった
 そのエラーメッセージに誰かも困っています


Slide 97

Slide 97 text

あじぇんだ
 1. 自己紹介
 2. 初級編:スロークエリを追え!
 3. 中級編:エラーログを追え!
 4. 上級編:未知のエラーを追え!
 5. 番外編:何もしてないのにDBが壊れた
 6. まとめ


Slide 98

Slide 98 text

1. 番外編:何もしてないのにDBが壊れた
 続きはBuildersconで!


Slide 99

Slide 99 text

あじぇんだ
 1. 自己紹介
 2. 初級編:スロークエリを追え!
 3. 中級編:エラーログを追え!
 4. 上級編:未知のエラーを追え!
 5. 番外編:何もしてないのにDBが壊れた
 6. まとめ


Slide 100

Slide 100 text

まとめ
 今日、学びはありましたか?


Slide 101

Slide 101 text

まとめ
 今日、学びはありましたか?
 ↓
 DBAの仕事のほんの一部です


Slide 102

Slide 102 text

まとめ
 でもそのDBAの仕事を
 みんなが出来るようにするのが
 DBREの仕事です


Slide 103

Slide 103 text

まとめ
 仕組みで課題を解決する


Slide 104

Slide 104 text

まとめ
 技術で課題を解決する


Slide 105

Slide 105 text

まとめ
 理想への一歩目を踏み出すのは
 自分自身


Slide 106

Slide 106 text

まとめ
 ご清聴ありがとうございました