あなたの知らないpostgresql監視の世界

79
あなたの知らない PostgreSQL 監視の世界 中西 剛紀

Upload: yoshinori-nakanishi

Post on 15-Apr-2017

3.021 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: あなたの知らないPostgreSQL監視の世界

あなたの知らない PostgreSQL 監視の世界

中西 剛紀

Page 2: あなたの知らないPostgreSQL監視の世界

2

自己紹介 • 氏名 : 中西 剛紀 (なかにし よしのり) • 所属 : TIS株式会社 OSS推進室 • お仕事 : OSSのサポート, 技術支援 • 主な活動領域 : PostgreSQL全般

– 日本PostgreSQLユーザ会(JPUG)でたまに講演 http://www.slideshare.net/naka24nori/pg-monzpostgre-sql

–  PostgreSQLエンタープライズコンソーシアム(PGECons)で技術検証活動 http://itpro.nikkeibp.co.jp/atcl/column/15/052800134/052900004/?ST=oss&a

•  pg_monzの開発メンバー

Page 3: あなたの知らないPostgreSQL監視の世界

3

AGENDA

•  PostgreSQLの監視に使える情報 •  PostgreSQLの監視に使えるツール •  PostgreSQLの監視パターン •  PostgreSQLのログについて考える

Page 4: あなたの知らないPostgreSQL監視の世界

4

PostgreSQLの運用でやるべきこと

• データベース運用の目的 – DBの状態を把握して健全な状態に保つ

• データベース運用の種類 – 死活監視 – リソース監視 – 性能分析/チューニング – バックアップ/リストア

• 監視が運用管理の基本 – 正しく現状を把握しなければ何もできない

Page 5: あなたの知らないPostgreSQL監視の世界

5

PostgreSQLの運用でやるべきこと

• データベース運用の目的 – DBの状態を把握して健全な状態に保つ

• データベース運用の種類 – 死活監視 – リソース監視 – 性能分析/チューニング – バックアップ/リストア

• 監視が運用管理の基本 – 正しく現状を把握しなければ何もできない

今回お話する範囲

Page 6: あなたの知らないPostgreSQL監視の世界

6

PostgreSQLの監視に使える情報

Page 7: あなたの知らないPostgreSQL監視の世界

7

PostgreSQLの監視に使える情報

•  PostgreSQLの標準機能 – コマンド – 関数 – 稼働統計情報 – ログ

Page 8: あなたの知らないPostgreSQL監視の世界

8

PostgreSQLの監視に使える情報

• コマンド

• 関数

参考:PostgreSQL  9.4.4  マニュアル 第9章関数と演算子  h0ps://www.postgresql.jp/document/9.4/html/func>ons-­‐info.html

コマンド名 説明pg_isready PostgreSQLサーバの接続状態を検査する。(9.3以降)

参考:PostgreSQL  9.4.4  マニュアル II.  PostgreSQLクライアントアプリケーション  h0ps://www.postgresql.jp/document/9.4/html/reference-­‐client.html  

関数名 説明pg_is_in_recovery() リカバリ実施中であれば真を返す。

pg_database_size() データベースで使用されるディスク容量を返す。pg_table_size() テーブルで使用されるディスク容量を返す。

(インデックスは除外)

Page 9: あなたの知らないPostgreSQL監視の世界

9

PostgreSQLの監視に使える情報

• 稼働統計情報 ビュー名 説明pg_stat_activity 接続中のサーバプロセスに関連する情報

pg_stat_archiver アーカイバプロセスに関する情報 (9.4以降)pg_stat_bgwriter バックグラウンドライタプロセスの活動状況pg_stat_database DB単位のアクティビティ状況pg_stat_**_tables テーブル単位のアクティビティ状況pg_stat_**_indexes インデックス単位のアクティビティ状況pg_statio_**_tables テーブル単位のI/Oに関する情報pg_statio_**_indexes インデックス単位のI/Oに関する情報pg_statio_**_sequences シーケンス単位のI/Oに関する情報pg_stat_user_functions 関数の実行に関する情報pg_stat_replication レプリケーションのアクティビティ状況

参考:PostgreSQL  9.4.4  マニュアル 第27章データベース活動状況の監視  h0ps://www.postgresql.jp/document/9.4/html/monitoring-­‐stats.html  

Page 10: あなたの知らないPostgreSQL監視の世界

10

PostgreSQLの監視に使える情報

• ログ – 何らかの事象が発生したことを出力

• 深刻なレベル(PANIC,FATAL,ERROR)から、 特に影響ないレベル(INFO)まで

– 処理されたSQL • 設定時間を超過したSQL(スロークエリ) • 監査目的で全てのSQLを出力することも可能

– チェックポイント、自動VACUUMの実行 – デッドロックの発生 – 出力形式

• テキスト(プレーン、CSV) •  syslog • イベントログ

Page 11: あなたの知らないPostgreSQL監視の世界

11

PostgreSQLの監視に使えるツール

Page 12: あなたの知らないPostgreSQL監視の世界

12

PostgreSQLの監視に使えるツール

•  contrib – pg_stat_statements – file_fdw

