在您可以进行任何操作之前,您必须在磁盘上初始化一个数据库存储区域。我们称之为数据库集群。(SQL标准使用术语目录集群。)数据库集群是单个正在运行的数据库服务器实例管理的一组数据库。初始化后,数据库集群将包含一个名为postgres
的数据库,它被用作实用程序、用户和第三方应用程序使用的默认数据库。数据库服务器本身不需要postgres
数据库存在,但许多外部实用程序程序假定它存在。在初始化期间,每个集群中还会创建另外两个数据库,分别命名为template1
和template0
。顾名思义,这些将用作随后创建的数据库的模板;它们不应用于实际工作。(有关在集群中创建新数据库的信息,请参见第 22 章。)
在文件系统方面,数据库集群是一个单个目录,所有数据都将存储在该目录下。我们称之为数据目录或数据区域。您完全可以自行选择数据存储位置。没有默认值,尽管/usr/local/pgsql/data
或/var/lib/pgsql/data
等位置很受欢迎。数据目录必须在使用之前进行初始化,使用initdb程序,该程序与PostgreSQL一起安装。
如果您使用的是预打包的PostgreSQL版本,它很可能会有一个放置数据目录的特定约定,并且它也可能提供一个创建数据目录的脚本。在这种情况下,您应该使用该脚本而不是直接运行initdb
。有关详细信息,请参阅包级文档。
要手动初始化数据库集群,请运行initdb
并使用-D
选项指定数据库集群所需的文件系统位置,例如
$
initdb -D /usr/local/pgsql/data
请注意,您必须以PostgreSQL用户帐户登录后才能执行此命令,该帐户在上一节中进行了介绍。
或者,您可以通过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 创建的模板数据库中使用的顺序,除非删除和重新创建它们。使用除C
或POSIX
之外的区域设置也会影响性能。因此,第一次做出正确的选择非常重要。
initdb
还设置数据库集群的默认字符集编码。通常,应选择与区域设置匹配的字符集编码。有关详细信息,请参见第 23.3 节。
非C
和非POSIX
区域设置依赖于操作系统的排序库来进行字符集排序。这控制存储在索引中的键的排序。因此,集群无法切换到不兼容的排序库版本,无论是通过快照恢复、二进制流复制、不同的操作系统还是操作系统升级。
许多安装在其数据库集群上创建文件系统(卷),而不是机器的“root”卷。如果您选择这样做,不建议尝试将辅助卷的最顶层目录(挂载点)用作数据目录。最佳做法是在挂载点目录中创建一个由PostgreSQL用户拥有的目录,然后在该目录中创建数据目录。这避免了权限问题,特别是对于pg_upgrade等操作,并且还确保在辅助卷脱机时干净地失败。
通常,任何具有 POSIX 语义的文件系统都可以用于 PostgreSQL。用户出于各种原因更喜欢不同的文件系统,包括供应商支持、性能和熟悉度。经验表明,在其他条件相同的情况下,仅通过切换文件系统或进行较小的文件系统配置更改,不应该期望出现重大的性能或行为变化。
可以使用NFS用于存储 PostgreSQL 数据目录的文件系统。 PostgreSQL 不会对NFS文件系统做任何特殊处理,这意味着它假设NFS的行为与本地连接的驱动器完全相同。 PostgreSQL 不使用任何已知在NFS上具有非标准行为的功能,例如文件锁定。
使用NFS与 PostgreSQL 的唯一严格要求是文件系统必须使用 hard
选项挂载。使用 hard
选项,如果出现网络问题,进程可能会无限期地 “挂起”,因此此配置需要仔细的监控设置。 soft
选项将在出现网络问题时中断系统调用,但 PostgreSQL 不会重复以这种方式中断的系统调用,因此任何此类中断都将导致报告 I/O 错误。
不需要使用 sync
挂载选项。 async
选项的行为就足够了,因为 PostgreSQL 会在适当的时候发出 fsync
调用来刷新写入缓存。(这类似于它在本地文件系统上的工作方式。)但是,强烈建议在存在 sync
导出选项的 NFS 服务器 系统上使用该选项(主要是 Linux)。否则,NFS 客户端上的 fsync
或等效操作实际上不能保证到达服务器上的永久存储,这可能会导致类似于使用参数 fsync 关闭运行的损坏。这些挂载和导出选项的默认值在供应商和版本之间有所不同,因此建议在任何情况下都检查并可能明确指定它们,以避免任何歧义。
在某些情况下,可以通过 NFS 或更底层的协议(如 iSCSI)访问外部存储产品。在后一种情况下,存储显示为块设备,并且可以在其上创建任何可用的文件系统。这种方法可能会使 DBA 免于处理 NFS 的一些特性,但当然,远程存储管理的复杂性会在其他层面上发生。
如果您在文档中看到任何不正确的内容,与您对特定功能的体验不符,或者需要进一步澄清,请使用 此表格 报告文档问题。