Ubuntu版 PostgreSQL と コミュニティ版 PostgreSQLの違いのまとめ

Ubuntu版 PostgreSQL は、同一マシンに複数のデータベースクラスタを簡単に同居できるようにするため、コミュニティ版 PostgreSQLにはない、コマンドを提供しています。

* Ubuntu版 PostgreSQLでは、データベースクラスタを作成するときには、initdbコマンドの代わりに pg_createclusterコマンドを使用する。
* Ubuntu版 PostgreSQLでは、pg_ctl コマンドの代わりに pg_ctlclusterコマンドを使用する。
* Ubuntu版 PostgreSQLには、データベースクラスタの情報を表示する pg_lsclusters コマンドがある。
* Ubuntu版 PostgreSQLには、コミュニティ版にはない、データベースクラスタを削除するコマンドがある。

initdb, pg_ctl コマンド等がインストールされていないわけではないようです。/usr/lib/postgresql/14/bin/ フォルダに格納されていました。フルパス/usr/lib/postgresql/14/bin/pg_ctl で指定して、pg_ctl コマンドを実施すると、動作しました。

```
postgres@:~$Ubuntu /usr/lib/postgresql/14/bin/pg_ctl status -D /var/lib/postgresql/14/main
pg_ctl: server is running (PID: 861)
/usr/lib/postgresql/14/
bin/postgres "-D" "/var/lib/postgresql/14/main" "-c" "config_file=/etc/postgresql/14/main/postgresql.conf"
```

## pg_lsclusters コマンド

--help オプションで使い方を表示
```
postgres@~$ pg_lsclusters --help
Usage: /usr/bin/pg_lsclusters [-hjs]

Options:
  -h --no-header   Omit column headers in output
  -j --json        JSON output
  -s --start-conf  Include start.conf information in status column
     --help        Print help
```

pg_lsclusters コマンドでデータベースクラスタの情報を確認します。
```
postgres@:~$ pg_lsclusters
Ver Cluster Port Status Owner    Data directory              Log file
14  main    5432 online postgres /var/lib/postgresql/14/main /var/log/postgresql/postgresql-14-main.log
```

## PostgreSQLデータベース(データベースクラスタ)の制御

