16.3. データベースサーバの起動

データベースにアクセスするためには、まずデータベースサーバを起動しなくてはいけません。 データベースサーバプログラムはpostgresという名前です。 postgresプログラムは自分が使用するデータがどこにあるのかを知っている必要があり、これは-Dオプションで指定できます。 したがって、サーバを起動する一番簡単な方法は、以下のようなコマンドとなります。

$ postgres -D /usr/local/pgsql/data

上記のコマンドは、サーバをフォアグラウンドで実行させます。 これは、PostgreSQLユーザアカウントにログインして実行されなくてはいけません。 -Dオプションが指定されていない場合、サーバはPGDATA環境変数で指定されたデータディレクトリを使用しようと試みます。 どちらの変数も指定されていなければ失敗します。

通常は、バックグラウンドでpostgresを起動することをお勧めします。 そのためには以下のように通常のシェルの構文を使います。

$ postgres -D /usr/local/pgsql/data >logfile 2>&1 &

この例のように、サーバの標準出力標準エラー出力をどこかに保管しておくことが重要です。 これは追跡記録的な目的と問題の原因究明に役立ちます (ログファイルの取り扱いについての全体的な説明については項22.3を参照してください)。

postgresプログラムには、この他にも多くのコマンドラインオプションを指定することができます。 詳細はpostgresリファレンスページと後述の第17章を参照してください。

こうしたシェル構文は長くなりがちです。 そのため、pg_ctlラッパプログラムが提供されていて、いくつかのタスクを単純化しています。 以下に例を示します。

pg_ctl start -l logfile

これは、サーバをバックグラウンドで起動し、出力を指定されたログファイルに書き出します。 -Dオプションは、ここでもpostgresの場合と同じ意味を持ちます。 pg_ctlによってサーバを停止させることもできます。

通常、コンピュータが起動された時にデータベースサーバも一緒に起動したい場合が多いと思われます。 自動起動スクリプトは、オペレーティングシステム固有のものです。 いくつかはPostgreSQL/contrib/start-scriptsディレクトリに同梱されています。 このインストールにはおそらくroot権限が必要となります。

起動時にデーモンを開始する方法はシステムによって異なります。 多くのシステムには/etc/rc.localファイルや/etc/rc.d/rc.localファイルがあります。 他のシステムではrc.dディレクトリが使用されます。 何を実行するにしても、サーバはPostgreSQLユーザアカウントで起動させなければなりません。 rootであってはいけませんし、他のユーザでもいけません。 したがって、su -c '...' postgresを使用してコマンドを実行した方が良いでしょう。 以下に例を示します。

su -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog' postgres

さらにいくつかのオペレーティングシステム固有の提案を挙げます (ここでは一般的な値で説明していますので、各項目において適切なインストールディレクトリとユーザ名に置き換えて読んでください)。

サーバが実行している間は、そのPIDはデータディレクトリの中のpostmaster.pidファイルに記述されています。 これは同じデータディレクトリで複数のサーバインスタンスが実行されるのを防止し、また、サーバの終了にも使うことができます。

16.3.1. サーバ起動の失敗

サーバの起動が失敗する理由として、代表的なものがいくつかあります。 サーバのログファイルをチェックするか、(標準出力や標準エラーをリダイレクトせずに)手動で起動して、どのようなエラーメッセージが出ているか確認してください。 以下に、よく発生するエラーメッセージのいくつかをより詳細に説明します。

LOG:  could not bind IPv4 socket: Address already in use
HINT:  Is another postmaster already running on port 5432? If not, wait a few seconds and retry.
FATAL:  could not create TCP/IP listen socket

これはたいていの場合メッセージが示す通りの意味です。 既にサーバが動いているポートで別のpostmasterを起動しようとしたことを示しています。 しかし、カーネルエラーメッセージがAddress already in useやそれに類似したものではない場合は、別の問題の可能性もあります。 例えば、予約済みのポート番号でサーバを起動しようとすると下記のようなメッセージが出ます。

$ postgres -p 666
LOG:  could not bind IPv4 socket: Permission denied
HINT:  Is another postmaster already running on port 666? If not, wait a few seconds and retry.
FATAL:  could not create TCP/IP listen socket

次のようなメッセージが表示された場合、

FATAL:  could not create shared memory segment: Invalid argument
DETAIL:  Failed system call was shmget(key=5440001, size=4011376640, 03600).

これは、おそらくカーネルによる共有メモリのサイズの上限がPostgreSQLが作ろうとしている作業領域よりも小さい可能性があります(この例では4011376640バイトです)。 または、System V方式の共有メモリサポートがカーネルにまったく設定されていない可能性もあります。 一時的な策として、(shared_buffersを使用して)サーバを通常よりも少ないバッファ数で起動することもできます。 しかし最終的には、カーネルを再設定し、使用可能な共有メモリサイズを増やした方が良いでしょう。 このメッセージは、同じマシン上で複数のサーバを起動しようとした時に、要求された領域の合計がカーネルの上限を超えた場合にも表示されます。

下記のようなエラーはディスクの空き容量がなくなったということを示しているわけではありません

FATAL:  could not create semaphores: No space left on device
DETAIL:  Failed system call was semget(5440126, 17, 03600).

これはカーネルのSystem Vセマフォの上限が、PostgreSQLが作成しようとしている数よりも小さいということを意味しています。 上記のように、許可される接続の数を減らして(max_connectionsを使用して)サーバを起動させることで問題は回避できるかもしれませんが、最終的にはカーネルの設定を変えてセマフォの上限を増やした方が良いでしょう。

"illegal system call"というエラーが表示された場合は、使用しているカーネルでは共有メモリやセマフォがまったくサポートされていない可能性があります。 その場合、これらの機能を使えるようにカーネルを設定し直すことが唯一の選択肢となります。

System V IPC設備の設定についての詳細は項16.4.1を参照してください。

16.3.2. クライアント接続の問題

クライアント側で起こり得るエラー状態はきわめて多様で、アプリケーションに依存します。 その中のいくつかはサーバが起動された方法と直接関係するかもしれません。 以下で説明する以外の状態については各々のクライアントアプリケーションの資料を参照してください。

psql: could not connect to server: Connection refused
        Is the server running on host "server.joe.com" and accepting
        TCP/IP connections on port 5432?

これは一般的な"接続するサーバが見つけられませんでした"という失敗です。 TCP/IP通信を試みた時に上記のように表示されます。 よくある間違いはサーバにTCP/IPを許可する設定を忘れていることです。

代わりに、ローカルのサーバにUnixソケット通信を試みると下記のような表示が出ます。

psql: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

最後の行は、クライアントが正しいところに接続しようとしていることを実証するのに役立ちます。 もしそこに動いているサーバがない場合、典型的なカーネルエラーメッセージは、表示されているようにConnection refusedもしくはNo such file or directoryとなります (この場合のConnection refusedはサーバが接続要求を受け付け拒否したわけではないということを理解しておくことが大切です。 もしそうだった場合は項20.3で示されるような別のメッセージが表示されます)。 Connection timed outのような他のメッセージは、例えばネットワーク接続の欠如のようなもっと根本的な問題を表しています。