2025年9月25日: PostgreSQL 18 发布!
支持的版本:当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本:devel
不支持的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

18.2. 创建数据库集群 #

在可以进行任何操作之前,必须在磁盘上初始化一个数据库存储区域。我们称之为数据库集群。(SQL标准术语是目录集群。)数据库集群是由单个正在运行的数据库服务器实例管理的数据库集合。初始化后,数据库集群将包含一个名为postgres的数据库,该数据库用于实用程序、用户和第三方应用程序的默认数据库。数据库服务器本身不需要postgres数据库存在,但许多外部实用程序都假定它存在。初始化期间,每个集群中还会创建另外两个数据库,分别命名为template1template0。顾名思义,它们将用作后续创建的数据库的模板;不应将其用于实际工作。(有关集群内创建新数据库的信息,请参阅第 22 章。)

从文件系统角度来看,数据库集群是所有数据将存储在其下的一个目录。我们称之为数据目录数据区域。数据的存储位置完全由您决定。没有默认位置,尽管/usr/local/pgsql/data/var/lib/pgsql/data等位置很受欢迎。数据目录在使用前必须使用initdb程序进行初始化,该程序随PostgreSQL一起安装。

如果您使用的是预打包版本的PostgreSQL,它可能有关于放置数据目录位置的特定约定,并且可能还提供用于创建数据目录的脚本。在这种情况下,您应该优先使用该脚本,而不是直接运行initdb。有关详细信息,请参阅打包文档。

要手动初始化数据库集群,请运行initdb,并使用-D选项指定数据库集群所需的文件系统位置,例如

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

请注意,您必须在登录到PostgreSQL用户帐户时执行此命令,该帐户在上一节中已介绍。

提示

除了-D选项外,还可以设置环境变量PGDATA

或者,可以通过pg_ctl程序运行initdb,如下所示

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

如果您使用pg_ctl来启动和停止服务器(请参阅第 18.3 节),那么这样做可能会更直观,这样pg_ctl将是您用于管理数据库服务器实例的唯一命令。

initdb将尝试创建指定的目录(如果它尚不存在)。当然,如果initdb没有写入父目录的权限,这将失败。通常建议PostgreSQL用户不仅拥有数据目录,还拥有其父目录,这样就不会出现问题。如果父目录也不存在,您将需要使用root权限先创建它(如果祖父目录不可写)。因此,该过程可能如下所示:

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

initdb将拒绝在数据目录存在且已包含文件时运行;这是为了防止意外覆盖现有安装。

由于数据目录包含数据库中存储的所有数据,因此必须确保其免受未经授权的访问。因此,initdb会撤销除PostgreSQL用户(以及可选的组)以外所有人的访问权限。启用时,组访问是只读的。这允许集群所有者同组中的非特权用户备份集群数据或执行其他仅需要读取访问权限的操作。

请注意,在现有集群上启用或禁用组访问需要关闭集群,并在重新启动PostgreSQL之前设置所有目录和文件的适当模式。否则,数据目录中可能会存在模式混合。对于仅允许所有者访问的集群,适当的模式是目录的0700和文件的0600。对于也允许组读取的集群,适当的模式是目录的0750和文件的0640

但是,虽然目录内容是安全的,但默认的客户端身份验证设置允许任何本地用户连接到数据库,甚至成为数据库超级用户。如果您不信任其他本地用户,我们建议您使用initdb-W--pwprompt--pwfile选项之一为数据库超级用户分配密码。另外,指定-A scram-sha-256,以便不使用默认的trust身份验证模式;或者在运行initdb之后修改生成的pg_hba.conf文件,但第一次启动服务器之前。(其他合理的做法包括使用peer身份验证或文件系统权限来限制连接。有关更多信息,请参阅第 20 章。)

initdb还会初始化数据库集群的默认区域设置。通常,它只是采用环境中的区域设置并将其应用于已初始化的数据库。可以为数据库指定不同的区域设置;有关更多信息,请参阅第 23.1 节initdb设置了特定数据库集群使用的默认排序顺序,虽然您可以创建具有不同排序顺序的新数据库,但在删除并重新创建initdb创建的模板数据库之前,其排序顺序无法更改。使用非CPOSIX区域设置也会影响性能。因此,首次正确做出此选择非常重要。

initdb还设置了数据库集群的默认字符集编码。通常应选择与区域设置匹配的编码。有关详细信息,请参阅第 23.3 节

C和非POSIX区域设置依赖于操作系统在字符集排序方面的整理库。这控制着索引中存储的键的排序。因此,集群无法通过快照恢复、二进制流复制、不同的操作系统或操作系统升级切换到不兼容的整理库版本。

18.2.1. 使用辅助文件系统 #

许多安装在机器的卷以外的文件系统(卷)上创建数据库集群。如果您选择这样做,不建议尝试使用辅助卷的最顶层目录(挂载点)作为数据目录。最佳做法是在由PostgreSQL用户拥有的挂载点目录内创建一个目录,然后在此目录内创建数据目录。这可以避免权限问题,特别是对于pg_upgrade等操作,并且在辅助卷脱机时也能确保干净地失败。

18.2.2. 文件系统 #

通常,任何具有POSIX语义的文件系统都可以用于PostgreSQL。用户出于各种原因偏好不同的文件系统,包括供应商支持、性能和熟悉度。经验表明,在其他条件相同的情况下,仅仅切换文件系统或进行小的文件系统配置更改不应该期望有重大的性能或行为变化。

18.2.2.1. NFS #

可以为存储PostgreSQL数据目录使用NFS文件系统。PostgreSQL不对NFS文件系统做任何特殊处理,这意味着它假设NFS行为与本地连接的驱动器完全相同。PostgreSQL不使用任何已知在NFS上行为不标准的函数,例如文件锁定。

使用NFSPostgreSQL的唯一硬性要求是使用hard选项挂载文件系统。使用hard选项,如果存在网络问题,进程可能会无限期地挂起,因此此配置需要仔细的监控设置。soft选项会在网络问题时中断系统调用,但PostgreSQL不会重复中断的系统调用,因此任何此类中断都会导致报告I/O错误。

不一定需要使用sync挂载选项。async选项的行为就足够了,因为PostgreSQL会适时发出fsync调用以刷新写缓存。(这类似于它在本地文件系统上的工作方式。)但是,强烈建议在存在sync导出选项的系统(主要是Linux)的NFS服务器上使用该选项。否则,NFS客户端上的fsync或等效操作实际上不能保证到达服务器上的永久存储,这可能会导致类似于在参数fsync关闭的情况下运行的损坏。这些挂载和导出选项的默认值在供应商和版本之间有所不同,因此建议在任何情况下都要检查并可能显式指定它们,以避免任何歧义。

在某些情况下,可以通过NFS或更低级别的协议(如iSCSI)访问外部存储产品。在后一种情况下,存储显示为块设备,并且可以在其上创建任何可用的文件系统。这种方法可以使DBA不必处理NFS的一些特性,但当然,管理远程存储的复杂性会在其他级别上发生。

提交更正

如果您在文档中看到任何不正确、与您的实际体验不符或需要进一步澄清的内容,请使用此表单报告文档问题。