[SadServers] 解説 "Manhattan": can't write data into database.
SadServersの問題の解説です。 URLは、https://sadservers.com/newserver/manhattan#
SadServers って何? って人は、 SadServers解説 を見てください。
一言でいうと、LeetCode (コーディング問題集) の Linuxサーバ設定版のようなものです。
問題
Level: Medium
Description: Your objective is to be able to insert a row in an existing Postgres database. The issue is not specific to Postgres and you don't need to know details about it (although it may help).
Helpful Postgres information: it's a service that listens to a port (:5432) and writes to disk in a data directory, the location of which is defined in the data_directory parameter of the configuration file /etc/postgresql/14/main/postgresql.conf. In our case Postgres is managed by systemd as a unit with name postgresql.
あなたの目的は、既存の Postgres データベースに行を挿入できるようにすることです。この問題はPostgresに特有のものではないので、それについて詳細を知る必要はありません(役に立つかもしれませんが)。
Postgresはポート(:5432)をリッスンし、データディレクトリのディスクに書き込むサービスです。その場所は、設定ファイル/etc/postgresql/14/main/postgresql.confのdata_directoryパラメータで定義されています。この例では、Postgresはsystemdによってpostgresqlという名前で管理されています。
Test: (from default admin user) sudo -u postgres psql -c "insert into persons(name) values ('jane smith');" -d dt
Should return:INSERT 0 1
テスト:(デフォルトの管理者ユーザから) sudo -u postgres psql -c "insert into persons(name) values ('jane smith');" -d dt
INSERT 0 1を返すはずです。
解き方
まず、Testにあるコマンドを叩いて、どうなるかチェックします。
root@ip-172-31-46-86:/home/admin# sudo -u postgres psql -c "insert into persons(name) values ('jane smith');" -d dt
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory
Is the server running locally and accepting connections on that socket?
なにやら、 psql
がエラーとなっています。 エラーメッセージを見ても原因が不明なので、postgresqlのログを確認します。
/var/log
以下にあることが多いので、
# ログは/var/log以下にあることが多いので、 /var/logに移動して、ls
root@ip-172-31-46-86:/home/admin# cd /var/log/
root@ip-172-31-46-86:/var/log# ls
alternatives.log daemon.log.2.gz kern.log.1 syslog.3.gz
alternatives.log.1 daemon.log.3.gz kern.log.2.gz syslog.4.gz
apt daemon.log.4.gz kern.log.3.gz syslog.5.gz
auth.log debug kern.log.4.gz syslog.6.gz
auth.log.1 debug.1 lastlog sysstat
auth.log.2.gz debug.2.gz messages unattended-upgrades
auth.log.3.gz debug.3.gz messages.1 user.log
auth.log.4.gz debug.4.gz messages.2.gz user.log.1
btmp dpkg.log messages.3.gz user.log.2.gz
btmp.1 dpkg.log.1 messages.4.gz user.log.3.gz
chrony dpkg.log.2.gz postgresql user.log.4.gz
cloud-init-output.log dpkg.log.3.gz private wtmp
cloud-init.log dpkg.log.4.gz syslog
daemon.log faillog syslog.1
daemon.log.1 kern.log syslog.2.gz
# postgresqlフォルダ発見。
# postgresqlフォルダに移動し、ls
root@ip-172-31-46-86:/home/admin# cd /var/log/postgresql/
root@ip-172-31-46-86:/var/log/postgresql# ls
postgresql-14-main.log
# ログファイル (postgresql-14-main.log)発見したので、中身を確認
root@ip-172-31-46-86:/var/log/postgresql# cat postgresql-14-main.log
2022-11-09 15:01:03.038 UTC [651] FATAL: could not create lock file "postmaster.pid": No space left on device
pg_ctl: could not start server
Examine the log output.
# `No space left on device`とあるので、ディスク容量不足と推測
# df で ディスク容量確認
root@ip-172-31-46-86:/var/log/postgresql# df
Filesystem 1K-blocks Used Available Use% Mounted on
udev 229356 0 229356 0% /dev
tmpfs 47692 1528 46164 4% /run
/dev/nvme1n1p1 8026128 1233672 6363200 17% /
tmpfs 238456 0 238456 0% /dev/shm
tmpfs 5120 0 5120 0% /run/lock
tmpfs 238456 0 238456 0% /sys/fs/cgroup
/dev/nvme1n1p15 126710 278 126432 1% /boot/efi
/dev/nvme0n1 8378368 8378340 28 100% /opt/pgdata
# /opt/pgdata ディスクの使用率が100%と判明。
# /opt/pgdataに移動して、ファイル確認
root@ip-172-31-46-86:/var/log/postgresql# cd /opt/pgdata
root@ip-172-31-46-86:/opt/pgdata# ls -l
total 8285620
-rw-r--r-- 1 root root 69 May 21 22:20 deleteme
-rw-r--r-- 1 root root 7516192768 May 21 22:06 file1.bk
-rw-r--r-- 1 root root 967774208 May 21 22:17 file2.bk
-rw-r--r-- 1 root root 499712 May 21 22:23 file3.bk
drwx------ 19 postgres postgres 4096 May 21 22:24 main
# file1.bk, file2.bk, file3.bkがでかい。 bkだからバックアップファイルか? 消してしまおう。
root@ip-172-31-46-86:/opt/pgdata# rm file*.bk
# postgresqlを再起動
root@ip-172-31-46-86:/opt/pgdata# systemctl restart postgresql
# testのコマンドを実行
root@ip-172-31-46-86:/opt/pgdata# sudo -u postgres psql -c "insert into persons(name) values ('jane smith');" -d dt
INSERT 0 1
# INSERT 0 1が返ったのでOK!
Discussion