PostgreSQL サーバの起動と停止

<br>
<br>

起動方法がいろいろありすぎて混乱したのでまとめました。
大別すると以下の通りです。

1. OS のデーモン管理コマンドから起動する方法
    1. macOS の場合 ... `brew services` コマンド
    2. Ubuntu の場合 ... `service` コマンド
    3. Windows10 の場合 ... `net` コマンド
2. PostgreSQL のコマンドから起動する方法
    1. `postgres` コマンド
    2. `pg_ctl` コマンド

<br>
<br>


## はじめに

### 〇 コマンドのまとめ

以下の通りです。

```
#
# 1. OS のデーモン管理コマンドから、起動する方法
#


# 1.1. macOS の場合
# 起動
brew services start postgresql

# 停止
brew services stop postgresql

# 再起動
# なし pg_ctl で再起動する。


# 1.2. Ubuntu の場合
# 起動
sudo service postgresql start

# 停止
sudo service postgresql stop

# 再起動
# なし pg_ctl で再起動する。


# 1.3. Windows の場合
#   お使いのパソコンの CPU、PostgreSQL のバージョンによって
#   末尾の -x64-12 は変わってきます。ここでは
#   パソコンの CPU が 64 bit で
#   PostgreSQL のバージョンが 12 の場合
# 起動
net start postgresql-x64-12

# 停止
net stop postgresql-x64-12

# 再起動
# なし pg_ctl で再起動する。
```
```
#
# 2.  PostgreSQL のコマンドから、起動する方法
#


# 2.1. postgres コマンド
# 起動
postgres -D 設定ファイルへのパス

# 停止
# なし pg_ctl で停止する。

# 再起動
# なし pg_ctl で再起動する。


# 2.2. pg_ctl コマンド
# 起動
pg_ctl -D 設定ファイルへのパス start

# 停止
pg_ctl -D 設定ファイルへのパス stop

# 再起動
pg_ctl -D 設定ファイルへのパス restart
```

<br>

### 〇 設定ファイルへのパス

「設定ファイルへのパス」の書式は、以下のような物です。

```
# 1) macOS の場合
postgres -D /usr/local/var/postgres

# 2) Ubuntu で PostgreSQL 10 の場合
#   PostgreSQL のバージョンによって、ファイルパスが変わります。
postgres -D /etc/postgresql/10/main

# 3) Windows10 で PostgreSQL 12 の場合
#   PostgreSQL のバージョンによって、ファイルパスが変わります。
#   クォーテーション ' またはダブルクーテーション " で囲む必要があります。
postgres -D "C:/Program Files/PostgreSQL/12/data"
```



<br>
<br>



## 1. デーモン管理コマンドから、起動する方法

1. Windows10 の場合 ... `net` コマンド
2. macOS の場合 ... `brew services` コマンド
3. Ubuntu の場合 ... `service` コマンド



### 1.1. macOS の場合

`sudo brew install postgresql` でインストールしたものと仮定します。

`sudo brew services` コマンドから操作できます。

```
sudo brew services start postgresql
sudo brew services stop postgresql
```

<br>

### 1.2. Ubuntu の場合

`sudo apt install postgresql` でインストールしたものと仮定します。

`service` コマンドから操作できます。

```
sudo service postgresql start
sudo service postgresql stop
```

