gihyo.jp
事象分析
- パフォーマンス低下の前兆のログは必ずしもERRORやWARNINGではない
- でも何でもかんでもログ出力すると負荷が大きい
- サービス環境以外でログレベルを変える等の対策を検討する
テーブル統計情報の取得
- システム、初めは元気だったが稼働しているうちに遅くなりがち
pg_stats
に保存される統計情報を定期的に保存しておくとよい
クエリ統計情報の取得
postgres=# SELECT * FROM pg_stat_user_functions;
funcid | schemaname | funcname | calls | total_time | self_time
--------+------------+----------+-------+------------+-----------
(0 rows)
pg_stat_statements
- こちらは拡張モジュールなので
CREATE EXTENSION
で有効化する必要がある
CREATE EXTENSION pg_stat_statements;
postgres=# SELECT * FROM pg_stat_statements;
userid | dbid | queryid | query | calls | total_time | min_time | max_time | mean_time | stddev_time | rows | shared_blks_hit | shared_blks_read | shared_blks_dirtied | shared_blks_written | local_blks_hit | local_blks_read | local_blks_dirtied | local_blks_written | temp_blks_read | temp_blks_written | blk_read_time | blk_write_time
--------+-------+----------------------+-------------------------------------+-------+--------------------+--------------------+--------------------+--------------------+-------------+------+-----------------+------------------+---------------------+---------------------+----------------+-----------------+--------------------+--------------------+----------------+-------------------+---------------+----------------
10 | 13408 | -1739183385080879393 | create extension pg_stat_statements | 1 | 7.3282 | 7.3282 | 7.3282 | 7.3282 | 0 | 0 | 852 | 129 | 53 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
10 | 13408 | -3725811799635485246 | SHOW shared_preload_libraries | 1 | 0.011 | 0.011 | 0.011 | 0.011 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
10 | 13408 | -7520291481456088499 | select count(*) from tbl | 1 | 194.11110000000002 | 194.11110000000002 | 194.11110000000002 | 194.11110000000002 | 0 | 1 | 0 | 66372 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
10 | 13408 | 1930089032433548407 | SELECT * FROM pg_stat_statements | 1 | 0.0752 | 0.0752 | 0.0752 | 0.0752 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
(4 rows)
システムリソース情報の取得
事象分析の流れ
- 情報を取得する
- 問題の再現方法
- 発生時の状況
- 設定ファイル
- データベースのサイズ・運用期間
- 事象を分析する
- 原因を絞り込む
- チューニングを実施して効果を測定する
- 影響を評価する
- 何かしら副作用がある
- インデックスを作成したらメンテナンスコストが上がる
- 統計情報の精度を上げたために取得に時間がかかる
- etc.
- システム全体として妥当であるか評価する
スケールアップ
- 丁寧にチューニングするのではなく、札束で殴るという選択肢
【事例1】SSDに置き換えが有効なケース
- PostgreSQLはHDDへのランダムアクセスが最もコストが高いと想定している
- デフォルトの基準値は seq:random = 1:4
#seq_page_cost = 1.0 # measured on an arbitrary scale
#random_page_cost = 4.0 # same scale as above
- SSDではseqとrandomで性能差がほとんどないので1:1に近づける
- ランダムアクセスはいつ発生するか
- インデックススキャン
- パラレルスキャン
- 宣言的パーティショニング
- コスト基準値の設定をサボると、インデックススキャンのほうが実際には速いのに、ランダムアクセスのコストが過大に見積もられ、シーケンシャルスキャンが選択されてしまったりする
【事例2】メモリ容量の拡張が有効なケース
- PostgreSQLではディスクI/Oが支配的
- 共有バッファを大きくし、リレーションのデータを多く展開することで…
- ディスクI/Oを抑えられる
- メモリ管理のCPU負荷は上がる
- LinuxならばHugePage設定もあわせてチューニングしよう
- 1ページあたりの容量を増やす = ページテーブルは小さくなる = メモリ管理のCPU負荷抑えられる