支援的版本:目前 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2

18.3. 啟動資料庫伺服器 #

在任何人可以存取資料庫之前,您必須啟動資料庫伺服器。資料庫伺服器程式稱為 postgres

如果您使用的是預先封裝的 PostgreSQL 版本,它幾乎肯定包含根據您作業系統的慣例將伺服器作為背景任務執行的規定。 使用套件的基礎架構來啟動伺服器會比弄清楚如何自己執行此操作要輕鬆得多。 請查閱套件層級的文件以取得詳細資訊。

手動啟動伺服器的最基本方法是直接調用 postgres,使用 -D 選項指定資料目錄的位置,例如

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

這會讓伺服器在前台執行。 必須在登入 PostgreSQL 使用者帳戶時執行此動作。 如果沒有 -D,伺服器會嘗試使用環境變數 PGDATA 指定的資料目錄。 如果未提供該變數,則會失敗。

通常,最好在背景中啟動 postgres。 為此,請使用常用的 Unix shell 語法

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

如上所示,務必將伺服器的 stdoutstderr 輸出儲存在某處。 它將有助於稽核目的和診斷問題。 (有關日誌檔處理的更全面討論,請參閱第 24.3 節。)

postgres 程式也採用許多其他命令列選項。 如需更多資訊,請參閱 postgres 參考頁面和下方的 第 19 章

這種 shell 語法很快就會變得乏味。 因此,提供封裝程式 pg_ctl 以簡化某些任務。 例如

pg_ctl start -l logfile

這會在背景中啟動伺服器,並將輸出放入指定的日誌檔中。 -D 選項在此處的含義與 postgres 相同。 pg_ctl 也能夠停止伺服器。

通常,您會在電腦啟動時啟動資料庫伺服器。 自動啟動腳本是作業系統特定的。 在 PostgreSQLcontrib/start-scripts 目錄中,散佈了一些範例腳本。 安裝其中一個需要 root 權限。

不同的系統在啟動時啟動 daemons 有不同的慣例。 許多系統都有檔案 /etc/rc.local/etc/rc.d/rc.local。 其他系統使用 init.drc.d 目錄。 無論您做什麼,伺服器都必須由 PostgreSQL 使用者帳戶執行而不是 root 或任何其他使用者。 因此,您可能應該使用 su postgres -c '...' 形成您的命令。 例如

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

以下是一些更多特定於作業系統的建議。 (在每種情況下,請務必在使用通用值的地方使用正確的安裝目錄和使用者名稱。)

  • 對於 FreeBSD,請查看 PostgreSQL 原始碼發行套件中的檔案 contrib/start-scripts/freebsd

  • OpenBSD 上,將以下行新增至檔案 /etc/rc.local

    if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postgres ]; then
        su -l postgres -c '/usr/local/pgsql/bin/pg_ctl start -s -l /var/postgresql/log -D /usr/local/pgsql/data'
        echo -n ' postgresql'
    fi
    
  • Linux 系統上,新增

    /usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data
    

    /etc/rc.d/rc.local/etc/rc.local 或查看 PostgreSQL 原始碼發行套件中的檔案 contrib/start-scripts/linux

    使用 systemd 時,您可以使用以下服務單元檔案(例如,在 /etc/systemd/system/postgresql.service):

    [Unit]
    Description=PostgreSQL database server
    Documentation=man:postgres(1)
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=notify
    User=postgres
    ExecStart=/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
    ExecReload=/bin/kill -HUP $MAINPID
    KillMode=mixed
    KillSignal=SIGINT
    TimeoutSec=infinity
    
    [Install]
    WantedBy=multi-user.target
    

    使用 Type=notify 需要使用 configure --with-systemd 建置伺服器二進位檔。

    仔細考慮逾時設定。 在撰寫本文時,systemd 的預設逾時時間為 90 秒,並且會終止未在該時間內報告就緒的程序。 但是,在啟動時可能需要執行崩潰恢復的 PostgreSQL 伺服器可能需要更長的時間才能準備好。 建議的 infinity 值會停用逾時邏輯。

  • NetBSD 上,根據您的偏好,使用 FreeBSDLinux 的啟動腳本。

  • Solaris 上,建立一個名為 /etc/init.d/postgresql 的檔案,其中包含以下行:

    su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data"
    

    然後,在 /etc/rc3.d 中建立一個指向它的符號連結,命名為 S99postgresql

當伺服器運行時,它的PID會儲存在資料目錄中的 postmaster.pid 檔案中。這用於防止多個伺服器實例在同一個資料目錄中運行,並且也可以用於關閉伺服器。

18.3.1. 伺服器啟動失敗 #

伺服器可能無法啟動有幾個常見的原因。請檢查伺服器的日誌檔,或手動啟動它(不重新導向標準輸出或標準錯誤),並查看出現什麼錯誤訊息。下面我們更詳細地解釋一些最常見的錯誤訊息。

LOG:  could not bind IPv4 address "127.0.0.1": 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 any TCP/IP sockets

這通常表示它所建議的:您試圖在已運行伺服器的同一個埠上啟動另一個伺服器。但是,如果核心錯誤訊息不是 Address already in use 或類似的變體,則可能存在不同的問題。例如,嘗試在保留的埠號上啟動伺服器可能會顯示類似這樣的訊息

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

像這樣的訊息

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

可能表示您的核心對共享記憶體大小的限制小於 PostgreSQL 嘗試建立的工作區域(在此範例中為 4011376640 位元組)。只有在將 shared_memory_type 設定為 sysv 時,才可能發生這種情況。在這種情況下,您可以嘗試以小於正常數量的緩衝區 (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) 啟動伺服器來解決此問題,但您最終需要增加核心限制。

有關配置 System VIPC工具的詳細資訊,請參閱 第 18.4.1 節

18.3.2. 用戶端連線問題 #

雖然用戶端可能發生的錯誤狀況非常多樣且取決於應用程式,但其中一些可能與伺服器的啟動方式直接相關。除下面顯示的條件外,其他條件應記錄在各自的用戶端應用程式中。

psql: error: connection to server at "server.joe.com" (123.123.123.123), port 5432 failed: Connection refused
        Is the server running on that host and accepting TCP/IP connections?

這是通用的 我找不到可以通訊的伺服器 失敗。當嘗試 TCP/IP 通訊時,它看起來像上面這樣。一個常見的錯誤是忘記配置伺服器以允許 TCP/IP 連線。

或者,當嘗試使用 Unix 域套接字與本地伺服器通訊時,您可能會收到此訊息

psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory
        Is the server running locally and accepting connections on that socket?

如果伺服器確實正在運行,請檢查用戶端對套接字路徑(此處為 /tmp)的想法是否與伺服器的 unix_socket_directories 設定一致。

連線失敗訊息始終顯示伺服器位址或套接字路徑名稱,這有助於驗證用戶端是否嘗試連線到正確的位置。如果實際上沒有伺服器在那裡監聽,則核心錯誤訊息通常是 Connection refusedNo such file or directory,如圖所示。(重要的是要意識到,在此上下文中,Connection refused 並非表示伺服器已收到您的連線請求並拒絕了它。在這種情況下,將產生不同的訊息,如 第 20.15 節所示。)其他錯誤訊息(例如 Connection timed out)可能表示更根本的問題,例如缺乏網路連線或防火牆阻止連線。

提交更正

如果您在文件中發現任何不正確、與您使用特定功能的經驗不符或需要進一步澄清的地方,請使用此表格來回報文件問題。