pg_ctlclusterコマンドの使い方を確認するため、--help オプションを指定したが・・・
```
postgres@~$ pg_ctlcluster --help
Unknown option: help
```
--help オプションがない。しょうがないので man コマンドで pg_ctlcluster の使い方を確認。
[pg_ctlclusterのman](https://manpages.ubuntu.com/manpages/trusty/en/man8/pg_ctlcluster.8.html)


```
pg_ctlcluster [options] cluster-version cluster-name action -- [pg_ctl options]

       where action = start|stop|restart|reload|promote
```

cluster-version、cluster-nameには、pg_lsclustersコマンドで表示された Ver 14, Cluster mainを指定します。

### PostgreSQLデータベースの状態を確認する

action に status を指定して、データベースの状態を確認します。　
```
postgres@:~$ pg_ctlcluster 14 main status
pg_ctl: server is running (PID: 868)
/usr/lib/postgresql/14/bin/postgres "-D" "/var/lib/postgresql/14/main" "-c" "config_file=/etc/postgresql/14/main/postgresql.conf"
```

### データベースクラスタの起動
action に start を指定して、データベースクラスタを起動します。

```
postgres@:~$ pg_ctlcluster 14 main start 
Warning: the cluster will not be running as a systemd service. Consider using systemctl:
  sudo systemctl start postgresql@14-main
```
pg_ctlcluster で起動すると警告がでました。systemctl コマンドを使用することを考えてください と表示されます。


```
postgres@:~$ pg_ctlcluster 14 main status
pg_ctl: server is running (PID: 4418)
/usr/lib/postgresql/14/bin/postgres "-D" "/var/lib/postgresql/14/main" "-c" "config_file=/etc/postgresql/14/main/postgresql.conf"
```

### データベースクラスタの停止
action に stop を指定して、データベースクラスタを停止します。


#### stopの主なオプション

|オプション|説明|
|--|--|
|-D データベースクラスタ名<br>--pgdata=データベースクラスタ名|対象となるデータベースクラスタを指定|
|-m シャットダウンモード|３つのシャットダウン方式のいずれかを指定する。|
|-W|シャットダウンの完了を待たずにコマンド発行元に制御を戻す。|
|-t 最大待ち時間|シャットダウンが完了するまでの待ち時間を指定する。指定がない場合は60秒になる|

#### シャットダウンモード

|シャットダウンモード|説明|
|--|--|
|f または fast|高速シャットダウン<br>デフォルトのモード<br>実行中の処理を中断し、クライアント接続を全て強制的に切断してからシャットダウンする。実行中のトランザクションはロールバックされ、実行される前に戻る|
|i または immediate|即時シャットダウン<br>実行中の処理を強制終了し、クライアント接続を全て強制的に切断してからシャットダウンする。次回起動時に回復処理を実行する|
|s または smart|スマートシャットダウン<br>全てのクライアント接続が切断されてからシャットダウンする。実行中の処理はシャットダウンの前に正常に完了される。|

#### fastとimmediateの違い
fastでは実行中のトランザクションを実行前の状態に戻すロールバックなどの処理を行ってからシャットダウンしますが、immediateは終了処理を行わずにサーバープロセス自体を停止する点で異なります。immediateはサーバのプロセスがクラッシュして停止したのと同じなので、次回起動時に回復処理を実行するためサーバに負荷がかかります。特にimmediateにする理由が無い場合は、fastでシャットダウンした方が良いです。

#### コマンド実施例

stop コマンドに オプションを何も指定しないで実行した場合、シャットダウンモードは fast で シャットダウンが完了するまでの最大待ち時間が 60秒となります。
```
postgres@:~$ pg_ctlcluster 14 main stop
postgres@:~$ pg_ctlcluster 14 main status
pg_ctl: no server running
```

### データベースクラスタの再起動
action に restart を指定して、データベースクラスタを再起動します。action に stop を実行したあと、startを実行することと同じです。

```
postgres@:~$ pg_ctlcluster 14 main status
pg_ctl: server is running (PID: 4751)
/usr/lib/postgresql/14/bin/postgres "-D" "/var/lib/postgresql/14/main" "-c" "config_file=/etc/postgresql/14/main/postgresql.conf"

postgres@:~$ pg_ctlcluster 14 main restart
Warning: the cluster will not be running as a systemd service. Consider using systemctl:
  sudo systemctl restart postgresql@14-main
postgres@:~$ pg_ctlcluster 14 main status
pg_ctl: server is running (PID: 4793)
/usr/lib/postgresql/14/bin/postgres "-D" "/var/lib/postgresql/14/main" "-c" "config_file=/etc/postgresql/14/main/postgresql.conf"
```

### 設定ファイルの再読込
action に reload を指定して、設定ファイルを再読込させます。

PostgreSQLサーバに「postgresql.conf」、「pg_hba.conf」(クライアント認証に関する設定をするためのファイル)などの設定ファイルの再読み込みを実行するサブコマンドです。(反映できないパラメータもあります。)
```
postgres@~$ pg_ctlcluster 14 main reload
```

### その他のactionについて
pg_ctlcluster コマンドには、kill コマンドがないようです。


```
postgres@:~$ pg_ctlcluster 14 main status
pg_ctl: server is running (PID: 4753)

postgres@~$ pg_ctlcluster 14 main kill KILL 4753
Error: Usage: /usr/bin/pg_ctlcluster <version> <cluster> <action> [-- <pg_ctl options>]
```

### データベースクラスタの作成

pg_createclusterコマンドのヘルプオプションで使い方を確認
```
# pg_createcluster \?
Usage: /usr/bin/pg_createcluster [options] <version> <cluster name> [-- <initdb options>]

Options:
  -u <uid>      cluster owner and superuser (default: 'postgres')
  -g <gid>      group for data files (default: primary group of owner)
  -d <dir>      data directory (default: 
                /var/lib/postgresql/<version>/<cluster name>)
  -s <dir>      socket directory (default: /var/run/postgresql for clusters
                owned by 'postgres', /tmp for other clusters)
  -l <dir>      path to desired log file (default:
                /var/log/postgresql/postgresql-<version>-<cluster>.log)
  --locale <encoding>
                set cluster locale (default: inherit from environment)
  --lc-collate/ctype/messages/monetary/numeric/time <locale>
                like --locale, but only set for a particular category
  -e <encoding> Default encoding (default: derived from locale)
  -p <port>     port number (default: next free port starting from 5432)
  --start       start the cluster after creating it
  --start-conf auto|manual|disabled
                Set automatic startup behaviour in start.conf (default: 'auto')
  --createclusterconf=file alternative createcluster.conf to use
  --environment=file alternative environment file to use
  <initdb options> other options to pass to initdb
```

cluster-version、cluster-name に14, test を指定してデータベースクラスタを作成。
```
$ pg_createcluster 14 test
Creating new PostgreSQL cluster 14/test ...
/usr/lib/postgresql/14/bin/initdb -D /var/lib/postgresql/14/test --auth-local peer --auth-host scram-sha-256 --no-instructions
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "ja_JP.UTF-8".
The default database encoding has accordingly been set to "UTF8".
initdb: could not find suitable text search configuration for locale "ja_JP.UTF-8"
The default text search configuration will be set to "simple".

Data page checksums are disabled.

fixing permissions on existing directory /var/lib/postgresql/14/test ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... Asia/Tokyo
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
Warning: systemd does not know about the new cluster yet. Operations like "service postgresql start" will not handle it. To fix, run:
  sudo systemctl daemon-reload
Ver Cluster Port Status Owner    Data directory              Log file
14  test    5433 down   postgres /var/lib/postgresql/14/test /var/log/postgresql/postgresql-14-test.log
```
ポート番号は、5433 で作成されたようです。

### データベースクラスタの削除 (pg_dropcluster)
pg_dropclusterは、データベースクラスタを削除するコマンドです。

ヘルプオプションで使用方法を確認
```
$ pg_dropcluster \?
Usage: /usr/bin/pg_dropcluster [--stop] <version> <cluster>
```

man コマンドで使い方を確認

[pg_dropclusterのman](https://manpages.ubuntu.com/manpages/trusty/man8/pg_dropcluster.8.html)


cluster-version、cluster-name に14, test を指定してデータベースクラスタを削除
```
$ pg_dropcluster --stop 14 test
Warning: stopping the cluster using pg_ctlcluster will mark the systemd unit as failed. Consider using systemctl:
  sudo systemctl stop postgresql@14-test
Warning: systemd was not informed about the removed cluster yet. Operations like "service postgresql start" might fail. To fix, run:
  sudo systemctl daemon-reload
```

### 参考情報
* [Ubuntu で PostgreSQL を使ってみよう(続編)](https://lets.postgresql.jp/documents/tutorial/ubuntu/4)
* [資料編：Ubuntu特有のPostgreSQL用コマンド](https://lets.postgresql.jp/documents/tutorial/ubuntu/5)