2024 年 9 月 26 日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不支持的版本: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 系统上,添加

    /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,可能表示更基本的问题,例如网络连接故障或防火墙阻止连接。

提交更正

如果您在文档中看到任何不正确的内容,与您对特定功能的体验不符,或者需要进一步澄清,请使用 此表单 报告文档问题。