打印

PostgreSQL学习文档 8.0 继续

16.2. 创建数据库集群

在你做任何事情之前,你必须初始化磁盘上的数据库的存储区间。 我们管它叫数据库集群。(SQL 使用术语目录集群。) 一个数据库集群是一系列数据库的集合,这些数据库可以通过单个数据库服务器的实例管理。 在初始化后,一个数据库集群将包含一个叫template1的数据库。 正如其名一样,这个数据库将作为随后创建的数据库的模版;在实际工作中不应该使用这个库。 (参阅 Chapter 18 获取有关创建数据库的信息。)

用文件系统的术语来说,一个数据库集群将是一个目录,所有数据都将存放在这个目录中。 我们把它称做数据目录或数据区。 在哪里存放数据完全是你的选择,我们没有缺省值,尽管 /usr/local/pgsql/data 或 /var/lib/pgsql/data 这样的目录很常用。 要初始化一个数据库集群,可以使用命令 initdb, 这个命令与 PostgreSQL 一起安装。你可以用-D 标识你为你的数据库系统选择的文件系统位置,例如:

$ initdb -D /usr/local/pgsql/data

请注意你必须以PostgreSQL用户的身份来执行这条命令, 这一点我们在前面一节描述过。

    提示: 作为 -D选项的替代品,你还可以使用环境变量 PGDATA。

如果你声明的路径还不存在,initdb 将试图创建它。 你很有可能缺少做这些事情的权限(如果你按照我们的建议创建了一个非特权帐户的话)。 这时,你可以自己创建该目录(以root身份)然后把该目录的所有权交给PostgreSQL用户或者赋与她写权限。 下面是可能有效的方法:

root# mkdir /usr/local/pgsql/data
root# chown postgres /usr/local/pgsql/data
root# su postgres
postgres$ initdb -D /usr/local/pgsql/data

如果数据目录看起来象已经初始化过了,那么 initdb 会拒绝运行。

因为数据目录包含所有存储在数据库里的数据,所以出于安全考虑,这个目录不能给任何非授权用户访问。因此, initdb 禁止除 PostgreSQL 用户帐户以外的任何用户访问这个目录。

不过,因为目录的内容是安全的,所以缺省的客户端认证设置允许任意局部用户联接到数据库甚至成为超级用户。 如果你不信任你的本地用户,我们建议你使用 initdb 的选项 -W, --pwprompt 或者 --pwfile 给超级用户赋予一个口令。 还有,声明 -A md5 或者 -A password,这样就不会使用缺省的 trust。 或者在 initdb 之后, 在你第一次启动服务器之前修改 pg_hba.conf,让它使用 md5 或者 password,而不是 trust 认证方式。 (另外一些合理的方法包括 ident 认证或者用文件系统权限限止联接。 参阅 Chapter 19 获取更多细节。)

initdb 同时也为数据库集群初始化缺省区域。 通常,它将只是使用环境中的区域设置并且把它们应用与初始化的数据库。 我们可以为数据库声明不同的区域;有关这些的更多信息可以在 Section 20.1 中找到。 在特定数据库集群里的排序顺序是由 initdb 设置的, 而且以后就不能更改了,除非转储所有数据,重新运行initdb, 并重新装载数据。使用非 C 或者 POSIX 的区域还会有性能影响。 因此,第一次就选择正确很重要。

initdb 还为数据库集群设置缺省的字符集编码。 通常这个应该选择与区域匹配。详见 Section 20.2。

TOP

16.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放到某个地方是非常重要的,就象在上面建议的这样。 这样做既可以帮助审计又可以帮助诊断问题。 (参阅 Section 21.3 获取有关日志文件处理的更完整的讨论。)

postmaster 还接受一些其他的一些命令行选项。 更多的信息请参考手册页 postmaster 和下面的 Section 16.4。

这些 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 -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

    *

      在 Linux 系统里,要么往 /etc/rc.d/rc.local 文件里加上下面几行:

      /usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data

      要么看看 PostgreSQL 程序版本里的文件 contrib/start-scripts/linux。
    *

      在 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。

postmaster 运行的时候,它的PID是保存在数据目录里的文件 postmaster.pid 里的。这样做是为了避免多个postmaster在同一个数据目录内运行,此文件同样可以用于关闭postmaster。
16.3.1. 服务器启动失败

有几个非常常见的原因会导致 postmaster 启动失败。 通过检查 postmaster 日志或者使用手工启动的方法(不做 stdout和stderr 的重定向), 就可以看到错误信息。下面我们更详细地解释了其中一些错误信息。

LOG:  could not bind IPv4 socket: 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 TCP/IP listen socket

就象它提示的那样:你试图在已经有一个 postmaster 运行着的端口上再运行了一个 postmaster。不过,如果内核的错误信息不是 Address already in use 或者是其它的变种,那就有可能是别的毛病。 比如,试图在一个保留的端口上运行postmaster会收到下面这样的信息:

$ postmaster -p 666
LOG:  could not bind IPv4 socket: Permission denied
HINT:  Is another postmaster already running on port 666? If not, wait a few seconds and retry.
FATAL:  could not create TCP/IP listen socket

象这样的信息

FATAL:  could not create shared memory segment: Invalid argument
DETAIL:  Failed system call was shmget(key=5440001, size=4011376640, 03600).

可能意味着你的内核对共享内存区的限制小于PostgreSQL 试图分配的缓冲区大小(本例中是 4011376640 字节)。 或者可能意味着你根本就没有配置System-V风格的共享内存支持。 作为一个临时的解决办法,你可以试着以小于正常数量的缓冲区数(-B开关)启动服务器。 你最终还是会希望重新配置你的内核,以增加共享内存的尺寸。如果你试图在同一台机器上启动多个服务器, 而且她们所需的总空间超过了内核的限制,也会报这个错。

象下面这样的错误

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

并不意味着着你已经用光磁盘空间了。 它的意思是你的内核的System V信号灯的限制小于 PostgreSQL 想创建的数量。和上面一样,你可以通过减少允许的连接数(-N开关)来绕开,但最终你还是会希望增加内核的限制。

如果你收到一个 "illegal system call" 错误,那么很有可能是你的内核根本不支持共享内存或者信号灯。 如果是这样的话,你的唯一选择就是重新配置你的内核并且把这些特性打开。

关于配置系统System V IPC资源的细节见 Section 16.5.1。
16.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 通讯时它看起来象上面的样子。 常见的错误是忘记把服务器配置成允许 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 19.3 里面显示的那样) 其它象 Connection timed out 这样的信息表示更基本的问题,比如缺少网络联接等。

TOP


感谢一直以来您对我们的支持!
当前时区 GMT+8, 现在时间是 2008-9-6 11:25 京ICP证060528 号

Designed By 17DST