PostgreSQL 導入後 サーバに接続できないときの対処法

PostgreSQL をインストールしたばかりのとき、以下のようなエラーを目にすることがあります。

最新の PostgreSQL 11 を Ubuntu 18.04 にインストールした際にも発生することがあります。

$ psql
psql: could not connect to server: No such file or directory
    Is the server running locally and accepting
psql: サーバに接続できませんでした: No such file or directory
      ローカルにサーバが稼動していますか?
      Unixドメインソケット"/var/run/postgresql/.s.PGSQL.5432"で通信を受け付けていますか?

このときの解決策として、PostgreSQLをアンインストールして環境を再構築するという記述が、しばしば見受けられます。

それで問題が解決すれば良いのですけれども、同じ問題が再発することがあります。

私の経験上、再インストールによって解決する問題は version を指定せずにパッケージマネージャから RDBMS をインストールして、正しいファイルや設定を読み込めていないことが多いので、そうでない場合にはあまり効果が期待できないです。

では、どうするかと言うと、経験上の判断から locale settings や cluster を見に行くことが多いです。




本題に入る前に、再現性を高めるために、いつものバージョン情報とインストール時の設定を掲載しておきます。

europa@Jupiter:~$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="18.04.2 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.2 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

$ psql -V
psql (PostgreSQL) 11.4 (Ubuntu 11.4-1.pgdg18.04+1)

導入時に行ったこと
参照: PostgreSQL: Linux downloads (Ubuntu)

$ sudo apt update && sudo apt -y upgrade
$ wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
$ echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)"-pgdg main | sudo tee /etc/apt/sources.list.d/pgdg.list
$ sudo apt update
$ sudo apt install postgresql-11  -y 
$ sudo passwd postgres && su - postgres

ここまででインストールに成功すると、冒頭 Connection refused error に遭遇することがあるかもしれません。

$ psql -p 5432 -h localhost
could not connect to server: Connection refused Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432? could not connect to server: Connection refused Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432?

psql: サーバに接続できませんでした: Connection refused
	サーバはホスト "localhost" (::1) で稼動しており、
	また、ポート 5432 で TCP/IP 接続を受け付けていますか?
サーバに接続できませんでした: Connection refused
	サーバはホスト "localhost" (127.0.0.1) で稼動しており、
	また、ポート 5432 で TCP/IP 接続を受け付けていますか?

まずはプログラムが動いているかどうか確認します。動作していないと、そもそも繋がりません。