• サードパーティ – pg_statsinfo – pg_monz – pgBadger – Fluentd

Page 13: あなたの知らないPostgreSQL監視の世界

13

pg_stat_statements •  PostgreSQLサーバで実行された クエリの情報を収集する共有ライブラリ – 8.4からcontribとして配布されている。 – クエリ種別、実行回数、総実行時間を収集 – 稼働統計情報と同様のビューを提供 – 永安さんの資料が詳しい

• 「今そこにある危機」を捉える ~ pg_stat_statements revisited http://www.slideshare.net/uptimejp/pgstatstatements-revisited

Page 14: あなたの知らないPostgreSQL監視の世界

14

pg_statsinfo

•  PostgreSQLサーバの稼働統計情報(+α)を定期的に収集・蓄積するツール –  http://pgstatsinfo.sourceforge.net/pg_statsinfo-ja.html

•  pg_stats_reporterで蓄積した統計情報 からグラフィカルなレポートを出力可能

• NTTさんが開発しているOSS •  PostgreSQLの性能管理ツールとしては 一番知名度が高い。

Page 15: あなたの知らないPostgreSQL監視の世界

15

pg_monz(ぴーじーもんず) •  ZabbixにPostgreSQLの監視機能を  追加するテンプレート&スクリプト

–  http://pg-monz.github.io/pg_monz/

•  TISとSRA OSS, Inc.日本支社で共同開発 • Apache License Version 2.0で公開 •  2015年 4月 Version 2.0 リリース

Page 16: あなたの知らないPostgreSQL監視の世界

16

Zabbixについて少々 • オープンソースの統合監視ソフトウェア • 監視ツールに必要な機能を網羅

– いろんな機器(NW,サーバ,MW,アプリ)に対応 – 対応プラットフォーム(OS)も多い – 収集データの蓄積、傾向分析 – メール等での障害通知 – WebインタフェースによるGUIで操作可

• ラトビアのZabbix SIAが開発元 – 国内の導入事例が増加しています。 – クラウドでの引き合い多数(¥的な面で)

Page 17: あなたの知らないPostgreSQL監視の世界

17

PostgreSQLの監視パターン

Page 18: あなたの知らないPostgreSQL監視の世界

18

救急患者レベル

• 事象を検知したら即座に対応しよう。 • 死活監視 • ログ監視 • レプリケーション監視

Page 19: あなたの知らないPostgreSQL監視の世界

19

死活監視(標準機能) •  psコマンドでプロセスを確認

•  SQL実行の可否を確認

-bash-4.1$ ps auxwf|egrep "^postgres|^USER" USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND postgres 13470 0.0 3.0 324640 15068 pts/0 S 05:55 0:00 /usr/pgsql-9.4/bin/postgres postgres 13471 0.0 0.3 179792 1520 ? Ss 05:55 0:00 \_ postgres: logger process postgres 13473 0.0 0.6 324748 3152 ? Ss 05:55 0:00 \_ postgres: checkpointer process postgres 13474 0.0 0.5 324776 2900 ? Ss 05:55 0:00 \_ postgres: writer process postgres 13475 0.0 1.1 324640 5860 ? Ss 05:55 0:00 \_ postgres: wal writer process postgres 13476 0.0 0.5 325044 2552 ? Ss 05:55 0:00 \_ postgres: autovacuum launcher process postgres 13477 0.0 0.2 179784 1464 ? Ss 05:55 0:00 \_ postgres: archiver process postgres 13478 0.0 0.3 179916 1728 ? Ss 05:55 0:00 \_ postgres: stats collector process

-bash-4.1$ psql -t -c "SELECT 1" 1 -bash-4.1$ echo $? 0 -bash-4.1$ pg_ctl stop -bash-4.1$ psql –t -c "SELECT 1" psql: could not connect to server: No such file or directory

Is the server running locally and accepting connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

-bash-4.1$ echo $? 2

Page 20: あなたの知らないPostgreSQL監視の世界

20

死活監視(標準機能) •  pg_ctl statusコマンドで確認

•  pg_isreadyコマンドで確認(9.3以降)

-bash-4.1$ pg_ctl status pg_ctl: server is running (PID: 13616) /usr/pgsql-9.4/bin/postgres -bash-4.1$ echo $? 0 -bash-4.1$ pg_ctl stop -bash-4.1$ pg_ctl status pg_ctl: no server running -bash-4.1$ echo $? 3

-bash-4.1$ pg_isready /tmp:5432 - accepting connections -bash-4.1$ echo $? 0 -bash-4.1$ pg_ctl stop -bash-4.1$ pg_isready /tmp:5432 - no response -bash-4.1$ echo $? 2

Page 21: あなたの知らないPostgreSQL監視の世界

21

死活監視(ツール活用)

•  pg_monz で死活監視 – SQL(SELECT 1)を定期的に実行して確認 – 実行に失敗したらZabbixのトリガーで検知 – Zabbixのアクションを定義することで、 トリガー検知時のメール通知等が可能

Page 22: あなたの知らないPostgreSQL監視の世界

