KITA Eng.

北海道でサーバー技術者として歩み出したひとが綴るblog。

PostgreSQLで実行中のクエリを確認する方法-9.1までと9.2以降-

PostgreSQLで現在実行されているSQLは、pg_stat_activityってViewで確認することができる。

一番簡単に表示させるなら、

postgres=# SELECT * FROM pg_stat_activity;

でOK。

PostgreSQL 9.5.0での実行例(9.1まではちょっと表示が変わります。後述)
datid | datname  |  pid  | usesysid | usename  | application_name | client_addr | client_hostname | client_port |         backend_start         |          xact_start           |          query_start          |         state_change          | waiting | state  | backend_xid | backend_xmin |              query
-------+----------+-------+----------+----------+------------------+-------------+-----------------+-------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+---------+--------+-------------+--------------+---------------------------------
 12411 | postgres | 11192 |       10 | postgres | psql             |             |                 |          -1 | 2016-01-09 15:34:28.559856+09 | 2016-01-09 15:35:08.508961+09 | 2016-01-09 15:35:08.508961+09 | 2016-01-09 15:35:08.508963+09 | f       | active |             |          661 | select * from pg_stat_activity;
(1 row)

ってな感じで出ます。項目が多すぎて見にくいです。

クエリが大量に実行されているわけじゃないという前提なら、拡張表示に切り替えればよいので、PostgreSQLのメタコマンド\xを使いましょう。

PostgreSQL 9.5.0での実行例
postgres=# \x
Expanded display is on.

postgres=# select * from pg_stat_activity;
-[ RECORD 1 ]----+--------------------------------
datid            | 12411
datname          | postgres
pid              | 11192
usesysid         | 10
usename          | postgres
application_name | psql
client_addr      |
client_hostname  |
client_port      | -1
backend_start    | 2016-01-09 15:34:28.559856+09
xact_start       | 2016-01-09 15:38:53.004232+09
query_start      | 2016-01-09 15:38:53.004232+09
state_change     | 2016-01-09 15:38:53.004234+09
waiting          | f
state            | active
backend_xid      |
backend_xmin     | 661
query            | select * from pg_stat_activity;

が、大抵の場合、実行中のクエリを確認するときって、長く居座っているやつとか、暴走しているクエリを確認するときが多いと思われるので、pidqueryquery_startあたりでしょう。これぐらいに表示情報を絞れば、拡張表示なしで実行中クエリの一覧が見やすい感じで出るでしょう。

ということで、SQL文をちょっと改善します。

postgres=# SELECT pid, query_start, substr(query, 0, 80) AS query FROM pg_stat_activity WHERE state='active' ORDER BY query_start;
  • 必要なpidqueryquery_startを抜き出すようにします。
  • queryが長いときはqueryで画面いっぱいになるのも見づらいので、substr()関数を使ってqueryの最初の80文字分だけを取り出す。ASで項目名をqueryにしといて見栄えよく(!?)しておく。
  • queryが実行された時間の順番でソートして表示する。
  • aciveなクエリだけに絞って表示
PostgreSQL 9.5.0での実行例
postgres=# SELECT pid, query_start, substr(query, 0, 80) AS query FROM pg_stat_activity WHERE state='active' ORDER BY query_start;
  pid  |          query_start          |                                     substr
-------+-------------------------------+---------------------------------------------------------------------------------
 11192 | 2016-01-09 15:49:21.064259+09 | SELECT pid, query_start, substr(query, 0, 80) FROM pg_stat_activity WHERE state
(1 row)

queryの最初の80文字にしているのは、自分の環境だとそのぐらいの長さだとちょうど折り返されずに表示されて、見やすいからです。この数字は各々の環境に合わせて変えると快適と思われます。AS queryは別になくたっていいんですが、項目名がちゃんとなってたほうが素敵でしょ?っていう自己満足です。

で、ここまでPostgreSQL 9.5.0での実行例でご紹介しましたが、構築したのが結構前の環境だとPostgreSQLの環境が9.1以前の環境もまだまだ動いているのではないでしょうか。pg_stat_activityの項目名が9.2から変更されたようで、上で紹介した改善版SQL文がうまく動くのは、PostgreSQL 9.2以降となってます。

Postgresql 9.1.19で、pg_stat_activityを確認してみると。
postgres@hostname:~$ psql -p 5435
psql (9.5.0, server 9.1.19)
Type "help" for help.

postgres=# \x
Expanded display is on.

postgres=# select * from pg_stat_activity;
-[ RECORD 1 ]----+--------------------------------
datid            | 11951
datname          | postgres
procpid          | 9694
usesysid         | 10
usename          | postgres
application_name | psql
client_addr      |
client_hostname  |
client_port      | -1
backend_start    | 2016-01-09 15:19:22.71923+09
xact_start       | 2016-01-09 15:19:28.293887+09
query_start      | 2016-01-09 15:19:28.293887+09
waiting          | f
current_query    | select * from pg_stat_activity;

となっていて、pidprocpidquerycurrent_querystatusという項目がない、という状況です。activeな奴だけに絞れませんが、、、以下のようなSQL文で実行するしかなさそうです。

PostgreSQL 9.1.19での実行例
postgres=# SELECT procpid, query_start, substr(current_query, 0, 80) AS query FROM  pg_stat_activity ORDER BY query_start;
 procpid |          query_start          |                                      query
---------+-------------------------------+---------------------------------------------------------------------------------
    9694 | 2016-01-09 16:07:19.574144+09 | SELECT procpid, query_start, substr(current_query, 0, 80) AS query FROM pg_stat
(1 row)

以下のページを参考にさせてもらって、確認をしようと思ったら古い環境でできなかったので、気がついたのでした。些細なことですが、走り出しの人にとってはちょっとはまるかもなところです。ご注意を!

qiita.com