3.3. 启动数据库服务器 #
在任何人访问数据库之前,必须先启动数据库服务器。数据库服务器称为
postmaster。postmaster 必须知道应到哪里查找它要使用的数据。这通过 -D 选项指定。因此,启动服务器最简单的方法是:
$ postmaster -D /usr/local/pgsql/data
这会让服务器在前台运行。必须以 PostgreSQL
用户账户登录后再执行此操作。如果不使用 -D,服务器会尝试使用环境变量 PGDATA 所指定的数据目录。如果两者都未提供,则会失败。
要在后台启动 postmaster,可使用常见的 shell 语法:
$ postmaster -D /usr/local/pgsql/data > logfile 2>&1 &如上所示,把服务器的stdout和 stderr输出保存到某个地方非常重要。这有助于审计,也有助于诊断问题。(关于日志文件处理的更深入讨论,见第 8.4 节。)
postmaster 还接受许多其他命令行选项。更多信息请见参考页以及下面的第 3.4 节。特别是,要让服务器接受 TCP/IP 连接(而不只是 Unix 域套接字连接),必须指定 -i 选项。
这些 shell 语法很快就会让人觉得繁琐。因此提供了 shell 脚本包装器 pg_ctl 来简化一些任务。例如:
pg_ctl start -l logfile
会在后台启动服务器,并把输出写入指定的日志文件。这里的
-D 选项含义与在 postmaster 中相同。
pg_ctl 还可用于停止服务器。
通常,你会希望在计算机启动时就启动数据库服务器。自动启动脚本依赖于操作系统。PostgreSQL 在 /contrib/start-scripts 目录中附带了一些示例脚本。安装这些脚本可能需要 root 权限。
不同系统在引导时启动守护进程的惯例各不相同。许多系统有
/etc/rc.local或/etc/rc.d/rc.local
文件,其他系统则使用rc.d目录。无论采用哪种方式,服务器都必须由PostgreSQL用户账户而不是
root或其他用户来启动。因此,你大概应该在命令中使用
su -c '...' postgres 这种形式。例如:
su -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog' postgres
下面是一些与操作系统相关的补充建议。(务必把它们替换为正确的安装目录和用户名。)
在FreeBSD上,请查看PostgreSQL 源码发布包中的
contrib/start-scripts/freebsd文件。在OpenBSD上,把以下内容加入
/etc/rc.local文件:if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postmaster ]; then su - -c '/usr/local/pgsql/bin/pg_ctl start -l /var/postgresql/log -s' postgres echo -n ' postgresql' fi/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data
加入
/etc/rc.d/rc.local,或者查看 PostgreSQL源码发布包中的contrib/start-scripts/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。
当 postmaster 运行时,其PID
保存在数据目录中的postmaster.pid文件里。这用于防止多个 postmaster 在同一个数据目录上运行,也可以用来关闭
postmaster。
3.3.1. 服务器启动失败 #
postmaster 启动失败有几种常见原因。请检查 postmaster 的日志文件,或者手工启动它(不要重定向标准输出和标准错误),看看出现了什么错误消息。有些错误消息是不言自明的,但有些不是,如下所示:
FATAL: StreamServerPort: bind() failed: Address already in use
Is another postmaster already running on that port?
这通常就是字面上的意思:你试图在一个已有 postmaster 运行的端口上再启动另一个 postmaster。不过,如果内核错误消息不是
Address already in use或类似变体,也可能是别的问题。例如,试图在一个保留端口号上启动 postmaster,可能会得到类似下面的消息:
$ postmaster -i -p 666
FATAL: StreamServerPort: bind() failed: Permission denied
Is another postmaster already running on that port?
像下面这样的消息:
IpcMemoryCreate: shmget(key=5440001, size=83918612, 01600) failed: Invalid argument FATAL 1: ShmemCreate: cannot create region
这样的消息可能表示内核对共享内存大小的限制小于
PostgreSQL 尝试创建的缓冲区区域(本例中为 83918612 字节)。也可能表示你的内核中根本没有配置 System V
风格的共享内存支持。作为临时解决办法,可以尝试以少于通常数量的缓冲区启动 postmaster(-B 开关)。最终还是需要重新配置内核,增大允许的共享内存大小。如果尝试在同一台机器上启动多个 postmaster,而它们请求的总空间超出内核限制,也可能看到这条消息。
像下面这样的错误:
IpcSemaphoreCreate: semget(key=5440026, num=16, 01600) failed: No space left on device
这样的错误并不意味着你已经用光了磁盘空间。它表示你的内核对System V
信号量数量的限制,小于PostgreSQL想要创建的数量。和上面一样,你也许可以通过以减少的允许连接数(-N 开关)启动 postmaster 来暂时绕过这个问题,但最终还是应该提高内核限制。
如果收到 “illegal system call” 错误,很可能是内核根本不支持共享内存或信号量。在这种情况下,唯一的办法就是重新配置内核以启用这些功能。
关于配置System V IPC功能的细节请见第 3.5.1 节。
3.3.2. 客户端连接问题 #
客户端一侧可能出现的错误种类很多,并且依赖于具体应用,但其中有一些可能直接与服务器的启动方式有关。除下面列出的几种情况外,其他问题应查阅相应客户端应用的文档。
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 通信时,它就会显示为上述形式。一个常见错误是忘记使用 -i 选项,使 postmaster 能接受 TCP/IP 连接。
另一种情况是,尝试通过 Unix 套接字与本地 postmaster 通信时,会得到以下消息:
psql: could not connect to server: Connection refused
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
最后一行有助于确认客户端是否正尝试连接到正确的位置。如果那里实际上没有运行 postmaster,内核错误消息通常会像示例那样是 Connection refused 或 No such file or directory。(要注意,在这里 Connection refused 并不表示 postmaster 收到了你的连接请求并拒绝了它——那种情况会产生另一条消息,如第 6.3 节所示。)其他错误消息,例如 Connection timed out,可能表示更底层的问题,例如网络不通。