22

ログ監視(標準機能)

• ログに出力されるメッセージを確認 – PANIC/FATAL/ERRORが監視候補

深刻度 説明PANIC データベースインスタンス全体に影響する致命的な問題

FATAL 接続エラー、強制切断といったセッションレベルに影響する問題LOG 管理者向けの情報。チェックポイント、VACUUM、スロークエリ等ERROR SQLを中断させる原因となったエラー。シンタックスエラー等WARNING ユーザへの警告。トランザクションブロック外でのCOMMIT等NOTICE ユーザの補助となる情報。長い識別子の切り詰めに関する注意等INFO ユーザが明示的に出力する補助情報。VACUUM VERBOSEの出力等 DEBUG1..5 開発者向けの詳細情報。運用時には出力しない。

Page 23: あなたの知らないPostgreSQL監視の世界

23

ログ監視(ツール活用)

•  pg_monzでログ監視 – ログファイルの内容を定期的に確認 – PANIC/FATAL/ERRORを含むメッセージを検出したらZabbixのトリガーで検知

– Zabbixのアクションを定義することで、 トリガー検知時のメール通知等が可能

Page 24: あなたの知らないPostgreSQL監視の世界

24

レプリケーション監視(標準機能)

• スレーブがつながっているか? – マスタのpg_stat_replicationビューで確認

postgres=# select client_addr, state, sent_location, replay_location, sync_priority,sync_state from pg_stat_replication;

client_addr | state | sent_location | replay_location | sync_priority | sync_state --------------+-----------+---------------+-----------------+---------------+------------ 192.168.1.14 | streaming | 0/5F02FAB8 | 0/5F02FAB8 | 1 | sync 192.168.1.15 | streaming | 0/5F02FAB8 | 0/5F02FAB8 | 2 | potential

Page 25: あなたの知らないPostgreSQL監視の世界

25

レプリケーション監視(ツール活用)

•  pg_monzでレプリケーション監視 – どのサーバがPrimary/Standbyか確認可能

– マスタのpg_stat_replicationビューの情報を定期的に取得し、以下情報を確認可能

•  Standbyへのデータ伝搬の遅延状況 • 同期レプリケーションのプライオリティ

Page 26: あなたの知らないPostgreSQL監視の世界

26

レプリケーション監視 その2 • マスタが2つあったらヤバい。 • 違うデータベースとして不整合が広がる。

PostgreSQL  (スレーブ)  

PostgreSQL  (スレーブ)  

PostgreSQL  (マスタ)  

更新 同期

同期

PostgreSQL  (スレーブ)  

PostgreSQL  (新マスタ)  

PostgreSQL  (旧マスタ)  

更新 同期

あれ??

更新

Page 27: あなたの知らないPostgreSQL監視の世界

27

レプリケーション監視(標準機能)

•  pg_is_in_recovery関数で確認

•  pg_stat_replicationビューで確認

postgres=# SELECT pg_is_in_recovery(); ★マスタで実行 pg_is_in_recovery ------------------- f postgres=# SELECT pg_is_in_recovery(); ★スレーブで実行 pg_is_in_recovery ------------------- t

postgres=# SELECT COUNT(*) FROM pg_stat_replication; ★マスタで実行 count ------- 2 postgres=# SELECT COUNT(*) FROM pg_stat_replication; ★スレーブで実行 count ------- 0

Page 28: あなたの知らないPostgreSQL監視の世界

28

レプリケーション監視(ツール活用)

•  pg_monzでマスタの数を監視 – クラスタ内のマスタ、スレーブ数をチェック

– 本来の数(1つ)じゃなかったらトリガーで検知

Page 29: あなたの知らないPostgreSQL監視の世界

29

レプリケーション監視 その3 • 同期スレーブがいなくなるとヤバい。 • マスタ更新不可により実質サービス停止

PostgreSQL  (非同期

スレーブ)  

PostgreSQL  (同期

スレーブ)  PostgreSQL  

(マスタ)  更新 同期

同期

PostgreSQL  (potential)  

PostgreSQL  (sync)  

PostgreSQL  (マスタ)  

更新NG  

あれ??

参照OK  

参照  

Page 30: あなたの知らないPostgreSQL監視の世界

30

レプリケーション監視(標準機能)

•  pg_stat_replicationビューで確認

postgres=# SELECT COUNT(*) FROM pg_stat_replication; ★マスタで実行 count ------- 2 ⇒ 問題なし postgres=# SELECT COUNT(*) FROM pg_stat_replication; ★マスタで実行 count ------- 0 ⇒ スレーブが1つもいないので問題あり

Page 31: あなたの知らないPostgreSQL監視の世界

31

レプリケーション監視(ツール活用)

•  pg_monzで同期スレーブの数を監視 – 同期レプリケーションを設定している場合、スレーブがいなくなったらトリガーで検知

Page 32: あなたの知らないPostgreSQL監視の世界

32

レントゲンに怪しい影が、、レベル • 事態が深刻化する前に手を打とう。 • データベース容量 • WALアーカイブ • デッドロック • 長時間かかっている処理

