在任何人访问数据库之前,必须先启动数据库服务器。数据库服务器程序名为 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 还可用于停止服务器。
通常,你会希望在计算机启动时就启动数据库服务器。 自动启动脚本依赖于操作系统。PostgreSQL 在 contrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本需要 root 权限。
不同系统在引导时启动守护进程的惯例各不相同。许多系统有/etc/rc.local或/etc/rc.d/rc.local文件,其他系统则使用init.d或rc.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
/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可以禁用该超时逻辑。
在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文件里。这可以防止多个服务器实例在同一个数据目录上运行,也可以用来关闭服务器。
服务器启动失败有几种常见原因。请检查服务器日志文件,或者手工启动服务器(不要重定向标准输出和标准错误),看看出现了什么错误消息。下面将更详细地解释一些最常见的错误消息。
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 V信号量数量的限制,小于PostgreSQL想要创建的数量。和上面一样,你也许可以通过减少允许的连接数(max_connections)来暂时绕过这个问题,但最终还是应该提高内核限制。
如果收到 “illegal system call” 错误,很可能是内核根本不支持共享内存或信号量。在这种情况下,唯一的办法就是重新配置内核以启用这些功能。
关于配置System V IPC功能的细节请见Section 18.4.1。
客户端一侧可能出现的错误种类很多,并且依赖于具体应用,但其中有一些可能直接与服务器的启动方式有关。除下面列出的几种情况外,其他问题应查阅相应客户端应用的文档。
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"?
最后一行有助于确认客户端是否正尝试连接到正确的位置。如果那里实际上没有运行服务器,内核错误消息通常会像示例那样是 Connection refused 或 No such file or directory。(要注意,在这里 Connection refused 并不表示服务器收到了你的连接请求并拒绝了它;那种情况会产生另一条消息,如 Section 20.4 所示。)其他错误消息,例如 Connection timed out,可能表示更底层的问题,例如网络不通。