Oracle Linux 8にPostgreSQL 13をインストールしデータベースを作成する

## アジェンダ
1 はじめに
2 環境説明及び前提条件
3 PostgreSQL13インストール
4 PostgreSQL13へ接続
5 ロール作成
6 データベース作成
7 まとめ

## 1 はじめに
こんにちは、NTTデータ先端技術の陰です。
今回は、Oracle Cloud Infrastructure(OCI)で提供しているOracle Linux8でPostgreSQL13(PSQL13)をインストールしデータベースを作成する方法について紹介します。

## 2 環境説明及び前提条件
今回、作業を実施する環境情報及び前提条件は以下の通りです。

##### 環境情報
OSイメージ：Oracle-Linux-8.7
リージョン：ap-tokyo-1 (日本東部(東京))

##### 前提条件
①シェル・ターミナル・コンソールがセットアップされていること
②インスタンスが作成されていること
③インスタンスにSSH接続できること
④インスタンスからインタネットにアクセスできること

## 3 PostgreSQL13インストール
まず、PSQL13をインストールするために必要なPostgreSQLのリポジトリRPMをインストールします。
```:実行コマンド
$ sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
```

PostgreSQLのリポジトリをインストールした後、そのままPSQL13をインストールするとOS標準で入っているPostgreSQLモジュールとインストールしたリポジトリが競合してしまい、インストールパッケージが見つからずエラーが発生してしまいます。
```:エラーログ
Error: Unable to find a match: postgresql13-server
```

インストールしたリポジトリとOS標準のモジュールが競合しないようにOS標準のモジュールを無効化します。
```:実行コマンド
$ sudo dnf -qy module disable postgresql
```

次、PSQL13サーバをインストールします。
```:実行コマンド
$ sudo dnf install -y postgresql13-server
```

PSQLのバージョンを確認しインストールが無事完了していることを確認します。
```:実行コマンド&出力ログ
$ psql --version
psql (PostgreSQL) 13.9
```

PostgreSQLのインストールでは自動起動が無効になっていてデータベースも自動的に初期化されてない状態なのでインストールを完了するためにはデータベースを初期化するコマンドと自動起動を有効にするコマンドを実行する必要がありあす。
```:実行コマンド
$ sudo /usr/pgsql-13/bin/postgresql-13-setup initdb　 ←　　データベース初期化
$ sudo systemctl enable postgresql-13 　←　　PSQL13自動起動有効
$ sudo systemctl start postgresql-13 　←　　PSQL13起動
```

## 4 PostgreSQL13へ接続
PostgreSQLではデフォルトの接続認証方式としてpeer認証方式が設定されているので、PostgreSQLインストール時にデフォルトで作成されるOSユーザ（postgres）に切り替えることで接続することが可能です。

※peer認証方式とは、カーネルからクライアント上のOSユーザ名を取得し、それをデータベースユーザ名として使用することです。
※PostgreSQLインストール時にOSユーザ（postgres）とDBユーザ（postgres）がデフォルトで作成されます。

```:実行コマンド&出力ログ
$ su - postgres 
$ psql -U postgres
psql (13.9)
Type "help" for help.

postgres=# 
```

## 5 ロール作成
CREATE ROLEコマンドを使用し新しいロールを作成します。
オプションの数が多く色々設定することが可能ですが、今回はユーザ認証を行いログインできるようにロールを作成します。

※CREATE ROLEコマンドの詳細オプションついては以下のサイトで確認できます。
https://www.postgresql.jp/document/13/html/sql-createrole.html
```:実行コマンド
CREATE ROLE pgtest LOGIN PASSWORD 'pgtestのパスワード';
```

作成したロールでデータベースを作成するためにはスーパーユーザーか、 CREATEDB 権限を持っている必要があります。
```:実行コマンド
ALTER ROLE pgtest WITH SUPERUSER;
ALTER ROLE pgtest CREATEDB;
```
作成したロールに必要な権限を付与せず、CREATE DATABASEコマンドを実行すると以下のようなエラーが発生します。
```:エラーログ
ERROR:  permission denied to create database
```

## 6 データベース作成
CREATE DATABASEコマンドを使用し新しいデータベースを作成します。
オプションの数が多く色々設定することが可能ですが、今回は[5 ロール作成](#5-ロール作成)で作成したロール（pgtest）所有で日本語の入力ができるようにデータベースを作成します。

※CREATE DATABASEコマンドの詳細オプションについては以下のサイトで確認できます。
https://www.postgresql.jp/document/13/html/sql-createdatabase.html

```:実行コマンド
CREATE DATABASE pgtest WITH ENCODING='UTF8' LC_COLLATE='ja_JP.utf8' LC_CTYPE='ja_JP.utf8' OWNER=pgtest TEMPLATE=template0;
```

※日本語の入力ができるデータベースを作成しようとするとCREATE DATABASE時に日本語用のlocaleがインストールされてないことが原因でエラーが発生する場合があります。
```:エラーログ
ERROR:  invalid locale name: "ja_JP.utf8"
```
ロケールエラーが発生した場合は以下のリンクから対処法をご確認ください。
https://qiita.com/EumJinman/private/fee647cac84626be2214

CREATE DATABASEコマンド実行後、データベースが作成されていることを確認します。
```:実行コマンド&出力ログ
postgres=# \l
                                 List of databases
 Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-----------+----------+----------+-------------+-------------+------------------
pgtest    | pgtest   | UTF8     | ja_JP.utf8  | ja_JP.utf8  | 
postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
```
## 7 まとめ
今回は、Oracle Linux 8にPSQL13をインストールしデータベースを作成する方法について紹介しました。
PSQL13をインストールする際には、PSQL13をインストールするために用意したリポジトリRPMとOS標準で入っているPostgreSQLモジュールが競合してしまいエラーが発生しないようにPSQL13をインストールする前にOS標準のPostgreSQLモジュールを無効化する必要があることに注意してください。