Page 33: あなたの知らないPostgreSQL監視の世界

33

データベース容量(標準機能)

• データベースクラスタのディレクトリをduコマンドで確認

• 関数で確認

[postgres@pgsql01 9.4]$ du -sh data 611M data

postgres=# select pg_size_pretty(pg_database_size(‘testdb’)); ★データベース  pg_size_pretty ---------------- 171 MB testdb=# select pg_size_pretty(pg_table_size(‘pgbench_accounts’)); ★テーブル pg_size_pretty ---------------- 130 MB

Page 34: あなたの知らないPostgreSQL監視の世界

34

データベース容量(ツール活用) •  pg_monzでデータベース容量を確認

– DB単位にグラフを表示可能 – 閾値を超過したらZabbixのトリガーで検知

Page 35: あなたの知らないPostgreSQL監視の世界

35

WALアーカイブ(標準機能) •  PITRでの復旧にWALアーカイブが必要 • WALアーカイブに失敗したログを確認

– 深刻度がLOG,WARNINGなので注意

cp: cannot create regular file `/var/lib/pgsql/9.4/archive_bad/000000010000000000000008': No such file or directory < 2015-11-11 10:04:50.609 UTC >LOG: archive command failed with exit code 1 < 2015-11-11 10:04:50.609 UTC >DETAIL: The failed archive command was: cp pg_xlog/000000010000000000000008 /var/lib/pgsql/9.4/archive_bad/000000010000000000000008 cp: cannot create regular file `/var/lib/pgsql/9.4/archive_bad/000000010000000000000008': No such file or directory < 2015-11-11 10:04:51.614 UTC >LOG: archive command failed with exit code 1 < 2015-11-11 10:04:51.614 UTC >DETAIL: The failed archive command was: cp pg_xlog/000000010000000000000008 /var/lib/pgsql/9.4/archive_bad/000000010000000000000008 cp: cannot create regular file `/var/lib/pgsql/9.4/archive_bad/000000010000000000000008': No such file or directory < 2015-11-11 10:04:52.618 UTC >LOG: archive command failed with exit code 1 < 2015-11-11 10:04:52.618 UTC >DETAIL: The failed archive command was: cp pg_xlog/000000010000000000000008 /var/lib/pgsql/9.4/archive_bad/000000010000000000000008 < 2015-11-11 10:04:52.619 UTC >WARNING: archiving transaction log file "000000010000000000000008" failed too many times, will try again later

Page 36: あなたの知らないPostgreSQL監視の世界

36

WALアーカイブ(標準機能)

•  pg_stat_archiverビューで確認(9.4以降)

postgres=# select * from pg_stat_archiver; -[ RECORD 1 ]------+------------------------------ archived_count | 12 last_archived_wal | 00000001000000000000000E last_archived_time | 2015-11-11 10:10:50.629021+00 failed_count | 6 last_failed_wal | 000000010000000000000008 last_failed_time | 2015-11-11 10:05:52.719825+00 stats_reset | 2015-11-06 08:10:16.027035+00

Page 37: あなたの知らないPostgreSQL監視の世界

37

デッドロック(標準機能)

• デッドロック発生をログで確認 –  log_lock_waitsパラメータを設定して出力

•  pg_stat_databaseビューで確認

2015-11-12 14:52:07 JST [10382] LOG: process 10382 detected deadlock while waiting for AccessExclusiveLock on relation 16420 of database 16400 after 1000.088 ms

postgres=# SELECT datname,deadlocks FROM pg_stat_database where datname = 'testdb'; datname | deadlocks ---------+----------- testdb | 2

Page 38: あなたの知らないPostgreSQL監視の世界

38

デッドロック(ツール活用)

•  pg_monzでデッドロック監視 – DB単位のデッドロック発生数を定期的に確認 – 一定時間内の発生数が閾値を超過したら Zabbixのトリガーで検知

•  pg_statsinfoでデッドロック監視 – DB単位のデッドロック発生数を収集

Page 39: あなたの知らないPostgreSQL監視の世界

39

長時間かかっている処理

• ロングクエリ – 開始されてから長時間終了していないクエリ

• ロングトランザクション – BEGIN~COMMITまでが長時間の処理 – VACUUMやHOTによるガベージ回収処理を妨げ、DBの肥大化を起こす要因

Page 40: あなたの知らないPostgreSQL監視の世界

40

長時間かかっている処理(標準機能)

•  pg_stat_activityビューで確認 – xact_start: トランザクション開始時刻 – query_start: 現在のクエリ開始時刻

postgres=# SELECT pid, state, waiting, (now() - xact_start)::interval(3) AS tx_duration, (now() - query_start)::interval(3) AS sql_duration, query FROM pg_stat_activity WHERE pid <> pg_backend_pid();

pid | state | waiting | tx_duration | sql_duration | query -------+--------+---------+--------------+--------------+---------------------- 10266 | active | f | 00:02:00.303 | 00:00:14.175 | SELECT pg_sleep(60);

Page 41: あなたの知らないPostgreSQL監視の世界

41

長時間かかっている処理(ツール活用)

