PostgreSQL 16導入メモ

# はじめに
PostgreSQLをChatGPTのretriveとして使ってみたかったのと、その環境でpgvectorを検証するため、ConoHa VPSにPostgreSQL16.1をソースからコンパイルし、導入した際の備忘録です。
パッケージではなく、ソースで導入した背景としては、なるべく最新のバージョンを利用したかった為です。
また、特記事項なき場合は作業用の一般ユーザーでコマンド実行します。

# ディレクトリ構成
- ソース
```/usr/local/src```
- バイナリ他
```/usr/local/pgsql161/```
- データ
```/data/pgdata161/```
- ログ
```/var/log/pglog161/```

# 前提パッケージの導入
PostgreSQL16をコンパイルして導入するために、必要になったパッケージです。
libsystemdはsystemdサービスとしてPostgreSQLを登録したかった為、libicuはPostgreSQL16から標準となったICUロケールに対応させるために導入しました。
```
sudo apt install libsystemd-dev build-essential libreadline-dev zlib1g-dev libicu-dev pkgconf
```

# Linuxアカウント・グループの追加
今後、ソースからビルドし、アプリケーションの導入をする際は、/usr/local/srcを利用していこうと思うのですが、rootでコンパイルなどをしたくないため、システム管理用のユーザーグループを作成ました。

```shell:rootで実施
groupadd -g 2000 sysadm
usermod -G sysadm <ユーザー名>
chgrp sysadm /usr/local/src/
chgrp 755 /usr/local/src/
```

またPostgreSQLを管理・実行するユーザー及びグループも作成しました。
```shell:rootで実施
groupadd -g 1234 postgres
adduser postgres -uid 1234 --gid 1234
Adding user `postgres' ...
Adding new user `postgres' (1234) with group `postgres' ...
Creating home directory `/home/postgres' ...
Copying files from `/etc/skel' ...
New password: 任意のパスワードを指定
Retype new password: 任意のパスワードを入力
passwd: password updated successfully
Changing the user information for postgres
Enter the new value, or press ENTER for the default
        Full Name []: 
        Room Number []: 
        Work Phone []: 
        Home Phone []: 
        Other []: 
Is the information correct? [Y/n] Y
```

# 導入
■ソース取得・展開
wgetコマンドでソースを取得し、展開します。
```
cd /usr/local/src
wget https://ftp.postgresql.org/pub/source/v16.1/postgresql-16.1.tar.bz2
tar xvf postgresql-16.1.tar.bz2
```
■コンパイルフラグ設定
configureコマンドでPostgreSQLのコンパイル時に有効無効を設定するコンパイルフラグを指定します。
他の設定は```./configure --help```で表示されます。
```
cd postgresql-16.1
./configure --prefix=/usr/local/pgsql161 --with-systemd
```
エラーメッセージが表示されないことを確認します。
■コンパイルと導入
```
make -j2
sudo make install
```
エラー無くコンパイルされ、インストールされたことを確認します。
■データ用ディレクトリの準備
```
mkdir -p /data/pgdata161
chown postgres.postgres /data/pgdata161
chmod 700 /data/pgdata161
mkdir -p /var/log/pglog161/
chown postgres.postgres /var/log/pglog161/
chmod 700 /var/log/pglog161/
```
■PostgreSQL DBセットアップ
PostgreSQL管理ユーザーにスイッチし、DBのセットアップを行います。
まずは、PostgreSQL関連のコマンドを実行できるように環境変数をプロファイルに追加します。
```
sudo su - postgres
vi .profile
--下記の行を一番最後に追加します
export PATH=/usr/local/pgsql161/bin:$PATH:
--保存して閉じます
source .profile
```
DBの初期化を行います。
no-localeオプションはDBの初期ロケールに操作している環境のロケールが継承されないようにするための指定です。
```shell:postgresユーザーで実施
initdb --no-locale -D /data/pgdata161/
```
エラーが無いことを確認します。
次に、PostgreSQLの設定ファイルを編集します。
主にログ出力先とその内容の設定です。
```
cd /data/pgdata161
cp -p postgresql.conf postgresql.conf.org
vi postgresql.conf
--下記の行を編集します
logging_collector = on
log_directory = '/var/log/pglog161'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log
log_rotation_size = 0
log_line_prefix = '%m [%p] ' 
--保存して閉じます
```
postgresユーザーからログアウトし、元のユーザーに戻ります。
■systemdサービス定義ファイルの作成
下記の内容でsystemdサービス定義ファイルを作成します。
```shell:/lib/systemd/system/postgresql.service
[Unit]
Description=PostgreSQL16.1 database server
Documentation=man:postgres(1)
 
