postgresql 9.6 から 14.6 に移行した際のメモ

# 環境・背景

- OS: CentOS7
- DB: Postgresql 9.6
もともとのPostgresql9.6は、yumを使用してインストールしました。

この環境に Postgresql 14.6 をインストールし、既存のDB等を移行したい。

# Postgresql 14.6 のインストール

## yum リポジトリの追加

`yum search`で探してみましたが、見つけられる最新版はv13だったため、v14を取得するためのリポジトリを追加します。

```
$ sudo yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
```

## インストール

```
$ sudo yum -y install postgresql14-server postgresql14-contrib
```

## 初期化

ちなみに、必要かどうかは検証していませんが、ここから先は postgres ユーザーで行っています。

```
$ su - postgres

$ /usr/pgsql-14/bin/initdb -D /var/lib/pgsql/14/data/
```

# 移行開始

## v9.6サービス停止

``` bash
$ sudo systemctl stop postgresql-9.6.service
```

## アップグレード開始！

```
$ /usr/pgsql-14/bin/pg_upgrade -b /usr/pgsql-9.6/bin/ -B /usr/pgsql-14/bin/ -d /var/lib/pgsql/9.6/data/ -D /var/lib/pgsql/14/data/
```

### ところが

エラーが出ました。どうやらログインのセキュリティ設定に問題がある模様。

```
Checking cluster versions                                   ok

ソケット"/var/lib/pgsql/.s.PGSQL.50432"上でのサーバーへの接続に失敗しました: fe_sendauth: no password supplied

以下のコマンドで起動した移行元postmasterに接続できませんでした:
"/usr/pgsql-9.6/bin/pg_ctl" -w -l "pg_upgrade_server.log" -D "/var/lib/pgsql/9.6/data" -o "-p 50432 -b  -c listen_addresses='' -c unix_socket_permissions=0700 -c unix_socket_directories='/var/lib/pgsql'" start
失敗しました、終了しています
```

### 設定を変更して再実行

v9.6 の設定ではmd5パスワード認証を指定しているところ、認証を外して trust にしてやらないと pg_upgrade がエラーになるらしいので、設定を変更します。

- /var/lib/pgsql/9.6/data/pg_hba.conf

``` text
# "local" is for Unix domain socket connections only
local   all             all                                     trust 
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 trust 
```

改めて `pg_upgrade` を実行すると、別のエラーが出ました。

```
Checking for presence of required libraries                 致命的

旧の環境で、新の環境にはないローダブルライブラリを参照しています。
これらのライブラリを新の環境に追加するか、もしくは旧の環境から
それらを使っている関数を削除してください。 問題のライブラリの一覧は、
以下のファイルに入っています:
    loadable_libraries.txt

失敗しました、終了しています
```

`loadable_libraries.txt`を確認し、記述されている必要なライブラリをv14環境に追加します。

### 必要なライブラリをv14環境に追加

v14 のサービスを起動します。

``` bash
$ sudo systemctl start postgresql-14
```

今回は `pgcrypto`が不足していたので、追加します。
```
$ psql
# create extension pgcrypto;
CREATE EXTENSION
# \q
```

v14 のサービスを停止します。

``` bash
$ sudo systemctl stop postgresql-14
```

## 改めてアップグレード開始

``` bash
$ /usr/pgsql-14/bin/pg_upgrade -b /usr/pgsql-9.6/bin/ -B /usr/pgsql-14/bin/ -d /var/lib/pgsql/9.6/data/ -D /var/lib/pgsql/14/data/
```

```
リレーション"ほげほげテーブル"のコピー中にエラー: ファイル"コピー先ディレクトリ"に書けませんでした: デバイスに空き領域がありませ ん
失敗しました、終了しています
```

ほげええ

管理者に仮想マシンの容量を拡張してもらうまで中断じゃ中断


## 再開そして完了

- initDBをやり直してv14の環境を再構築します。
- 途中まで進んだupgrade作業の結果作成されたファイルやディレクトリを削除します。
（残ったままpg_upgradeするとエラーになりますが、表示される問題のディレクトリを都度削除して再実行。を繰り返しました）

```
$ /usr/pgsql-14/bin/pg_upgrade -b /usr/pgsql-9.6/bin/ -B /usr/pgsql-14/bin/ -d /var/lib/pgsql/9.6/data/ -D /var/lib/pgsql/14/data/

整合性チェックを実行しています。
-----------------------------
Checking cluster versions                                   ok
Checking database user is the install user                  ok
Checking database connection settings                       ok
Checking for prepared transactions                          ok
Checking for system-defined composite types in user tables  ok
Checking for reg* data types in user tables                 ok
Checking for contrib/isn with bigint-passing mismatch       ok
Checking for user-defined encoding conversions              ok
Checking for user-defined postfix operators                 ok
Checking for incompatible polymorphic functions             ok
Checking for tables WITH OIDS                               ok
Checking for invalid "sql_identifier" user columns          ok
Checking for invalid "unknown" user columns                 ok
Creating dump of global objects                             ok
Creating dump of database schemas
                                                            ok
Checking for presence of required libraries                 ok
Checking database user is the install user                  ok
Checking for prepared transactions                          ok
Checking for new cluster tablespace directories             ok

この後pg_upgradeが失敗した場合は、続ける前に新しいクラスタを
initdbで再作成する必要があります。

アップグレードを実行しています。
------------------
Analyzing all rows in the new cluster                       ok
Freezing all rows in the new cluster                        ok
Deleting files from new pg_xact                             ok
Copying old pg_clog to new server                           ok
Setting oldest XID for new cluster                          ok
Setting next transaction ID and epoch for new cluster       ok
Deleting files from new pg_multixact/offsets                ok
Copying old pg_multixact/offsets to new server              ok
Deleting files from new pg_multixact/members                ok
Copying old pg_multixact/members to new server              ok
Setting next multixact ID and offset for new cluster        ok
Resetting WAL archives                                      ok
Setting frozenxid and minmxid counters in new cluster       ok
Restoring global objects in the new cluster                 ok
Restoring database schemas in the new cluster
                                                            ok
ユーザーリレーションのファイルをコピーしています
                                                            ok
Setting next OID for new cluster                            ok
Sync data directory to disk                                 ok
Creating script to delete old cluster                       ok
Checking for hash indexes                                   ok
Checking for extension updates                              ok

アップグレードが完了しました
----------------
オプティマイザーの統計情報は、pg_upgrade では転送されません。
新サーバーを起動した後、以下のコマンドを実行することを検討してください:
    /usr/pgsql-14/bin/vacuumdb --all --analyze-in-stages

このスクリプトを実行すると、旧クラスタのデータファイル ./delete_old_cluster.shが削除されます:

```

アップグレードが完了しました！指示された通り新サーバーを起動します

``` bash
$ systemctl start postgresql-14
```

指示された通り、統計情報の算出を行います。

```
$ su - postgres
# /usr/pgsql-14/bin/vacuumdb --all --analyze-in-stages
```

完了！

あとは `/var/lib/pgsql/14/data/postgresql.conf`や`/var/lib/pgsql/14/data/pg_hba.conf`を編集して外部からの接続を許可して再起動して、接続確認をして移行完了です。
そのあとで旧環境（v9.6）を消すのがいいと思います。私はいろいろあってしばらく残しておきますが。

以上です。


# 参考資料

[PostgreSQL を CentOS にインストールするには](https://qiita.com/tom-sato/items/e1903cb974fb6c6d5664)
[PostgreSQL 14.5文書 pg_upgrade](https://www.postgresql.jp/document/14/html/pgupgrade.html)