•  pg_monzでロングクエリを確認 – 一定時間以上かかっているクエリの数を 定期的に確認

– 閾値を超過したらZabbixのトリガーで検知

Page 42: あなたの知らないPostgreSQL監視の世界

42

体力測定レベル • データベースの稼働状況を把握しよう。 • データベースのスループット • データベースの接続数 • キャッシュヒット率 • チェックポイント、VACUUMの実行状況 • 一時ファイルの書き出し • 実行されたSQLの実行時間

Page 43: あなたの知らないPostgreSQL監視の世界

43

データベースのスループット

• 日頃の処理量を知っておこう。 – 平常時、ピーク時のトランザクション量 – 性能問題の原因切り分けの基礎情報

Page 44: あなたの知らないPostgreSQL監視の世界

44

データベースのスループット(標準機能)

•  pg_stat_databaseビューで確認 – 取得できるのは累積値 – 実際に利用するには単位秒あたりの 差分値を計算する等の工夫が必要

postgres=# select datname,xact_commit,xact_rollback from pg_stat_database where datname = 'testdb';

-[ RECORD 1 ]-+------- datname | testdb xact_commit | 17727 xact_rollback | 4

Page 45: あなたの知らないPostgreSQL監視の世界

45

データベースのスループット(ツール活用)

•  pg_monzでスループットを確認 – DB単位にグラフを表示可能 – pg_statsinfoも同様のグラフ表示が可能

Page 46: あなたの知らないPostgreSQL監視の世界

46

データベースの接続数(標準機能)

•  pg_stat_activityビューで確認 postgres=# SELECT datname,pid,state,SUBSTRING(query,1,45) FROM pg_stat_activity; datname | pid | state | substring ----------+-------+---------------------+----------------------------------------------- postgres | 10162 | active | SELECT datname,pid,state,SUBSTRING(query,1,45 testdb | 10179 | active | UPDATE pgbench_accounts SET abalance = abalan testdb | 10180 | active | END; testdb | 10181 | idle in transaction | UPDATE pgbench_tellers SET tbalance = tbalanc testdb | 10182 | active | UPDATE pgbench_branches SET bbalance = bbalan testdb | 10183 | active | END; testdb=# select count(*) AS connections from pg_stat_activity; connections ------------- 6

Page 47: あなたの知らないPostgreSQL監視の世界

47

データベースの接続数(ツール活用) •  pg_monzで接続数を確認

– インスタンス、DB単位にグラフを表示可能 – 閾値を超過したらZabbixのトリガーで検知

Page 48: あなたの知らないPostgreSQL監視の世界

48

データベースの接続数(ツール活用) •  pg_statsinfoで接続数を確認

– インスタンス単位の情報、グラフを表示可能

Page 49: あなたの知らないPostgreSQL監視の世界

49

キャッシュヒット率

• DBはディスクにアクセスしない方が速い。 – どれだけメモリだけで処理できたか? = キャッシュヒット率

– 一般的に90%以上を維持するのが目標

Page 50: あなたの知らないPostgreSQL監視の世界

50

キャッシュヒット率(標準機能)

•  pg_stat_databaseビューで確認

•  pg_statio_user_tablesビューで確認

postgres=# SELECT datname,round(blks_hit*100/(blks_hit+blks_read), 2) AS cache_hit_ratio FROM pg_stat_database WHERE blks_read > 0;

datname | cache_hit_ratio ----------+----------------- postgres | 99.00 testdb | 97.00

testdb=# SELECT relname,round(heap_blks_hit*100/(heap_blks_hit+heap_blks_read), 2) AS cache_hit_ratio FROM pg_statio_user_tables WHERE heap_blks_read > 0 ORDER BY cache_hit_ratio;

relname | cache_hit_ratio ------------------+----------------- pgbench_accounts | 36.00 pgbench_branches | 99.00 pgbench_tellers | 99.00 pgbench_history | 99.00

Page 51: あなたの知らないPostgreSQL監視の世界

51

キャッシュヒット率(ツール活用)

•  pg_monzでキャッシュヒット率を確認 – DB単位にグラフを表示可能 – 閾値を下回ったらZabbixのトリガーで検知 – テーブル単位のキャッシュヒット率も収集

•  pg_statsinfoでキャッシュヒット率を確認 – DB単位に表示可能

Page 52: あなたの知らないPostgreSQL監視の世界

52

チェックポイント

• 更新されたメモリ上のページをディスクに書き出す処理

• チェックポイント実行中に行われている処理の性能に影響をおよぼすことがある。 – チェックポイントを頻繁に実行している? – サーバ負荷が高い時間帯にチェックポイントが行われている?

Page 53: あなたの知らないPostgreSQL監視の世界

53

チェックポイント(標準機能) • ログを確認

–  log_checkpointsパラメータを設定して出力

•  pg_stat_bgwriterビューで確認 testdb=# SELECT checkpoints_timed,checkpoints_req,checkpoint_write_time,

checkpoint_sync_time,buffers_checkpoint from pg_stat_bgwriter; -[ RECORD 1 ]---------+-------- checkpoints_timed | 568 checkpoints_req | 0 checkpoint_write_time | 1343894 checkpoint_sync_time | 2062 buffers_checkpoint | 38659

