Postgresql 中文操作指南

19.3. Starting the Database Server #

在任何人可以访问数据库之前,你必须启动数据库服务器。数据库服务器程序称为 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 &

以如上所示的方式将服务器的 stdout 和 stderr 输出存储在某处非常重要。这将有助于进行审计和诊断问题。(请参见 Section 25.3 以获得对日志文件操作的更深入讨论。)

postgres 程序还会获取许多其他命令行选项。有关详细信息,请参阅 postgres 参考页和 Chapter 20 (如下)。

这种 shell 语法很快就变得很繁琐。因此,提供了包装程序 pg_ctl 来简化某些任务。例如:

pg_ctl start -l logfile

将启动服务器后台并把输出放入指定日志文件。-D 选项在此的含义与 postgres 相同。pg_ctl 还能够停止服务器。

通常,您希望在计算机启动时启动数据库服务器。自动启动脚本是操作系统特定的。PostgreSQL 中 contrib/start-scripts 目录中分发了几个示例脚本。安装它们需要 root 权限。

不同的系统在启动时间启动守护进程时有不同的约定。许多系统都有文件 /etc/rc.local/etc/rc.d/rc.local。其他系统使用 init.drc.d 目录。无论您做什么,服务器都必须由 PostgreSQL 用户账户 and not by root 或任何其他用户运行。因此,您可能应该使用 su postgres -c '…​' 形成命令。例如:

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

以下是一些更具体的操作系统建议。(在每种情况下,请务必使用我们显示通用值时使用的正确安装目录和用户名。)

在服务器正在运行时,其 PID 存储在数据目录中的文件 postmaster.pid 中。这用于防止多个服务器实例在同一数据目录中运行,也可以用于关闭服务器。

19.3.1. Server Start-up Failures #

有几个常见的原因会导致服务器无法启动。检查服务器日志文件,或手动启动它(不重定向标准输出或标准错误),看看出现了哪些错误消息。下面我们更详细地解释一些最常见的错误消息。

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 设施的详细信息,请参见 Section 19.4.1

19.3.2. Client Connection Problems #

尽管客户端端的可能错误条件多种多样,并且依赖于应用程序,但其中一些可能直接与服务器的启动方式相关。除以下所示以外的条件应记录在各自的客户端应用程序中。

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 refusednot 不意味着服务器收到你的连接请求并拒绝该请求很重要。此情况将生成另一条消息,如 Section 21.15 中所示。)其他错误消息(例如 Connection timed out)可能表明存在更根本性的问题,例如缺乏网络连接性,或防火墙阻止了连接。