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

データベースにアクセスするためには、まずデータベースサーバ を起動しなくてはいけません。データベースサーバは postmasterと呼ばれます。postmaster は 自分が作業するデータがどこにあるのかを知らなければいけません。 これはオプション-Dで行われます。したがって、 例えばサーバを起動する一番簡単な方法は、

> postmaster -D /usr/local/pgsql/data
となり、これはサーバをフォアグラウンドで走らせます。これもまた Postgres ユーザアカウントにログインして実行されなくてはいけません。 -Dなしだと、サーバはデータディレクトリを環境変数 PGDATAで指定されたディレクトリを使おうとします。 どちらでも出来ない場合は失敗します。

バックグランドでpostmasterを起動する ためには通常の shell 構文を使います。

> postmaster -D /usr/local/pgsql/data > logfile 2>&1 &
ここで示されているように、サーバの出力をどこかに残しておくのは 非常に良いことです。監視と問題の判断の両方に役立ちます。

postmaster はいくつかの別のコマンドラインオプションを指定することも できます。さらに詳しい情報はレファレンスページの実行時設定の部分を 参照してください。特に、postmaster が TCP/IP 接続を許容するためには ( Unix ドメインソケットではなくて)オプション -iを 指定しなくてはいけません。

この shell 構文はすぐに長くなります。ですから shell スクリプトラッパー pg_ctlコマンドが提供されいくつかのタスクを カプセル化します。例えば、

pg_ctl start -l logfile
はサーバをバックグラウンドで起動し、出力を指定されたログファイルに 書き出します。オプション-Dは postmaster を直接 呼び出すのと同じことです。pg_ctl は対称的な"stop"操作も実装しています。

通常は、コンピュータがブートされた時にデータベースサーバも起動 してもらいたいと思います。しかしこれは強制されているわけではありません。 PostgreSQLサーバは権限を持たないアカウント からでもルートの介入なしで動かすことができます。

ブート時にデーモンを開始する方法はシステムによって異なりますが、 精通しておいたほうが良いでしょう。多くのシステムにはファイル /etc/rc.local/etc/rc.d/rc.localがあり、そのようなコマンド を置いておくには悪い場所ではありません。何をするにしてもサーバは Postgresユーザアカウントで起動し、 root ではいけませんし他のユーザでもいけません。 したがってsu -c '...' postgresのような 専用のコマンドを作っておいたほうが良いでしょう。例えば下記のように なります。

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

さらに幾つかのオペレーティングシステム固有の提案を挙げます。 (適切なインストールディレクトリと自分が選んだユーザ名に 置き換えて下さい。)

postmasterが動いている間は、その PID は データディレクトリの中のファイルpostmaster.pid にあります。これは同じデータディレクトリで動く複数の postmaster の 調整をし、postmaster の終了にも使うことができます。

3.3.1. サーバ起動の失敗

postmaster の起動が失敗する理由としては、一般的なものがいくつか あります。postmaster のログファイルをチェックするか、どのような エラーメッセージが出ているか見るために手動で始めてみて下さい (標準出力か標準エラーをリダイレクトせずに)。いくつかの可能な エラーメッセージは比較的自明ですが、そうではないものはここで 説明します。

FATAL: StreamServerPort: bind() failed: Address already in use
        Is another postmaster already running on that port?
これは通常は以下を意味します。もうすでに postmaster が動いている ポートで偶然に二つめを起動してしまったのです。しかし、もしカーネル エラーメッセージがAddress already in use ではなかったり、それに似たようなものだった場合は別の問題かも しれません。例えば、 予約ずみのポート番号で postmaster を起動しよう とすると次のような結果が出ます。
> postmaster -i -p 666
FATAL: StreamServerPort: bind() failed: Permission denied
        Is another postmaster already running on that port?

IpcMemoryCreate: shmget(key=5440001, size=83918612, 01600) failed: Invalid argument
FATAL 1:  ShmemCreate: cannot create region
上記のようなメッセージが出たら、おそらく共有メモリ領域のカーネル の上限が Postgres が作ろうとしているバッファ領域よりも小さい のでしょう。(この例では 83918612 バイトです。) もしくは System V 方式 の共有メモリサポートがカーネルに全く設定されていないということも ありえます。一時的な策として postmaster を通常よりも少ないバッファ 数で起動することもできます(-B オプションで変更)。 しかし最終的にはカーネルは許容される共有メモリサイズまで増やしたほうが よいでしょう。 このメッセージは、同じマシン上で複数の postmaster を起動させようと するときに要求された空間の合計がカーネルの上限を越えた場合にも 出ます。

下記のようなエラー

IpcSemaphoreCreate: semget(key=5440026, num=16, 01600) failed: No space left on device
はディスクの空き容量がなくなったというわけでは ありません。これは使っているカーネルの System V セマフォの上限がPostgresが作ろうと している数よりも小さいということです。上記のようにバックエンドプロセス を減らして postmaster を起動させることで問題は回避できるかもしれません が(-N オプションで変更)、最終的にはカーネルの上限を 増やした方が良いでしょう。

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

System V IPC 設備の設定についての詳細はSection 3.5.1 で説明されています。

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

クライアント側の起こり得るエラー状態はほとんど無限であり アプリケーションに依存します。そのなかのいくつかはサーバの 起動された方法と直接関係するかもしれません。下記で説明する以外 の状態では各々のクライアントアプリケーションの資料を見て下さい。

PQconnectPoll() -- connect() failed: Connection refused
	Is the postmaster running (with -i) at 'server.joe.com'
	and accepting connections on TCP/IP port 5432?
これは一般的な"接続するサーバが見つけられませんでした" という失敗です。TCP/IP 通信を試みた時に上記のような表示が出ます。 よくある間違いは postmaster に TCP/IP を許可する-i オプションをつけ忘れていることです。

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

connectDBstart() -- connect() failed: No such file or directory
	Is the postmaster running locally
	and accepting connections on Unix socket '/tmp/.s.PGSQL.5432'?

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