2015-11-12 13:37:53 JST [7602] LOG: checkpoint starting: time 2015-11-12 13:42:23 JST [7602] LOG: checkpoint complete: wrote 7418 buffers (45.3%); 0 transaction log file(s) added, 0 removed, 0 recycled; write=269.201 s, sync=0.421 s, total=269.685 s; sync files=17, longest=0.418 s, average=0.024 s 2015-11-12 17:49:22 JST [10679] LOG: checkpoints are occurring too frequently (25 seconds apart)

Page 54: あなたの知らないPostgreSQL監視の世界

54

チェックポイント(ツール活用) •  pg_monzでチェックポイントを確認

– checkpoint_timeouts/segments契機で 実行されたチェックポイント実行回数を収集

– 一定期間のチェックポイント発生回数が 閾値を超過したらZabbixのトリガーで検知

•  pg_statsinfoでチェックポイントを確認 – checkpoint_timeouts/segments契機で 実行されたチェックポイント実行回数を収集

– 平均および最大の処理時間を表示可能 – チェックポイントが走った時間帯をレポートの各種グラフに重ね合わせることも可能

Page 55: あなたの知らないPostgreSQL監視の世界

55

VACUUM

• 不要なレコードを回収する処理 – ちゃんと実行されないとDBが肥大化する。

Page 56: あなたの知らないPostgreSQL監視の世界

56

VACUUM(標準機能) • ログを確認

–  log_autovacuum_min_durationパラメータを設定して出力

•  pg_stat_user_tablesビューで確認

2015-11-12 13:36:30 JST [10188] LOG: automatic vacuum of table "testdb.public.pgbench_tellers": index scans: 0 pages: 0 removed, 25 remain tuples: 533 removed, 100 remain, 0 are dead but not yet removable buffer usage: 86 hits, 0 misses, 0 dirtied avg read rate: 0.000 MB/s, avg write rate: 0.000 MB/s system usage: CPU 0.00s/0.00u sec elapsed 0.00 sec

testdb=# SELECT relname,n_live_tup,n_dead_tup,last_autovacuum,autovacuum_count FROM pg_stat_user_tables where relname = 'pgbench_accounts';

-[ RECORD 1 ]----+------------------------------ relname | pgbench_accounts n_live_tup | 1002477 n_dead_tup | 0 last_autovacuum | 2015-11-12 17:50:26.224429+09 autovacuum_count | 1

Page 57: あなたの知らないPostgreSQL監視の世界

57

VACUUM(ツール活用) •  pg_monzでVACUUMを確認

– テーブル単位にVACUUMが実行された回数、 不要領域の割合を収集

•  pg_statsinfoでVACUUMを確認 – テーブル単位にVACUUMが実行された回数、 不要領域の割合を収集

– 平均および最大の処理時間を表示可能

Page 58: あなたの知らないPostgreSQL監視の世界

58

一時ファイルの書き出し

• 大きなデータを処理しようとすると ディスクに一時ファイルを作成する。 – ソートやテーブル結合時のハッシュ生成 – work_memパラメータの大きさに依存

7

4

9

2

DISK

•  対象データを全てメモリに保持 •  メモリ上でクイックソートを実行

7

4

9

2

2

4

7

9

2

4

7

9

8

1

3

5

1

3

5

8

DISK DISK

・・・

【対象データ < 作業メモリ】 作業メモリ

【対象データ > 作業メモリ】 作業メモリ

•  データの一部をメモリに保持 •  メモリ上でソート実行 •  ソート結果をDISKに戻す

繰り返し

Page 59: あなたの知らないPostgreSQL監視の世界

59

一時ファイルの書き出し(標準機能)

• ログを確認 –  log_temp_filesパラメータを設定して出力

•  pg_stat_databaseビューで確認

2015-11-11 20:52:33 JST [7801] LOG: temporary file: path "base/pgsql_tmp/pgsql_tmp7801.1", size 53157 2015-11-11 20:52:33 JST [7801] STATEMENT: select * from pg_settings where name = 'log_temp_files';

postgres=# select datname,temp_files,temp_bytes from pg_stat_database where datname = 'testdb';

-[ RECORD 1 ]-------- datname | testdb temp_files | 1 temp_bytes | 14016512

Page 60: あなたの知らないPostgreSQL監視の世界

60

一時ファイルの書き出し(ツール活用)

•  pg_monzで一時ファイル書き出しを確認 – DB単位に書きだされたデータ量を収集 – 閾値を超過したらZabbixのトリガーで検知

•  pg_statsinfoで一時ファイル書き出しを確認 – DB単位に書きだされたファイル数、 データ量を収集

Page 61: あなたの知らないPostgreSQL監視の世界

61

腐ったミカンは除去しよう • 一握りの悪者が全体の足を引っ張る。 • 遅いSQLは早く見つけて撲滅しよう。

Page 62: あなたの知らないPostgreSQL監視の世界

62

遅いSQL(標準機能)

