docker-composeで立てたPostgreSQLのVolume(保存先)をUSBメモリ(外部)にする@RaspberryPi4(できなかったけど、、)
はじめに
SDカードは死にやすいとグーグル先生が仰っているため、USBメモリ(128GB)を購入してそちらにDBを保存することにした。
結論、3日頑張ってもできなかったので諦め。
SDカードに溜めて、周期的にUSBにバックアップすることにする。
周期は1日なのか1時間なのか、今後確認だな~。
参考文献
まずは、USBを自動マウントさせるところからやりましょう。
/etc/fstabをいじったらラズパイ4が起動しなくなりました。
同じようなコトをしちゃう人が多いみたいですね…
上記を参考にしました。うちには幸いなことにラズパイ3が動いていたので、ラズパイ4からSDカードを抜いてさしました。
/media/pi/rootfs/ にルート以下がマウントされているので、/etc/fstabを修正することに。
PARTUUID=54FF-D402 /mnt/usb/str1 exfat auto,rw,async,dev,suid,exec,noatime 0 2
上記ではだめだったみたいなので、下記に直してみたところ、
UUID="54FF-D402" /mnt/str1 exfat defaults,noatime,nofail 0 0
これでちゃんと上がってきました。
あとは、docker-compose-ymlのvolumesを下記にすればOK。
volumes:
- "/mnt/str1/postgresql/data/:/var/lib/postgresql/data"
ということでdocker起動しましたが、・・・が、以下のエラーが…
postgres-sm | chown: changing ownership of '/var/lib/postgresql/data': Operation not permitted
chmodしても、zオプション付けてもダメ。
上記のエラーでググると死ぬほど出てくるけどなんか有用な回答が無いぞ。。。
所有者が何なのか、他のディレクトリで適当に作成したVolumesの中身をのぞいてみると、
drwxr-x--- 1 999 root 128K 4月 30 17:44 data
のようになっていた。
999なんてユーザいねーぞ。。。しゃーないからuseraddでuid=999をdockerにして、再度/etc/fstabを編集。追加でdefault表記を外してみた。
UUID="54FF-D402" /mnt/str1 exfat user,rw,suid,dev,exec,suid,auto,async,noatime,nofail,uid=999 0 0
起動させたら何やら違うエラーが・・・
FATAL: data directory "/var/lib/postg
resql/data" has invalid permissionsDETAIL: Permissions should be u=rwx (0700) or u=rwx,g=rx (0750).
進展してよかた。パーミッションがデフォルトだったので、fstabにマスクを追加。
UUID="54FF-D402" /mnt/str1 exfat user,rw,suid,dev,exec,suid,auto,async,noatime,nofail,uid=999,dmask=027,fmask=027,umask=027 0 0
再起動して、パーミッションが変わっていることを確認
drwxr-x--- 1 docker root 128K 1月 1 1970 str1
して再度実行。またまたエラー。。。
postgres-sm | running bootstrap script ... 2020-04-30 14:21:18.040 UTC [24] LOG: could not link file "pg_wal/xlog
temp.24" to "pg_wal/000000010000000000000001": Function not implemented
postgres-sm | 2020-04-30 14:21:18.044 UTC [24] FATAL: could not open file "pg_wal/000000010000000000000001": No s
uch file or directory
postgres-sm | child process exited with exit code 1
なんでファイルがみつからんのだ。downやってコンテナ消してるから再度ファイル作られると思ってたんだけど…
しゃーなしなので、いつだったか間違って作ってしまった、本来ならば初期時に作られるだろうファイルをごっそり移動。
docker@raspberrypi4:/mnt/str1/postgresql/data$ ls -alh
合計 3.2M
drwxr-x--- 1 docker root 128K 4月 30 23:44 .
drwxr-x--- 1 docker root 128K 4月 30 23:44 ..
-rwxr-x--- 1 docker root 3 4月 30 23:44 PG_VERSION
drwxr-x--- 1 docker root 128K 4月 30 23:44 base
drwxr-x--- 1 docker root 128K 4月 30 23:44 global
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_commit_ts
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_dynshmem
-rwxr-x--- 1 docker root 4.5K 4月 30 23:44 pg_hba.conf
-rwxr-x--- 1 docker root 1.6K 4月 30 23:44 pg_ident.conf
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_logical
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_multixact
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_notify
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_replslot
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_serial
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_snapshots
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_stat
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_stat_tmp
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_subtrans
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_tblspc
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_twophase
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_wal
drwxr-x--- 1 docker root 128K 4月 30 23:44 pg_xact
-rwxr-x--- 1 docker root 88 4月 30 23:44 postgresql.auto.conf
-rwxr-x--- 1 docker root 26K 4月 30 23:44 postgresql.conf
-rwxr-x--- 1 docker root 36 4月 30 23:44 postmaster.opts
docker-compose.ymlのDB先もしっかり修正。そして、実行。
いやーついに動いた。。。
1日かかってしもた。。。
ちゃんとDBが見えるかどうかもチェックする⇒なんかおかしい。
そう、リードはできてもライトができないのである。
Postgresqlのinitdbを実行するユーザで初期ファイルの書き込みがどうにもうまくいかない。
こんなブログもあった。
マウントを/postgres/dataから/postgresに変えるものだが、これだとデータの永続化はできない。/mnt/str1/postgres:/var/lib/postgresの部分は確かにそこにマウントするけれどもdata部分は別のvolumeが作成されてそちらにマウントされる。
pi@raspberrypi4:~ $ docker volume ls
DRIVER VOLUME NAME
local docker-settings_sm-db
local e1be6dd7630d21c1a5697df0b690be16cb46f7fb26c2da95075d7e68762a666c
pi@raspberrypi4:~ $
pi@raspberrypi4:~ $ docker volume inspect e1be6dd7630d21c1a5697df0b690be16cb46f7fb26c2da95075d7e68762a666c
[
{
"CreatedAt": "2020-05-02T05:18:11+09:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/e1be6dd7630d21c1a5697df0b690be16cb46f7fb26c2da95075d7e68762a666c/_data",
"Name": "e1be6dd7630d21c1a5697df0b690be16cb46f7fb26c2da95075d7e68762a666c",
"Options": null,
"Scope": "local"
}
]
pi@raspberrypi4:~ $
pi@raspberrypi4:~ $ docker volume inspect docker-settings_sm-db
[
{
"CreatedAt": "2020-05-02T16:30:30+09:00",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "docker-settings",
"com.docker.compose.version": "1.25.5",
"com.docker.compose.volume": "sm-db"
},
"Mountpoint": "/var/lib/docker/volumes/docker-settings_sm-db/_data",
"Name": "docker-settings_sm-db",
"Options": {
"device": "/mnt/str1/psgr/data/",
"o": "bind",
"type": "none"
},
"Scope": "local"
}
]
つまるところ、保存したかったところには保存できていない。
この後、uid=999をpostgresにしてみたり、docker-entrypoint.sh読んでみたりしたけど、よくわからんし、これ以上時間かけてもしゃーないからひとまず諦めて前に進めることにしました。ローカル環境の/etc/passwd /etc/groupをマウントしてしまうという手もあるらしいけど、そこまで変わりがないので今回はパス
一通りできたら、ラズパイのSDカードをそっくりバックアップしておこうと思う。
権限問題はlinuxでよくある話らしいが、こんなにも沼にはまってしまうとは。。。
完走できなかった感想
3日かけたのは時間のかけすぎだったかもしれない。
結局やりたいことは、急なデータ消失時のバックアップなので、わざわざやらなくてもと言ったところだった。
USBメモリへの保存は、周期的にクーロンかなにかでdata以下をtar.gzipすればいいかな。
zipしちゃえば200MBを超えるDBの生データも10Mぐらいになっちゃうし、当分は差分しなくてもOKと思う。
仮にデータ量が圧縮後に100MBあったとしても、1日1回のバックアップで3G/月(30points)、36.5G/年(365points)となる。
保存方法も1週間は全て残すけど、それ以降は1週間毎にするとかすれば、1日1回バックアップよりも細かい頻度で(1時間とか?)とったとしてもラズパイの寿命よりは長く保存できそう。
1週間*1時間毎*1回100MBだとしたら、7*24*0.1G=16.8G
それ以後は1週間毎に保存するとして、16.8+52週*0.1G=22GB/年
1回100MBならば5年以上、200MBになったとしても2年以上は持つ
正直そこまででかくなったら、毎回フルバックアップは無理なので、フルバックアップと差分バックアップを使い分けないといけないかと感じているけど、まだまだ先になりそうなので今は良しとする。