18.3. 启动数据库服务器

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

postgres程序还具有许多其他命令行选项。有关更多信息,请参见postgres参考页和下面的Chapter 19

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

pg_ctl start -l logfile

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

通常,您需要在计算机启动时启动数据库服务器。 自动启动脚本是特定于 os 的。 PostgreSQL 的contrib/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'

以下是一些针对特定 os 的建议。 (在每种情况下,请确保在显示通用值的地方使用正确的安装目录和用户名.)

  • 对于 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)

[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=0

[Install]
WantedBy=multi-user.target

使用Type=notify要求服务器二进制文件是使用configure --with-systemd构建的。

请仔细考虑超时设置。截至撰写本文时,systemd 的默认超时为 90 秒,它将终止在该时间内未通知就绪的进程。但是,可能需要在启动时执行崩溃恢复的 PostgreSQL 服务器可能需要更长的时间才能准备就绪。建议值为 0 禁用超时逻辑。

  • 在 NetBSD 上,根据喜好使用 FreeBSD 或 Linux 启动脚本。

  • 在 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 字节)。否则可能意味着您根本没有在内核中配置 System-V 样式的共享内存支持。作为临时的解决方法,您可以尝试使用比正常数量少的缓冲区(shared_buffers)启动服务器。您最终将需要重新配置内核,以增加允许的共享内存大小。如果尝试在同一台计算机上启动多个服务器,如果它们请求的总空间超过了内核限制,那么您也可能会看到此消息。

像这样的错误:

FATAL:  could not create semaphores: No space left on device
DETAIL:  Failed system call was semget(5440126, 17, 03600).

不是表示您已用完磁盘空间。这意味着您的内核对 System Vsignal 量的限制小于 PostgreSQL 要创建的数目。如上所述,您可以通过减少允许的连接数(max_connections)启动服务器来解决此问题,但最终您将希望增加内核限制。

如果收到“非法系统调用”错误,则可能是内核根本不支持共享内存或 signal 灯。在这种情况下,您唯一的选择是重新配置内核以启用这些功能。

Section 18.4.1中提供了有关配置 System V IPC 设施的详细信息。

18 .3.2. Client 端连接问题

尽管 Client 端可能发生的错误情况千差万别,并且取决于应用程序,但其中一些错误可能与服务器的启动方式直接相关。除以下所示条件外,其他应用程序应记录在案。

psql: could not connect to server: Connection refused
        Is the server running on host "server.joe.com" and accepting
        TCP/IP connections on port 5432?

这是一般性的“我找不到要交谈的服务器”失败。尝试进行 TCP/IP 通信时,看起来像上面的样子。一个常见的错误是忘记将服务器配置为允许 TCP/IP 连接。

另外,尝试与本地服务器进行 Unix 域套接字通信时,您会得到以下信息:

psql: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

最后一行对于验证 Client 端是否尝试连接到正确的位置很有用。如果实际上那里没有服务器在运行,则内核错误消息通常为Connection refusedNo such file or directory,如图所示。 (很重要的一点是,在这种情况下Connection refused并不表示服务器得到了您的连接请求并拒绝了它.这种情况将产生不同的消息,如Section 20.15所示。)其他错误消息,例如Connection timed out可能表示更多基本问题,例如缺乏网络连接。