• スロークエリをログで確認 2015-11-11 19:47:48 JST [7619] LOG: duration: 145.893 ms statement: select count(*) from pgbench_accounts;

Page 63: あなたの知らないPostgreSQL監視の世界

63

遅いSQL(ツール活用)

•  auto_explainで遅いSQLの実行計画を 自動でログ記録

2015-11-11 19:47:48 JST [7619] LOG: duration: 92.204 ms plan: Query Text: select count(*) from pgbench_accounts; Aggregate (cost=29182.66..29182.67 rows=1 width=0) -> Seq Scan on pgbench_accounts (cost=0.00..26681.53 rows=1000453 width=0)

Page 64: あなたの知らないPostgreSQL監視の世界

64

遅いSQL(ツール活用)

•  pg_stat_statementsでデータベース全体への影響が大きいSQLを確認 – トータルの実行時間が長いSQL – 実行回数が多いSQL

postgres=# SELECT datname,SUBSTRING(query,1,40) AS query,calls, TRUNC(total_time::numeric,3) AS total_time FROM pg_stat_statements LEFT OUTER JOIN pg_database ON pg_stat_statements.dbid = pg_database.oid WHERE datname = 'testdb' ORDER BY total_time DESC LIMIT 5;

datname | query | calls | total_time ---------+-------------------------------------------------+-------+------------ testdb | UPDATE pgbench_accounts SET abalance = a | 12755 | 14088.258 testdb | select count(*) from pgbench_accounts; | 3 | 5740.594 testdb | SELECT c.oid AS relid, c.relnamespace, | 53 | 642.248 testdb | UPDATE pgbench_tellers SET tbalance = tb | 12755 | 386.210 testdb | UPDATE pgbench_branches SET bbalance = b | 12755 | 248.036

Page 65: あなたの知らないPostgreSQL監視の世界

65

遅いSQL(ツール活用)

• サーバログをpgBadgerで集計 – Perlスクリプトとして実装 – サーバログを指定して実行すると、ログを 分析したレポートをHTMLファイルで作成

– 永安さんの資料が詳しい。 •  pgBadgerでSQLログを分析する http://pgsqldeepdive.blogspot.jp/2012/12/pgbadgersql.html

Page 66: あなたの知らないPostgreSQL監視の世界

66

PostgreSQLのログについて考える

Page 67: あなたの知らないPostgreSQL監視の世界

67

なぜそのままではダメか? • ログをルーティングする機能がない。

– なんでも1つのログファイルに吐き出す。 – PostgreSQLサーバが起動できないような 深刻なエラーメッセージとスロークエリログが混在する。

• 深刻度/使い道が異なるものがごちゃまぜ。 – エラーレベルやカテゴリで分けられないので、ログから見たい情報を探すのが面倒

– grepするのが関の山。。。

Page 68: あなたの知らないPostgreSQL監視の世界

68

file_fdw •  FDW: 外部データラッパ

– DB外部のデータへ通常の表と同様にアクセス – 花田さんの資料が詳しい。

• 外部データラッパによるPostgreSQLの拡張http://www.slideshare.net/babystarmonja/postgre-sql-11764943

•  file_fdw: 外部ファイルをテーブル化 – サーバのファイルシステムにある データファイルにアクセス

– COPY FROMで読み込み可能なフォーマットに対応(CSV、タブ区切り等)

– 9.1からcontribとして配布されている。

Page 69: あなたの知らないPostgreSQL監視の世界

69

file_fdwでログを外部テーブル化 • CSVログを外部テーブル化してアクセス

testdb=# CREATE EXTENSION file_fdw; testdb=# CREATE SERVER pglog FOREIGN DATA WRAPPER file_fdw; testdb=# CREATE FOREIGN TABLE pglog (log_time timestamp(3) with time zone, testdb(# user_name text, database_name text, process_id integer, testdb(# connection_from text, session_id text, session_line_num bigint, testdb(# command_tag text, session_start_time timestamp with time zone, testdb(# virtual_transaction_id text, transaction_id bigint, error_severity text, testdb(# sql_state_code text, message text,detail text, hint text, testdb(# internal_query text, internal_query_pos integer, context text, testdb(# query text,query_pos integer, location text,application_name text testdb(# ) SERVER pglog testdb-# OPTIONS (filename '/var/lib/pgsql/9.4/data/pg_log/postgresql-Fri.csv', format 'csv'); testdb=# select log_time,user_name,database_name,process_id,error_severity,

message,application_name from pglog where message like 'duration%'; -[ RECORD 1 ]-------+------------------------------------------------------ log_time | 2015-11-06 08:33:31.528+00 user_name | postgres database_name | testdb process_id | 8962 error_severity | LOG message | duration: 5006.931 ms statement: select pg_sleep(5); application_name | psql

Page 70: あなたの知らないPostgreSQL監視の世界

70

file_fdwでログを外部テーブル化 • サーバログをSQL文で検索

– 絞込みや並べ替えが可能 • 深刻度,発生時刻,データベース,プロセスNo etc

– テーブルへのロード不要 • 最新のログデータにアクセスが可能 • データベースのサイズが膨らむ心配なし

