【DB】Postgresql-14のインストールから起動まで

# はじめに
OSS-DB の資格を取ろうと思ったので DB の勉強を始めました。
どうせ勉強するなら備忘として Qiita に投稿しようかなと。

今回は、VMWare Workstation 17 Player を使用し DB サーバを構築しました。
サーバの構築手順については割愛します。

OS は CentOS でバージョンは以下の通り。
```
[root@localhost ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
```

# Postgresql-14のインストールから起動まで
## PostgreSQL インストール
インストールから起動までの一連の流れを記載していきます。
今回は PostgreSQL-14 の手順になります。

### リポジトリパッケージのインストール
下記のコマンドを実行してリポジトリパッケージのインストールを行います。
`Complete!`と出力されれば OK

```
[root@localhost ~]# yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
```

### yum のアップデート
yum のアップデートを行います。
```
[root@localhost ~]# yum -y update
```

### 利用可能なパッケージを確認

現在利用可能なパッケージの一覧を取得します。
この中から好きなバージョンを選択します。
今回は、`postgresql14-server`にします。
```
[root@localhost ~]# yum list available | grep postgresql | grep server
postgresql-server.x86_64                  9.2.24-8.el7_9             updates
postgresql11-server.x86_64                11.20-1PGDG.rhel7          pgdg11
postgresql12-server.x86_64                12.15-1PGDG.rhel7          pgdg12
postgresql13-server.x86_64                13.11-1PGDG.rhel7          pgdg13
postgresql14-server.x86_64                14.8-1PGDG.rhel7           pgdg14
postgresql15-server.x86_64                15.3-1PGDG.rhel7           pgdg15
```

### インストール

先ほど確認したパッケージの中から、希望するバージョンをインストールします。
```
[root@localhost ~]# yum install -y postgresql14-server
```

### バージョン確認
インストール出来ているか確認します。
```
[root@localhost ~]# psql --version
psql (PostgreSQL) 14.8
```

### その他 確認
まずは postgres ユーザが存在するか確認
```
[root@localhost ~]# cat /etc/passwd | grep postgres
postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash
```

ホームディレクトリが`/var/lib/pgsql`になってますのでそこら辺も確認してみる。
所有者とグループが postgres になってますね。
```
[root@localhost ~]# ls -ld /var/lib/pgsql
drwx------. 3 postgres postgres 37 Jul 17 16:30 /var/lib/pgsql
```

## DB 起動
無事にインストールできたので DB を起動していこうと思います。

今回は`/var/lib/pgsql`配下にデータベースクラスタを作成するのではなく、
`/database`配下に作成してみようと思います。

### ディレクトリ作成
データベース領域のディレクトリを作成します。
```
[root@localhost ~]# mkdir /database
```

