Postgresql 中文操作指南

19.2. Creating a Database Cluster #

在执行任何操作之前,您必须初始化磁盘上的数据库存储区。我们称之为 database cluster。(SQL 标准使用术语目录集群。)数据库集群是由运行数据库服务器的一个实例管理的数据库集合。初始化后,数据库集群将包含一个名为 postgres 的数据库,该数据库旨在作为实用工具、用户和第三方应用程序使用的默认数据库。数据库服务器本身不要求存在 postgres 数据库,但许多外部实用工具程序假定它存在。在每个集群初始化过程中,另外创建两个数据库,分别命名为 template1template0。顾名思义,这些数据库将用作后续创建的数据库的模板;它们不应用于实际工作。(有关在集群中创建新数据库的信息,请参见 Chapter 23。)

在文件系统术语中,数据库集群是将存储所有数据的一个目录。我们称其为 data directorydata area 。将数据存储在何处完全由你决定。没有默认位置,但诸如 /usr/local/pgsql/data/var/lib/pgsql/data 之类的位置很常见。在使用之前,必须使用随 PostgreSQL 一起安装的程序 initdb 初始化数据目录。

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

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

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

请注意,必须在登录到 PostgreSQL 用户帐户时执行此命令,该帐户在上一部分中进行了描述。

Tip

作为 -D 选项的替代方法,可以设置环境变量 PGDATA

或者,你可以像这样通过 pg_ctl 程序运行 initdb

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

如果您使用 pg_ctl 开始和停止服务器(见 Section 19.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 文件,但在 before 首次启动服务器。 (其他合理的方法包括使用 peer 身份验证或文件系统权限来限制连接。有关详细信息,请参见 Chapter 21。)

initdb 还初始化数据库集群的默认区域设置。通常,它只会采用环境中的区域设置并将其应用到已初始化的数据库。可以为数据库指定其他区域设置;更多信息请参见 Section 24.1。initdb 创建的特定数据库集群中使用的默认排序顺序由 initdb 设置,虽然您可以使用不同的排序顺序创建新数据库,但在模板数据库中使用的顺序无法在不删除并重新创建它们的情况下进行更改。对于使用除 CPOSIX 之外的区域设置,也会存在性能影响。因此,首次正确做出此选择非常重要。

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

C 和非 POSIX 区域设置依赖于操作系统的排序规则库来进行字符集排序。这控制了存储在索引中的密钥的排序顺序。因此,一个群集无法通过快照还原、二进制流复制、不同的操作系统或操作系统升级切换到不兼容的排序规则库版本。

19.2.1. Use of Secondary File Systems #

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

19.2.2. File Systems #

一般来说,任何具有 POSIX 语法的文件系统都可以用于 PostgreSQL。由于各种原因,用户更喜欢不同的文件系统,包括供应商支持、性能和熟悉程度。经验表明,在其他条件相同的情况下,不应该仅仅因为切换文件系统或进行微小的文件系统配置更改,而期望产生重大的性能或行为变化。

19.2.2.1. NFS #

可以将 NFS 文件系统用于存储 PostgreSQL 数据目录。PostgreSQL 没有针对 NFS 文件系统采取任何特殊措施,这意味着它假设 NFS 的行为与本地连接的驱动器完全相同。PostgreSQL 没有使用任何已知在 NFS 上具有非标准行为的功能,例如文件锁定。

将 NFS 与 PostgreSQL 结合使用的唯一严格要求是文件系统使用 hard 选项装入。通过 hard 选项,如果出现网络问题,进程可能会无限期地“挂起”,所以此配置将需要精心设置监控。soft 选项将在出现网络问题时中断系统调用,但 PostgreSQL 不会重复以这种方式中断的系统调用,所以任何此类中断都会导致报告 I/O 错误。

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

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