Ubuntu 20.04 LTS へ do-release-upgrade した後に Postgresql 10から12にアップグレードした話(pg_upgradecluster編)

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. はじめに

一昨年、以下のような記事を書きました。

https://qiita.com/ynott/items/80b1cdce52d7b6442573

これはこれで操作的には問題ないのですが、もう少し簡単な方法ってないのかな？と思って調べてみたら、以下のような記事を見つけました。

[pauloxnet – Upgrading PostgreSQL from version 11 to 12 on Ubuntu 20\.04 \(Focal Fossa\)](https://www.paulox.net/2020/04/24/upgrading-postgresql-from-version-11-to-12-on-ubuntu-20-04-focal-fossa/)

::: note warn
この方法は、Ubuntu特有のPostgresqlのアップグレード方法なので、その他のLinuxディストリビューションでは利用できません
:::

簡単に言うと`pg_upgradecluster`というコマンドを使ってPostgresql 11から12へアップグレードします。

# 1. Ubuntu で do-relesae-upgradeしました。

アップグレード後は以下のようになりました。
Postgresql 10と12がインストールされています。

```io
$ dpkg -l grep postgresql\*
要望=(U)不明/(I)インストール/(R)削除/(P)完全削除/(H)保持
| 状態=(N)無/(I)インストール済/(C)設定/(U)展開/(F)設定失敗/(H)半インストール/(W)トリガ待ち/(T)トリガ保留
|/ エラー?=(空欄)無/(R)要再インストール (状態,エラーの大文字=異常)
||/ 名前                      バージョン             アーキテクチ 説明
+++-=========================-======================-============-=====================================================
ii  grep                      3.4-1                  amd64        GNU grep, egrep and fgrep
ii  postgresql                12+214ubuntu0.1        all          object-relational SQL database (supported version)
ii  postgresql-10             10.19-0ubuntu0.18.04.1 amd64        object-relational SQL database, version 10 server
ii  postgresql-12             12.9-0ubuntu0.20.04.1  amd64        object-relational SQL database, version 12 server
ii  postgresql-client         12+214ubuntu0.1        all          front-end programs for PostgreSQL (supported version)
ii  postgresql-client-10      10.19-0ubuntu0.18.04.1 amd64        front-end programs for PostgreSQL 10
ii  postgresql-client-12      12.9-0ubuntu0.20.04.1  amd64        front-end programs for PostgreSQL 12
ii  postgresql-client-common  214ubuntu0.1           all          manager for multiple PostgreSQL client versions
ii  postgresql-common         214ubuntu0.1           all          PostgreSQL database-cluster manager
```

# 2. 動いているクラスターを確認する

`pg_lsclusters`コマンドで動作しているディレクトリを確認します。

```io
$ pg_lsclusters
Ver Cluster Port Status Owner    Data directory              Log file
10  main    5432 online postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log
12  main    5433 online postgres /var/lib/postgresql/12/main /var/log/postgresql/postgresql-12-main.log
```

psでも10と12が両方動いているのが分かります。

```io
$ ps axwwu | grep postgres
postgres    1024  0.0  0.7 213964 29492 ?        Ss   17:45   0:00 /usr/lib/postgresql/12/bin/postgres -D /var/lib/postgresql/12/main -c config_file=/etc/postgresql/12/main/postgresql.conf
postgres    1025  0.0  0.7 246740 28812 ?        S    17:45   0:00 /usr/lib/postgresql/10/bin/postgres -D /var/lib/postgresql/10/main -c config_file=/etc/postgresql/10/main/postgresql.conf
postgres    1074  0.0  0.1 214092  6620 ?        Ss   17:45   0:00 postgres: 12/main: checkpointer
postgres    1075  0.0  0.1 214104  6124 ?        Ss   17:45   0:00 postgres: 12/main: background writer
postgres    1076  0.0  0.2 213964 10284 ?        Ss   17:45   0:00 postgres: 12/main: walwriter
postgres    1077  0.0  0.2 214528  8616 ?        Ss   17:45   0:00 postgres: 12/main: autovacuum launcher
postgres    1078  0.0  0.1  68464  5092 ?        Ss   17:45   0:00 postgres: 12/main: stats collector
postgres    1079  0.0  0.1 214528  6792 ?        Ss   17:45   0:00 postgres: 12/main: logical replication launcher
postgres    1125  0.0  0.1 246848  6600 ?        Ss   17:45   0:00 postgres: 10/main: checkpointer process
postgres    1126  0.0  0.1 246740  6120 ?        Ss   17:45   0:00 postgres: 10/main: writer process
postgres    1127  0.0  0.2 246740 10244 ?        Ss   17:45   0:00 postgres: 10/main: wal writer process
postgres    1128  0.0  0.1 247288  7412 ?        Ss   17:45   0:00 postgres: 10/main: autovacuum launcher process
postgres    1129  0.0  0.1 101788  5556 ?        Ss   17:45   0:00 postgres: 10/main: stats collector process
postgres    1130  0.0  0.1 247156  7268 ?        Ss   17:45   0:00 postgres: 10/main: bgworker: logical replication launcher
```


# 3. 動いているPostgresql 12を止める

現在動いているPostgresql 12は、Postgresql 10が入っているためにアップグレードする用としてインストールされたものですが、データは移行されておらず、db initだけ実行されている状態です。データは入っていないのですが、Postgresql 10からの移行時に邪魔になるので削除します。

```io
$ sudo pg_dropcluster 12 main --stop
```

削除された確認する

```io
$ pg_lsclusters
Ver Cluster Port Status Owner    Data directory              Log file
10  main    5432 online postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log
```

バージョン 10だけになりました。
ディレクトリも10だけ残っています。

```io
$ ls -la /var/lib/postgresql/
合計 28
drwxr-xr-x  3 postgres postgres 4096  1月  2 18:24 .
drwxr-xr-x 55 root     root     4096  1月  2 16:26 ..
-rw-------  1 postgres postgres  980  1月  2 18:20 .bash_history
-rw-------  1 postgres postgres 2901 12月 17 12:00 .psql_history
-rw-------  1 postgres postgres 3776 12月  3 18:45 .viminfo
drwxr-xr-x  3 postgres postgres 4096 10月 22  2020 10
-rw-rw-r--  1 postgres postgres  246 12月  3 18:45 exec_command.sh
```

# 4. Postgresql 10のデータをバックアップする

念のためにPostgresql 10のデータをバックアップしておきます。

```io
$ sudo -i
$ su - postgres
$ pg_dumpall -f /tmp/postgres10-all.dump
$ ls -la /tmp/postgres10-all.dump
-rw-rw-r-- 1 postgres postgres 482059  1月  2 18:28 /tmp/postgres10-all.dump
```

# 5. `pg_upgradecluster`でアップグレードする

以下のコマンドでアップグレードします。

```
sudo pg_upgradecluster 10 main
```

`sudo pg_upgradecluster -v 12 10 main` でも良いようです。

[資料編：Ubuntu特有のPostgreSQL用コマンド \| Let's POSTGRES](https://lets.postgresql.jp/documents/tutorial/ubuntu/5)

<details><summary>アップグレード時の出力ログ</summary><div>

```
$ sudo pg_upgradecluster 10 main
Stopping old cluster...
Restarting old cluster with restricted connections...
Notice: extra pg_ctl/postgres options given, bypassing systemctl for start operation
Creating new PostgreSQL cluster 12/main ...
/usr/lib/postgresql/12/bin/initdb -D /var/lib/postgresql/12/main --auth-local peer --auth-host md5 --encoding UTF8 --lc-collate ja_JP.UTF-8 --lc-ctype ja_JP.UTF-8
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "ja_JP.UTF-8".
initdb: could not find suitable text search configuration for locale "ja_JP.UTF-8"
The default text search configuration will be set to "simple".

Data page checksums are disabled.

fixing permissions on existing directory /var/lib/postgresql/12/main ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... Asia/Tokyo
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

Success. You can now start the database server using:

    pg_ctlcluster 12 main start

Ver Cluster Port Status Owner    Data directory              Log file
12  main    5433 down   postgres /var/lib/postgresql/12/main /var/log/postgresql/postgresql-12-main.log

Starting new cluster...
Notice: extra pg_ctl/postgres options given, bypassing systemctl for start operation
Roles, databases, schemas, ACLs...
 set_config
------------

(1 row)

 set_config
------------

(1 row)

 set_config
------------

(1 row)

 set_config
------------

(1 row)

Fixing hardcoded library paths for stored procedures...
Upgrading database onlyoffice...
Analyzing database onlyoffice...
Fixing hardcoded library paths for stored procedures...
Upgrading database template1...
Analyzing database template1...
Fixing hardcoded library paths for stored procedures...
Upgrading database postgres...
Analyzing database postgres...
Copying old configuration files...
Copying old start.conf...
Copying old pg_ctl.conf...
Stopping target cluster...
Stopping old cluster...
Disabling automatic startup of old cluster...
Configuring old cluster to use a different port (5433)...
Starting target cluster on port 5432...

Success. Please check that the upgraded cluster works. If it does,
you can remove the old cluster with
    pg_dropcluster 10 main

Ver Cluster Port Status Owner    Data directory              Log file
10  main    5433 down   postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log
Ver Cluster Port Status Owner    Data directory              Log file
12  main    5432 online postgres /var/lib/postgresql/12/main /var/log/postgresql/postgresql-12-main.log

```

</div></details>

# 6. アップグレードされたか確認する

再度、pg_lsclustersコマンドを実行してアップグレードされたか確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/70ed16ef-cf18-71f9-9092-3becbcd68402.png)

10がdownで12がonlineなので移行できているようです。
psコマンドでも確認してみます。

```io
$ ps axwwu | grep postgres
postgres    5308  0.0  0.7 213964 29496 ?        Ss   18:30   0:00 /usr/lib/postgresql/12/bin/postgres -D /var/lib/postgresql/12/main -c config_file=/etc/postgresql/12/main/postgresql.conf
postgres    5310  0.0  0.1 214088  6724 ?        Ss   18:30   0:00 postgres: 12/main: checkpointer
postgres    5311  0.0  0.1 214104  6096 ?        Ss   18:30   0:00 postgres: 12/main: background writer
postgres    5312  0.0  0.2 213964 10332 ?        Ss   18:30   0:00 postgres: 12/main: walwriter
postgres    5313  0.0  0.2 214660  8792 ?        Ss   18:30   0:00 postgres: 12/main: autovacuum launcher
postgres    5314  0.0  0.1  68596  5868 ?        Ss   18:30   0:00 postgres: 12/main: stats collector
postgres    5315  0.0  0.1 214528  7132 ?        Ss   18:30   0:00 postgres: 12/main: logical replication launcher
user        5785  0.0  0.0   4572   732 pts/0    S+   18:35   0:00 grep --color=auto postgres
```

問題なさそうです。

# 7. アプリケーションの挙動を確認して古いPostgresqlのClusterを削除する

```io
sudo pg_dropcluster 10 main
```

削除されたのを確認する

```io
$ pg_lsclusters
Ver Cluster Port Status Owner    Data directory              Log file
12  main    5432 online postgres /var/lib/postgresql/12/main /var/log/postgresql/postgresql-12-main.log
```

古いパッケージも削除します。

```io
sudo apt-get purge postgresql-10 postgresql-client-10
```

# 8. まとめ

pg_dumpallしてインポートするよりも簡単に移行する事ができました。


# 9. Postgresql 13から15にアップグレードした話を書きました

Ubuntu 22.04 LTS で Postgresql 13から15にアップグレードした話(pg_upgradecluster編) - Qiita

https://qiita.com/ynott/items/ca130c4b70533a91d3d3