DockerでPostgreSQL公式イメージを起動する際にスロークエリ出力を有効にする

2020-04-11Docker,PostgreSQL

はじめに

特にDocker ComposeでPostgreSQL公式イメージを利用しようと思った場合に、postgresql.conf を編集せずにスロークエリログの出力を有効にする方法について紹介します。

検証環境

$ docker --version
Docker version 19.03.8, build afacb8b

$ docker-compose --version
docker-compose version 1.25.4, build 8d51620a

普通にPostgreSQLを起動した場合

起動

まずは普通にPostgreSQLを起動してみます。

PostgreSQLを起動する場合、通常は docker run -d というように -d オプションを付与してデーモン起動させます。

ただし、今回はログを意図的に表示させたいこともあり -d オプションを付けずに起動します。
PostgreSQLイメージでは以下の環境変数3つは起動に必須です。

  • POSTGRES_PASSWORD
  • POSTGRES_USER
  • POSTGRES_DB
$ docker run --rm --name=postgres_test \
  -e POSTGRES_PASSWORD=testpass \
  -e POSTGRES_USER=testuser \
  -e POSTGRES_DB=testdb \
  postgres:9.6.17

アクセスして設定を確認

起動したコンテナ上のPostgreSQLデータベースに psql コマンドを使ってログインしてみます。
docker run したターミナルとは別に、ターミナルを立ち上げます。(WindowsならコマンドプロンプトあるいはPowerShellになるのかな?)

$ docker \
  exec -i -t postgres_test \
  psql -h localhost -U testuser testdb

psql (9.6.17)
Type "help" for help.

testdb=# show all;
                name            |              setting               |                                                          description
...(一部抜粋)...
 log_min_duration_statement     | -1                                 | Sets the minimum execution time above which statements will be logged.
...(一部抜粋)...

psql 上で show all; コマンドを実行するとデータベースの設定情報が出力されます。
log_min_duration_statement という設定パラメータの値が、スロークエリログ出力対象の設定値となります。
SQLの実行に log_min_duration_statement の設定値以上の時間がかかった場合、ログ出力されます。
ただし -1 の場合にはスロークエリログは出力されません。

処理に3秒以上かかった場合にログ出力させるようにする

log_min_duration_statement の設定値を変更するには postgresql.conf に設定を追記するという方法がありますが、これだとPostgreSQL公式イメージを利用した新たなDockerイメージを作らなければなりません。
Dockerfileを作成することなくログ出力させるには、 docker run 実行時のコマンドに引数を追加してやります。

起動

$ docker run --rm --name=postgres_test \
  -e POSTGRES_PASSWORD=testpass \
  -e POSTGRES_USER=testuser \
  -e POSTGRES_DB=testdb \
  postgres:9.6.17 \
  -c log_min_duration_statement=2000

アクセスして設定を確認

docker run したターミナルとは別に、ターミナルを立ち上げ、 psql で接続して設定を確認してみます。

$ docker \
  exec -i -t postgres_test \
  psql -h localhost -U testuser testdb

psql (9.6.17)
Type "help" for help.

testdb=# show all;
                name                 |                 setting                  |                                                          description

----
...(省略)...
 log_min_duration_statement          | 2s                                       | Sets the minimum execution time above which statements will be logged.
...(省略)...

先程は -1 だった設定値が 2s となっていることがわかります。
SQL実行に2秒以上かかった場合にログに出力される設定になったはずです。

動作確認

正しく動作するか動作を確認してみます。

pg_sleep() というPostgreSQLの関数を利用することで意図的に実行時間を操作できます。
引数はsleepする時間を秒単位で指定します。

まずは1秒スリープさせてみます。

testdb=# select pg_sleep(1);
 pg_sleep
----------

(1 row)

docker run コマンドを実行しているターミナルには変化はないはずです。
次に2秒スリープさせてみます。

testdb=# select pg_sleep(2);
 pg_sleep
----------

(1 row)

docker run させているターミナルに以下の1行が追記されているはずです。

LOG:  duration: 2005.038 ms  statement: select pg_sleep(2);

処理に時間がかかったSQL文がログに出力されていることがわかります。

Docker Composeで利用する場合

最後に Docker Comopose で利用する場合を想定した docker-compose.yml の記述方法を掲載しておきます。

---
version: "3"
services:
  postgresql:
    image: postgres:9.6.17
    environment:
      POSTGRES_PASSWORD: testpass
      POSTGRES_USER: testuser
      POSTGRES_DB: testdb
    ports:
      - 5432:5432
    command: -c log_min_duration_statement=250

ひとこと

Webページの速度改善などに参考にしていただければ幸いです。

2020-04-11Docker,PostgreSQL