$ service postgresql status
● postgresql.service - PostgreSQL RDBMS
   Loaded: loaded (/lib/systemd/system/postgresql.service; enabled; vendor prese
   Active: active (exited) since Fri 2019-07-20 08:46:24 CST; 31min ago
 Main PID: 2178 (code=exited, status=0/SUCCESS)
    Tasks: 0 (limit: 1130)
   CGroup: /system.slice/postgresql.service

$ ps -ef|grep postgres
postgres 3950  2503  0 09:20 pts/0    00:00:00 grep postgres

プログラムが動作していることを確認できましたら、ソケット(プログラムとネットワークの接続口)の状態を見に行きます。

$ ss -tunelp|grep 5432

PostgreSQL に接続するために必要なところなので、きちんと動いていれば状態を確認できます。

ここの反応が今はありませんので、うまく行っていませんね。

ということで、現在のクライアント認証はどうなっているのかを見に行きます。

認証設定ファイルは "pg_hba.conf" という名前で保存されていることが伝統なので、探し出して現在の設定を把握します。

$ sudo find / -name pg_hba.conf
$

ところが、なぜか該当ファイルが見当たらないので、決め打ちで探しにいきます。

$ ls /etc/postgresql/
$ ls -a /etc/postgresql
.  ..  

そうすると、そこにあるはずのディレクトリが存在しません。

設定の問題以前に、設定ファイルそのものがありません。

ようやく、ここからが本題なのですけれども、必要なファイルが無いときは初期化したり、ツールで作成させると問題の解決につながることもあります。

$ sudo pg_createcluster 11 main --start
Creating new PostgreSQL cluster 11/main ...
/usr/lib/postgresql/11/bin/initdb -D /var/lib/postgresql/11/main --auth-local peer --auth-host md5
データベースシステム内のファイルの所有者は"postgres"となります。
このユーザがサーバプロセスも所有する必要があります。

データベースクラスタは以下のロケールで初期化されます。
  COLLATE:  C.UTF-8
  CTYPE:    C.UTF-8
  MESSAGES: C.UTF-8
  MONETARY: en_US.UTF-8
  NUMERIC:  en_US.UTF-8
  TIME:     en_US.UTF-8
そのためデフォルトのデータベース符号化方式はUTF8に設定されました。
デフォルトのテキスト検索設定はenglishに設定されました。

データベージのチェックサムは無効です。

既存のディレクトリ/var/lib/postgresql/11/mainの権限を修正します ... 完了
サブディレクトリを作成します ... 完了
max_connectionsのデフォルト値を選択します ... 100
shared_buffersのデフォルト値を選択します ... 128MB
selecting default timezone ... America/Chicago
動的共有メモリの実装を選択します ... posix
設定ファイルを作成します ... 完了
ブートストラップスクリプトを実行します ... 完了
ブートストラップ後の初期化を行っています ... 完了
データをディスクに同期します...完了

成功しました。以下のようにしてデータベースサーバを起動できます。

    pg_ctlcluster 11 main start

Ver Cluster Port Status Owner    Data directory              Log file
11  main    5432 online postgres /var/lib/postgresql/11/main /var/log/postgresql/postgresql-11-main.log

必要なファイルが揃いますと、設定ファイルも検索で見つかるようになりますし、RDBMS にも接続できるようになります。

$ sudo find / -name pg_hba.conf
/etc/postgresql/11/main/pg_hba.conf

$ su - postgres -c psql
Password: 

これでも、まだ接続できなかったらサーバ側の設定でポートが開放されているか、認証設定はどうなっているかを疑ってください。

まとめますと、インストールされた RDBMS の version と、プログラムの起動状態、クライアント認証、初期化の有無、そして IP アドレスやポートのサーバ設定などを順を追って確認していくと問題の原因に行き当たる確率が高いです。


[改訂新版]内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 (Software Design plus)

終業後はロードバイクで浜名湖 – 浜松 移住体験

東海道新幹線に乗っていると、多島海のすぐ隣を通り抜け、南国風の樹木が並ぶ、開放的な景観が目に飛び込んでくる場所があります。

両側に水面が広がっていて、まるで水の上を走っているような気分になります。

東京行きの列車では、ここを過ぎるとトンネルが連続する区間が始まり、新大阪行きの列車では直後に名古屋に到着するアナウンスが入ります。

そのあたりが三信遠と呼ばれる地域で、三河湾があって、浜名湖があって、南アルプスこと赤石山脈の入り口があります。

私も博士課程の学生の頃は、なぜか毎週、新幹線に乗って京都から東京に通う生活を送っていたので、訪れたこともないのに既視感と親近感があります。

そんなところに仕事で「来ていただけませんか?」と誘われれば、よろこんで行ってしまいます。こっそりと自転車も携帯しながら。




趣味のものまで持っていくと、さすがに荷物が増えすぎて持ちきれませんので、ビンディングシューズやヘルメット、着替えの服や予備の靴やカメラなどは事前にホテルに郵送しました。

あとは待ち合わせ場所をホテルのエントランスに指定して、待合せ時刻よりも早めに到着して、自転車もフロントに預けてしまえば完璧です。

スーツケースを持ち歩く、いつもの出張よりも簡単な気がします。

手荷物に余裕がありましたので「ロード乗りなら一度は食べておけ」と言われる『牛肉どまん中』弁当も、この機会に試食してみました。

偉い人の好物らしく、たしかに冷めていても美味しいです。強いクセも、臭いもなく、万人向けの味で、非常に質と完成度が高いと感じました。

でも、この値段なら、私なら「レストランに行ってしまうかな」とも思います。

浜松にはうなぎと餃子の他にも、げんこつハンバーグの『さわやか』、ラーメン、遠州焼き、三ケ日みかんと名物も豊富にあって目移りするほどです。

私はアレルギーで海産物を口にできないので、うなぎは撮影するだけですけれども、食べ物が美味しいというのは良いですね。

たくさん食べたら、たくさん走ることが幸せを感じる秘訣です。

浜松は遠州地方の中心に位置しており、東を向けば牧ノ原台地と御前崎、西を向けば浜名湖と三河湾、北側には三方原と秋葉山が聳えているという立地なので、走る場所には事欠かないだろうと思っていました。

実際に来てみますと、思いのほかに浜名湖が至近距離にあり、文字通りに毎日の終業後に通えることが分かりました。

17時に業務を終えても、このあたりは東京よりも日照も日没も遅いので、夏場は19時ぐらいまで明るいです。

浜名湖の入り口にある舞阪まで、元城町からでも 12km およそ 30分ぐらいで到着しますので、湖西や舘山寺ぐらいまでであれば無理なく通えます。

ただし一つだけ注意点がありまして、人口や都市規模を考えると異様に車が多く、どこまで行っても市街地が途切れませんし、車の量も減りません。

サイクリングスポットとして注目を集めている場所の中で、ここまで交通量が多いところは他に見たことがありません。それどころか、全国の政令市の中でも有数の車社会なのではないかと思えるほどです。

いちおう札幌、仙台、新潟、岡山、広島、北九州には行ったことがありまして、京都や福岡には住んでいたこともあるのですが、浜松の道路や市街地はそれらの何れとも違います。

浜松の場合は駅前や中心市街地と郊外との区別が曖昧で、どちらも同じぐらい多くの交通量があります。

平野が広いためなのか、市街地そのものの面積も大きく、ようやく市街地を脱したと思いきや、その直後に愛知や静岡の隣町の市街地に繋がります。

東海道沿いの主要都市はどこもそうなのかもしれませんが、必ずしも都市の中心部に向かう車ばかりではなく、中心部から辺縁部に向かう車も決して少なくはなく、双方向に大きな流動があるので、より広範囲での交流があることを実感させます。

冬季の積雪も考えなくていいですし、生活環境も東京よりも遥かに良好、食べ物も美味しく、産業の一大集積地だけに仕事にも不自由せず、政令市ならではの利便性も兼ね備えていて、移住先としては理想的な候補の一つであることに変わりはありませんが、住んでみないと分からないこともあるのだと痛感しました。

住んでみないと分からないと言えば、早朝に天竜川を遡っていくと凄い景色をご覧になれます。有名なのは浜名湖ですが、これも実際に来て、走った人にしか分からない贅沢です。

その話はまた次回にでも

さくらの VPS に CentOS7 を入れて SSH と Firewalld の設定につまづいた話

数年前から契約している、さくらインターネットの仮想専用サーバーの1つに「標準OSインストール」から CentOS x86_64 をいれて SSHD と Firewall と Port の設定をしようと思ったけど、うまく行かなったという話です。

さくらの VPS も何件か契約しておりまして、そのうち1つは CentOS 6.1 で動いていました。

これを久しぶりにアップデートしようとしたところ、Upgrade Tool はリンクが切れており、ミラーリストもURIが変わっていて、いろいろ大変なことに気がつきました。

力づくで解決するよりも新規にOSを入れ直して再設定したほうが早そうだったので /etc 以下のいくつかのファイルをローカルに保存して、コントロールパネルから OS を再インストールすることに決めました。

スタートアップスクリプト [Public] CentOS_yum-update を選択して、インストールは無事に終了しました。

# cat /proc/version
Linux version 3.10.0-957.10.1.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gccversion 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Mon Mar 18 15:06:45 UTC 2019

VNCコンソールは使い勝手が悪いので、さっそくリモートからのアクセスを許容すべく、ポートの割当を書き換えて SSHD を再起動します。

# vi /etc/ssh/sshd_config
# systemctl restart sshd.service

つぎに割り当てたポートを開放し、不要なポートを閉鎖すべく、Firewalld の設定を書き換えます。

CentOS 6 までの iptables とは勝手が違いますね。

# start systemctl start firewalld
# firewall-cmd --version
0.4.4.5
# firewall-cmd --remove-service=ssh --permanent 
# firewall-cmd --add-service=ssh --zone=public --permanent
# cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/ssh.xml
# vi /etc/firewalld/services/ssh.xml
# firewall-cmd --reload
# firewall-cmd --list-all|grep -a port

リモートから接続されている場合、Firewalld を起動すると一度ここで通信が切断されます。




これで設定がうまく行ったのかと思いきや、ssh 接続を試みると Connection timed out でエラーになります。

何かがおかしいなと思い、開放されているポートを調べてみるのですが、設定的に間違いはなさそうです。

# ss -t -l -n
# grep -i port /etc/ssh/sshd_config

何かがおかしいので、一時的に22番ポートを開放すると、普通に ssh 接続できるようになります。

# vi /etc/ssh/sshd_config
# systemctl restart sshd.service
# vi /etc/firewalld/services/ssh.xml
# firewall-cmd --reload

これは一体どういうことなの???

ほかに理由が思い当たらないので「あまり意味はないだろうな」とも思いつつ、SELinux の設定も変更してみます。

# semanage port --add --type ssh_port_t --proto tcp NNNN
# semanage port --list | grep -w ssh

意味はないだろうとは思っていましたけど、当然ながら結果は同じでした。

調べてみると、さくらインターネットのVPSでは /etc/iptables/iptables.rule に独自の設定を行っているようです。

もしかしたら、22番以外のポートを閉じる設定をどこかで行っているのでないかと、総当りで探していると、こんなものを発見。

2019年6月27日 さくらのVPS 「パケットフィルタ」提供開始のお知らせ 
https://www.sakura.ad.jp/information/announcements/2019/06/27/1968200552/

新機能のパケットフィルタによってOSインストール時にはデフォルトで 22 番以外のポートが閉じられている設定になっていました。

しかも、パケットフィルタが導入されたのは、今日から数えて30日前の 6月27日 です。

これでは新しすぎて、いくら検索しても同一の事例が見つからないわけです。ほかの契約サーバでは問題なく ssh 接続できるのに、このサーバだけ接続できない理由にも合点がいきました。

結局、ネットワークの設定をほとんど見直して、半日を費やしましたけどコントロールパネルからパケットフィルタを無効化すると、問題なくリモート接続できるようになりました。

こうなったら、あとはもう SSH root login と Password Authentication を禁止、御役御免の22番は閉鎖して、ユーザー作成と公開鍵認証を済ませてしまえば、いつもどおりです。

# adduser piyo && usermod -aG sudo piyo
# mkdir /home/piyo
# su piyo && cd ~
$ mkdir /home/piyo/.ssh && chmod 700 /home/piyo/.ssh && sudo chown piyo:piyo /home/piyo/.ssh
$ touch /home/piyo/.ssh/authorized_keys && chmod 600 /home/piyo/.ssh/authorized_keys

いつの間にか、いろいろ変わっているので、定期的に環境を見直しておかないとダメですね。


[改訂新版]プロのためのLinuxシステム構築・運用技術 (Software Design plus)