• 複数ログファイルの検索は工夫が必要 – ローテーションによるログファイルの切替 – ファイル名を固定化(例:曜日単位)

•  postgresql-Sun.csv,postgresql-Mon.csv ... – 9.5から外部テーブルの継承をサポート

• 複数ログテーブルのパーティション化も可能に

Page 71: あなたの知らないPostgreSQL監視の世界

71

Fluentdで加工したログを収集 •  file_fdwで検索するにはこんな点が不足

– ログの種別を持っていない • スロークエリ,チェックポイント,デッドロックetc

– ログファイル毎に1テーブル • 複数サーバのログをまとめたい • 種別が違うログは分けて管理したい

– ログメッセージに含まれる値を使いたい • スロークエリのduration、statement

•  Fluentdで検索しやすい形にログを加工 – 詳しくはOSC 2015 Hokkaidoの資料を参照

http://www.ospn.jp/osc2015-do/pdf/OSC2015_do_tis.pdf

Page 72: あなたの知らないPostgreSQL監視の世界

72

Fluentd

•  Fluentdとは –  http://www.fluentd.org/ – 軽量でプラガブルなログ収集ツール – Apache License Version 2.0

•  Fluentdの特徴 – ログ管理を3つの層に分けて管理

• インプット、バッファ、アウトプット – 各層がプラガブルなアーキテクチャ

• 用途に応じたプラグインを追加するだけで使える

Page 73: あなたの知らないPostgreSQL監視の世界

73

Fluentdでログを収集する

PostgreSQL

Fluentd(td-agent)

DBサーバ

PostgreSQLサーバプロセス

PostgreSQLサーバログ(postgresql.csv)

PostgreSQL接続ライブラリ

DBサーバ

PostgreSQL

DBサーバ

Fluentd

PostgreSQL Fluentd

ログ集約サーバ

Fluentd(td-agent)

PostgreSQL

fluentdテーブルtag::Text � (me::Times

tampz �record::Jsonb �

・・・� ・・・� ・・・�

Page 74: あなたの知らないPostgreSQL監視の世界

74

収集したログをSQLで検索する

• スロークエリを検索(時間が長い10件) testdb=##SELECT time, record#>>'{hostname}' as host, record#>>'{duration}' as duration,

record#>>'{statement}' as statement FROM fluentd WHERE tag = 'pgsql.slow_query'

ORDER BY (record#>'{duration}') desc LIMIT 10; time | host | duration | statement ------------------------+---------+----------+--------------------- 2015-06-07 08:33:48+00 | pgsql02 | 2004.107 | select pg_sleep(2); 2015-06-07 02:25:08+00 | pgsql01 | 2003.866 | select pg_sleep(2); 2015-06-07 08:45:48+00 | pgsql03 | 2003.767 | select pg_sleep(2); 2015-06-07 02:25:10+00 | pgsql01 | 2003.621 | select pg_sleep(2); 2015-06-07 08:45:51+00 | pgsql03 | 2003.461 | select pg_sleep(2); 2015-06-07 08:33:51+00 | pgsql02 | 2003.376 | select pg_sleep(2); 2015-06-07 02:25:02+00 | pgsql01 | 2003.374 | select pg_sleep(2); 2015-06-07 08:33:54+00 | pgsql02 | 2003.247 | select pg_sleep(2); 2015-06-07 08:45:46+00 | pgsql03 | 2002.880 | select pg_sleep(2); 2015-06-07 02:25:05+00 | pgsql01 | 2002.092 | select pg_sleep(2);

Page 75: あなたの知らないPostgreSQL監視の世界

75

pg_monzでスロークエリを監視

pg_monzをカスタマイズすれば、 スロークエリの発生回数も監視できる

Page 76: あなたの知らないPostgreSQL監視の世界

76

まとめ

Page 77: あなたの知らないPostgreSQL監視の世界

77

監視の観点を理解しよう

• 救急患者レベル • レントゲンに怪しい影が、、レベル • 体力測定レベル • 腐ったミカン = 遅いSQL

Page 78: あなたの知らないPostgreSQL監視の世界

78

ツールをうまく組み合わせよう •  pg_monzは「監視」ツール

– 発生した問題に即座にアクションを起こす。 – 性能分析に使う情報「も」集められる。

•  pg_statsinfoは「性能分析」ツール – 過去時点の情報をひとまず保管しておき、 後でゆっくりと問題を分析する。

– 発生した問題に対するアクションは、 別の監視ツールに任せる。

•  PostgreSQLのサーバログ – 障害メッセージは監視ツールで素早く検出 – 後で分析するログはFluentdで収集

Page 79: あなたの知らないPostgreSQL監視の世界

79

pg_monz をよろしくおねがいします

• 入手先や使い方http://pg-monz.github.io/pg_monz/

• 問い合わせ – pg_monz ユーザーグループ[email protected]

• 試行環境を自動構築するAnsible Playbook等をGitHubから入手できます。 https://github.com/tech-sketch/pg_monz-trial

• フィードバックをお待ちしています。