> [serviceコマンド - 日経クロステック](https://xtech.nikkei.com/it/article/COLUMN/20070605/273739/)
> 指定されたLinuxデーモン（サービス）の起動や停止，ステータスの確認を実行する。実際はシェル・スクリプトであり，/sbin/serviceをテキスト・エディタなどで開くとスクリプトの中身を確認できる。

<br>

`/etc/init.d/postgres` からも操作できます。下に掲載した記事によると実行している内容は service コマンドと同じで service コマンドを使った方が便利だそうです。

```
sudo /etc/init.d/networking start
sudo /etc/init.d/networking stop
```

> [/etc/init.d ディレクトリ - Linux豆知識 184](https://linuc.org/study/knowledge/514/)
> 「/etc/init.d」は、デーモンなどの起動スクリプトが設置されているディレクトリです。

<div></div>

> [serviceコマンド - 日経クロステック](https://xtech.nikkei.com/it/article/COLUMN/20070605/273739/)
> また，serviceコマンドの中では，/etc/init.d（/etc/rc.d/init.d）にあるサービス・スクリプトを実行しているだけである。そのため，/etc/init.d以下のスクリプトを直接実行してもserviceコマンドと同じ作業ができるが，全サービスのステータスを表示したりパスをいちいち入力する必要がないため，**コマンドとして使ったほうが便利である**。

<br>

### 1.3. Windows の場合

公式サイトから専用のインストーラをダウンロードしてインストールしたものと仮定します。

* [Windows Installers - PostgreSQL](https://www.postgresql.org/download/windows/)

`net` コマンドから操作できます。

```
net start postgresql-x64-12
net stop postgresql-x64-12
# 「管理者として実行」する必要があります。
```

* [図入りでわかりやすい How can I start PostgreSQL on Windows? - Stackoverflow](https://stackoverflow.com/questions/36629963/how-can-i-start-postgresql-on-windows#answer-53062239)

GUI, Services.msc からも操作できます。サービス名がわからない場合、この GUI, Services.msc で確認して `net` コマンドを打つとよいかなと思います。

```
# x64-12 という文字はお使いの環境によって、異なります。
Type here to search > Services.msc > postgresql-x64-12 > 右クリック > プロパティ > General タブ > start をクリック
Type here to search > Services.msc > postgresql-x64-12 > 右クリック > プロパティ > General タブ > stop をクリック
```

* [図入りでわかりやすい Stop PostgreSQL from starting on Windows? - StackExchange](https://serverfault.com/questions/311565/stop-postgresql-from-starting-on-windows#answer-796520)

<br>

### 〇 デーモンってなに？

上記では便宜上、デーモンを管理する `brew services`, `service`, `net` コマンドをまとめて「デーモン管理コマンド」と呼ぶことにしました。

* [デーモン - 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word11000.html)

デーモンは英語で書くと daemon になります。10 年くらい昔は、メールの宛先を間違えると This mail was sent from the mailer daemon. 的なメッセージを受け取っていました。この「メーラーだえもん」ってなんだろうって思いながら、メールを書いていました。

最初は **「OS のデーモン管理コマンドから、起動する方法」をオススメしたいです。** なぜなら、大抵の場合、OS が提供する「デーモン管理コマンドを経由してから、起動する方法」が、「PostgreSQL のコマンドから、起動する方法」よりも簡単に起動できるからです。これは以下２つの理由からです。詳細は後述します。

1. PostgreSQL の設定ファイルが、どこに保存されているか分からないから。
2. `postgres` コマンド, `pg_ctl` コマンドへのパスが通っていないから。

* [パスを通す - 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word18470.html)


<br>
<br>




## 2. 直接 PostgreSQL から、起動する方法

以下の２種類が用意されています。

1. `postgres` コマンド
2. `pg_ctl` コマンド

<!--

〇 起動できない場合

`postgres` コマンドや `pg_ctl` コマンドから起動できない場合があります。後述する管理ソフト `service`, `brew services`, `net` から起動すると上手く動くケースがあるようです。そちらから、起動を試みてください。

  -->


### 〇 -D オプション

-D オプションには `設定ファイルへのパス` を記述します。

> [postgres -D datadir](https://www.postgresql.org/docs/12/app-postgres.html)
> Specifies the file system location of the database configuration files. See Section 19.2 for details.
 
> [pg_ctl -D datadir]()
> Specifies the file system location of the database configuration files. If this option is omitted, the environment variable PGDATA is used.


### 〇 設定ファイルへのパスの確認方法

以下の SQL コマンドで確認できます。

```
SHOW data_directory;
```

デーモン管理コマンドから起動していてかつ `pg_read_all_settings` という権限が付与されたユーザ（正確にはロールというらしいですが）で psql コマンドを使ってサーバに接続できる場合に使えます。使いどころは、あまりないかもしれませんが。

<!--
（知らなかったら psql コマンドを使えないので、あまり意味のない知識ですが。OS と同時に PostgreSQL サーバを起動する設定をいれていた場合は、この方法を使って確認することができます。）。

`設定ファイルへのパス` は OS や PostgreSQL のバージョンによって異なります。いくつか例を示します。Windows10 の場合は、クォーテーション `"` で括る必要があります。

|OS|PostgreSQL|設定ファイルへのパス|
|:--:|:--:|:--:|
|macOS|10.12|/usr/local/var/postgres|
|Ubuntu|10.12|/var/lib/postgresql/10/main|
|Windows10|12.2|"C:/Program Files/PostgreSQL/12/data"|

  -->


### 〇 postgres や pg_ctl が使えない場合

`psql` コマンドは使えるのに、そのほかの主だったコマンド、例えば `postgres` コマンドや　`pg_ctl` コマンドが使えないことがあります。

`postgres` コマンドや　`pg_ctl` コマンドが使えない原因として、パスが通っていない可能性があります。この症状の対策として、自分の環境では以下のようなパスを通しました。

```
# macOS の場合
/usr/local/opt/postgresql@10.12/bin

# Ubuntu の場合
/usr/lib/postgresql/10/bin/

# Windows10 の場合
C:\Program Files\PostgreSQL\12\bin

# PostgreSQL のバージョンごとにパスが変化することに
# 留意してください。
```


最初は、OS ごとにコマンドの体系が異なるのかなと、とんでもない勘違いしていました。

* [pg_ctl: command not found, what package has this command? - Ask Ubuntu](https://askubuntu.com/questions/385416/pg-ctl-command-not-found-what-package-has-this-command)
* [WSL にて postgres コマンドが使えない。 - teratail](https://teratail.com/questions/172133)


もし分からなければ、そのようなケースでは、最初は無理をせず、起動と停止は上記のデーモン管理コマンドから行えば良いのかなと思います。


### 〇 疑問

`psql` だけは、特別扱いして PostgreSQL がインストールされたときに使えるようにパスを通してくれるのに、なんで他のコマンドはインストールしたときに使えるようにパスを自動的に追加してくれないのでしょうか？

パスを通すと大量にコマンドを登録することになります。

```
$ ls /usr/lib/postgresql/10/bin/
clusterdb   dropuser           pg_basebackup   pg_dumpall      pg_resetwal  pg_test_fsync   pgbench     reindexdb
createdb    initdb             pg_controldata  pg_isready      pg_restore   pg_test_timing  postgres    vacuumdb
createuser  oid2name           pg_ctl          pg_receivewal   pg_rewind    pg_upgrade      postmaster  vacuumlo
dropdb      pg_archivecleanup  pg_dump         pg_recvlogical  pg_standby   pg_waldump      psql
$
```

不用意にパスを追加して、すでに導入されているコマンドと名前が被ってしまい、障害が発生するような事態を避けるために、自動でパスを全部追加するのは避けたということなのでしょうか。パスを追加する場合は自己責任で注意してやってくださいね、という思いがあるのでしょうか。Docker のようにコマンドを階層化してくれていたらよかったのですが。




### 〇 postgres と pg_ctl の違い

pg_ctl コマンドは postgres コマンドのラッパらしいです。

> postgresプログラムには、この他にも多くのコマンドラインオプションを指定することができます。 詳細はpostgresマニュアルページと後述の第19章を参照してください。こうしたシェル構文は長くなりがちです。そのため、 pg_ctl **ラッパ** プログラムが提供されていて、いくつかのタスクを単純化しています。 
> [18.3. データベースサーバの起動](https://www.postgresql.jp/document/11/html/server-start.html)

大抵の場合は、ラッパの方が機能が制限されるような気がします。なぜならラッパは「複雑なものを簡単に使えるようにしておいたよ」という類（たぐい）のものなので、簡単にする分、機能は削ぎ落とされてしまうからです。

* [ラッパ - 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word191.html)



ただ、今回の「PostgreSQL サーバの起動と停止方法まとめ」という観点から見ると `pg_ctl` コマンドは、「起動」だけではなく「停止」も「再起動」もでき、`postgres` コマンドよりも機能が豊富です。`postgres` コマンドは「停止」や「再起動」の機能は、提供されていません。

ドキュメントによると `pg_ctl` は `postgres` コマンドのラッパとのことなので `postgres` コマンドも「停止」や「再起動」があるのかな、と思ったのですが、まだ見つけられないでいます。

また `pg_ctl` と `postgres` コマンドの関係、使い分けは、正直わかりません。現状とりあえず `postgres` コマンドには停止 stop がないので `pg_ctl` で統一しています。


### 〇 疑問

コマンドを使えないままにしていて大丈夫なのでしょうか？困ることがなければ、そのままにしておいても、大丈夫かなと思っています。稀にサンプルコードで、ユーザの作成削除、データベースの作成削除などのデータベースの簡単な操作を、上記のコマンドで書いた説明を見かけす。しかし、その程度であれば psql から操作を行えばよいかなと思います。

```
# これらのコマンドが使えなくても...
createdb
dropdb
createuser
dropdb

# psql でサーバにログインして操作できる。
CREATE DATABASE 
DROP DATABASE
CREATE USER 
DROP USER
```

なぜ、このように２種類のコマンドがあるかは `createuser` コマンドを題材にして teratail に書きました。

* [[PostgreSQL] createuserコマンドの-Uについて - teratail](https://teratail.com/questions/265138#reply-379734)

<br>
<br>

## おわりに
以上になります。ありがとうございました。


<br>
<br>