为什么80%的码农都做不了架构师?>>>
2013.1.1 PG学习笔记
Chapter 17. Server Setup and Operation
第17章 服务器设置和操作
17.1. The PostgreSQL User Account
17.1. PostgreSQL用户账号
As with any server daemon that is accessible to the outside world, it is advisable to run PostgreSQL under a
separate user account. This user account should only own the data that is managed by the server, and should
not be shared with other daemons. (For example, using the user nobody is a bad idea.) It is not advisable to
install executables owned by this user because compromised systems could then modify their own binaries.
和任何可以从外部访问的服务器守护进程一样,建议在一个单独的用户账户下去运行PostgreSQL。
这个用户账号应该只拥有被服务器管理的数据,而且不应该与其他后台进程共享这些数据。(例如,使用nobody用户是一个
坏主意。) 不建议这个用户拥有安装可执行文件的权限,因为这样的话受攻击的系统可以修改自己拥有的二进制文件。
To add a Unix user account to your system, look for a command useradd or adduser. The user name postgres is
often used, and is assumed throughout this book, but you can use another name if you like.
为了向你的系统增加一个用户帐户,参考useradd命令或adduser。用户名postgres经常使用,并且在本书中都假设这个名字
,但你能使用另一个你喜欢的名字。
17.2. Creating a Database Cluster
17.2. 创建数据库集群
Before you can do anything, you must initialize a database storage area on disk. We call this a database
cluster. (SQL uses the term catalog cluster.) A database cluster is a collection of databases that is
managed by a single instance of a running database server. After initialization, a database cluster will
contain a database named postgres, which is meant as a default database for use by utilities, users and
third party applications. The database server itself does not require the postgres database to exist, but
many external utility programs assume it exists. Another database created within each cluster during
initialization is called template1. As the name suggests, this will be used as a template for subsequently
created databases; it should not be used for actual work. (See Chapter 21 for information about creating new
databases within a cluster.)
在你做任何事情之前,你必须初始化磁盘上的数据库存储区。我们称之为数据库集群。(SQL使用术语目录集群。)
一个数据库集群是一系列数据库的集合,这些数据库被一个正在运行的数据库服务器的一个实例管理。
初始化之后,数据库集群将包含一个叫postgres的数据库,它是作为一个默认的数据库被实用工具,用户,第三方应用程序
使用。
数据库服务器本身不需要postgres数据库存在,但许多外部实用工具程序都假设它存在。
在初始化期间在每个集群中的创建的另一个数据库被称为template1。顾名思义,这个数据库将被作为随后创建数据库的模
版;它不应该被用于实际的工作。
(参阅21章 获取有关在集群中创建新的数据库的信息)
In file system terms, a database cluster will be a single directory under which all data will be stored. We
call this the data directory or data area. It is completely up to you where you choose to store your data.
There is no default, although locations such as /usr/local/pgsql/data or /var/lib/pgsql/data are popular. To
initialize a database cluster, use the command initdb, which is installed with PostgreSQL. The desired file
system location of your database cluster is indicated by the -D option, for example:
$ initdb -D /usr/local/pgsql/data
Note that you must execute this command while logged into the PostgreSQL user account, which is described in
the previous section.
Tip: As an alternative to the -D option, you can set the environment variable PGDATA.
在文件系统方面,一个数据库集群将是一个单独的目录,所有的数据将被存储在这个目录中。我们称之为数据目录或数据区
。你选择在哪里存储你的数据完全取决于你。它没有默认值,尽管例如/usr/local/pgsql/data or /var/lib/pgsql/data这
样的路径是很常用。为了初始化数据库,使用initdb命令,这个命令与PostgreSQL一起安装。你的数据库集群所需的文件系
统路径通过-D选项指示,例如:
$ initdb -D /usr/local/pgsql/data
请注意你必须以PostgreSQL用户的身份执行这条命令,这一点在前面的章节描述过。
提示:作为-D选项的替代方案,你可以设置环境变量PGDATA。
Alternatively, you can run initdb via the pg_ctl program like so:
$ pg_ctl -D /usr/local/pgsql/data initdb
This may be more intuitive if you are using pg_ctl for starting and stopping the server (see Section 17.3),
so that pg_ctl would be the sole command you use for managing the database server instance.
或者,你能通过pg_ctl程序运行initdb:
$ pg_ctl -D /usr/local/pgsql/data initdb
如果你是使用pg_ctl启动和停止服务器(见Section 17.3),这可能是更直观的,以便pg_ctl将是你使用管理数据库服务器实
例的唯一命令。
initdb will attempt to create the directory you specify if it does not already exist. It is likely that it
will not have the permission to do so (if you followed our advice and created an unprivileged account). In
that case you should create the directory yourself (as root) and change the owner to be the PostgreSQL user.
Here is how this might be done:
root# mkdir /usr/local/pgsql/data
root# chown postgres /usr/local/pgsql/data
root# su postgres
postgres$ initdb -D /usr/local/pgsql/data
initdb will refuse to run if the data directory looks like it has already been initialized.
如果你指定的目录不存在,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将会拒绝运行。
Because the data directory contains all the data stored in the database, it is essential that it be secured
from unauthorized access. initdb therefore revokes access permissions from everyone but the PostgreSQL user.
因为数据目录包含所有存储在数据库中的数据,所以至关重要的是对于自来非授权的访问它是安全的。因此,initdb撤销除
了PostgreSQL用户以外的任何用户的访问权限。
However, while the directory contents are secure, the default client authentication setup allows any local
user to connect to the database and even become the database superuser. If you do not trust other local
users, we recommend you use one of initdb's -W, --pwprompt or --pwfile options to assign a password to the
database superuser. Also, specify -A md5 or -A password so that the default trust authentication mode is not
used; or modify the generated pg_hba.conf file after running initdb, but before you start the server for the
first time. (Other reasonable approaches include using peer authentication or file system permissions to
restrict connections. See Chapter 19 for more information.)
然而,尽管目录内容是安全的,但是默认客户端认证设置允许任何本地用户连接数据库甚至称为数据库超级用户。如果你不
信任其他的本地用户,我们建议你使用initdb的选项-W或者--pwprompt或者--pwfile给数据库超级用户赋予一个口令。也可
以指定-A md5或者-A password以便不使用默认trust身份验证模式;或者在initdb之后,在第一次启动服务器之前修改
pg_hba.conf文件。(其他合理的方法包括使用peer认证或者文件系统权限限制连接。更多信息见Chapter 19。)
initdb also initializes the default locale for the database cluster. Normally, it will just take the locale
settings in the environment and apply them to the initialized database. It is possible to specify a
different locale for the database; more information about that can be found in Section 22.1. The default
sort order used within the particular database cluster is set by initdb, and while you can create new
databases using different sort order, the order used in the template databases that initdb creates cannot be
changed without dropping and recreating them. There is also a performance impact for using locales other
than C or POSIX. Therefore, it is important to make this choice correctly the first time.
initdb也为数据库集群初始化默认语言环境。通常,它将只是使用环境中的语言环境设置并且应用它们到初始化数据中。为
数据库指定不同的语言环境,这是可能的;关于这些的更多信息可以在Section 22.1中找到。
在特定数据库集群中使用的默认排序规则被initdb设置,尽管你能使用不同的排序规则创建新的数据库,但是在模版数据库
中使用的规则(initdb创建的)不能更改,除非删除并重建它们。
使用非C或者POSIX的语言环境也会有性能的影响。因此第一次做出正确的选择是非常重要的。
initdb also sets the default character set encoding for the database cluster. Normally this should be chosen
to match the locale setting. For details see Section 22.3.
initdb也为数据库集群设置默认的字符集编码。通常,这个应该选择与语言环境设置配置的。详见Section 22.3。
17.2.1. Network File Systems
17.2.1. 网络文件系统
Many installations create database clusters on network file systems. Sometimes this is done directly via
NFS, or by using a Network Attached Storage (NAS) device that uses NFS internally. PostgreSQL does nothing
special for NFS file systems, meaning it assumes NFS behaves exactly like locally-connected drives (DAS,
Direct Attached Storage). If client and server NFS implementations have non-standard semantics, this can
cause reliability problems (see http://www.time-travellers.org/shane/papers/NFS_considered_harmful.html).
Specifically, delayed (asynchronous) writes to the NFS server can cause reliability problems; if possible,
mount NFS file systems synchronously (without caching) to avoid this. Also, soft-mounting NFS is not
recommended. (Storage Area Networks (SAN) use a low-level communication protocol rather than NFS.)
许多安装是在网络文件系统上安装数据库集群。有时,这是直接通过NFS做到,或者通过使用一个Network Attached
Storage(NAS)设备(其内部使用NFS)做到。
PostgreSQL不会特殊针对NFS文件系统,意味着它假设NFS的行为就像locally-connected驱动器(DAS, Direct Attached
Storage)。如果客户端和服务器的NFS实现有不标准的语义,这可能会导致可靠性问题(见http://www.time-
travellers.org/shane/papers/NFS_considered_harmful.html)。具体地说,延时的(异步的)写到NFS服务器可能导致可靠
性问题;如果可能,同步地挂载NFS文件系统(没有缓存)去避免这个问题。同时,不推荐soft-mounting NFS。(Storage Area
Networks (SAN)使用底层通信协议而不是NFS。)
17.3. Starting the Database Server
17.3. 启动数据库服务器
Before anyone can access the database, you must start the database server. The database server program is
called postgres. The postgres program must know where to find the data it is supposed to use. This is done
with the -D option. Thus, the simplest way to start the server is:
$ postgres -D /usr/local/pgsql/data
which will leave the server running in the foreground. This must be done while logged into the PostgreSQL
user account. Without -D, the server will try to use the data directory named by the environment variable
PGDATA. If that variable is not provided either, it will fail.
在任何人可以访问数据库之前,你必须启动数据库服务器。数据库服务器程序叫postgres。postgres程序必须知道到那里找
到它应该使用的数据。这是利用-D选项做到的。因此,启动服务器最简单的方式是:
$ postgres -D /usr/local/pgsql/data
这样将把服务器放在前台运行。这个步骤必须以PostgreSQL用户帐户登录来做到。没有-D选项,服务器将要尝试使用环境变
量PGDATA命名的数据目录。如果环境变量也没有,服务器将启动失败。
Normally it is better to start postgres in the background. For this, use the usual Unix shell syntax:
$ postgres -D /usr/local/pgsql/data >logfile 2>&1 &
It is important to store the server's stdout and stderr output somewhere, as shown above. It will help for
auditing purposes and to diagnose problems. (See Section 23.3 for a more thorough discussion of log file
handling.)
通常最好在后台启动postgres。为此,要使用通常的shell语法:
$ postgres -D /usr/local/pgsql/data >logfile 2>&1 &
把服务器的标准输出和标准错误输出存储在某个地方是非常重要的,如上所示。这有助于审计和诊断问题。(有关日志文件
处理更深入的讨论见Section 23.3)
The postgres program also takes a number of other command-line options. For more information, see the
postgres reference page and Chapter 18 below.
postgres程序也也有可以接受一些其他的命令行选项。更多信息见postgres参考页面和下面的Chapter 18。
This shell syntax can get tedious quickly. Therefore the wrapper program pg_ctl is provided to simplify some
tasks. For example:
pg_ctl start -l logfile
will start the server in the background and put the output into the named log file. The -D option has the
same meaning here as for postgres. pg_ctl is also capable of stopping the server.
这个shell语法很容易变得乏味起来。因此封装程序pg_ctl被提供去简化一些任务。例如:
pg_ctl start -l logfile
将在后台启动数据库并把输出放到指定的日志文件中。-D选项和postgres中的含义一样。pg_ctl还可以关闭数据库。
Normally, you will want to start the database server when the computer boots. Autostart scripts are
operating-system-specific. There are a few distributed with PostgreSQL in the contrib/start-scripts
directory. Installing one will require root privileges.
通常,你会希望在计算机启动的时候启动数据库服务器。自动启动脚本是与操纵系统相关的。PosgreSQL自带了几个,放在
contrib/start-scripts目录。安装它们将需要root权限。
Different systems have different conventions for starting up daemons at boot time. Many systems have a file
/etc/rc.local or /etc/rc.d/rc.local. Others use init.d or rc.d directories. Whatever you do, the server must
be run by the PostgreSQL user account and not by root or any other user. Therefore you probably should form
your commands using su postgres -c '...'. For example:
su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog'
不同的系统在启动时启动守护进程有不同的约定。许多系统有名称为/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'
Here are a few more operating-system-specific suggestions. (In each case be sure to use the proper
installation directory and user name where we show generic values.)
这里是一些比较相信的与操作系统相关的建议。(在每个例子里我们使用具体数值的地方,请务必使用合适的安装目录和用
户名)
For FreeBSD, look at the file contrib/start-scripts/freebsd in the PostgreSQL source distribution.
对于FreeBSD,查看PostgreSQL源代码发布包中的contrib/start-scripts/freebsd文件。
On OpenBSD, add the following lines to the file /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
在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
On Linux systems either add
/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data
to /etc/rc.d/rc.local or /etc/rc.local or look at the file contrib/start-scripts/linux in the PostgreSQL
source distribution.
在Linux系统上,可以在/etc/rc.d/rc.local或者/etc/rc.local中增加
/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data
或者PostgreSQL源代码发布包中查看contrib/start-scripts/linux文件。
On NetBSD, use either the FreeBSD or Linux start scripts, depending on preference.
在NetBSD上,根据你的喜好选择FreeBSD或者Linux的启动脚本。
On Solaris, create a file called /etc/init.d/postgresql that contains the following line:
su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data"
Then, create a symbolic link to it in /etc/rc3.d as S99postgresql.
在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。
While the server is running, its PID is stored in the file postmaster.pid in the data directory. This is
used to prevent multiple server instances from running in the same data directory and can also be used for
shutting down the server.
服务器运行的时候,它的PID保存在数据目录的postmaster.pid文件中。该文件是用来阻止多个服务器实例运行在同一个数
据目录里,该文件也可以用于关闭服务器。
17.3.1. Server Start-up Failures
17.3.1. 服务器启动失败
There are several common reasons the server might fail to start. Check the server's log file, or start it by
hand (without redirecting standard output or standard error) and see what error messages appear. Below we
explain some of the most common error messages in more detail.
有几个非常常见的原因导致服务器可能启动失败。检查服务器的日志或者手动启动服务器(没有重定向标准输出和标准错误
输出),查看出现了什么错误信息。下面我们更详细的解释一些最常见的错误信息。
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
This usually means just what it suggests: you tried to start another server on the same port where one is
already running. However, if the kernel error message is not Address already in use or some variant of that,
there might be a different problem. For example, trying to start a server on a reserved port number might
draw something like:
就像它提示的那样:你试图在同一个端口上启动另一个server,而这个端口上有一个server已经在运行。不过,如果内核错
误不是Address已经在使用或者它的一些变种,那就可能是不同的问题。例如,尝试在一个保留的端口上启动server可能会
出现如下信息:
$ postgres -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
A message like:
信息如下:
FATAL: could not create shared memory segment: Invalid argument
DETAIL: Failed system call was shmget(key=5440001, size=4011376640, 03600).
probably means your kernel's limit on the size of shared memory is smaller than the work area PostgreSQL is
trying to create (4011376640 bytes in this example). Or it could mean that you do not have System-V-style
shared memory support configured into your kernel at all. As a temporary workaround, you can try starting
the server with a smaller-than-normal number of buffers (shared_buffers). You will eventually want to
reconfigure your kernel to increase the allowed shared memory size. You might also see this message when
trying to start multiple servers on the same machine, if their total space requested exceeds the kernel
limit.
可能意味着你的内核对共享内存大小的限制小于PostgreSQl尝试创建的工作区(本例中是4011376640字节)。或者这可能意味
着你根本没有System-V-style共享内存支持配置到你的内核。作为一个临时解决方案,你可能试着使用小于正常数量的缓冲
区(共享缓冲区)启动服务器。你最终将希望重新配置你的内核,以增加允许的共享内存的大小。当你尝试在同一台机器上启
动多个服务器,如果它们所需的总空间超过了内核的限制,你也会看到这样的信息。
An error like:
错误信息如下:
FATAL: could not create semaphores: No space left on device
DETAIL: Failed system call was semget(5440126, 17, 03600).
does not mean you've run out of disk space. It means your kernel's limit on the number of System V
semaphores is smaller than the number PostgreSQL wants to create. As above, you might be able to work around
the problem by starting the server with a reduced number of allowed connections (max_connections), but
you'll eventually want to increase the kernel limit.
并不意味着你已经用光了磁盘空间。它意味着你的内核对System V 信号灯的限制小于PostgreSQL想要创建的数量。和上面
一样,你可能能够通过减少运行的连接数(max_connections)启动服务器来解决这个问题,但是你最终将希望增加内核的限
制。
If you get an "illegal system call" error, it is likely that shared memory or semaphores are not supported
in your kernel at all. In that case your only option is to reconfigure the kernel to enable these features.
如果你受到一个"illegal system call"的错误,那么很可能你的内核根本不支持共享内存或信号灯。如果这样的话,你的
唯一选择就是重新配置你的内核来启动这些特性。
Details about configuring System V IPC facilities are given in Section 17.4.1.
关于配置System V IPC功能的详细信息见Section 17.4.1.
17.3.2. Client Connection Problems
17.3.21 客户端连接问题
Although the error conditions possible on the client side are quite varied and application-dependent, a few
of them might be directly related to how the server was started. Conditions other than those shown below
should be documented with the respective client application.
虽然在客户端出现的错误条件是非常多样的,且依赖于应用程序的,但其中一些可能直接和服务器是怎样启动的直接相关。
除了以下提到的几个以外的问题都应该记录在各自的客户机应用程序。
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?
This is the generic "I couldn't find a server to talk to" failure. It looks like the above when TCP/IP
communication is attempted. A common mistake is to forget to configure the server to allow TCP/IP
connections.
这是一个具体的"I couldn't find a server to talk to"的错误。当试图进行TCP/IP通讯时看起来像上面那样。常见的错
误是忘记配置服务器去允许TCP/IP连接。
Alternatively, you'll get this when attempting Unix-domain socket communication to a local server:
或者,当尝试通过Unix-domain套接字与本地服务器通信时,你会看到这些信息:
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"?
The last line is useful in verifying that the client is trying to connect to the right place. If there is in
fact no server running there, the kernel error message will typically be either Connection refused or No
such file or directory, as illustrated. (It is important to realize that Connection refused in this context
does not mean that the server got your connection request and rejected it. That case will produce a
different message, as shown in Section 19.4.) Other error messages such as Connection timed out might
indicate more fundamental problems, like lack of network connectivity.
最后一行在验证客户端尝试连接到正确的位置是有效的。如果事实上没有服务器在那里运行,内核错误通常是例如
Connection refused或者No such file or directory。(这是很重要的:意识到上下文中Connection refused信息并不意味
着服务器接受了你的连接请求并然后拒绝了连接。这种情况下会产生不同的信息,见Section 19.4.) 其他的信息向
Connection timed out可能指示更基础的问题,比如缺少网络连接。