2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 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 許可權。

不同的系統在啟動時的守護程序啟動方式上具有不同的約定。許多系統都有 /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 系統上,將以下命令之一新增到 /etc/rc.d/rc.local/etc/rc.local 中,或者檢視 PostgreSQL 原始碼分發中的 contrib/start-scripts/linux 檔案:

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

    或者檢視 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 V 的詳細資訊IPC設施,請參見 第 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 通訊時,它看起來像上面這樣。一個常見的錯誤是忘記配置 listen_addresses 以便伺服器接受遠端 TCP 連線。

或者,當嘗試與本地伺服器進行 Unix-domain 套接字通訊時,您可能會收到此錯誤:

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.16 節 所示。)其他錯誤訊息,例如 Connection timed out,可能表示更根本的問題,例如網路連線丟失或防火牆阻止了連線。

提交更正

如果您在文件中看到任何不正確之處、與您在使用特定功能時的體驗不符或需要進一步澄清的內容,請使用 此表格 報告文件問題。