【Mastodon】pg_repackでインスタンス無停止のDB不要領域削除

わたしは地元の情報を共有するローカルSNSとして**「[十日町市のMastodon](https://tokamstdn.jp/)」**というインスタンスを運用しています。

また、個人開発のWebアプリ**「[まちかどルート](https://machiroute.herokuapp.com)」**と連動させているMastodonインスタンス**「[アナザーギルド](https://another-guild.com/)」**も管理しています。

ここでは、それらに**pg_repack**という拡張機能をインストールしたときのメモを残します。

# インスタンスの環境

* さくらのクラウド
* CentOS 7.7.1908
* Mastodon v3.0.1
* PostgreSQL 12.0

# pg_repackとは

PostgreSQLの拡張機能として使えます。

こちら↓で詳しく解説されています。

**運用で役立つツールpg_repackのご紹介**
https://qiita.com/bwtakacy/items/3be7a3e1540ccef7c9e3

要は、データの書き込みや削除を繰り返すうちに膨らんでしまったDBをきれいに整頓することで、ストレージの空き容量を増やすことにつながります。

しかもPostgreSQL標準の`VACUUM`と違ってMastodonインスタンスを停止させずに実行できることが特徴です。

MastodonというSNSは、WordPressのように自分のサーバーにインストールして好きなように運用できますが、そのぶん自己責任でいろいろな保守をしなければいけません。

pg_repackはPostgreSQL 9.6.15のときから愛用していて、自分にとって有用な保守ツールになっています。

# 旧バージョンの削除

まず、古いバージョンのPostgreSQLがインストールされていないかどうかを確認します。

```console
# rpm -qa | grep postgres
```

わたしの場合、PostgreSQL 9.6.15がサーバーに残っていたせいで、以前インストールしていた旧バージョンのpg_repackが邪魔をして現PostgreSQL 12.0でうまく動作しませんでした。

もし上記コマンドで旧バージョンのPostgreSQLが残っていることがわかったら

```console
# rpm -e postgresql96-contrib-9.6.15-1PGDG.rhel7.x86_64
# rpm -e postgresql96-devel-9.6.15-1PGDG.rhel7.x86_64
# rpm -e postgresql96-server-9.6.15-1PGDG.rhel7.x86_64
# rpm -e postgresql96-9.6.15-1PGDG.rhel7.x86_64
# rpm -e postgresql96-libs-9.6.15-1PGDG.rhel7.x86_64
```

というコマンドでひとつずつ削除していきます。

# ライブラリのインストール

pg_repackのコンパイル時に下記のライブラリが必要でした。ひとつずつインストールしておきます。

```console
# yum install llvm-toolset-7 llvm5.0
# yum install clang
```

# パスの確認

旧バージョンのPostgreSQL 9.6.15でpg_repackをインストールしたとき `/etc/profile.d/psql96.sh` というファイルを作成してパスを通していました。

そのファイルをサーバーから削除したうえで、以下のようにファイルを作り直し、新しいパスを通します。

```
ファイルを新規作成します
# vi /etc/profile.d/psql12.sh

この1行を追記⇒ファイル保存(要viコマンド)
export PATH=$PATH:/usr/pgsql-12/bin
```

# pg_repackのインストール

ここではPostgreSQL 12.0に対応した**pg_repack v1.4.5**をインストールします。

手順は下記のとおりです。必要なファイルをダウンロード・解凍したうえで`make`コマンドでインストールしていきます。

```console
# wget -O - --no-check-certificate https://github.com/reorg/pg_repack/archive/ver_1.4.5.tar.gz | tar zxvf -
# cd pg_repack-ver_1.4.5
# make
# make install
```

続いて、PostgreSQL 12.0のDB（DBNAMEはここでは`mastodon`）にpg_repackを登録します。

```console
# su - mastodon
$ cd live
$ sudo su - postgres -c 'psql -d mastodon -c "CREATE EXTENSION pg_repack;"'
```

以上でpg_repackのインストールが完了します。

# DB不要領域を削除

Mastodonでとくにストレージ容量を使う`statuses`と`conversations`というふたつのテーブルに対して実行してみます。

コマンドは下記のとおりです。

```console
$ sudo su - postgres -c 'pg_repack -d mastodon -t statuses'
$ sudo su - postgres -c 'pg_repack -d mastodon -t conversations'
```

以上のコマンドによってMastodonインスタンスを停止させることなく、DBの不要領域を削除し、サーバーのストレージの空き容量を増やすことができます。

ちなみにわたしの場合は2年分の不要領域があったせいか、百数十MBを節約できました。

# 余談: アップグレード時の注意

今後PostgreSQLをメジャーアップグレードするとき`pg_upgrade`というコマンドを使うことになると思います。

その際、pg_repackに限らず拡張機能をインストールしているとうまく`pg_upgrade`コマンドが通りません。

そんなとき、下記のようにして、アップグレード前に拡張機能をアンインストールしておきます。

```console
# su - mastodon
$ cd live
$ sudo su - postgres -c 'psql -d mastodon -c "DROP EXTENSION pg_repack;"'
```

なお、インストールしてある拡張機能を確認する方法は以下のとおりです。

```
$ psql
mastodon=> \dx

List of installed extensions
   Name    | Version |   Schema   |  Description
-----------+---------+------------+-----------------
 pg_repack | 1.4.5   | public     | Reorganize...
 plpgsql   | 1.0     | pg_catalog | PL/pgSQL...
(2 rows)

mastodon=> \q
```