[Service]
Type=notify
User=postgres
ExecStart=/usr/local/pgsql161/bin/postgres -D /data/pgdata161/
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
TimeoutSec=0
 
[Install]
WantedBy=multi-user.target
```
■systemdサービスから起動
```shell
sudo systemctl daemon-reload
sudo systemctl start postgresql
```
下記のコマンドでサービスの稼働状況を確認します
```shell
sudo systemctl status postgresql
● postgresql.service - PostgreSQL16.1 database server
     Loaded: loaded (/lib/systemd/system/postgresql.service; disabled; vendor preset: enabled)
     Active: active (running) since Sat 2024-01-06 12:45:29 JST; 4s ago
       Docs: man:postgres(1)
   Main PID: 271102 (postgres)
      Tasks: 7 (limit: 1012)
     Memory: 15.8M
        CPU: 33ms
     CGroup: /system.slice/postgresql.service
             ├─271102 /usr/local/pgsql161/bin/postgres -D /data/pgdata161/
             ├─271103 "postgres: logger " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
             ├─271104 "postgres: checkpointer " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
             ├─271105 "postgres: background writer " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
             ├─271107 "postgres: walwriter " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
             ├─271108 "postgres: autovacuum launcher " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
             └─271109 "postgres: logical replication launcher " "" "" "" "" "" "" "" "" "" "" "" "" ""

Jan 06 12:45:29 XXX-XXX-XXX-XXX systemd[1]: Starting PostgreSQL16.1 database server...
Jan 06 12:45:29 XXX-XXX-XXX-XXX postgres[271102]: 2024-01-06 12:45:29.833 JST [271102] LOG:  redirecting log output to logging collector process
Jan 06 12:45:29 XXX-XXX-XXX-XXX postgres[271102]: 2024-01-06 12:45:29.833 JST [271102] HINT:  Future log output will appear in directory "/var/log/pglog161".
Jan 06 12:45:29 XXX-XXX-XXX-XXX systemd[1]: Started PostgreSQL16.1 database server.
```
# 動作確認
psqlコマンドで初期に作成されているデータベースを確認します。
```shell:postgresユーザーで実施
psql -l
                                                   List of databases
   Name    |  Owner   | Encoding  | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules |   Access privileges   
-----------+----------+-----------+-----------------+---------+-------+------------+-----------+-----------------------
 postgres  | postgres | SQL_ASCII | libc            | C       | C     |            |           | 
 template0 | postgres | SQL_ASCII | libc            | C       | C     |            |           | =c/postgres          +
           |          |           |                 |         |       |            |           | postgres=CTc/postgres
 template1 | postgres | SQL_ASCII | libc            | C       | C     |            |           | =c/postgres          +
           |          |           |                 |         |       |            |           | postgres=CTc/postgres
(3 rows)
```
PostgreSQLのpostgresユーザーにパスワードを指定します。
```
psql -U postgres
psql (16.1)
Type "help" for help.

postgres=# \password postgres
Enter new password for user "postgres": 
Enter it again: 

postgres=# \q
```
再度パスワードを必須にしてログインを確認します。
```
psql -U postgres -W
Password: 
psql (16.1)
Type "help" for help.

postgres=# 
```

# PostgreSQLセキュリティ設定変更
初期状態ではパスワード無しでログインできてしまいますので、pg_hba.confの設定を変更し、パスワードが要求されるようになるように変更します。
```shell:postgresユーザーで実行
cd /data/pgdata191
cp -p pg_hba.conf pg_hba.conf.org
vi pg_hba.conf
---下記内容を編集(UNIX domainソケットとlocal接続をtrustからpasswordに変更)
# "local" is for Unix domain socket connections only
local   all             all                                     password
# IPv4 local connections:
host    all             all             127.0.0.1/32            password
# IPv6 local connections:
host    all             all             ::1/128                 password
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     trust
host    replication     all             127.0.0.1/32            trust
host    replication     all             ::1/128                 trust
---保存して閉じる
```
PostgreSQLをリロードします。
```shell
sudo systemctl reload postgresql
```
再度接続確認をします。
```shell:postgresユーザーで実行
psql -U postgres
Password for user postgres: 
psql (16.1)
Type "help" for help.
```