✍️

SadServers解説#15 "Manhattan": can't write data into database.

2024/04/22に公開

https://ja.wikipedia.org/wiki/マンハッタン

問題概要

シナリオ

データベースに書き込むことができません

問題詳細

あなたの目標は、既存のPostgresデータベースにレコードを挿入できるようにすることです。
今回の問題はPostgres固有のものではないため、詳細を知る必要はありません(ただし、それが役立つ場合もあります)。

【PostgresのTips】
Postgresは、ポート(:5432)をリッスンし、ディスクにデータを書き込むサービスです。データディレクトリの場所は、構成ファイル「/etc/postgresql/14/main/postgresql.conf」のdata_directoryパラメータで定義されています。また、Postgresは、postgresqlという名前で、systemdのモジュールとして管理されています。

解決判定

Check My Solutionボタンをクリックしてください。

解答が正解かどうか、コマンドプロンプト上で確認することも可能です。次のコマンドを実行して、以下と同じ出力が得られた場合はOKです。

$ sudo -u postgres psql -c "insert into persons(name) values ('jane smith');" -d dt
Should return:INSERT 0 1

 

問題解決の方針

【表示する】

まずは、解決判定のコマンドを実行し、エラーメッセージに沿って問題を切り分けましょう。もしも調査に行き詰ってしまった場合は、ログを見に行きましょう。

解決の手順を表示する
  1. postgresコマンドを実行し、エラーメッセージに沿って調査
  2. ログを調査

 

ヒント

一部、SadServers公式のヒントを改変しています。

ヒント1

まずは、postgresコマンドを実行してみましょう。

# 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: エラー: サーバーへのソケット "/var/run/postgresql/.s.PGSQL.5432" の接続に失敗しました: ファイルやディレクトリが存在しません
サーバーはローカルで実行され、そのソケットへの接続を受け付けていますか?

Postgresに接続できないようですが、具体的な問題点は分かりませんね。
一応ポートの状態も見てみます。

# ss -natu | grep :5432

ポートも開いていません。

ヒント2

Postgresが稼働しているか確認しましょう?Postgresはsystemdに登録されているそうなので、systemctlコマンドで確認できます。

実行コマンド
# systemctl status postgresql
● postgresql.service - PostgreSQL RDBMS
   Loaded: loaded (/lib/systemd/system/postgresql.service; enabled; vendor preset: enabled)
   Active: active (exited) since Mon 2024-04-22 12:35:15 UTC; 35s ago
  Process: 661 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
 Main PID: 661 (code=exited, status=0/SUCCESS)

Apr 22 12:35:15 i-069f5ccb1cfa4aeca systemd[1]: Starting PostgreSQL RDBMS...
Apr 22 12:35:15 i-069f5ccb1cfa4aeca systemd[1]: Started PostgreSQL RDBMS.

起動時のログも出力されていません…。

ヒント3

念のため、再起動して改善するか試してみましょう。

実行コマンド
# sudo systemctl restart postgresql
# 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?

再起動しても変わりませんね…

ヒント4

Postgresのログを確認してみましょう。ログは、多くの場合/var/logに保存されています。

実行コマンド
# ls -l /var/log | grep postgre
drwxrwxr-t 2 root postgres 4096 Apr 22 12:35 postgresql
# tail /var/log/postgresql/postgresql-14-main.log
2024-04-22 12:43:03.053 UTC [888] FATAL:  could not create lock file "postmaster.pid": No space left on device
pg_ctl: could not start server
Examine the log output.

「postmaster.pid」というロックファイルを作成できませんでした:デバイス上に空き領域がありません
pg_ctl: サーバーを起動できませんでした
ログの出力を調べてください。

役立ちそうなログが出力されていました。
容量が足りず、posgreサービスが起動できないようです。

ヒント5

ディスク容量を確認しましょう。

実行コマンド
# df -h
Filesystem       Size  Used Avail Use% Mounted on
udev             224M     0  224M   0% /dev
tmpfs             47M  1.5M   46M   4% /run
/dev/nvme1n1p1   7.7G  1.2G  6.1G  17% /
tmpfs            233M     0  233M   0% /dev/shm
tmpfs            5.0M     0  5.0M   0% /run/lock
tmpfs            233M     0  233M   0% /sys/fs/cgroup
/dev/nvme1n1p15  124M  278K  124M   1% /boot/efi
/dev/nvme0n1     8.0G  8.0G   28K 100% /opt/pgdata

/opt/pgdataの容量が100%になっているようです。/opt/pgdataがPostgresの使っているディレクトリであるかどうか、念のため、設定ファイルを確認します。

# grep "/opt/pgdata" /etc/postgresql/14/main/postgresql.conf
data_directory = '/opt/pgdata/main'             # use data in another directory

/opt/pgdataがPostgresの使っているディレクトリで間違いなさそうです。

ヒント6

Postgresのデータで削除できるものがないか確認し、削除しましょう。

実行コマンド
# ls -l /opt/pgdata/
total 8285620
-rw-r--r--  1 root     root             69 May 21  2022 deleteme
-rw-r--r--  1 root     root     7516192768 May 21  2022 file1.bk
-rw-r--r--  1 root     root      967774208 May 21  2022 file2.bk
-rw-r--r--  1 root     root         499712 May 21  2022 file3.bk
drwx------ 19 postgres postgres       4096 May 21  2022 main

どうやら、サイズの大きなバックアップファイルが複数あるようです。これをどかしてしまいましょう。今回は後先考えず消してしまいますが、業務では別の場所に退避させましょう。

# rm -i /opt/pgdata/file1.bk
# sudo systemctl restart postgresql
# ss -natu | grep :5432
tcp LISTEN 0 128 127.0.0.1:5432 0.0.0.0:* 
# sudo -u postgres psql -c "insert into persons(name) values ('jane smith');" -d dt
INSERT 0 1

5432のポートが開き、レコードも挿入できました!

 
「いきなり問題を解き始めても調べるばかりになってしまう…」 「やりたいことが分かっても、コマンドが分からない…」 という方は、下記の記事でLinuxのコマンドを復習してから、SadServersの問題に取り掛かってみてはいかがでしょうか。
https://zenn.dev/comf_nakamura/articles/linux_command

問題一覧はこちら

https://zenn.dev/comf_nakamura/articles/sadservers_sitemap

Discussion