### ディスクのマウント
必要に応じて[コチラ](#20230718-追記) を参考に、作成した /database にディスクをマウントします。

### ディレクトリ作成
`/database/data`と`/database/backup`を作成
前者は、データベースクラスタとして利用。
後者は、データベースのバックアップで利用予定。
```
[root@localhost ~]# mkdir /database/{data,backup}
```

### 所有者、グループの変更
root で作成したため、postgres に変更しておきます。
```
[root@localhost ~]# chown -R postgres:postgres /database/
```

下記のようになっていれば OK
```
[root@localhost ~]# ls -ld /database/
drwxr-xr-x. 4 postgres postgres 32 Jul 17 16:39 /database/
[root@localhost ~]#
[root@localhost ~]# ls -la /database/
total 0
drwxr-xr-x.  4 postgres postgres  32 Jul 17 16:39 .
dr-xr-xr-x. 18 root     root     240 Jul 17 16:39 ..
drwxr-xr-x.  2 postgres postgres   6 Jul 17 16:39 backup
drwxr-xr-x.  2 postgres postgres   6 Jul 17 16:39 data
```

### データベースクラスタの作成
まずは postgres ユーザに変更
```
[root@localhost ~]# su - postgres
```

データベースクラスタの作成
`Success. You can now start the database server using:`と出力されれば OK
`bash: initdb: command not found...`と出力された場合は、[command not found](#command-not-found)を参照
```
[postgres@localhost ~]# initdb -D /database/data
```

### データベースクラスタ作成確認
きちんと作成されているか確認します。
```
[postgres@localhost ~]$ ls -al /database/data/
total 60
drwx------. 19 postgres root      4096 Jul 17 16:50 .
drwxr-xr-x.  4 postgres root        32 Jul 17 16:39 ..
drwx------.  5 postgres postgres    41 Jul 17 16:50 base
drwx------.  2 postgres postgres  4096 Jul 17 16:50 global
drwx------.  2 postgres postgres     6 Jul 17 16:50 pg_commit_ts
drwx------.  2 postgres postgres     6 Jul 17 16:50 pg_dynshmem
-rw-------.  1 postgres postgres  4789 Jul 17 16:50 pg_hba.conf
-rw-------.  1 postgres postgres  1636 Jul 17 16:50 pg_ident.conf
drwx------.  4 postgres postgres    68 Jul 17 16:50 pg_logical
drwx------.  4 postgres postgres    36 Jul 17 16:50 pg_multixact
drwx------.  2 postgres postgres     6 Jul 17 16:50 pg_notify
drwx------.  2 postgres postgres     6 Jul 17 16:50 pg_replslot
drwx------.  2 postgres postgres     6 Jul 17 16:50 pg_serial
drwx------.  2 postgres postgres     6 Jul 17 16:50 pg_snapshots
drwx------.  2 postgres postgres     6 Jul 17 16:50 pg_stat
drwx------.  2 postgres postgres     6 Jul 17 16:50 pg_stat_tmp
drwx------.  2 postgres postgres    18 Jul 17 16:50 pg_subtrans
drwx------.  2 postgres postgres     6 Jul 17 16:50 pg_tblspc
drwx------.  2 postgres postgres     6 Jul 17 16:50 pg_twophase
-rw-------.  1 postgres postgres     3 Jul 17 16:50 PG_VERSION
drwx------.  3 postgres postgres    60 Jul 17 16:50 pg_wal
drwx------.  2 postgres postgres    18 Jul 17 16:50 pg_xact
-rw-------.  1 postgres postgres    88 Jul 17 16:50 postgresql.auto.conf
-rw-------.  1 postgres postgres 28782 Jul 17 16:50 postgresql.conf
```

### ユニットファイルの修正
postgresql-14 を起動する際に使用するユニットファイルの設定を変更していきます。
まずは、root ユーザに戻ります。
```
[postgres@localhost ~]# exit
```

続いてユニットファイルの変更
```
[root@localhost ~]# vi /usr/lib/systemd/system/postgresql-14.service
```

修正箇所は以下の通り。
何を変更したかというと、環境変数`PGDATA`の値を変更してます。
PGDATA の値はデータベースクラスタのパスを定義します。

今回は initdb の際に`/database/data/`を指定しているので、そのパスに変更するわけです。
```
Environment=PGDATA=/var/lib/pgsql/14/data/			★ 修正前
Environment=PGDATA=/database/data/					★ 修正後
```

変更後は下記のような状態に。
```
[root@localhost ~]# cat /usr/lib/systemd/system/postgresql-14.service
# It's not recommended to modify this file in-place, because it will be
# overwritten during package upgrades.  It is recommended to use systemd
# "dropin" feature;  i.e. create file with suffix .conf under
# /etc/systemd/system/postgresql-14.service.d directory overriding the
# unit's defaults. You can also use "systemctl edit postgresql-14"
# Look at systemd.unit(5) manual page for more info.

# Note: changing PGDATA will typically require adjusting SELinux
# configuration as well.

# Note: do not use a PGDATA pathname containing spaces, or you will
# break postgresql-14-setup.
[Unit]
Description=PostgreSQL 14 database server
Documentation=https://www.postgresql.org/docs/14/static/
After=syslog.target
After=network-online.target

[Service]
Type=notify

User=postgres
Group=postgres

# Note: avoid inserting whitespace in these Environment= lines, or you may
# break postgresql-setup.

# Location of database directory
#Environment=PGDATA=/var/lib/pgsql/14/data/			★ 修正前
Environment=PGDATA=/database/data/					★ 修正後

# Where to send early-startup messages from the server (before the logging
# options of postgresql.conf take effect)
# This is normally controlled by the global default set by systemd
# StandardOutput=syslog

# Disable OOM kill on the postmaster
OOMScoreAdjust=-1000
Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
Environment=PG_OOM_ADJUST_VALUE=0

ExecStartPre=/usr/pgsql-14/bin/postgresql-14-check-db-dir ${PGDATA}
ExecStart=/usr/pgsql-14/bin/postmaster -D ${PGDATA}
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT

# Do not set any timeout value, so that systemd will not kill postmaster
# during crash recovery.
TimeoutSec=0

# 0 is the same as infinity, but "infinity" needs systemd 229
TimeoutStartSec=0

TimeoutStopSec=1h

[Install]
WantedBy=multi-user.target
```

### daemon-reload
ユニットファイル変更後は下記コマンドを実行します。
初回起動時は実行しなくても平気かも？
```
[root@localhost ~]# systemctl daemon-reload
```

### サービス起動
postgresql を起動します。
```
[root@localhost ~]# systemctl start postgresql-14
```

### 起動状態確認
正常に起動できているかを確認します。
`Active: active (running)`と出力されていれば OK
```
[root@localhost ~]# systemctl status postgresql-14
```

### DB接続
DBに接続してみます。まずはユーザ変更。
```
[root@localhost ~]# su - postgres
```

DB接続
```
[postgres@localhost ~]$ psql
psql (14.8)
Type "help" for help.

postgres=#
```

ログアウトは`\q`です。

# 追記

## 2023/7/17 追記

### postgresql-14 自動起動設定
上記の手順ですと、サーバの再起動時に DB が停止してしまいます。
postgresql-14 を自動起動にする場合は下記のコマンドを実行してください。
```
[root@localhost ~]# systemctl enable postgresql-14
Created symlink from /etc/systemd/system/multi-user.target.wants/postgresql-14.service to /usr/lib/systemd/system/postgresql-14.service.
```

念のため下記コマンドでも確認
`enabled`と出力されれば OK
```
[root@localhost ~]# systemctl is-enabled postgresql-14
```

### .bash_profile の修正
.bash_profile の内容を一部修正します。
修正しなくても起動などは問題なく出来ます。

まずは、postgres ユーザに変更
```
[root@localhost ~]# su - postgres
```

.bash_profile 編集
ユニットファイルの修正と似たような修正です。
修正前：`PGDATA=/var/lib/pgsql/14/data`
修正後：`PGDATA=/database/data`
```
[postgres@localhost ~]# vi ~/.bash_profile
```

修正後は下記のような感じ
```
[postgres@localhost ~]$ cat ~/.bash_profile
[ -f /etc/profile ] && source /etc/profile
# PGDATA=/var/lib/pgsql/14/data        ★ 修正前
PGDATA=/database/data                  ★ 修正後
export PGDATA
export PATH=/usr/pgsql-14/bin:$PATH
# If you want to customize your settings,
# Use the file below. This is not overridden
# by the RPMS.
[ -f /var/lib/pgsql/.pgsql_profile ] && source /var/lib/pgsql/.pgsql_profile
PS1='[\u@\h \W]\$'
```

以上

## 2023/07/18 追記
VMWareでディスクを追加できたので、追加したディスクをデータベース領域として使用します。

### ディスク確認
まずは追加したディスクをOSが認識できているかを確認する。
sdb が追加したディスク。まだマウントされておりません。
```
[root@localhost ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   20G  0 disk
tqsda1   8:1    0  300M  0 part /boot
tqsda2   8:2    0    2G  0 part [SWAP]
mqsda3   8:3    0 17.7G  0 part /
sdb      8:16   0   20G  0 disk
sr0     11:0    1 1024M  0 rom
```

ディスクにファイルシステムがあるかどうかを確認する。
出力に`data`だけが表示されている場合は、デバイスにはファイルシステムが存在していません。
```
[root@localhost ~]# file -s /dev/sdb
/dev/sdb: data
```

ファイルシステムを作成する。
```
[root@localhost ~]# mkfs -t xfs /dev/sdb
meta-data=/dev/sdb               isize=512    agcount=4, agsize=1310720 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=5242880, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
```

再度ディスクのファイルシステムを確認する。
今度はファイルシステムが`XFS`になっていることが確認できます。
```
[root@localhost ~]# file -s /dev/sdb
/dev/sdb: SGI XFS filesystem data (blksz 4096, inosz 512, v2 dirs)
```

マウントします。
```
[root@localhost ~]# mount /dev/sdb /database
```

マウントされているか確認します。
sdb のマウントポイントが /database になっているので OK
```
[root@localhost ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   20G  0 disk
tqsda1   8:1    0  300M  0 part /boot
tqsda2   8:2    0    2G  0 part [SWAP]
mqsda3   8:3    0 17.7G  0 part /
sdb      8:16   0   20G  0 disk /database
sr0     11:0    1 1024M  0 rom
```

ついでに /database の容量を調べる。
Available が 20GB ありそうなので OK
```
[root@localhost ~]# df
Filesystem     1K-blocks    Used Available Use% Mounted on
devtmpfs          481864       0    481864   0% /dev
tmpfs             497732       0    497732   0% /dev/shm
tmpfs             497732    8480    489252   2% /run
tmpfs             497732       0    497732   0% /sys/fs/cgroup
/dev/sda3       18555904 4929884  13626020  27% /
/dev/sda1         303780  195500    108280  65% /boot
tmpfs              99548      12     99536   1% /run/user/42
tmpfs              99548       0     99548   0% /run/user/0
/dev/sdb        20961280   32992  20928288   1% /database
```

ただ、このままだとサーバ再起動時にマウントされていない状態に戻ってしまうので、
起動時に自動マウントする設定を追加します。

ディスクの UUID を表示
`1d26f0c5-92f9-4094-9940-db62a98732a2`をコピーします。
```
[root@localhost ~]# blkid
/dev/sda1: UUID="c750867f-9e22-4d79-a2cf-79460c5f3372" TYPE="xfs"
/dev/sda2: UUID="675936fb-5c98-47e6-adff-78b404129196" TYPE="swap"
/dev/sda3: UUID="ad6eccd5-21b5-491b-af15-8d8a9b8dbe51" TYPE="xfs"
/dev/sdb: UUID="1d26f0c5-92f9-4094-9940-db62a98732a2" TYPE="xfs"
```

`/etc/fstab`の一番下に追加します。
UUID の内容は自身のディスクの ID にしてください。
それ以外は同じでとりあえず OK です。
```
[root@localhost ~]# vi /etc/fstab
[root@localhost ~]# cat /etc/fstab
UUID=ad6eccd5-21b5-491b-af15-8d8a9b8dbe51 /                       xfs     defaults        0 0
UUID=c750867f-9e22-4d79-a2cf-79460c5f3372 /boot                   xfs     defaults        0 0
UUID=675936fb-5c98-47e6-adff-78b404129196 swap                    swap    defaults        0 0
UUID=1d26f0c5-92f9-4094-9940-db62a98732a2 /database               xfs     defaults        0 0
```

再起動してもマウントされていれば OK です。


# エラー対応
手順の中でエラーが発生した個所の対処法を記載します。

## command not found
データベースクラスタ作成時に下記のエラーが発生した場合。
```
[postgres@localhost ~]$ initdb -D /database/data
bash: initdb: command not found...
```

### ユーザ変更
postgres ユーザに変更します。
```
su - postgres
```

### .bash_profile の修正
.bash_profile を修正します。
.bash_profile とはログインしたときに読み込まれる設定ファイルです。
```
vi ~/.bash_profile
```

どの行でもいいので下記を追加します。
```
export PATH=/usr/pgsql-14/bin:$PATH
```

追加後は以下のような感じです。
```
[postgres@localhost ~]$ cat ~/.bash_profile
[ -f /etc/profile ] && source /etc/profile
PGDATA=/var/lib/pgsql/14/data
export PGDATA
export PATH=/usr/pgsql-14/bin:$PATH			★追加
# If you want to customize your settings,
# Use the file below. This is not overridden
# by the RPMS.
[ -f /var/lib/pgsql/.pgsql_profile ] && source /var/lib/pgsql/.pgsql_profile
PS1='[\u@\h \W]\$ '
```

### .bash_profile の反映
設定しただけでは反映されないため、手動で反映させます。
```
source ~/.bash_profile
```

以上で完了なので、`initdb`のところからやり直しです。

# さいごに

最後までご覧いただきありがとうございました。

毎回気になるのですが、DBの構築ってインフラとアプリどちらの担当なんですかね？
私はインフラエンジニアですが、まだDBの構築はしたことないんですよねー。。

どちらにせよ、もしかしたら今後やることになるかもしれないので、
引き続き勉強は続けていこうと思います！