かなり大変だったので、備忘録として。
・経緯
3年ほど前にRaspberry Piでmastodonサーバを立ち上げて運用していたのだが、1年前に何かの拍子でブートメディア(microSD)が破損し起動不能になってしまった。
幸いなことにブートセクション以外は生きていたのでデータを取り出すことは出来たのだが、データディレクトリからデータベースを復旧するのにそこそこ苦労した。
・環境
マシン→Raspberry Pi 4B (arm64)
前OS→Raspberry Pi OS (buster) (32bit)
現OS→Ubuntu(Server) 22.04 (64bit)
今回は32bitから64bitへの移行であるが、データディレクトリから移植するとなると非常に大きな障壁が存在する。それは、(おそらくPostgreSQLに限った話ではないだろうが) 同じデータベースでも異なるアーキテクチャでは(ファイルシステムの上で)同じように保存されないためである。
・安直にファイルを移動させてみる
最初はデータディレクトリを同じところに置いておけばそれで勝手に読み込んでくれると思っていたのであるが、出てきたメッセージはこれである。
FATAL: database files are incompatible with server
DETAIL: The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL.
要するに32bitのマシンでは8Byte(=64bit)の浮動小数点数(FLOAT)を値渡し(by-value)できないので、前のデータはUSE_FLOAT8_BYVAL
というフラグが無効になっていたのだが、今は64bitのOS上で動いていて有効になっているから互換性がないですよというエラーである。
・じゃあ32bitの環境で...
じゃあ自分のパソコン(amd64/Ubuntu(Desktop) 18.04(64bit))でDockerを使って32bitのPostgreSQLを動かしてやろうじゃんということでi386/postgres
イメージを引っ張ってきて動かしてみたら今度はコレである。
FATAL: incorrect checksum in control file
どうやら32bit同士でもアーキテクチャが違うとチェックサムの関数が違ったりするようである。
・最終的な解決策
結局、Raspberry Pi上でarm32v7/postgres
のイメージを使ってDockerコンテナを立てる必要があった。PostgreSQLのサービスがたったのを確認すればpg_dumpを使ってDBをダンプしよう。
或いは(armのマシンを使うことができない状況にあるなどの場合は)、QEMUなどのCPUエミュレータを用いることで、amd64上のDockerでarm32v7のコンテナを動かすことができればうまく行くかもしれない。(未検証)
・その他細々としたエラーの処理
-
設定ファイル関係でエラーが出ることがある。今回は
/var/lib/postgresql
以下しかデータを保管していなかったので、/etc/postgresql
以下にあった設定ファイル(postgresql.conf
など)が無いといって怒られた。ファイルシステムごとバックアップをする際は設定ファイルも保管しておくとよいだろう。今回は特に弄っていなかったため、適当にデフォルトのものをコピーした。 - 設定ファイルによってはロケール(時間や通貨などのフォーマットの指定)でエラーが出ることがある。
FATAL: invalid value for parameter "lc_monetary": "ja_JP.UTF-8"
このような場合は
localedef -i ja_JP -f UTF-8 ja_JP.UTF-8
でシステムにロケールを追加してやれば通るようになる。
こういう問題に直面するたびに低レイヤの知識が足りないなと思う。精進します。