数据库管理

1.产品概述

优炫数据库(UXDB)是一款自主研发的企业级关系型数据库,其技术核心采用多引擎架构,同时支持行存储、列存储及混合存储模式以应对不同的负载场景;通过实时应用集群(SRAC)与主备集群技术,结合读写分离和在线弹性扩容机制,实现了高可用性与高性能扩展能力。在安全层面,产品提供了从身份鉴别、强制访问控制到数据加密及全生命周期审计的多层次防护体系。此外,该数据库具备自治能力,支持自动配置、自调优及智能故障修复,并可通过大规模并行处理(MPP)架构实现PB级数据的高效在线分析处理。

2.服务器设置和操作

本章讨论如何设置和运行数据库服务器以及其与操作系统的交互。

2.0.实例管理

2.0.1.概述

优炫数据库管理系统UXDB由数据库文件和UXDB实例组成。

  • 数据库文件:数据库文件为存储用户数据以及元数据的一组磁盘文件。

  • 元数据:是描述数据库结构、配置和控制有关的信息。

UXDB数据库实例管理的所有数据在物理上都以操作系统文件的方式存放在磁盘上。

UXDB实例具有如下特点。

  1. 包含若干对存储的数据进行操作的数据库服务进程,还包括分配和管理内存,统计各种信息,以及实现各种协调工作的后台进程。一台设备上,可以同时运行多个实例。

  2. 实例注册成功后,会有唯一的名字标志一个实例。

  3. 一个UXDB实例在操作系统上表现为一个UXDB进程,它可以由控制器启动,也可以单独用命令行启动。

  4. 一个UXDB实例管理多个逻辑上的数据库。启动一个UXDB实例后,使用客户端可以访问到这个实例管理的任意一个数据库。

  5. 正常情况下,UXDB在安装过程中,会自行初始化注册一个UXDB实例。但如果数据库安装过程中初始化失败,请参见创建实例,手动注册UXDB实例。

2.0.2.创建实例

使用initdb创建实例

打开控制台工具,在命令工具中执行命令进入UXDB服务器的目录uxdbinstall/uxsql/bin,执行initdb的命令注册实例。

  • 用法

    initdb [option...] [ --uxdata | -D ]directory

  • 常用选项

    -D directory
    指定数据库集群应该存放的目录。这是initdb要求的唯一信息,但是你可以通过设定UXDBTA环境变量来避免书写它,这很方便因为之后数据库服务器(uxdb)可以使用同一个变量来找到数据库目录。

    [--pwfile=]filename
    让initdb从一个文件读取数据库超级用户的口令。该文件的第一行被当作口令。

    -W
    提示设置一个口令,该口令会被程序以MD5默认加密算法加密后存储至系统表ux_authid中的rolepassword字段中。

    -U username
    选择数据库超级用户的用户名。这个的默认值是实际运行initdb的用户的名称。超级用户的名字不重要,但是你可以选择保留常用的名字uxdb,即使操作系统的用户名不同。

    详细请参见《优炫数据库管理系统服务端工具使用手册》initdb部分。

  • 示例

    使用命令initdb创建一个数据库实例,数据库实例的数据目录位置由-D选项指定(此处指定数据目录位置为/opt/uxdbinstall/dbsql/data)。

    $ initdb -D /opt/uxdbinstall/dbsql/data
    
  • 注意

    1. 如果数据目录不存在,initdb命令将尝试创建-D选项指定的数据目录,但该操作可能因为权限不足而失败(若数据目录的父目录属于root用户)。

    2. 不能以root用户运行initdb。

使用ux_ctl
  • 用法

    ux_ctl init[db] [-D datadir] [-o initdb-options]

    init或initdb模式将创建一个新的UXDB数据库实例,此模式调用initdb命令。

  • 常用选项

    -D datadir
    指定数据库配置文件的文件系统位置。

    -o initdb-options
    指定要直接传递给initdb命令的选项。

    详细请参见《优炫数据库管理系统服务端工具使用手册》ux_ctl部分。

  • 示例

    $ ux_ctl initdb -D /opt/uxdbinstall/dbsql/data -o '-W '
    

2.0.3.删除实例

删除实例即移除UXDB数据库集群目录。

使用removedb工具

当不再需要某服务时,数据库管理员可以将它移除。

  • 用法

    removedb [option...] [ --uxdata | -D ]directory

  • 常用选项

    -D directory
    指定数据库集群的数据目录示例。

    -F
    强制删除给定的数据库集群,小心使用这个选项。

  • 示例

    $ removedb -D /opt/uxdbinstall/dbsql/data
    
  • 注意

    在UXDB运行期间,禁止删除集群目录。

2.0.4.查看实例状态

使用ux_ctl status

status模式检查一个服务器是否运行在指定的数据目录中。如果存在正在运行的服务区,其PID和用来调用它的命令行选项将被显示。如果没有在运行的服务器,ux_ctl将返回退出状态3。如果没有指定一个可以访问的数据目录,ux_ctl将返回退出状态4。

  • 用法

    ux_ctl status [-D datadir]

  • 常用选项

    -D datadir
    指定数据库配置文件的文件系统位置。

  • 示例

    显示服务器状态。

    $ ux_ctl status
    
使用uxdb

可通过如下命令,查看数据库服务器当前状态。

$ ps -ef|grep uxdb

uxdb进程存在,即为正常开启状态,否则数据库服务器未启动。

2.1.创建数据库集群

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

在文件系统术语中,数据库集群是一个单个目录,其中存储了所有数据。我们称之为 数据目录 或 数据区域。您可以完全自行选择存储数据的位置。没有默认值,尽管像 /usr/local/uxsql/data 或 /var/lib/uxsql/data 这样的位置很受欢迎。必须使用程序 initdb(与 UXDB 一起安装)初始化数据目录,然后才能使用它。

如果您使用的是预打包版本对于 UXDB,它可能有一个特定的约定来放置数据目录,并且可能还提供一个创建数据目录的脚本。在这种情况下,你应该优先使用该脚本,而不是直接运行 initdb。请参阅软件包级别的文档以获取详细信息。 要手动初始化数据库集群,请运行 initdb 并使用 -D 选项指定所需的数据库集群文件系统位置,例如:

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

请注意,您必须在 UXDB 用户帐户中执行此命令,该帐户在前一节中有描述。

提示

作为 -D 选项的替代方案,您可以设置环境变量 UXDATA。

或者,您可以通过 ux_ctl 程序运行 initdb,例如:

$ ux_ctl -D /usr/local/uxsql/data initdb

如果您正在使用 ux_ctl 启动和停止服务器(请参见启动数据库服务器),则这可能更直观,因此ux_ctl 将是您用于管理数据库服务器实例的唯一命令。

如果指定的目录不存在,则 initdb 将尝试创建该目录。当然,如果 initdb 没有在父目录中写入的权限,则此操作将失败。通常建议 UXDB用户不仅拥有数据目录,而且还拥有其父目录,以便这不成为问题。如果所需的父目录也不存在,则需要首先创建它,如果祖父目录不可写,则需要使用root权限。因此,该过程可能如下所示:

root# mkdir /usr/local/uxsql
root# chown uxdb /usr/local/uxsql
root# su uxdb
uxdb$ initdb -D /usr/local/uxsql/data

如果数据目录存在并且已经包含文件,则 initdb 将拒绝运行;这是为了防止意外覆盖现有安装。由于数据目录包含存储在数据库中的所有数据,因此必须确保它受到未经授权的访问。因此,initdb 撤消了除 UXDB用户以外的所有人的访问权限,并且可选地撤消了组的访问权限。启用组访问权限时,它是只读的。这允许与群集所有者在同一组中的非特权用户备份群集数据或执行其他仅需要读取访问权限的操作。

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

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

initdb还会初始化数据库群集的默认区域设置。通常,它将只采用环境中的区域设置并将其应用于初始化的数据库。可以为数据库指定不同的区域设置;有关更多信息,请参见本地化支持。在特定数据库群集中使用的默认排序顺序由initdb设置,虽然您可以使用不同的排序顺序创建新数据库,但是不能在删除和重新创建它们之前更改initdb创建的模板数据库中使用的顺序。使用除C或POSIX之外的区域设置还会对性能产生影响。因此,第一次正确地进行选择非常重要。

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

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

2.1.1.使用辅助文件系统

许多安装将其数据库群集创建在机器的“根”卷之外的文件系统(卷)上。如果您选择这样做,则不建议尝试使用辅助卷的顶级目录(挂载点)作为数据目录。最佳做法是在挂载点目录中创建一个由 UXDB用户拥有的目录,然后在其中创建数据目录。这避免了权限问题,特别是对于操作如ux_upgrade等的操作,它还确保了如果辅助卷被脱机,则失败干净。

2.1.2.文件系统

通常,任何具有 POSIX 语义的文件系统都可以用于 UXDB。用户出于各种原因喜欢不同的文件系统,包括供应商支持、性能和熟悉度。经验表明,在其他条件相等的情况下,仅仅从文件系统切换或进行微小的文件系统配置更改并不会带来主要的性能或行为变化。

2.1.2.1.NFS

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

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

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

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

2.2.启动数据库服务器

在任何人可以访问数据库之前,您必须启动数据库服务器。数据库服务器程序称为uxdb。

如果您使用的是预打包版本的 UXDB,它几乎肯定包括根据您的操作系统的约定将服务器作为后台任务运行的规定。使用包的基础设施启动服务器将比自己找出如何做这件事要少得多。有关详细信息,请参阅包级文档。

手动启动服务器的基本方法只是直接调用uxdb,并使用-D选项指定数据目录的位置,例如:

$ uxdb -D /usr/local/uxsql/data

这将使服务器在前台运行。这必须在登录到 UXDB用户帐户时完成。如果没有-D,服务器将尝试使用由环境变量UXDATA命名的数据目录。如果也没有提供该变量,它将失败。

通常最好在后台启动uxdb。为此,请使用通常的Unixshell语法:

$ uxdb -D /usr/local/uxsql/data >logfile 2>&1 &

将服务器的stdout和stderr输出存储在上面所示的位置非常重要。它将有助于审计目的和诊断问题。(有关日志文件处理的更全面讨论,请参见日志文件维护。)

uxdb程序还采用许多其他选项,命令行选项。有关更多信息,请参见服务器配置。

这个shell语法很快就会变得乏味。因此,提供了包装器程序ux_ctl来简化一些任务。例如:

ux_ctl start -l logfile

将在后台启动服务器并将输出放入指定的日志文件中。这里的-D选项与uxdb的含义相同。ux_ctl也能够停止服务器。

通常,您会希望在计算机启动时启动数据库服务器。自动启动脚本是操作系统特定的。在 UXDB的contrib/start-scripts目录中分发了一些示例脚本。安装需要root权限。

不同的系统在启动守护程序时有不同的约定。许多系统有一个文件/etc/rc.local或/etc/rc.d/rc.local。其他系统使用init.d或rc.d目录。无论您做什么,服务器都必须由 UXDB用户帐户运行,而不是由root或任何其他用户运行。因此,您可能应该使用su uxdb -c '...'来形成您的命令。例如:

su uxdb -c 'ux_ctl start -D /usr/local/uxsql/data -l serverlog'

以下是一些操作系统特定的建议。 (在每种情况下,请确保使用正确的安装目录和用户名,其中我们显示通用值。)

  • 对于FreeBSD,请查看 UXDB源分发中的文件contrib/start-scripts/freebsd。

  • 在OpenBSD上,请将以下行添加到文件/etc/rc.local中:

    if [ -x /usr/local/uxsql/bin/ux_ctl -a -x /usr/local/uxsql/bin/uxdb ]; then
      su -l uxdb -c '/usr/local/uxsql/bin/ux_ctl start -s -l /var/uxsinodb/log -D /usr/local/uxsql/data'
      echo -n ' uxsinodb'
    fi
    
  • 在Linux系统上,要么将

    /usr/local/uxsql/bin/ux_ctl start -l logfile -D /usr/local/uxsql/data
    

    添加到/etc/rc.d/rc.local或/etc/rc.local,要么查看 UXDB源分发中的文件contrib/start-scripts/linux。

    使用systemd时,可以使用以下服务单元文件(例如,在/etc/systemd/system/uxsinodb.service中):

    [Unit]
    Description=UXsinoDB database server
    Documentation=man:uxdb(1)
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=notify
    User=uxdb
    ExecStart=/usr/local/uxsql/bin/uxdb -D /usr/local/uxsql/data
    ExecReload=/bin/kill -HUP $MAINPID 
    KillMode=mixed 
    KillSignal=SIGINT
    TimeoutSec=infinity 
    
    [Install]
    WantedBy=multi-user.target 
    

    使用 Type=notify 需要服务器二进制文件使用 configure --with-systemd 进行构建。

    仔细考虑超时设置。截至本文撰写时,systemd 的默认超时时间为90秒,如果进程在该时间内未报告准备就绪,则会被终止。但是,可能需要在启动时执行崩溃恢复的UXsinoDB服务器可能需要更长的时间才能准备就绪。建议使用 infinity 来禁用超时逻辑。

  • 在NetBSD上,根据个人偏好使用 FreeBSD 或 Linux 启动脚本。

  • 在 Solaris 上,创建一个名为 /etc/init.d/uxsinodb 的文件,其中包含以下行:

    su - uxdb -c "/usr/local/uxsql/bin/ux_ctl start -l logfile -D /usr/local/uxsql/data"
    

    然后,在 /etc/rc3.d 中创建一个符号链接,名为 S99uxsinodb。

当服务器正在运行时,它的PID存储在数据目录中的文件 uxmaster.pid 中。这用于防止在同一数据目录中运行多个服务器实例,并且也可以用于关闭服务器。

2.2.1.启动和关闭服务

使用ux_ctl

服务器管理工具ux_ctl将在后台启动服务器,并将输出存储在指定的日志文件中。

  • 用法

    ux_ctl start [-D datadir] [-l filename] [-W] [-t seconds] [-s] [-o options] [-p path] [-c]

  • 常用选项

    -D datadir
    指定数据库配置文件的文件系统位置。如果这个选项被忽略,将使用环境变量UXDATA。

    -l filename
    追加服务器日志输出到filename。如果该文件不存在,它会被创建。umask被设置成077,这样默认情况下不允许其他用户访问该日志文件。

    -W
    不等待操作完成。

    -t seconds
    指定等待一个操作完成时要等待的最大秒数(见选项-w)。默认为UXCTLTIMEOUT环境变量的值,如果该环境变量没有设置则默认为60秒。

    -o options
    指定被直接传递给uxdb命令的选项。-o可以被指定多次,所有给定的选项都会被传递。

    -p path
    指定uxdb可执行程序的位置。默认情况下,uxdb可执行程序可以从ux_ctl相同的目录得到,或者如果没有在那里找到,则在硬写的安装目录中获得。

    在init模式中,这个选项类似于指定了initdb可执行程序的位置。

    详细请参见《优炫数据库管理系统服务端工具使用手册》ux_ctl部分。

  • 示例

    start模式启动一个新的服务器。

    $ ux_ctl start -D /opt/uxdbinstall/dbsql/data -l logfile
    

    当服务器启动后运行时,其PID将被保存在数据目录中的uxmaster.pid文件,防止多个服务器实例运行在同一个数据目录中。

使用uxdb
  • 用法

    uxdb [option...]

  • 常用选项

    -B NBUFFERS
    共享缓冲区的数量。

    -c NAME=VALUE
    设置运行时间参数。

    -C NAME
    打印运行时参数的值。

    -d 1-5
    调试级别。

    -D DATADIR
    数据库目录。

    -e
    使用欧洲日期输入格式(DMY)。

    -F
    关闭fsync。

    -h HOSTNAME
    主机名或IP地址进行监听。

    -i
    启用TCP/IP连接。

    -k DIRECTORY
    Unix域套接字位置。

    -l
    启用SSL连接。

    -N MAX-CONNECT
    允许的最大连接数

    详细请参见《优炫数据库管理系统服务端工具使用手册》uxdb部分。

  • 示例

    • 示例一

      通过-D选项来指定数据库配置文件在系统中的位置(/opt/uxdbinstall/dbsql/data),启动uxdb。

      $ uxdb -D /opt/uxdbinstall/dbsql/data
      

      注意

      1. 上述命令必须以数据库用户登录后进行操作。
      2. 如果没有-D选项,服务器将尝试使用环境变量UXDBDATA命名的目录。如果环境变量未被提供,则此启动服务器操作将失败。
    • 示例二

      使用Unix shell语法,在后台启动uxdb。

      $ uxdb -D /opt/uxdbinstall/dbsql/data >logfile 2>&1 &
      

      该命令会将服务器的stdout和stderr输出存储到某个地方,这将有益于审计和诊断问题。

2.2.2.服务器启动失败

有几个常见原因可能导致服务器无法启动。检查服务器的日志文件,或手动启动它(不要重定向标准输出或标准错误),看看出现了什么错误消息。以下我们详细解释一些最常见的错误消息。

LOG:  could not bind IPv4 address "127.0.0.1": Address already in use
HINT:  Is another uxmaster already running on port 5432? If not, wait a few seconds and retry.
FATAL:  could not create any TCP/IP sockets

这通常意味着正如它所建议的那样:您尝试在已经运行一个服务器的端口上启动另一个服务器。但是,如果内核错误消息不是 Address already in use 或其变体,则可能存在不同的问题。例如,尝试在保留的端口号上启动服务器可能会引起以下情况:

$ uxdb -p 666
LOG:  could not bind IPv4 address "127.0.0.1": Permission denied
HINT:  Is another uxmaster already running on port 666? If not, wait a few seconds and retry.
FATAL:  could not create any TCP/IP sockets

像这样的消息:

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

可能意味着您的内核对共享内存大小的限制小于 UXDB 尝试创建的工作区大小(在此示例中为 4011376640 字节)。只有在将 shared_memory_type 设置为 sysv 时才有可能发生这种情况。在这种情况下,您可以尝试使用比正常数量更小的缓冲区(shared_buffers)启动服务器,或重新配置内核以增加允许的共享内存大小。当尝试启动多个如果同一台机器上的服务器所请求的总空间超过内核限制,则会出现错误,例如:

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

这并不意味着您已经用完了磁盘空间。它意味着您的内核对SystemV信号量的数量限制比UXsinoDB要创建的数量小。与上面一样,您可以通过使用减少的允许连接数(max_connections)启动服务器来解决问题,但最终您将想要增加内核限制。

有关配置System V IPC设施的详细信息,请参见共享内存和信号量。

2.2.3.客户端连接问题

虽然客户端可能出现的错误条件非常多样化且与应用程序相关,但其中一些可能直接与服务器的启动方式有关。除了下面显示的条件之外,其他条件应在相应的客户端应用程序中进行记录。

uxsql: error: connection to server at "server.joe.com" (123.123.123.123), port 5432 failed: Connection refused
  Is the server running on that host and accepting TCP/IP connections?”

这是通用的“我找不到要交谈的服务器”故障。当尝试进行TCP/IP通信时,它看起来像上面那样。常见的错误是忘记配置服务器以允许TCP/IP连接。或者,当尝试使用本地服务器的Unix域套接字通信时,您可能会遇到以下错误:

uxsql: error: connection to server on socket "/tmp/.s.UXSQL.5432" failed: No such file or directory
  Is the server running locally and accepting connections on that socket?”

如果服务器确实正在运行,请检查客户端对套接字路径(这里是/tmp)的理解是否与服务器的unix_socket_directories设置相符。

连接失败消息始终显示服务器地址或套接字路径名,这在验证客户端是否尝试连接正确位置时非常有用。如果实际上没有服务器在那里侦听,则内核错误消息通常是Connection refused或No such file or directory。(重要的是要意识到,在这种情况下,Connection refused并不意味着服务器收到了您的连接请求并拒绝了它。那种情况将产生不同的消息,如认证问题所示。)其他错误消息,如Connection timed out,可能表示更基本的问题,例如缺乏网络连接性或防火墙阻止连接。

2.3.管理内核资源

UXsinoDB 有时会耗尽各种操作系统资源限制,特别是当多个服务器副本在同一系统上运行或在非常大的安装中。本节介绍了 UXDB使用的内核资源以及解决与内核资源消耗相关的问题的步骤。

2.3.1.共享内存和信号量

UXsinoDB 需要操作系统提供进程间通信 (IPC) 功能,特别是共享内存和信号量。类 Unix 系统通常提供 “System V”IPC、“POSIX” IPC 或两者都提供。Windows 有自己的实现,这里不讨论。

默认情况下,UXsinoDB 分配非常少量的 System V 共享内存以及更大量的匿名 mmap 共享内存。或者,可以使用单个大的System V 共享内存区域 (参见shared_memory_type)。此外,还需要大量的信号量,可以是 System V 信号量,也可以是 POSIX信号量。目前,在Linux和FreeBSD系统上使用POSIX信号量,而其他平台使用System V信号量。

System V IPC功能通常受到系统范围内的分配限制。当UXsinoDB超过其中一个限制时,服务器将拒绝启动,并应该留下一条有指导意义的错误消息,描述问题以及如何解决它(请参见服务器启动失败)。不同系统中命名的相关内核参数是一致的;下表给出了概述。然而,设置它们的方法是不同的。以下是一些平台的建议。

表 System V IPC参数

名称描述运行一个UXsinoDB实例所需的值
SHMMAX共享内存段的最大尺寸(字节)至少 1kB,但是默认值通常要高一些
SHMMIN共享内存段的最小尺寸(字节)1
SHMALL可用共享内存的总量(字节或页面)如果是字节,同SHMMAX;如果是页面,为ceil(SHMMAX/PAGE_SIZE),加上其他应用程序的空间
SHMSEG每个进程的最大共享内存段数目只需要 1 段,但是默认值高很多
SHMMNI系统范围内的最大共享内存段数目像SHMSEG外加其他应用的空间
SEMMNI信号量标识符(即,集合)的最大数目至少ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16) 加上其他应用程序的空间
SEMMNS系统范围内的最大信号量数目ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16) * 17 加上其他应用程序的空间
SEMMSL每个集合中信号量的最大数目至少 17
SEMMAP信号量映射中的项数见文本
SEMVMX信号量的最大值至少 1000 (默认值常常是 32767,如非必要不要更改)

UXsinoDB需要一些System V共享内存的字节(通常是64位平台上的48个字节)来存储每个服务器的副本。在大多数现代操作系统上,这个数量可以很容易地分配。然而,如果您运行许多服务器副本或明确配置服务器使用大量的System V共享内存(请参见shared_memory_type和dynamic_shared_memory_type),则可能需要增加SHMALL,它是系统范围内 System V 共享内存的总量。请注意,SHMALL 在许多系统上是以页面而不是字节为单位衡量的。

共享内存段的最小大小(SHMMIN)不太可能引起问题,对于 UXDB,它应该最多为大约 32 字节(通常只有1字节)。系统范围内的最大段数(SHMMNI)或每个进程的最大段数(SHMSEG)不太可能引起问题,除非您的系统将它们设置为零。

使用 System V 信号量时,UXsinoDB每允许一个连接(max_connections)、允许的自动清理工作进程(autovacuum_max_workers)和允许的后台进程(max_worker_processes)使用一个信号量,每组16 个。每个这样的组还将包含第 17 个信号量,其中包含一个“魔术数字”,以检测与其他应用程序使用的信号量集的冲突。系统中信号量的最大数量由SEMMNS 设置,因此必须至少与 max_connections 加上 autovacuum_max_workers 加上max_wal_senders 加上 max_worker_processes 加上每 16个允许的连接和工作进程的一个额外的信号量(请参阅表 System V IPC参数中的公式)。参数SEMMNI 确定系统上可以同时存在的信号量集的数量限制。因此,此参数必须至少为 ceil((max_connections +autovacuum_max_workers + max_wal_senders + max_worker_processes + 5)/ 16)。降低允许的连接数是故障的临时解决方法,这些故障通常会以令人困惑的措辞“设备上没有剩余空间”从函数 semget 报告。

在某些情况下,还可能需要将 SEMMAP 增加到至少与 SEMMNS 相同的数量级。如果系统具有此参数(许多系统没有),则它定义了信号量资源映射的大小,在其中每个连续的可用信号量块都需要一个条目。当释放信号量集时,它要么添加到与释放块相邻的现有条目中,要么在新的映射条目下注册。如果映射已满,则释放的信号量将丢失(直到重新启动)。信号量空间的碎片化随着时间的推移可能会导致可用信号量比应有的少。

与“信号量撤消”相关的各种其他设置,例如 SEMMNU 和 SEMUME,不会影响 UXDB。

使用 POSIX 信号量时,所需的信号量数量与 System V相同,即每允许一个连接(max_connections)、允许的自动清理工作进程(autovacuum_max_workers)和允许的后台进程(max_worker_processes)使用一个信号量。在此选项首选的平台上,没有特定的内核限制POSIX 信号量的数量。

AIX
通常不需要对诸如SHMMAX等参数进行特殊配置,因为它似乎已经配置为允许所有内存用作共享内存。这是其他数据库(如DB/2)通常使用的配置。

但是,可能需要修改全局ulimit信息在/etc/security/limits,因为文件大小(fsize)和文件数(nofiles)的默认硬限制可能太低。

FreeBSD
默认的共享内存设置通常足够好,除非您已将shared_memory_type设置为sysv。在此平台上不使用System V信号量。

可以使用sysctl或loader接口更改默认IPC设置。以下参数可以使用sysctl设置:

# sysctl kern.ipc.shmall=32768
# sysctl kern.ipc.shmmax=134217728

要使这些设置在重新启动后持久化,请修改/etc/sysctl.conf。

如果您已将shared_memory_type设置为sysv,您可能还希望配置内核将System V共享内存锁定到RAM并防止其被分页到交换空间中。这可以使用sysctl设置kern.ipc.shm_use_phys来实现。

如果在FreeBSD jail中运行,则应将其sysvshm参数设置为new,以便它具有自己独立的System V共享内存命名空间。(在FreeBSD 11.0之前,需要从jails启用对主机IPC命名空间的共享访问,并采取措施避免冲突。)

NetBSD
默认的共享内存设置通常足够好,除非您已将shared_memory_type设置为sysv。您通常需要增加kern.ipc.semmni和kern.ipc.semmns,因为NetBSD的默认设置对这些设置来说太小了。

可以使用sysctl调整IPC参数,例如:

# sysctl -w kern.ipc.semmni=100

要使这些设置在重新启动后持久化,请修改/etc/sysctl.conf。

如果您已将shared_memory_type设置为sysv,您可能还希望配置内核将System V共享内存锁定到RAM并防止其被分页到交换空间中。这可以使用sysctl设置kern.ipc.shm_use_phys来实现。

OpenBSD
默认的共享内存设置通常足够好,除非您已将shared_memory_type设置为sysv。您通常需要增加kern.seminfo.semmni 和 kern.seminfo.semmns,因为 OpenBSD 的默认设置太小了。

可以使用 sysctl 调整 IPC 参数,例如:

# sysctl kern.seminfo.semmni=100

要使这些设置在重新启动后保持,请修改 /etc/sysctl.conf。

HP-UX
默认设置通常足够满足正常安装的需求。

可以在 System Administration Manager (SAM) 的 Kernel Configuration → Configurable Parameters 中设置 IPC 参数。完成后选择 Create A New Kernel。

Linux
默认的共享内存设置通常足够好,除非您已将 shared_memory_type 设置为 sysv,即使在旧的内核版本中也是如此,这些版本的默认值很低。在此平台上不使用System V 信号量。

可以通过 sysctl 接口更改共享内存大小设置。例如,允许 16 GB:

$ sysctl -w kernel.shmmax=17179869184
$ sysctl -w kernel.shmall=4194304

要使这些设置在重新启动后保持,请参阅 /etc/sysctl.conf。

macOS
默认的共享内存和信号量设置通常足够好,除非您已将 shared_memory_type 设置为 sysv。

在 macOS 中配置共享内存的推荐方法是创建一个名为 /etc/sysctl.conf 的文件,其中包含变量分配,例如:

kern.sysv.shmmax=4194304
kern.sysv.shmmin=1
kern.sysv.shmmni=32
kern.sysv.shmseg=8
kern.sysv.shmall=1024

请注意,在某些 macOS 版本中,必须在 /etc/sysctl.conf 中设置所有五个共享内存参数,否则这些值将被忽略。

SHMMAX 只能设置为 4096 的倍数。

在此平台上,SHMALL 以 4 kB 页面为单位。

可以在运行时更改除 SHMMNI 之外的所有设置,使用 sysctl。但最好还是通过 /etc/sysctl.conf 设置您喜欢的值,以便这些值在重新启动后保持。

Solaris
illumos
默认的共享内存和信号量设置通常足够满足大多数UXsinoDB应用程序的需求。Solaris 的默认 SHMMAX 是系统RAM的四分之一。要进一步调整此设置,请使用与 uxdb 用户关联的项目设置。例如,以 root 身份运行以下命令:

projadd -c "UXsinoDB DB用户" -K "project.max-shm-memory=(privileged,8GB,deny)" -U uxdb -G uxdb user.uxdb

该命令添加了user.uxdb项目,并将uxdb用户的共享内存最大值设置为8GB,该设置将在用户下次登录或重新启动UXsinoDB时生效(不是重新加载)。以上假设UXsinoDB由uxdb用户在uxdb组中运行。不需要重新启动服务器。

对于将有大量连接的数据库服务器,建议进行其他内核设置更改,例如:

project.max-shm-ids=(priv,32768,deny)
project.max-sem-ids=(priv,4096,deny)
project.max-msg-ids=(priv,4096,deny)

此外,如果您在区域内运行UXsinoDB,还可能需要提高区域资源使用限制。

2.3.2.systemd RemoveIPC

如果使用systemd,则必须注意操作系统不会过早地删除IPC资源(包括共享内存)。这在从源代码安装UXsinoDB时尤其需要注意。使用UXsinoDB的发行版软件包的用户不太可能受到影响,因为uxdb用户通常被创建为系统用户。

logind.conf中的RemoveIPC设置控制在用户完全注销时是否删除IPC对象。系统用户不受影响。此设置在默认的systemd中默认为开启状态,但某些操作系统发行版将其默认为关闭状态。

当此设置为开启状态时,通常会观察到用于并行查询执行的共享内存对象在似乎随机的时间被删除,导致在尝试打开和删除它们时出现错误和警告,例如:

WARNING: could not remove shared memory segment "/UXsinoDB.1450751626": No such file or directory

不同类型的IPC对象(共享内存与信号量,System V与POSIX)由systemd略有不同的处理方式,因此可能观察到某些IPC资源未以与其他资源相同的方式被删除。但是,不建议依赖这些微小的差异。

“用户注销”可能发生在维护作业中或手动进行,例如管理员登录为uxdb用户或类似用户,因此通常很难进行预防。

“系统用户”是从/etc/login.defs中的SYS_UID_MAX设置在systemd编译时确定的。

打包和部署脚本应小心地使用useradd -r、adduser --system或等效命令将uxdb用户创建为系统用户。

或者,如果用户帐户创建不正确或无法更改,则建议在/etc/systemd/logind.conf或其他适当的配置文件中设置:

RemoveIPC=no

注意

这两件事中至少要确保其中之一,否则 UXDB 服务器将非常不可靠。

2.3.3.资源限制

类 Unix 操作系统强制执行各种资源限制,这可能会干扰您的 UXDB 服务器的操作。特别重要的是,每个用户的进程数量限制、每个进程的打开文件数量限制以及每个进程可用的内存量限制。每个限制都有一个“硬”限制和一个“软”限制。软限制是实际计数的限制,但用户可以将其更改为硬限制。只有 root 用户才能更改硬限制。系统调用 setrlimit 负责设置这些参数。Shell 的内置命令 ulimit(Bourne shells)或 limit(csh)用于从命令行控制资源限制。在基于 BSD 的系统中,文件 /etc/login.conf 控制登录时设置的各种资源限制。相关参数是 maxproc、openfiles 和 datasize。例如:

default:\
...
  :datasize-cur=256M:\
  :maxproc-cur=256:\
  :openfiles-cur=256:\
...

(-cur 是软限制。附加 -max 以设置硬限制。)

内核还可以对某些资源设置系统范围的限制。

在 Linux 上,内核参数 fs.file-max 确定内核将支持的最大打开文件数。可以使用 sysctl -w fs.file-max=N 更改它。要使设置在重新启动后持久存在,请在 /etc/sysctl.conf 中添加一个赋值。每个进程的文件最大限制在内核编译时固定;有关更多信息,请参阅 /usr/src/linux/Documentation/proc.txt。

UXsinoDB 服务器每个连接使用一个进程,因此您应该为至少提供与允许的连接数相同的进程,以及您需要的其他系统。这通常不是问题,但如果在一台机器上运行多个服务器,则可能会变得紧张。

默认情况下,打开文件的限制通常设置为“社交友好”值,允许许多用户在机器上共存,而不使用不适当的系统资源比例。如果在一台机器上运行多个服务器,则可能是您想要的,但在专用服务器上,您可能希望提高此限制。

另一方面,一些系统允许单个进程打开大量文件;如果超过几个进程这样做,则很容易超过系统范围的限制。如果发现这种情况发生,并且您不想更改系统范围的限制,则可以设置 UXDB 的 max_files_per_process 配置参数以限制打开文件的使用。

2.3.4.Linux 内存超额配置

Linux的默认虚拟内存行为对于UXsinoDB不是最佳的。由于内核实现内存超额分配的方式,如果UXsinoDB或其他进程的内存需求导致系统耗尽虚拟内存,内核可能会终止UXsinoDB的邮件管理员(监督服务器进程)。

如果发生这种情况,您将看到一个内核消息,类似于以下内容(请查阅系统文档和配置以查找此类消息的位置):

Out of Memory: Killed process 12345 (uxdb)。

这表示由于内存压力,uxdb进程已被终止。虽然现有的数据库连接将继续正常工作,但不会接受新的连接。要恢复,需要重新启动UXsinoDB。

避免此问题的一种方法是在可以确保其他进程不会使机器耗尽内存的机器上运行UXsinoDB。如果内存紧张,增加操作系统的交换空间可以帮助避免此问题,因为只有在物理内存和交换空间耗尽时才会调用OOM killer。

如果UXsinoDB本身是导致系统内存耗尽的原因,可以通过更改配置来避免此问题。在某些情况下,降低与内存相关的配置参数,特别是shared_buffers、work_mem和hash_mem_multiplier可能有所帮助。在其他情况下,问题可能是由于允许太多连接到数据库服务器本身。在许多情况下,减少max_connections并改用外部连接池软件可能更好。

可以修改内核的行为,使其不会超额分配内存。尽管此设置不会完全防止OOM killer被调用,但它将显着降低机会,因此会导致更强大的系统行为。这是通过通过sysctl选择严格的超额分配模式完成的:

sysctl -w vm.overcommit_memory=2

或在/etc/sysctl.conf中放置一个等效的条目。您可能还希望修改相关设置vm.overcommit_ratio。有关详细信息,请参阅内核文档文件https://www.kernel.org/doc/Documentation/vm/overcommit-accounting。

另一种方法是,可以在不修改vm.overcommit_memory的情况下,将uxmaster进程的特定于进程的OOM分数调整值设置为-1000,从而确保它不会成为OOM killer的目标。最简单的方法是在启动uxmaster之前,在uxmaster的启动脚本中执行以下操作:

echo -1000 > /proc/self/oom_score_adj

请注意,此操作必须以root身份执行,否则将无效;因此,root所有的启动脚本是执行此操作的最简单的地方。如果您这样做,还应在启动脚本中在调用uxmaster之前设置以下环境变量:

export UX_OOM_ADJUST_FILE=/proc/self/oom_score_adj
export UX_OOM_ADJUST_VALUE=0

这些设置将导致uxmaster 子进程使用普通的值为零的 OOM score adjustment 运行,所以 OOM 杀手仍能在需要时把它们作为目标。如果你想要子进程用某些其他 OOM score adjustment 值运行,可以为UX_OOM_ADJUST_VALUE使用其他的值(UX_OOM_ADJUST_VALUE也能被省略,那时它会被默认为零)。如果你没有设置UX_OOM_ADJUST_FILE,子进程将使用和 uxmaster 相同的 OOM score adjustment 运行,这是不明智的,因为重点是确保 uxmaster 具有优先的设置。

2.3.5.Linux大页面

使用大页面可以减少使用大块连续内存(如UXsinoDB)时的开销,特别是在使用大值的shared_buffers时。要在UXsinoDB中使用此功能,您需要一个带有CONFIG_HUGETLBFS=y和CONFIG_HUGETLB_PAGE=y的内核。您还必须配置操作系统以提供所需大小的足够大的页面。要确定所需的大页面数,请使用uxdb命令查看shared_memory_size_in_huge_pages的值。请注意,必须关闭服务器才能查看此运行时计算的参数。示例如下:

$ uxdb -D $UXDATA -C shared_memory_size_in_huge_pages
3170
$ grep ^Hugepagesize /proc/meminfo
Hugepagesize:       2048 kB
$ ls /sys/kernel/mm/hugepages
hugepages-1048576kB  hugepages-2048kB

在此示例中,默认值为2MB,但您还可以使用huge_page_size显式请求2MB或1GB,以适应由shared_memory_size_in_huge_pages计算的页面数。虽然在此示例中至少需要3170个大页面,但如果机器上的其他程序也需要大页面,则应该使用更大的设置。我们可以使用以下命令设置:

# sysctl -w vm.nr_hugepages=3170

不要忘记将此设置添加到/etc/sysctl.conf。为了在重新启动后重新应用设置,对于非默认的巨大页面大小,我们可以使用以下命令:

# echo 3170 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

还可以使用内核参数在启动时提供这些设置,例如 hugepagesz=2M hugepages=3170。

有时内核无法立即分配所需数量的巨大页面,可能需要重复命令或重新启动。(在重新启动后,大多数机器的内存应该可用于转换为巨大页面。)要验证给定大小的巨大页面分配情况,请使用以下命令:

$ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

还可能需要通过设置 sysctl 中的 vm.hugetlb_shm_group,或者使用 ulimit -l给数据库服务器的操作系统用户授予使用巨大页面的权限。

UXsinoDB的巨大页面的默认行为是在可能的情况下使用它们,使用系统的默认巨大页面大小,并在失败时回退到普通页面。要强制使用巨大页面,可以在uxsinodb.conf 中将huge_pages 设置为 on。请注意,使用此设置,如果没有足够的巨大页面可用,UXsinoDB 将无法启动。

有关 Linux 巨大页面功能的详细说明,请参见https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt。

2.4.关闭服务器

有几种方法可以关闭数据库服务器。 在底层,它们都归结为向监管进程 uxdb 发送信号。

如果您使用的是预打包版本的UXsinoDB,并且使用了其提供的启动服务器的方法,则应该使用其提供的停止服务器的方法。请参阅包级文档以获取详细信息。

在直接管理服务器时,您可以通过向 uxdb 进程发送不同的信号来控制关闭类型:

SIGTERM
这是 智能关闭 模式。 收到 SIGTERM后,服务器禁止新连接,但允许现有会话正常结束工作。只有在所有会话终止后,它才会关闭。如果服务器在请求智能关闭时处于恢复状态,则只有在所有常规会话终止后,才会停止恢复和流式复制。

SIGINT
这是 快速关闭 模式。 服务器禁止新连接,并向所有现有服务器进程发送SIGTERM,这将导致它们中止当前事务并迅速退出。然后等待所有服务器进程退出,最后关闭。

SIGQUIT
这是 立即关闭 模式。 服务器将向所有子进程发送 SIGQUIT 并等待它们终止。如果有任何进程在5秒内未终止,则它们将被发送SIGKILL。只有在所有子进程退出后,监管服务器进程才会退出,而不进行正常的数据库关闭处理。这将导致下次启动时恢复(通过重放 WAL日志)。这仅在紧急情况下建议使用。

ux_ctl程序提供了一个方便的接口来发送这些信号来关闭服务器。或者,您可以在非Windows系统上直接使用kill发送信号。可以使用ps程序或数据目录中的uxmaster.pid文件找到uxdb进程的PID。例如,要进行快速关闭:

$ kill -INT `head -1 /usr/local/uxsql/data/uxmaster.pid`

重要

最好不要使用SIGKILL关闭服务器。这样做将防止服务器释放共享内存和信号量。此外,SIGKILL会杀死uxdb进程,而不让它将信号传递给其子进程,因此可能需要手动杀死各个子进程。

要终止单个会话,同时允许其他会话继续,使用ux_terminate_backend()或向与会话关联的子进程发送SIGTERM信号。

2.4.1.使用ux_ctl关闭服务

ux_ctl的stop模式关闭运行在指定数据目录中的服务器。

  • 用法

    ux_ctl stop [-D datadir] [-m s[mart] | f[ast] | i[mmediate] ] [-W] [-t seconds] [-s]

  • 常用选项

    -m
    指定关闭模式,如下所示。

    1. “smart”模式:将等待所有客户端断开连接,并等待所有在线备份结束。

    2. “fast”模式(默认):不会等待客户端断开连接,并且将终止进行中的在线备份。所有活动事务都被回滚,并且客户端被强制断开连接,然后服务器被关闭。

    3. “immediate”模式:将立刻中止所有服务器进程。该模式将导致下一次重启时,数据库进行一次从崩溃中的恢复。

    -D datadir
    指定数据库配置文件的文件系统位置。如果这个选项被忽略,将使用环境变量UXDATA。

    详细请参见《服务端工具使用手册》ux_ctl部分。

  • 示例

    使用ux_ctl关闭运行在/opt/uxdbinstall/dbsql/data中的服务器。

    $ ux_ctl stop -D /opt/uxdbinstall/dbsql/data
    

2.4.2.使用kill

在非Windows系统上可以直接用kill发送关闭信号。可用ps程序或从数据目录的uxmaster.pid文件中找到uxdb进程的PID,执行快速关闭。假如数据目录为/opt/uxdbinstall/dbsql/data,执行如下命令。

$ kill -INT `head -1 /opt/uxdbinstall/dbsql/data/uxmaster.pid`

2.5.防止服务器欺骗

当服务器正在运行时,恶意用户无法取代正常的数据库服务器。然而,当服务器关闭时,本地用户可以通过启动自己的服务器来欺骗正常的服务器。欺骗服务器可以读取客户端发送的密码和查询,但无法返回任何数据,因为由于目录权限,UXDATA目录仍然是安全的。欺骗是可能的,因为任何用户都可以启动数据库服务器;除非进行特殊配置,否则客户端无法识别无效的服务器。

防止 local 连接欺骗的一种方法是使用只有受信任的本地用户具有写权限的 Unix 域套接字目录(unix_socket_directories)。这可以防止恶意用户在该目录中创建自己的套接字文件。如果您担心某些应用程序仍然引用/tmp 的套接字文件,因此容易受到欺骗攻击,在操作系统启动期间创建一个符号链接/tmp/.s.UXSQL.5432,指向已重定位的套接字文件。您还可能需要修改您的 /tmp清理脚本,以防止删除符号链接。

另一种 local 连接的选项是让客户端使用requirepeer指定连接到套接字的服务器进程的所需所有者。

为了防止 TCP 连接欺骗,可以使用 SSL 证书并确保客户端检查服务器的证书,或者使用 GSSAPI加密(如果它们在不同的连接上,则两者都可以使用)。

为了防止 SSL 欺骗,服务器必须配置为仅接受 hostssl 连接(ux_hba.conf 文件),并具有 SSL密钥和证书文件(使用 SSL 进行安全的 TCP/IP 连接)。TCP客户端必须使用 sslmode=verify-ca 或 sslmode=verify-full连接。要使用verify-full进行SSL连接并安装适当的根证书文件。

为了防止GSSAPI欺骗,服务器必须配置为仅接受hostgssenc连接(ux_hba.conf 文件)并使用gss进行身份验证。TCP客户端必须使用gssencmode=require进行连接。

2.6.加密选项

UXDB提供了多个加密级别,并提供了保护数据免受数据库服务器盗窃、不诚实的管理员和不安全的网络泄露的灵活性。加密也可能需要用于保护敏感数据,如医疗记录或金融交易。

密码加密
数据库用户密码存储为哈希值(由设置password_encryption确定),因此管理员无法确定分配给用户的实际密码。如果用于客户端身份验证的是SCRAM或MD5加密,则未加密的密码甚至在被发送到服务器之前就被客户端加密了,因此在服务器上从未出现未加密的密码。SCRAM 更受欢迎,因为它是一个互联网标准,比 UXDB 特定的 MD5 身份验证协议更安全。

特定列的加密
uxcrypto模块允许加密存储某些字段。如果只有部分数据是敏感的,则这很有用。客户端提供解密密钥,数据在服务器上解密,然后发送到客户端。

在解密和客户端与服务器之间通信时,解密后的数据和解密密钥在服务器上存在一小段时间。这会出现一个短暂的时刻,其中数据和密钥可能会被具有完全访问数据库服务器权限的人(例如系统管理员)拦截。

数据分区加密
存储加密可以在文件系统级别或块级别执行。Linux 文件系统加密选项包括 eCryptfs 和 EncFS,而 FreeBSD 使用PEFS。块级别或整个磁盘加密选项包括 Linux 上的 dm-crypt + LUKS 和 FreeBSD 上的 GEOM 模块geli 和 gbde。许多其他操作系统也支持此功能,包括 Windows。

如果驱动器或整台计算机被盗,这种机制可以防止从驱动器读取未加密数据。这样做可以保护数据免受物理攻击,但无法保护数据免受网络攻击。当文件系统被挂载时,不会保护免受攻击,因为操作系统会提供数据的未加密视图。但是,为了挂载文件系统,需要某种方式将加密密钥传递给操作系统,有时密钥存储在挂载磁盘的主机的某个位置。

在网络中加密数据
SSL连接加密通过网络发送的所有数据:密码、查询和返回的数据。ux_hba.conf文件允许管理员指定哪些主机可以使用非加密连接(host),哪些需要SSL加密连接(hostssl)。此外,客户端可以指定只通过SSL连接到服务器。

GSSAPI加密连接加密通过网络发送的所有数据,包括查询和返回的数据。(不会通过网络发送密码。)ux_hba.conf文件允许管理员指定哪些主机可以使用非加密连接(host),哪些需要GSSAPI加密连接(hostgssenc)。此外,客户端可以指定只在GSSAPI加密连接上连接到服务器(gssencmode=require)。

Stunnel或SSH也可用于加密传输。

SSL主机认证
客户端和服务器都可以互相提供SSL证书。每一方都需要进行一些额外的配置,但这提供了比仅使用密码更强的身份验证。它可以防止计算机假装成服务器,只是为了读取客户端发送的密码。它还有助于防止“中间人”攻击,其中位于客户端和服务器之间的计算机假装成服务器,并读取和传递客户端和服务器之间的所有数据。

客户端加密
如果服务器机器的系统管理员不可信,则需要客户端加密数据;这样,未加密的数据永远不会出现在数据库服务器上。数据在发送到服务器之前在客户端上加密,在使用数据库结果之前必须在客户端上解密。

2.7.使用 SSL 进行安全的 TCP/IP 连接

UXDB原生支持使用SSL连接来加密客户端/服务器通信以提高安全性。这需要在客户端和服务器系统上都安装了OpenSSL,并且在构建时启用了UXDB中的支持。

术语SSL和TLS经常被互换使用,表示使用TLS协议进行安全加密连接。SSL协议是TLS协议的前身,即使SSL协议不再受支持,仍然将其用于加密连接。在UXDB中,SSL和TLS可互换使用。

2.7.1.基本设置

启用编译时支持SSL,可以通过将参数ssl设置为1来启动支持使用TLS 协议的加密连接的 UXDB服务器。uxsinodb.conf。服务器将在同一TCP端口上同时监听普通连接和SSL连接,并将与任何连接的客户端协商是否使用SSL。默认情况下,这取决于客户端的选择;有关如何设置服务器以要求某些或所有连接使用SSL的信息,请参见ux_hba.conf 文件。

要以SSL模式启动,必须存在包含服务器证书和私钥的文件。默认情况下,这些文件应该分别命名为server.crt和server.key,并位于服务器的数据目录中,但可以使用配置参数ssl_cert_file和ssl_key_file指定其他名称和位置。

在Unix系统上,server.key的权限必须禁止任何对世界或组的访问;通过命令chmod 0600 server.key实现这一点。或者,该文件可以由root拥有,并具有组读取访问权限(即0640权限)。该设置适用于操作系统管理证书和密钥文件的安装。然后,UXDB服务器运行的用户应该成为具有访问这些证书和密钥文件的组的成员。

如果数据目录允许组读取访问,则证书文件可能需要位于数据目录之外,以符合上述安全要求。通常,启用组访问是为了允许非特权用户备份数据库,在这种情况下,备份软件将无法读取证书文件,并可能出现错误。

如果私钥受到密码保护,则服务器将提示输入密码,并且在输入密码之前不会启动。默认情况下使用密码会禁用在没有服务器重启的情况下更改服务器的SSL配置的能力,但请参见ssl_passphrase_command_supports_reload。此外,受密码保护的私钥无法在Windows上使用。

server.crt中的第一个证书必须是服务器的证书,因为它必须与服务器的私钥匹配。还可以附加“中间”证书颁发机构的证书。这样做可以避免在客户端上存储中间证书的必要性,假设根和中间证书是使用v3_ca扩展创建的。(这将将证书的基本约束设置为CA为true。)这使中间证书的过期更容易。

不需要将根证书添加到server.crt中。相反,客户端必须拥有服务器证书链的根证书。

2.7.2.OpenSSL配置

UXsinoDB读取系统范围的OpenSSL配置文件。默认情况下,此文件名为openssl.cnf,并位于openssl version -d报告的目录中。可以通过设置环境变量OPENSSL_CONF来覆盖此默认值,以指定所需的配置文件的名称。

OpenSSL 支持各种强度不同的密码和认证算法。虽然可以在 OpenSSL 配置文件中指定密码列表,但是可以通过修改uxsinodb.conf 中的ssl_ciphers来为数据库服务器指定密码。

注意

使用 NULL-SHA 或 NULL-MD5密码可以实现身份验证而不带来加密开销。但是,中间人可以读取和传递客户端和服务器之间的通信。此外,加密开销与身份验证开销相比较小。因此,不建议使用NULL密码。

2.7.3.使用客户端证书

要求客户端提供受信任的证书,需要将信任的根证书颁发机构(CA)的证书放置在数据目录中的一个文件中,将参数ssl_ca_file设置为新文件名,并在适当的 hostssl 行中添加身份验证选项clientcert=verify-ca 或 clientcert=verify-full,并将其添加到 ux_hba.conf中。在 SSL 连接启动期间将请求客户端证书。

对于具有 clientcert=verify-ca 的 hostssl条目,服务器将验证客户端的证书是否由受信任的证书颁发机构之一签名。如果指定了clientcert=verify-full,服务器将不仅验证证书链,还将检查用户名或其映射是否与提供的证书的cn(公共名称)匹配。请注意,当使用 cert 认证方法时(请参见 证书认证),总是确保证书链验证。

如果希望避免在客户端上存储中间证书(假设根和中间证书是使用 v3_ca 扩展创建的),则可以在ssl_ca_file文件中添加链到现有根证书的中间证书。如果设置了参数ssl_crl_file 或ssl_crl_dir,则还将检查证书吊销列表(CRL)条目。

clientcert 身份验证选项适用于所有身份验证方法,但仅适用于在 ux_hba.conf 行中指定为 hostssl的行。当未指定 clientcert 时,仅当客户端提供证书并且已配置 CA 时,服务器才会根据其 CA文件验证客户端证书。

有两种方法可以强制用户在登录时提供证书。

第一种方法利用 ux_hba.conf 中 hostssl 条目的 cert身份验证方法,这样证书本身就用于身份验证,同时也用于加密通信。提供SSL 连接安全性。有关详细信息,请参见证书认证。 (使用 cert认证方法时,不需要显式指定任何 clientcert 选项。) 在这种情况下,证书中提供的 cn (通用名称)会与用户名或适用的映射进行检查。 第二种方法将任何 hostssl 条目的身份验证方法与设置 clientcert认证选项为 verify-ca 或 verify-full的客户端证书验证结合起来。前者仅强制证书有效,而后者还确保证书中的cn (通用名称) 与用户名或适用的映射相匹配。

2.7.4.SSL 服务器文件使用

下表总结了与服务器上 SSL设置相关的文件。(显示的文件名是默认名称。本地配置的名称可能不同。)

文件内容效果
ssl_cert_file ($UXDATA/server.crt)服务器证书发送给客户端来说明服务器的身份
ssl_key_file ($UXDATA/server.key)服务器私钥证明服务器证书是其所有者发送的,并不说明证书所有者是值得信任的
ssl_ca_file可信的证书颁发机构检查客户端证书是由一个可信的证书颁发机构签名的
ssl_crl_file被证书授权机构撤销的证书客户端证书不能出现在这个列表上

服务器在启动时和每当重新加载服务器配置时读取这些文件。在Windows系统上,每当为新的客户端连接生成新的后端进程时,它们也会被重新读取。

如果在服务器启动时检测到这些文件中的错误,服务器将拒绝启动。但是,如果在配置重新加载期间检测到错误,则会忽略这些文件,并继续使用旧的SSL配置。在 Windows 系统上,如果在后端启动时检测到这些文件中的错误,则该后端将无法建立 SSL连接。在所有这些情况下,错误条件都会在服务器日志中报告。

2.7.5.创建证书

创建证书要为服务器创建一个有效期为 365 天的简单自签名证书,请使用以下 OpenSSL 命令,将dbhost.yourdomain.com 替换为服务器的主机名:执行以下命令创建一个自签名的服务器证书:

openssl req -new -x509 -days 365 -nodes -text -out server.crt \
  -keyout server.key -subj "/CN=dbhost.yourdomain.com"

然后执行以下命令:

chmod og-rwx server.key

因为如果文件权限比这更宽松,服务器将拒绝该文件。 有关如何创建服务器私钥和证书的详细信息,请参阅 OpenSSL 文档。

虽然自签名证书可用于测试,但在生产中应使用由证书颁发机构(CA)签名的证书(通常是企业范围的根 CA)。

要创建一个可以由客户端验证身份的服务器证书,首先创建一个证书签名请求(CSR)和一个公钥/私钥文件:

openssl req -new -nodes -text -out root.csr \
-keyout root.key -subj "/CN=root.yourdomain.com"
chmod og-rwx root.key

然后,使用密钥签署请求以创建根证书颁发机构(使用 Linux 上的默认 OpenSSL 配置文件位置):

openssl x509 -req -in root.csr -text -days 3650 \
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
-signkey root.key -out root.crt

最后,创建由新根证书颁发机构签名的服务器证书:

openssl req -new -nodes -text -out server.csr \
-keyout server.key -subj "/CN=dbhost.yourdomain.com"
chmod og-rwx server.key
openssl x509 -req -in server.csr -text -days 365 \
-CA root.crt -CAkey root.key -CAcreateserial \
-out server.crt

server.crt 和 server.key 应存储在服务器上,root.crt应存储在客户端上,以便客户端可以验证服务器的叶证书是否由其信任的根证书签名。root.key 应离线存储,以便用于创建未来的证书。

还可以创建包括中间证书的信任链:

# root
openssl req -new -nodes -text -out root.csr \
-keyout root.key -subj "/CN=root.yourdomain.com"
chmod og-rwx root.key
openssl x509 -req -in root.csr -text -days 3650 \
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
-signkey root.key -out root.crt

# intermediate
openssl req -new -nodes -text -out intermediate.csr \
-keyout intermediate.key -subj "/CN=intermediate.yourdomain.com"
chmod og-rwx intermediate.key
openssl x509 -req -in intermediate.csr -text -days 1825 \
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
-CA root.crt -CAkey root.key -CAcreateserial \
-out intermediate.crt

# leaf
openssl req -new -nodes -text -out server.csr \
-keyout server.key -subj "/CN=dbhost.yourdomain.com"
chmod og-rwx server.key
openssl x509 -req -in server.csr -text -days 365 \
-CA intermediate.crt -CAkey intermediate.key -CAcreateserial \
-out server.crt

server.crt 和 intermediate.crt 应连接成一个证书文件包,并存储在服务器上。 server.key也应存储在服务器上。 root.crt应存储在客户端上,以便客户端可以验证服务器的叶证书是否由链接到其信任的根证书的证书链签名。root.key 和 intermediate.key 应离线存储,以便用于创建未来的证书。

2.8.TLCP连接

TLCP与SSL/TLS最大的不同是采用双证书:签名证书和加密证书,即拥有2对密钥。

SSL/TLS中服务端只需配置证书、私钥、根证书即可,而TLCP要求既要有签名证书、签名私钥(对应原密钥对),还要求有加密证书、加密私钥。

2.8.1.TLCP证书配置

进入安装目录$INSTALL_HOME/ thirdparty/gmssl/tlcp_certs/,修改mksert.sh脚本中ux_gmssl工具路径为真实安装路径。

# 生成双证书
sh  mkcert.sh 

# 证书生成命令参考mkcert.sh,配置文件参考ca.cnf和subca.cnf(cnf配置同openssl)。
# mkcert.sh脚本中设置了ux_gmssl工具所在路径默认为“/home/uxdb/uxdbinstall/thirdparty/gmssl/”,使用时以实际安装目录为准,进行修改即可。
	
# 拷贝客户端证书到默认路径
cp root.crt ~/.uxsinodb/
cp uxsinodb.crt ~/.uxsinodb/
cp uxsinodb.key ~/.uxsinodb/
cp uxsinodb_enc.crt ~/.uxsinodb/
cp uxsinodb_enc.key ~/.uxsinodb/
	
# 拷贝服务端证书到bin目录
cp root.crt ../../../dbsql/bin/
cp server.key ../../../dbsql/bin/
cp server.crt ../../../dbsql/bin/
cp server_enc.key ../../../dbsql/bin/
cp server_enc.crt ../../../dbsql/bin/

# 修改集群配置文件
vim UXDATA/uxsinodb.conf
ssl = 2
ssl_ciphers = 'ECC-SM2-SM4-CBC-SM3:ECDHE-SM2-SM4-CBC-SM3:ECC-SM2-SM4-GCM-SM3:ECDHE-SM2-SM4-GCM-SM3'
ssl_ecdh_curve = 'SM2'
ssl_cert_file = '../server.crt'
ssl_key_file = '../server.key'
ssl_enc_cert_file = '../server_enc.crt'
ssl_enc_key_file = '../server_enc.key'
ssl_ca_file = '../root.crt'

vim UXDATA/ux_hba.conf
hostssl all all 0.0.0.0/0 md5 00:00-24:00 clientcert=1
#host all all 0.0.0.0/0 md5 00:00-24:00

2.8.2.用户级别证书认证

以上配置都是用于通用的SSL连接配置。所有的数据库用户都可以使用该证书进行认证,建立SSL加密链接。若证书文件与数据库用户一一绑定,则该证书只能该数据库用户进行使用,其他用户使用报错。

用户级别认证方式的配置步骤相应场景与第一、二章节基本相同。不同点如下:

  1. 生成客户端证书时,命令行参数/C=CN/ST=China/L=Beijing/O=uxsino/OU=UXDB/CN=uxsino.com_client中CN对应的字段修改为 数据库用户名(如:/C=CN/ST=China/L=Beijing/O=uxsino/OU=UXDB/CN=uxsmo)

  2. 修改集群目录下客户端认证方式配置文件ux_hba中的用户认证方式为 证书认证,即cert。如:hostssl all all 0.0.0.0/0 cert clientcert=1

  3. UXDB 2122新特性,cert认证必须在verify-full模式下使用,所以cliencert必须是verify-full。即:hostssl all all 0.0.0.0/0 cert clientcert=verify-full

特别说明

TLCP模式支持使用cert认证,仅需修改生成客户端签名证书的CN即可。

配置步骤

TLS下key文件未加密为例,生成uxsmo用户的证书。

# 生成ca相关:
./ux_gmssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:SM2 -pkeyopt ec_param_enc:named_curve -out ca.key
./ux_gmssl req -new -days 365 -sm3 -x509 -key ca.key -text -subj "/C=CN/ST=China/L=Beijing/O=uxsino/OU=UXDB/CN=uxsino.com_CA" -out ca.crt

# 生成server相关
./ux_gmssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:SM2 -pkeyopt ec_param_enc:named_curve -out server.key
./ux_gmssl req -new -key server.key -out server.req -subj "/C=CN/ST=China/L=Beijing/O=uxsino/OU=UXDB/CN=uxsino.com_server" 
./ux_gmssl x509 -req -in server.req -CA ca.crt -CAkey ca.key -set_serial 111111 -text -days 365 -sm3 -out server.crt

# 生成client相关
./ux_gmssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:SM2 -pkeyopt ec_param_enc:named_curve -out uxsinodb.key
./ux_gmssl req -new -key uxsinodb.key -out uxsinodb.req -subj "/C=CN/ST=China/L=Beijing/O=uxsino/OU=UXDB/CN=uxsmo" 
./ux_gmssl x509 -req -in uxsinodb.req -CA ca.crt -CAkey ca.key -set_serial 111111 -text -days 365 -sm3 -out uxsinodb.crt

# 修改权限
chmod 0400 server.key
chmod 0400 uxsinodb.key

cp ca.crt ~/.uxsinodb/root.crt
cp uxsinodb.key ~/.uxsinodb/
cp uxsinodb.crt ~/.uxsinodb/

cp ca.crt ../../dbsql/bin/
cp server.key ../../dbsql/bin/
cp server.crt ../../dbsql/bin/

# 修改集群配置文件
vim UXDATA/uxsinodb.conf
ssl = 1
ssl_ciphers = 'TLS_SM4_GCM_SM3:TLS_SM4_CCM_SM3'
ssl_ecdh_curve = 'SM2'
ssl_cert_file = '../server.crt'
ssl_key_file = '../server.key'
ssl_ca_file = '../ca.crt'

vim UXDATA/ux_hba.conf
hostssl all all 0.0.0.0/0 cert 00:00-24:00 clientcert=verify-full
#host all all 0.0.0.0/0 md5 00:00-24:00

2.8.3.连接参数指定

客户端证书的默认位置为~/.uxsinodb,根证书为root.crt,client证书为uxsinodb.crt,client的key为uxsinodb.key。也可在登录时手动指定。如:

./uxsql "host=192.71.0.82 port=5432 dbname=uxdb user=uxsmo sslrootcert=/home/uxdb/uxdbinstall-gmssl/thirdparty/gmssl/ca.crt sslcert=/home/uxdb/uxdbinstall-gmssl/thirdparty/gmssl/uxsinodb.crt sslkey=/home/uxdb/uxdbinstall-gmssl/thirdparty/gmssl/uxsinodb.key"

参数介绍如下:

sslcert

此参数指定 Client 端 SSL 证书的文件名,以替换默认的~/.uxsinodb/uxsinodb.crt。如果未构建 SSL 连接,则忽略此参数。

sslkey

此参数指定用于 Client 端证书的密钥的位置。它可以指定将使用的文件名代替默认的~/.uxsinodb/uxsinodb.key,也可以指定从外部“引擎”获得的密钥(引擎是可加载 OpenSSL 的模块)。外部引擎规范应由冒号分隔的引擎名称和特定于引擎的键标识符组成。如果未构建 SSL 连接,则忽略此参数。

sslrootcert

此参数指定包含 SSL 证书颁发机构(CA)证书的文件的名称。如果该文件存在,则将验证服务器的证书是否已由这些机构之一签名。默认值为~/.uxsinodb/root.crt。

2.9.使用 SSH 隧道进行安全的 TCP/IP 连接

可以使用 SSH 加密客户端和 UXDB 服务器之间的网络连接。如果正确使用,即使对于不支持 SSL的客户端,这也提供了足够安全的网络连接。

首先确保在与 UXDB 服务器相同的机器上正确运行了一个 SSH 服务器,并且您可以使用某个用户的 ssh登录;然后您可以建立到远程服务器的安全隧道。安全隧道监听一个本地端口,并将所有流量转发到远程机器上的一个端口。发送到远程端口的流量可以到达其localhost 地址,或者如果需要,可以到达不同的绑定地址;它不会被视为来自您的本地机器。此命令从客户端机器创建一个安全隧道到远程机器foo.com:

ssh -L 63333:localhost:5432 joe@foo.com

-L 参数中的第一个数字 63333 是隧道的本地端口号;它可以是任何未使用的端口。(IANA 保留端口 49152 到 65535供私人使用。)此后的名称或 IP 地址是您要连接的远程绑定地址,即默认的 localhost。第二个数字 5432是隧道的远程端,例如您的数据库服务器使用的端口号。为了使用此隧道连接到数据库服务器,您需要在本地机器上连接到端口63333:

uxsql -h localhost -p 63333 uxdb

对于数据库服务器来说,它看起来就像您是连接到绑定地址为 localhost 的主机上的用户joe,并且它将使用为该用户到该绑定地址的连接配置的任何身份验证过程。请注意,服务器不会认为连接是SSL 加密的,因为实际上它在客户端和隧道之间没有加密。

SSH 服务器和 UXDB 服务器。这不会带来任何额外的安全风险,因为它们在同一台机器上。

为了使隧道设置成功,您必须被允许以 joe@foo.com 的身份通过 ssh 进行连接,就像您尝试使用 ssh 创建终端会话一样。

您也可以设置端口转发,如下所示:

ssh -L 63333:foo.com:5432 joe@foo.com

但是,数据库服务器将看到连接是从其 foo.com 绑定地址进入的,而默认设置 listen_addresses ='localhost' 并未打开该地址。这通常不是您想要的。

如果您必须通过某个登录主机“跳转”到数据库服务器,则可能的一种设置如下所示:

ssh -L 63333:db.foo.com:5432 joe@shell.foo.com

请注意,这种方式从 shell.foo.com 到 db.foo.com 的连接不会通过 SSH 隧道加密。当网络受到各种限制时,SSH 提供了相当多的配置可能性。有关详细信息,请参阅 SSH 文档。

提示

还有其他几个应用程序可以使用类似于刚才描述的过程提供安全隧道。

2.10.在Windows上注册事件日志

要在操作系统中注册 Windows 事件日志 库,请发出以下命令:

regsvr32 uxsql_library_directory/uxevent.dll

这将创建由事件查看器使用的注册表条目,默认情况下事件源命名为UXsinoDB。

要指定不同的事件源名称(请参见event_source),请使用/n 和 /i 选项:

regsvr32 /n /i:event_source_name uxsql_library_directory/uxevent.dll

要从操作系统中注销 事件日志 库,请发出以下命令:

regsvr32 /u [/i:event_source_name] uxsql_library_directory/uxevent.dll

注意

要在数据库服务器中启用事件日志记录,请修改 uxsinodb.conf 中的log_destination,将eventlog 包含在其中。

3.服务器配置

3.1.设置参数

3.1.1.参数名称和值

所有参数名称都不区分大小写。每个参数都有五种类型的值:布尔值、字符串、整数、浮点数或枚举(enum)。类型决定了设置参数的语法:

  • 布尔值: 值可以写成 on、 off、 true、 false、 yes、 no、 1、 0(不区分大小写),或者它们的任何明确前缀。

  • 字符串: 通常将值用单引号括起来,如果值中有单引号,则将其加倍。但是,如果值是一个简单的数字或标识符,则通常可以省略引号。(在某些上下文中,与SQL 关键字匹配的值需要引号。)

  • 数字(整数和浮点数): 可以使用常规的整数和浮点数格式指定数字参数;如果参数是整数类型,则将分数值四舍五入为最接近的整数。整数参数还可以接受十六进制输入(以0x 开头)和八进制输入(以以 0 开头的数字表示八进制数(例如 0775),以 0x 开头的数字表示十六进制数(例如'0xFF')。也可以使用十进制数(例如'255'),但这些格式不能有小数部分。不要使用千位分隔符。除了十六进制输入外,不需要使用引号。

  • 带单位的数字: 一些数字参数具有隐含的单位,因为它们描述了内存或时间的数量。单位可能是字节、千字节、块(通常为八千字节)、毫秒、秒或分钟。这些设置的未装饰数字值将使用设置的默认单位,可以从ux_settings.unit 中了解到。为了方便起见,可以显式指定单位来设置参数,例如 '120 ms'表示时间值,它们将被转换为参数的实际单位。请注意,要使用此功能,值必须写成字符串(带引号)。单位名称区分大小写,数字值和单位之间可以有空格。

    • 有效的内存单位是 B(字节)、kB(千字节)、MB(兆字节)、GB(千兆字节)和TB(太字节)。内存单位的乘数是 1024,而不是 1000。

    • 有效的时间单位是 us(微秒)、ms(毫秒)、s(秒)、min(分钟)、h(小时)和 d(天)。

    如果使用单位指定了小数值,则会将其舍入到下一个较小单位的倍数。例如,30.1 GB 将被转换为 30822 MB 而不是32319628902 B。如果参数是整数类型,则在任何单位转换后都会进行最终舍入到整数。

  • 枚举类型: 枚举类型参数的写法与字符串参数相同,但被限制为一组有限的值之一。此类参数允许的值可以从ux_settings.enumvals 中找到。枚举参数值不区分大小写。

3.1.2.通过配置文件设置参数

设置这些参数最基本的方法是编辑文件uxsinodb.conf,该文件通常保存在数据目录中。在初始化数据库集群目录时会安装默认副本。以下是该文件的示例:

# 这是一条注释
log_connections = yes
log_destination = 'syslog'
search_path = '"$user", public'
shared_buffers = 128MB

每行指定一个参数。名称和值之间的等号是可选的。空格不重要(除了在引号参数值内部),空行将被忽略。井号(#)将该行的其余部分标记为注释。不是简单标识符或数字的参数值必须用单引号括起来。要嵌入参数值中的单引号,请写入两个单引号(首选)或反斜杠单引号。如果文件包含同一参数的多个条目,则除最后一个条目外,其他条目都将被忽略。

以这种方式设置的参数为集群提供默认值。活动会话看到的设置将是这些值,除非它们被覆盖。被覆盖。以下部分描述了管理员或用户可以覆盖这些默认值的方法。

当主服务器进程接收到 SIGHUP 信号时,配置文件会被重新读取;可以通过从命令行运行 ux_ctl reload 或调用 SQL 函数ux_reload_conf()来最轻松地发送此信号。主服务器进程还会将此信号传播到所有当前运行的服务器进程,以便现有会话也采用新值(这将在它们完成任何当前正在执行的客户端命令后发生)。或者,您可以直接向单个服务器进程发送信号。某些参数只能在服务器启动时设置;对它们在配置文件中的条目进行的任何更改都将被忽略,直到服务器重新启动。在SIGHUP 处理期间,配置文件中的无效参数设置也将被忽略(但会被记录)。

除了 uxsinodb.conf,UXsinoDB 数据目录还包含一个名为 uxsinodb.auto.conf的文件,其格式与 uxsinodb.conf 相同,但旨在自动编辑,而不是手动编辑。此文件保存通过ALTER SYSTEM 命令提供的设置。每当读取uxsinodb.conf 时,都会读取此文件,并且其设置会以相同的方式生效。在 uxsinodb.auto.conf中的设置会覆盖 uxsinodb.conf 中的设置。

外部工具也可以修改 uxsinodb.auto.conf。不建议在服务器运行时执行此操作,因为并发的 ALTER SYSTEM命令可能会覆盖此类更改。这些工具可能只是将新设置附加到末尾,或者它们可能选择删除重复的设置或注释(如 ALTER SYSTEM 所做的那样)。

系统视图ux_file_settings可以帮助预测试配置文件的更改,或者在 SIGHUP 信号没有产生预期效果时进行诊断。

3.1.3.通过 SQL 进行参数交互

UXsinoDB 提供了三个 SQL 命令来建立配置默认值。已经提到的 ALTER SYSTEM 命令提供了一种可通过SQL访问的更改全局默认值的方法;它在功能上等同于编辑uxsinodb.conf。此外,还有两个命令允许在每个数据库或每个角色的基础上设置默认值:

  • ALTER DATABASE命令允许在每个数据库上覆盖全局设置。

  • ALTER ROLE命令允许用户使用特定于用户的值覆盖全局和每个数据库的设置。

使用 ALTER DATABASE 和 ALTER ROLE设置的值仅在启动新的数据库会话时应用。它们会覆盖从配置文件或服务器中获取的值。命令行可以设置全局默认值,也可以为会话设置默认值。请注意,有些设置在服务器启动后无法更改,因此不能使用这些命令(或下面列出的命令)进行设置。

一旦客户端连接到数据库,UXDB提供了两个额外的SQL命令(以及相应的函数)来与会话本地配置设置进行交互:

  • SHOW命令允许检查任何参数的当前值。相应的SQL函数是current_setting(setting_name text)。

  • SET命令允许修改那些可以在会话本地设置的当前值的参数;它对其他会话没有影响。许多参数可以由任何用户以这种方式设置,但是某些参数只能由超级用户和已被授予该参数的SET权限的用户设置。相应的SQL函数是set_config(setting_name,new_value, is_local)。

此外,系统视图ux_settings可以用于查看和更改会话本地值:

  • 查询此视图类似于使用SHOW ALL,但提供了更多细节。它也更灵活,因为可以指定过滤条件或连接其他关系。

  • 在此视图上使用UPDATE,特别是更新setting列,相当于发出SET命令。例如,以下命令的等效命令:

    SET configuration_parameter TO DEFAULT;
    

    是:

    UPDATE ux_settings SET setting = reset_val WHERE name = 'configuration_parameter';
    

3.1.4.通过壳体的参数相互作用

除了设置全局默认值或在数据库或角色级别附加覆盖之外,还可以通过shell工具将设置传递给UXsinoDB。服务器和libuxsql客户端库都可以通过shell接受参数值。

  • 在服务器启动期间,可以通过-c命令行参数将参数设置传递给uxdb命令。例如:

    uxdb -c log_connections=yes -c log_destination='syslog'
    

    以这种方式提供的设置会覆盖通过uxsinodb.conf或ALTER SYSTEM设置的设置,因此不能在不重新启动服务器的情况下全局更改它们。

  • 通过libuxsql启动客户端会话时,可以使用UXOPTIONS环境变量指定参数设置。以这种方式建立的设置构成会话的默认值,但不影响其他会话。由于历史原因,UXOPTIONS的格式类似于启动 uxdb 命令时使用的格式;具体来说,必须指定 -c 标志。例如,

    env UXOPTIONS="-c geqo=off -c statement_timeout=5min" uxsql
    

    其他客户端和库可能会提供自己的机制,通过 shell 或其他方式,允许用户在不直接使用 SQL 命令的情况下更改会话设置。

3.1.5.管理配置文件内容

UXsinoDB 提供了几个功能,用于将复杂的 uxsinodb.conf文件拆分成子文件。当管理具有相关但不完全相同配置的多个服务器时,这些功能特别有用。

除了单个参数设置外,uxsinodb.conf 文件还可以包含 include指令 ,它指定要读取和处理的另一个文件,就好像将其插入到此处的配置文件中一样。此功能允许将配置文件分成物理上分离的部分。包含指令看起来很简单:

include 'filename'

如果文件名不是绝对路径,则将其视为相对于包含引用配置文件的目录。可以嵌套包含。

还有一个 include_if_exists 指令,它的作用与 include指令相同,只是当引用的文件不存在或无法读取时,它不会将其视为错误条件,而是仅记录一条消息并继续处理引用配置文件。

uxsinodb.conf 文件还可以包含 include_dir 指令,它指定要包含的整个配置文件目录。它们看起来像这样:

include_dir 'directory'

非绝对目录名被视为相对于包含引用配置文件的目录。在指定的目录中,只有文件名以后缀 .conf 结尾的非目录文件将被包含。以 .字符开头的文件名也会被忽略,以防止出错,因为这些文件在某些平台上是隐藏的。在包含目录中,多个文件按文件名顺序处理(根据 C语言环境规则,即数字在字母前,大写字母在小写字母前)。

可以使用包含文件或目录来逻辑上分隔数据库配置的部分,而不是使用单个大的 uxsinodb.conf文件。考虑一个具有两个数据库服务器的公司,每个服务器具有不同数量的内存。它们可能会共享配置的某些元素,例如日志记录。但是服务器上与内存相关的参数将在两者之间有所不同。还可能存在服务器特定的自定义。管理此情况的一种方法是将站点的自定义配置更改分为三个文件。您可以将它们添加到uxsinodb.conf 文件的末尾以包含它们:

include 'shared.conf'
include 'memory.conf'
include 'server.conf'

所有系统都将具有相同的 shared.conf。每个具有特定内存量的服务器都可以共享memory.conf,并具有特定于服务器的自定义配置server.conf。另一种可能性是创建一个配置文件目录,并将此信息放入其中的文件中。例如,在uxsinodb.conf的末尾可以引用一个conf.d目录:

include_dir 'conf.d'

然后,您可以将conf.d目录中的文件命名为:

00shared.conf
01memory.conf
02server.conf

这种命名约定建立了这些文件将被加载的明确顺序。这很重要,因为在服务器读取配置文件时,对于特定参数遇到的最后一个设置将被使用。在这个例子中,conf.d/02server.conf中设置的内容将覆盖conf.d/01memory.conf中设置的值。

您也可以使用这种方法来描述文件的命名:

00shared.conf
01memory-8GB.conf
02server-foo.conf

这种排列方式为每个配置文件变体提供了一个唯一的名称。当几个服务器的配置都存储在一个地方(例如版本控制存储库)时,这可以帮助消除歧义。(将数据库配置文件存储在版本控制下也是一个值得考虑的好习惯。)

3.2.文件位置

除了已经提到的uxsinodb.conf文件外,UXsinoDB还使用另外两个手动编辑的配置文件,用于控制客户端身份验证(它们的使用在客户端认证中讨论)。默认情况下,这三个配置文件都存储在数据库集群的数据目录中。本节中描述的参数允许将配置文件放置在其他位置。(这样做可以简化管理。特别是当它们被单独保存时,通常更容易确保配置文件被正确备份。)

data_directory (string)

指定用于数据存储的目录。此参数只能在服务器启动时设置。

config_file (string)

指定主服务器配置文件(通常称为uxsinodb.conf)。此参数只能在uxdb命令行上设置。

hba_file (string)

指定主机基于身份验证的配置文件(通常称为ux_hba.conf)。此参数只能在服务器启动时设置。

ident_file (string)

指定用户名映射的配置文件(通常称为ux_ident.conf)。此参数只能在服务器启动时设置。另请参见用户名映射。

external_pid_file (string)

指定服务器应创建的附加进程ID(PID)文件的名称,以供服务器管理程序使用。此参数只能在服务器启动时设置。

在默认安装中,以上参数均未显式设置。相反,数据目录由-D命令行选项或UXDATA环境变量指定,并且所有配置文件都在数据目录中找到。

如果您希望将配置文件保留在数据目录之外,则uxdb``-D命令行选项或UXDATA环境变量必须指向包含配置文件的目录,并且必须在uxsinodb.conf(或命令行上)中设置data_directory参数以显示实际位于哪个数据目录。请注意,data_directory覆盖-D和UXDATA以获取数据目录的位置,但不适用于配置文件的位置。

如果您希望,可以使用参数config_file、hba_file或ident_file单独指定配置文件的名称和位置。config_file只能在uxdb命令行上指定,但其他参数可以在主配置文件中设置。如果所有三个参数加上data_directory都已显式设置,则不需要指定-D或UXDATA。

设置这些参数时,相对路径将相对于启动uxdb的目录进行解释。

3.3.连接和身份验证

3.3.1.连接设置

listen_addresses (string)

指定服务器用于监听客户端应用程序连接的 TCP/IP 地址。该值采用主机名或数字 IP 地址的逗号分隔列表形式。特殊条目 *对应于所有可用的 IP 接口。条目 0.0.0.0 允许监听所有 IPv4 地址,:: 允许监听所有 IPv6地址。如果列表为空,则服务器根本不监听任何 IP 接口,此时只能使用 Unix 域套接字连接到它。默认值为localhost,仅允许进行本地 TCP/IP“回环”连接。虽然客户端身份验证(客户端认证)允许对可以访问服务器的用户进行细粒度控制,但listen_addresses控制哪些接口接受连接尝试,这可以帮助防止在不安全的网络接口上重复进行恶意连接请求。此参数只能在服务器启动时设置。

port (integer)

服务器监听的 TCP 端口;默认为52025。请注意,如果将服务器放在公共网络上,则应将端口更改为非默认端口,以增加安全性。此参数只能在服务器启动时设置。

max_connections(integer)

确定数据库服务器的最大并发连接数。默认情况下,通常为100个连接,但如果您的内核设置不支持它(在initdb期间确定),则可能会更少。此参数只能在服务器启动时设置。在运行备用服务器时,必须将此参数设置为与主服务器相同或更高的值。否则,不允许在备用服务器中查询。

superuser_reserved_connections(integer)

确定为UXsinoDB超级用户保留的连接“插槽”数。最多可以同时有max_connections个连接处于活动状态。每当活动并发连接数至少为max_connections减去superuser_reserved_connections时,将仅接受超级用户的新连接,并且不会接受新的复制连接。默认值为三个连接。该值必须小于max_connections。此参数只能在服务器启动时设置。

unix_socket_directories(string)

指定服务器用于从客户端应用程序接收连接的Unix域套接字的目录。通过列出用逗号分隔的多个目录可以创建多个套接字。忽略条目之间的空格;如果需要在名称中包含空格或逗号,请使用双引号括起来。空值指定不侦听任何Unix域套接字,在这种情况下,只能使用TCP/ IP套接字连接到服务器。以@开头的值指定应创建抽象命名空间中的Unix域套接字(目前在Linux和Windows上支持)。在这种情况下,此值不指定“目录”,而是指定从中计算实际套接字名称的前缀,方式与文件系统命名空间相同。虽然可以自由选择抽象套接字名称前缀,因为它不是文件系统位置,但惯例仍然是使用类似于文件系统的值,例如@/tmp。默认值通常为/tmp,但可以在构建时更改。在Windows上,默认值为空,这意味着默认情况下不创建Unix域套接字。此参数只能在服务器启动时设置。除了套接字文件本身(命名为.s.UXSQL.nnnn,其中nnnn是服务器的端口号),每个unix_socket_directories目录中还将创建一个名为.s.UXSQL.nnnn.lock的普通文件。两个文件都不应手动删除。对于抽象命名空间中的套接字,不会创建锁定文件。

unix_socket_group (string)

设置 Unix 域套接字的所有组。 (套接字的所有者用户始终是启动服务器的用户。) 与参数 unix_socket_permissions结合使用,可用作 Unix 域连接的附加访问控制机制。默认情况下,这是空字符串,它使用服务器用户的默认组。此参数只能在服务器启动时设置。

此参数在 Windows 上不受支持。任何设置都将被忽略。抽象命名空间中的套接字也没有文件所有者,因此在这种情况下也会忽略此设置。

unix_socket_permissions (integer)

设置 Unix 域套接字的访问权限。Unix 域套接字使用通常的 Unix 文件系统权限集。参数值应为数字模式,格式应符合 chmod 和umask 系统调用所接受的格式。 (要使用惯用的八进制格式,数字必须以 0 (零) 开头。)

默认权限为 0777,表示任何人都可以连接。合理的替代方案是 0770 (仅用户和组,另请参见 unix_socket_group)和 0700 (仅用户)。 (请注意,对于 Unix 域套接字,只有写权限才有意义,因此设置或撤销读取或执行权限是没有意义的。)

此访问控制机制与 客户端认证 中描述的机制是独立的。

此参数只能在服务器启动时设置。

在某些系统上,特别是 Solaris 10 及更高版本,忽略套接字权限。在这种情况下,可以通过将unix_socket_directories 指向具有搜索权限限制的目录来实现类似的效果。

抽象命名空间中的套接字没有文件权限,因此在这种情况下也会忽略此设置。

bonjour (boolean)

启用通过 Bonjour 广告服务器的存在。默认值为关闭。此参数只能在服务器启动时设置。

bonjour_name (string)

指定 Bonjour 服务名称。如果将此参数设置为空字符串 '' (默认值),则使用计算机名称。如果服务器未编译支持Bonjour,则忽略此参数。此参数只能在服务器启动时设置。

tcp_keepalives_idle (integer)

指定在没有网络活动的情况下,操作系统应向客户端发送 TCP keepalive 消息之前的时间量。如果未指定单位,则将其视为秒。值为 0(默认值) 选择操作系统的默认值。此参数仅在支持 TCP keepalive的系统上受支持。TCP_KEEPIDLE或等效的套接字选项,在Windows上;在其他系统上,必须为零。在通过Unix域套接字连接的会话中,此参数将被忽略并始终读取为零。

注意

在Windows上,将值设置为0将将此参数设置为2小时,因为Windows没有提供读取系统默认值的方法。

tcp_keepalives_interval (integer)

指定未被客户端确认的TCP keepalive消息重新传输的时间。如果未指定单位,则将其视为秒。 值为0(默认值)选择操作系统的默认值。此参数仅在支持TCP_KEEPINTVL或等效套接字选项以及Windows的系统上受支持;在其他系统上,必须为零。在通过Unix域套接字连接的会话中,此参数将被忽略并始终读取为零。

注意

在Windows上,将值设置为0将将此参数设置为1秒,因为Windows没有提供读取系统默认值的方法。

tcp_keepalives_count (integer)

指定可以丢失的TCP keepalive消息数,然后将服务器与客户端的连接视为死亡。 值为0(默认值)选择操作系统的默认值。此参数仅在支持TCP_KEEPCNT或等效套接字选项的系统上受支持;在其他系统上,必须为零。在通过Unix域套接字连接的会话中,此参数将被忽略并始终读取为零。

注意

此参数不受Windows支持,必须为零。

tcp_user_timeout (integer)

指定在TCP连接被强制关闭之前,传输的数据可能保持未被确认的时间。 如果未指定单位,则将其视为毫秒。 值为0(默认值)选择操作系统的默认值。此参数仅在支持TCP_USER_TIMEOUT的系统上受支持;在其他系统上,必须为零。在通过Unix域套接字连接的会话中,此参数将被忽略并始终读取为零。

注意

此参数不受Windows支持,必须为零。

client_connection_check_interval (integer)

设置运行查询时检查客户端是否仍然连接的时间间隔。检查是通过轮询套接字执行的,并允许更早地中止长时间运行的查询,如果内核报告连接已关闭。

此选项依赖于Linux、macOS、illumos和BSD系列操作系统公开的内核事件,目前在其他系统上不可用。

如果未指定单位,则将其视为毫秒。默认值为0,表示禁用连接检查。没有连接检查,服务器将仅在下一次与套接字交互时检测到连接的丢失,当它等待、接收或发送数据时。

为了使内核能够在所有情况下(包括网络故障)可靠地检测到丢失的TCP连接并在已知时间内完成,可能还需要调整操作系统的TCPkeepalive设置,或者调整UXsinoDB的tcp_keepalives_idle、tcp_keepalives_interval和tcp_keepalives_count设置。

3.3.2.身份验证

authentication_timeout (integer)

客户端认证的最大允许时间为authentication_timeout,如果潜在客户端在此时间内未完成认证协议,则服务器将关闭连接。这可以防止挂起的客户端无限期地占用连接。如果未指定单位,则将其视为秒。默认值为一分钟(1m)。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

password_encryption (enum)

当在CREATE ROLE或ALTER ROLE中指定密码时,此参数确定用于加密密码的算法。可能的值为scram-sha-256,它将使用SCRAM-SHA-256加密密码,以及md5,它将密码存储为MD5哈希值。默认值为scram-sha-256。请注意,旧的客户端可能缺乏对SCRAM身份验证机制的支持,因此无法使用使用SCRAM-SHA-256加密的密码。有关详细信息,请参见密码认证。

krb_server_keyfile (string)

设置服务器的Kerberos密钥文件的位置。默认值为FILE:/usr/local/uxsql/etc/krb5.keytab(其中目录部分是在构建时指定的sysconfdir;使用ux_config --sysconfdir确定)。如果将此参数设置为空字符串,则会忽略它并使用系统相关的默认值。此参数只能在uxsinodb.conf文件或服务器命令行中设置。有关更多信息,请参见GSSAPI认证。

krb_caseins_users (boolean)

设置是否应该对GSSAPI用户名进行大小写不敏感处理。默认值为off(区分大小写)。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

db_user_namespace (boolean)

该参数启用了每个数据库的用户名称。默认情况下关闭此参数。 该参数只能在uxsinodb.conf文件或服务器命令行中设置。

如果启用此参数,则应将用户创建为 username@dbname 。当连接客户端传递 username 时,@和数据库名称将附加到用户名,并且服务器将查找该特定于数据库的用户名。请注意,在SQL环境中创建包含@的用户名时,您需要引用用户名。

启用此参数后,仍然可以创建普通的全局用户。 在客户端指定用户名时,只需附加@,例如joe@。 @将在服务器查找用户名之前被删除。

db_user_namespace会导致客户端和服务器的用户名表示不同。身份验证检查始终使用服务器的用户名进行,因此必须为服务器的用户名配置身份验证方法,而不是客户端的用户名。因为md5在客户端和服务器上都使用用户名作为盐,所以不能使用md5与db_user_namespace一起使用。

注意

此功能旨在作为临时措施,直到找到完整的解决方案为止。届时,将删除此选项。

3.3.3.SSL

有关设置SSL的更多信息,请参见使用SSL进行安全TCP/IP连接。用于控制使用TLS协议进行传输加密的配置参数的名称为ssl,这是由于历史原因,即使SSL协议的支持已被弃用,也是如此。在此上下文中,SSL与TLS可以互换使用。

ssl (boolean)

启用SSL连接。 该参数只能在uxsinodb.conf文件或服务器命令行中设置。 默认值为0代表关闭,1代表开启ssl并使用TSL协议,2代表开启ssl并使用TLCP协议。

ssl_ca_file (string)

指定包含SSL服务器证书颁发机构(CA)的文件的名称。 相对路径是相对于数据目录的。该参数只能在uxsinodb.conf文件或服务器命令行中设置。默认值为空,表示不加载CA文件,并且不执行客户端证书验证。

ssl_cert_file (string)

指定包含SSL服务器证书的文件的名称。 相对路径是相对于数据目录的。该参数只能在uxsinodb.conf文件或服务器命令行中设置。文件或服务器命令行中指定SSL证书的名称。默认值为server.crt。

ssl_crl_file (string)

指定包含SSL客户端证书吊销列表(CRL)的文件的名称。相对路径是相对于数据目录的。此参数只能在uxsinodb.conf文件或服务器命令行中设置。默认值为空,表示不加载CRL文件(除非设置了ssl_crl_dir)。

ssl_crl_dir (string)

指定包含SSL客户端证书吊销列表(CRL)的目录的名称。相对路径是相对于数据目录的。此参数只能在uxsinodb.conf文件或服务器命令行中设置。默认值为空,表示不使用CRL(除非设置了ssl_crl_file)。

该目录需要使用OpenSSL命令openssl rehash或c_rehash进行准备。有关详细信息,请参阅其文档。

使用此设置时,指定目录中的CRL将在连接时按需加载。可以将新的CRL添加到目录中,并立即使用。这与ssl_crl_file不同,后者会在服务器启动时或重新加载配置时加载文件中的CRL。两个设置可以一起使用。

ssl_key_file (string)

指定包含SSL服务器私钥的文件的名称。相对路径是相对于数据目录的。此参数只能在uxsinodb.conf文件或服务器命令行中设置。默认值为server.key。

ssl_ciphers (string)

指定允许SSL连接使用的SSL密码套件列表。有关此设置的语法和支持的值列表,请参见OpenSSL软件包中的ciphers手册页。仅影响使用TLS版本1.2及以下版本的连接。目前没有控制TLS版本1.3连接使用的密码选择的设置。默认值为HIGH:MEDIUM:+3DES:!aNULL。除非有特定的安全要求,否则默认值通常是一个合理的选择。

此参数只能在uxsinodb.conf文件或服务器命令行中设置。

默认值的说明:

HIGH
使用HIGH组中的密码套件(例如,AES、Camellia、3DES)的密码套件

MEDIUM
使用MEDIUM组中的密码套件(例如,RC4、SEED)的密码套件

+3DES
OpenSSL默认顺序HIGH 是有问题的,因为它将 3DES 排在 AES128 之上。这是错误的,因为 3DES提供的安全性比 AES128 低,而且速度也慢得多。+3DES 将其重新排序,排在所有其他 HIGH 和MEDIUM 密码之后。

!aNULL
禁用不进行身份验证的匿名密码套件。这种密码套件容易受到中间人攻击,因此不应使用。

可用的密码套件详细信息因OpenSSL版本而异。使用命令openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'查看当前安装的OpenSSL版本的实际详细信息。请注意,此列表在运行时基于服务器密钥类型进行过滤。

ssl_prefer_server_ciphers (boolean)

指定是否使用服务器的 SSL密码首选项,而不是客户端的密码首选项。此参数只能在uxsinodb.conf文件或服务器命令行中设置。默认值为on。

旧版 UXDB没有此设置,总是使用客户端的首选项。此设置主要是为了向后兼容这些版本。使用服务器的首选项通常更好,因为更可能服务器已经适当配置。

ssl_ecdh_curve (string)

指定在ECDH密钥交换中使用的曲线的名称。它需要被所有连接的客户端支持。它不需要与服务器的椭圆曲线密钥使用相同的曲线。此参数只能在uxsinodb.conf文件或服务器命令行中设置。默认值为prime256v1。

最常见的曲线的OpenSSL名称为:prime256v1(NIST P-256),secp384r1(NIST P-384),secp521r1(NIST P-521)。可用曲线的完整列表可以使用命令openssl ecparam -list_curves显示。但并不是所有曲线都可在TLS中使用。

ssl_min_protocol_version (enum)

设置要使用的最小 SSL/TLS协议版本。目前有效的值为:TLSv1、TLSv1.1、TLSv1.2、TLSv1.3。旧版的OpenSSL库不支持所有值;如果选择了不受支持的设置,将引发错误。协议版本在TLS 1.0 之前,即 SSL 版本 2 和 3,始终被禁用。

默认值为TLSv1.2,这符合本文撰写时的行业最佳实践。

此参数只能在uxsinodb.conf文件或服务器命令行中设置。

ssl_max_protocol_version (enum)

设置要使用的最大 SSL/TLS协议版本。有效值如下:对于ssl_min_protocol_version,加入了一个空字符串,允许任何协议版本。默认情况下允许任何版本。设置最大协议版本主要用于测试或某些组件无法使用较新协议的情况。

此参数只能在uxsinodb.conf文件或服务器命令行中设置。

ssl_dh_params_file (string)

指定包含用于所谓的短暂DH族SSL密码的Diffie-Hellman参数的文件的名称。默认为空,此时使用编译的默认DH参数。使用自定义DH参数可以减少如果攻击者成功破解编译在内的众所周知的DH参数的风险。您可以使用命令openssl dhparam -out dhparams.pem 2048创建自己的DH参数文件。

此参数只能在uxsinodb.conf文件或服务器命令行中设置。

ssl_passphrase_command (string)

设置在需要获取用于解密SSL文件(如私钥)的密码短语时调用的外部命令。默认情况下,此参数为空,这意味着使用内置提示机制。

该命令必须将密码短语打印到标准输出并以代码0退出。在参数值中,%p将替换为提示字符串。(对于文字%,请写%%。)请注意,提示字符串可能包含空格,因此请确保充分引用。如果存在,则从输出末尾剥离单个换行符。

该命令实际上不必提示用户输入密码短语。它可以从文件中读取密码短语,从密钥链设施中获取密码短语或类似的操作。用户需要确保所选机制足够安全。

此参数只能在uxsinodb.conf文件或服务器命令行中设置。

ssl_passphrase_command_supports_reload (boolean)

此参数确定在需要密码短语的密钥文件在配置重新加载期间是否也会调用由ssl_passphrase_command设置的密码短语命令。如果此参数关闭(默认值),则在重新加载期间将忽略ssl_passphrase_command,如果需要密码短语,则不会重新加载SSL配置。该设置适用于需要TTY进行提示的命令,当服务器运行时可能无法使用TTY。如果从文件中获取密码短语,则将此参数设置为on可能是合适的。

此参数只能在uxsinodb.conf文件或服务器命令行中设置。

3.4.资源消耗

3.4.1.内存

shared_buffers (integer)

设置数据库服务器用于共享内存缓冲区的内存量。默认值通常为128兆字节(128MB),但如果您的内核设置不支持它(在 initdb过程中确定),则可能会更少。此设置必须至少为128千字节。然而,通常需要比最小值高得多的设置以获得良好的性能。如果未指定单位,则将其视为块,即BLCKSZ 字节,通常为8KB。(非默认值的 BLCKSZ 会更改最小值。)此参数只能在服务器启动时设置。

如果您有一台专用的数据库服务器,内存为1GB或更多,则 shared_buffers的合理起始值为系统内存的25%。在某些工作负载下,甚至更大的shared_buffers 设置是有效的,但由于 UXDB还依赖于操作系统缓存,因此分配超过系统内存的内存量是不太可能的,而且可能会导致性能下降。

40%的RAM分配给shared_buffers比较小的分配更好。更大的shared_buffers设置通常需要相应增加max_wal_size,以便将大量新数据或更改数据的写入过程分散到较长的时间段内。在RAM小于1GB的系统上,适当分配较小的RAM百分比,以便为操作系统留出足够的空间。

huge_pages (enum)

控制是否为主共享内存区域请求大页面。有效值为try(默认值),on和off。将huge_pages设置为try时,服务器将尝试请求大页面,但如果失败,则返回默认值。将其设置为on时,无法请求大页面将阻止服务器启动。将其设置为off时,将不会请求大页面。

目前,仅在Linux和Windows上支持此设置。当设置为try时,在其他系统上将忽略此设置。在Linux上,仅在将shared_memory_type设置为mmap(默认值)时才支持此设置。

使用大页面会导致较小的页面表和更少的CPU时间用于内存管理,从而提高性能。有关在Linux上使用大页面的更多详细信息,请参见Linux 大页面。

在Windows上,大页面称为大页。要使用它们,您需要为运行UXsinoDB的Windows用户帐户分配用户权限“锁定内存中的页面”。您可以使用Windows组策略工具(gpedit.msc)分配用户权限“锁定内存中的页面”。要在命令提示符上作为独立进程而不是Windows服务启动数据库服务器,必须以管理员身份运行命令提示符或禁用用户访问控制(UAC)。当启用UAC时,普通命令提示符在启动时会撤消用户权限“锁定内存中的页面”。

请注意,此设置仅影响主共享内存区域。像Linux、FreeBSD和Illumos这样的操作系统也可以自动使用大页面(也称为“超级”页面或“大”页面)进行正常内存分配,而无需UXsinoDB的显式请求。在Linux上,这称为“透明巨大页面”(THP)。该功能已知会导致某些用户在某些Linux版本上的性能下降,因此目前不建议使用它(与显式使用huge_pages不同)。

huge_page_size (integer)

控制启用Linux 大页面时的大页面大小。默认值为零(0)。当设置为0时,将使用系统上的默认大页面大小。此参数仅可在服务器启动时设置。现代64位服务器架构上常见的页面大小包括:2MB和1GB(Intel和AMD),16MB和16GB(IBM POWER),以及64kB、2MB、32MB和1GB(ARM)。有关使用和支持的更多信息,请参见Linux 大页面。

目前仅支持在Linux上使用非默认设置。

temp_buffers (integer)

设置每个数据库会话中用于临时缓冲区的最大内存量。这些是仅用于访问临时表的会话本地缓冲区。如果没有指定单位,则将其视为块,即BLCKSZ字节,通常为8kB。默认值为8兆字节(8MB)。(如果BLCKSZ不是8kB,则默认值会按比例缩放。)此设置可以在单个会话中更改,但仅在会话中首次使用临时表之前进行;尝试更改该值的后续尝试将不会对该会话产生影响。

会话将根据temp_buffers的限制按需分配临时缓冲区。在不需要许多临时缓冲区的会话中设置大值的成本仅为缓冲区描述符,或每个temp_buffers增量约为64字节。但是,如果实际使用了缓冲区,将为其消耗额外的8192字节(或通常为BLCKSZ字节)。

max_prepared_transactions (integer)

设置可以同时处于“准备”状态的事务的最大数量。将此参数设置为零(默认值)将禁用准备事务功能。此参数只能在服务器启动时设置。

如果您不打算使用准备事务,则应将此参数设置为零,以防止意外创建准备事务。如果您正在使用准备事务,则可能希望max_prepared_transactions至少与max_connections一样大,以便每个会话都可以有一个准备事务挂起。

在运行备用服务器时,必须将此参数设置为与主服务器相同或更高的值。否则,将不允许在备用服务器中查询。

work_mem (integer)

设置查询操作(例如排序或哈希表)在写入临时磁盘文件之前可以使用的基本最大内存量。如果没有指定单位,则将其视为千字节。默认值为4兆字节(4MB)。请注意,对于复杂的查询,可能会并行运行多个排序或哈希操作;每个操作通常将被允许在开始将数据写入临时文件之前使用此值指定的尽可能多的内存。此外,可能会有几个正在运行的会话同时执行此类操作。因此,使用的总内存可能是work_mem值的多倍;在选择值时需要牢记这一点。排序操作用于ORDER BY、DISTINCT和合并连接。哈希表用于哈希连接、基于哈希的聚合、结果缓存节点和基于哈希的IN子查询处理。基于哈希的操作通常比等效的基于排序的操作更敏感于内存可用性。哈希表可用的内存通过将work_mem乘以hash_mem_multiplier来计算。这使得基于哈希的操作可以使用超过通常的work_mem基础量的内存。在查询操作溢出是常见情况的环境中,特别是当仅仅增加work_mem会导致内存压力(内存压力通常以间歇性的内存不足错误形式出现)时,考虑增加hash_mem_multiplier。默认值2.0通常在混合工作负载中有效。在work_mem已经增加到40MB或更多的环境中,范围在2.0-8.0或更高的更高设置可能是有效的。

maintenance_work_mem (integer)

指定维护操作(如VACUUM、CREATE INDEX和ALTER TABLE ADD FOREIGN KEY)使用的最大内存量。如果没有指定单位,则将其视为千字节。默认值为64兆字节(64MB)。由于一个数据库会话只能同时执行其中一个操作,并且通常不会有多个操作同时运行,因此将此值设置得比work_mem大得多是安全的。较大的设置可能会提高清理和恢复数据库转储的性能。请注意,当自动清理运行时,最多可以分配此内存的autovacuum_max_workers倍,因此不要将默认值设置得太高。通过单独设置autovacuum_work_mem可能有用。请注意,对于死元组标识符的收集,VACUUM只能利用最多1GB的内存。

autovacuum_work_mem (integer)

指定每个自动清理工作进程使用的最大内存量。如果没有指定单位,则将其视为千字节。默认值为-1,表示应使用maintenance_work_mem的值。可以在其他上下文中运行VACUUM时,该设置不会影响其行为。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

对于死元组标识符的收集,自动清理只能利用最多1GB的内存,因此将autovacuum_work_mem设置为高于该值的值对autovacuum扫描表时可以收集的死元组数量没有影响。

logical_decoding_work_mem (integer)

指定逻辑解码使用的最大内存量,在将某些解码更改写入本地磁盘之前。这限制了逻辑流复制连接使用的内存量。它的默认值为64兆字节(64MB)。由于每个复制连接仅使用此大小的单个缓冲区,并且安装通常不会有许多这样的连接并发(由max_wal_senders限制),因此可以将此值设置得比work_mem高得多,从而减少写入磁盘的解码更改量。

max_stack_depth (integer)

指定服务器执行堆栈的最大安全深度。此参数的理想设置是内核强制执行的实际堆栈大小限制(由ulimit -s或本地等效命令设置),减去一兆字节左右的安全裕量。需要安全裕量,因为堆栈深度不是在服务器的每个例程中都进行检查,而只在关键的潜在递归例程中进行检查。如果未指定此值,则将其视为千字节。默认设置为两兆字节(2MB),这是保守的小值,不太可能引起崩溃。但是,它可能太小,无法允许执行复杂的函数。只有超级用户和具有适当SET特权的用户才能更改此设置。

将max_stack_depth设置为高于实际内核限制的值将意味着失控的递归函数可能会使单个后端进程崩溃。在UXsinoDB可以确定内核限制的平台上,服务器不会允许将此变量设置为不安全的值。但是,并非所有平台都提供此信息,因此在选择值时应谨慎。

shared_memory_type (enum)

指定服务器应使用的共享内存实现,用于保存UXsinoDB的共享缓冲区和其他共享数据的主共享内存区域。可能的值为mmap(用于使用mmap分配的匿名共享内存),sysv(用于通过shmget分配的System V共享内存)和windows(用于Windows共享内存)。并非所有值都受所有平台支持;第一个支持的选项是该平台的默认选项。通常不建议使用sysv选项(在任何平台上都不是默认选项),因为它通常需要更多的配置和管理。只有超级用户和具有适当SET特权的用户才能更改此设置。

非默认内核设置允许大内存分配(参见共享内存和信号量)。

dynamic_shared_memory_type (enum)

指定服务器应使用的动态共享内存实现。可能的值为posix(使用shm_open分配的POSIX共享内存)、sysv(通过shmget分配的System V共享内存)、windows(用于Windows共享内存)和mmap(使用存储在数据目录中的内存映射文件模拟共享内存)。并非所有值都支持所有平台;通常,第一个支持的选项是该平台的默认选项。不建议使用mmap选项,因为操作系统可能会反复将修改后的页面写回磁盘,增加系统I/O负载;但在调试时,当ux_dynshmem目录存储在RAM磁盘上或其他共享内存设施不可用时,它可能是有用的。

min_dynamic_shared_memory (integer)

指定应在服务器启动时分配用于并行查询的内存量。当此内存区域被并发查询耗尽或不足时,新的并行查询尝试使用配置为dynamic_shared_memory_type的方法暂时从操作系统中额外分配共享内存,这可能会因内存管理开销而变慢。使用min_dynamic_shared_memory在启动时分配的内存受操作系统支持huge_pages设置的影响,在自动管理较大页面的操作系统上可能更有利。默认值为0(无)。此参数只能在服务器启动时设置。

3.4.2.磁盘

temp_file_limit (integer)

指定进程可以用于临时文件(例如排序和哈希临时文件或保持游标的存储文件)的最大磁盘空间。试图超过此限制的事务将被取消。如果未指定单位,则将其视为千字节。-1(默认值)表示没有限制。只有超级用户和具有适当SET特权的用户才能更改此设置。

此设置限制给定UXsinoDB进程在任何时刻使用的所有临时文件的总空间。应注意,用于显式临时表的磁盘空间(而不是在查询执行背后使用的临时文件)不计入此限制。

3.4.3.内核资源使用

max_files_per_process (integer)

设置每个服务器子进程允许同时打开的最大文件数。默认值为一千个文件。如果内核正在强制执行安全的每进程限制,则无需担心此设置。但在某些平台上(特别是大多数BSD系统),如果许多进程都尝试打开那么多文件,则内核将允许单个进程打开比系统实际支持的文件多得多的文件。如果您发现自己看到“文件打开太多”失败,请尝试减少此设置。此参数只能在服务器启动时设置。

3.4.4.基于成本的清理延迟

在执行 VACUUM 和ANALYZE 命令期间,系统会维护一个内部计数器,用于跟踪执行的各种 I/O操作的估计成本。当累积成本达到限制(由 vacuum_cost_limit 指定)时,执行操作的进程将休眠一段时间,由vacuum_cost_delay 指定。然后它将重置计数器并继续执行。

此功能的目的是允许管理员减少这些命令对并发数据库活动的 I/O 影响。有许多情况下,维护命令(如 VACUUM 和ANALYZE)不必快速完成;但是,通常非常重要的是这些命令不会显着干扰系统执行其他数据库操作的能力。基于成本的VACUUM 延迟提供了一种管理员实现此目标的方法。

对于手动发出的 VACUUM 命令,默认情况下禁用此功能。要启用它,请将 vacuum_cost_delay 变量设置为非零值。

vacuum_cost_delay (floating point)

当成本限制已超过时,进程将休眠的时间量。如果未指定单位,则将其视为毫秒。默认值为零,这将禁用基于成本的清理延迟功能。正值启用基于成本的清理。

使用基于成本的清理时,适当的 vacuum_cost_delay 值通常非常小,可能小于 1 毫秒。虽然vacuum_cost_delay 可以设置为小数毫秒值,但这些延迟在旧平台上可能无法准确测量。在这种平台上,将 VACUUM的受限资源消耗增加到 1 毫秒以上将需要更改其他 VACUUM 成本参数。尽管如此,您应该将 vacuum_cost_delay保持尽可能小,以便您的平台可以一致地测量;大的延迟没有帮助。

vacuum_cost_page_hit (integer)

估计在共享缓冲区中清理缓冲区的成本。它表示锁定缓冲池、查找共享哈希表和扫描页面内容的成本。默认值为1。

vacuum_cost_page_miss (integer)

估计从磁盘读取的缓冲区清理成本。这代表锁定缓冲池、查找共享哈希表、从磁盘读取所需的块并扫描其内容的工作量。默认值为2。

vacuum_cost_page_dirty (integer)

当清理先前干净的块时,收取的估计成本。它表示将脏块再次刷新到磁盘所需的额外I/O。默认值为20。

vacuum_cost_limit (integer)

累积成本将导致清理过程休眠。默认值为200。

注意

有些操作持有关键锁,应尽快完成。基于成本的清理延迟在这些操作期间不会发生。因此,实际成本可能累积得比指定的限制高得多。为避免在这种情况下无用的长时间延迟,实际延迟计算为vacuum_cost_delay* accumulated_balance / vacuum_cost_limit,最大值为vacuum_cost_delay*4。

3.4.5.后台写入器

有一个名为后台写入器的单独服务器进程,其功能是发出写入“脏”(新的或修改的)共享缓冲区的命令。当干净的共享缓冲区数量似乎不足时,后台写入器将一些脏缓冲区写入文件系统并将其标记为干净的。这减少了处理用户查询的服务器进程无法找到干净缓冲区并不得不自己写入脏缓冲区的可能性。但是,后台写入器确实会导致I/O负载总体增加,因为虽然一个反复脏的页面在检查点间隔内可能只被写入一次,但后台写入器可能在同一间隔内多次写入它。本小节讨论的参数可用于根据本地需求调整行为。

bgwriter_delay (integer)

指定后台写入器活动轮之间的延迟。在每个轮次中,写入器为一些脏缓冲区发出写入命令(可由以下参数控制)。然后它休眠bgwriter_delay的长度,然后重复。但是,如果缓冲池中没有脏缓冲区,它将进入更长的休眠,而不考虑bgwriter_delay。如果没有指定单位,则将其视为毫秒。默认值为200毫秒(200ms)。请注意,在许多系统上,延迟的有效分辨率为10毫秒;将bgwriter_delay设置为不是10的倍数的值可能会产生与设置为下一个更高的10的倍数相同的结果。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

bgwriter_lru_maxpages (integer)

在每轮中,后台写入程序最多写入这么多个缓冲区。将其设置为零将禁用后台写入。(注意,由单独的专用辅助进程管理的检查点不受影响。)默认值为100个缓冲区。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

bgwriter_lru_multiplier (floating point)

每轮写入的脏缓冲区数量基于服务器进程在最近几轮中所需的新缓冲区数量。平均最近需求乘以bgwriter_lru_multiplier,得出下一轮需要的缓冲区数量的估计值。脏缓冲区被写入,直到有足够多的干净可重用缓冲区可用。(但每轮最多只会写入bgwriter_lru_maxpages个缓冲区。)因此,1.0的设置表示“即时”策略,即恰好写入预测所需的缓冲区数量。较大的值提供了一些对需求峰值的缓冲,而较小的值则故意将写入留给服务器进程完成。默认值为2.0。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

bgwriter_flush_after (integer)

每当后台写入程序写入的数据量超过此值时,尝试强制操作系统将这些写入发出到底层存储。这样做将限制内核页缓存中脏数据的数量,减少在检查点结束时发出fsync或在操作系统后台以更大的批量写回数据时出现停顿的可能性。通常情况下,这将大大降低事务延迟,但在一些情况下,特别是在工作负载大于shared_buffers但小于操作系统的页缓存的情况下,性能可能会降低。此设置在某些平台上可能没有效果。如果未指定单位,则将其视为块,即BLCKSZ字节,通常为8kB。有效范围为0(禁用强制写回)到2MB。在Linux上,默认值为512kB,在其他地方为0。(如果BLCKSZ不是8kB,则默认值和最大值按比例缩放。)此参数只能在uxsinodb.conf文件或服务器命令行中设置。

较小的bgwriter_lru_maxpages和bgwriter_lru_multiplier值减少了后台写入程序引起的额外I/O负载,但也增加了服务器进程需要写入的可能性。进程将不得不为自己发出写入操作,延迟交互式查询。

3.4.6.异步行为

backend_flush_after(integer)

每当单个后端写入的数据量超过此值时,尝试强制操作系统将这些写入操作发送到底层存储。这样做将限制内核页面缓存中的脏数据量,减少在检查点结束时发出fsync或在后台以更大的批量写回数据时出现停顿的可能性。通常会大大降低事务延迟,但也有一些情况,特别是对于大于共享缓存但小于操作系统页面缓存的工作负载,性能可能会降低。此设置在某些平台上可能没有任何效果。如果未指定此值的单位,则将其视为块,即BLCKSZ字节,通常为8kB。有效范围为0(禁用强制写回)到2MB。默认值为0,即没有强制写回。(如果BLCKSZ不是8kB,则最大值与之成比例。)

effective_io_concurrency(integer)

设置UXsinoDB期望可以同时执行的并发磁盘I/O操作的数量。提高此值将增加任何单个UXsinoDB会话尝试并行启动的I/O操作数量。允许的范围是1到1000,或零以禁用异步I/O请求的发出。目前,此设置仅影响位图堆扫描。对于磁盘驱动器,此设置的良好起点是用于数据库的RAID 0条带或RAID 1镜像组成的单独驱动器的数量。(对于RAID 5,不应计算奇偶校验驱动器。)但是,如果数据库经常忙于发出并发会话中的多个查询,则较低的值可能足以使磁盘阵列保持繁忙状态。超过保持磁盘繁忙所需的值只会导致额外的CPU开销。SSD和其他基于内存的存储通常可以处理许多并发请求,因此最佳值可能在数百个左右。异步I/O取决于有效的posix_fadvise函数,某些操作系统缺少该函数。如果不存在该函数,则将此参数设置为除零以外的任何值都将导致错误。在某些操作系统(例如Solaris)上,该函数存在但实际上不起作用。在支持的系统上,默认值为1,否则为0。可以通过设置相同名称的表空间参数来覆盖特定表中的值。

maintenance_io_concurrency(integer)

类似于effective_io_concurrency,但用于代表许多客户端会话执行的维护工作。在支持的系统上,默认值为10,否则为0。可以通过设置同名的tablespace参数来覆盖特定表空间中表的值。

max_worker_processes(integer)

设置系统支持的后台进程的最大数量。此参数只能在服务器启动时设置。默认值为8。在运行备用服务器时,必须将此参数设置为与主服务器相同或更高的值。否则,不允许在备用服务器中查询。更改此值时,还要考虑调整max_parallel_workers、max_parallel_maintenance_workers和max_parallel_workers_per_gather。

max_parallel_workers_per_gather(integer)

设置单个Gather或GatherMerge节点可以启动的最大工作进程数。并行工作进程来自由max_worker_processes建立的进程池,受max_parallel_workers限制。请注意,请求的工作进程数量在运行时可能不可用。如果发生这种情况,则计划将以比预期更少的工作进程运行,这可能是低效的。默认值为2。将此值设置为0会禁用并行查询执行。请注意,并行查询可能会消耗比非并行查询更多的资源,因为每个工作进程都是一个完全独立的进程,对系统的影响与其他用户会话的影响大致相同。在选择此设置的值以及配置控制资源利用率的其他设置(例如work_mem)时,应考虑这一点。资源限制(例如work_mem)单独应用于每个工作进程,这意味着总利用率可能比任何单个进程通常情况下更高。

max_parallel_maintenance_workers(integer)

设置单个实用程序命令可以启动的最大并行工作进程数。目前,支持使用并行工作进程的并行实用程序命令仅为CREATE INDEX(仅在构建B树索引时)和不带FULL选项的VACUUM。并行工作进程来自由max_worker_processes建立的进程池,受限制通过max_parallel_workers设置并行操作的最大工作进程数。请注意,请求的工作进程数量可能在运行时不可用。如果发生这种情况,实用程序操作将使用比预期更少的工作进程运行。默认值为2。将此值设置为0将禁用实用程序命令使用并行工作进程。

请注意,并行实用程序命令不应消耗比等效的非并行操作更多的内存。这种策略与并行查询不同,后者通常逐个工作进程应用资源限制。并行实用程序命令将资源限制maintenance_work_mem视为应用于整个实用程序命令的限制,而不考虑并行工作进程的数量。但是,并行实用程序命令仍可能消耗大量的CPU 资源和 I/O 带宽。

max_parallel_workers (integer)

设置系统支持的并行操作的最大工作进程数。默认值为8。在增加或减少此值时,请考虑同时调整max_parallel_maintenance_workers和max_parallel_workers_per_gather。此外,请注意,如果此值高于max_worker_processes,则不会产生影响,因为并行工作进程是从该设置建立的工作进程池中获取的。

parallel_leader_participation (boolean)

允许领导进程在 Gather 和 Gather Merge 节点下执行查询计划,而不是等待工作进程。默认值为 on。将此值设置为 off可以减少工作进程因为领导进程读取元组不够快而被阻塞的可能性,但需要领导进程等待工作进程启动,然后才能生成第一个元组。领导进程对性能的帮助或阻碍程度取决于计划类型、工作进程数量和查询持续时间。

old_snapshot_threshold (integer)

设置查询快照可以使用的最短时间,而不会在使用快照时出现“快照过旧”错误的风险。已死亡的数据超过此阈值的时间将被允许进行清理。这可以帮助防止快照长时间保持使用而导致膨胀。为了防止由于清理数据而导致的不正确结果,当快照的年龄超过此阈值并且使用快照读取自快照生成后已修改的页面时,将生成错误。

如果未指定此值的单位,则将其视为分钟。值为 -1(默认值)将禁用此功能,实际上将快照年龄限制设置为无限制。此参数只能在服务器启动时设置。

生产工作的有用值可能在几个小时到几天之间。小的值(如 0或当启用此功能时,允许在事务ID回绕之前保留未使用的行。这可以减少在高并发负载下的锁竞争,从而提高性能。但是,这也会导致表膨胀,因为已删除的行将保留在表中,直到回滚段被重用或回滚段被删除。默认情况下,此功能处于禁用状态。可以使用ALTER TABLE命令启用它。允许的最大值为2G。只允许较短的值(例如1min)是因为它们有时可能对测试有用。虽然允许设置高达60d,但请注意,在许多工作负载中,极端膨胀或事务ID回绕可能发生在更短的时间范围内。

启用此功能时,关系末尾的空闲空间不能释放到操作系统,因为这可能会删除检测“快照过旧”条件所需的信息。分配给关系的所有空间仅在该关系内重用,除非显式释放(例如使用VACUUM FULL)。

此设置不尝试保证在任何特定情况下都会生成错误。实际上,如果可以从已实现结果集的游标生成正确的结果,则即使在引用表中的基础行已被清除的情况下,也不会生成错误。某些表不能早期安全地进行清理,因此不会受到此设置的影响,例如系统目录。对于这样的表,此设置既不会减少膨胀,也不会创建扫描时出现“快照过旧”错误的可能性。

3.5.预写式日志

有关调整这些设置的详细信息,请参见WAL 配置。

3.5.1.设置

wal_level (enum)

wal_level 确定写入预写式日志的信息量。默认值为 replica,它写入足够的数据以支持 WAL存档和复制,包括在备用服务器上运行只读查询。 minimal移除除了从崩溃或立即关闭中恢复所需的信息之外的所有日志记录。最后,logical添加支持逻辑解码所需的信息。每个级别都包括在所有较低级别记录的信息。此参数只能在服务器启动时设置。

minimal 级别生成最少的 WAL量。它不记录在创建或重写永久关系的事务中的行信息。这可以使操作更快。启动此优化的操作包括:

ALTER ... SET TABLESPACE
CLUSTER
CREATE TABLE
REFRESH MATERIALIZED VIEW (without CONCURRENTLY)
REINDEX
TRUNCATE

然而,最小 WAL 不包含足够的信息用于点时间恢复,因此必须使用 replica或更高级别以启用连续归档(archive_mode)和流二进制复制。事实上,如果max_wal_senders 不为零,则服务器甚至不会在此模式下启动。请注意,将 wal_level 更改为minimal 会使以前的基本备份无法用于点时间恢复和备用服务器。

在 logical 级别上,记录与 replica 相同的信息,以及从 WAL 中提取逻辑更改集所需的信息。使用logical 级别将增加 WAL 的容量,特别是如果许多表配置为 REPLICA IDENTITY FULL 并且执行了许多UPDATE 和 DELETE 语句。

fsync (boolean)

如果打开此参数,则 UXDB 服务器将尝试确保更新被物理写入磁盘,通过发出 fsync 系统调用或各种等效方法(参见wal_sync_method)。这确保数据库集群可以在操作系统或硬件崩溃后恢复到一致状态。

虽然关闭 fsync通常会带来性能优势,但这可能会导致在电源故障或系统崩溃时无法恢复的数据损坏。因此,只有在您可以轻松从外部数据重新创建整个数据库时才建议关闭fsync。

关闭 fsync的安全情况示例包括从备份文件加载新数据库集群、使用数据库集群处理一批数据后将数据库丢弃并重新创建、或用于经常重新创建且不用于故障转移的只读数据库克隆。仅高质量硬件不足以成为关闭fsync 的充分理由。

在将 fsync从关闭状态更改为开启状态时,为了可靠地进行恢复,必须将内核中的所有修改缓冲区强制写入持久存储。这可以在集群关闭时或在fsync 开启时通过运行 initdb --sync-only、运行 sync、卸载文件系统或重新启动服务器来完成。

在许多情况下,对于非关键事务,关闭synchronous_commit可以提供关闭 fsync 的潜在性能优势,而不会带来数据损坏的风险。

fsync 只能在 uxsinodb.conf 文件或服务器命令行中设置。如果关闭此参数,也应考虑关闭full_page_writes。

synchronous_commit (enum)

指定在数据库服务器向客户端返回“成功”指示之前必须完成多少 WAL 处理。有效值为remote_apply、on(默认值)、remote_write、local 和off。

如果 synchronous_standby_names 为空,则唯一有意义的设置是 on 和off;remote_apply、remote_write 和 local 提供与 on相同的本地同步级别。所有非 off 模式的本地行为是等待 WAL 刷新到磁盘。在off 模式下,没有等待,因此在向客户端报告成功和事务稍后被保证安全免受服务器崩溃之间可能会有延迟。(最大延迟是wal_writer_delay的三倍。)与 fsync 不同,将此参数设置为off不会创建任何数据库不一致的风险:操作系统或数据库崩溃可能导致一些最近已提交的事务丢失,但数据库状态将与这些事务已干净地中止时相同。因此,当性能比事务的耐久性更重要时,关闭synchronous_commit 可以是一种有用的替代方法。有关更多讨论,请参见 异步提交。

如果synchronous_standby_names不为空,则 synchronous_commit 还控制事务提交是否等待其 WAL 记录在备用服务器上处理。

当设置为 remote_apply时,提交将等待当前同步备用的回复,指示它们已接收事务的提交记录并应用它,以便在备用上对查询可见,并写入备用的持久存储。这将导致比以前的设置更大的提交延迟,因为它等待WAL 回放。当设置为 on时,提交将等待当前同步备用的回复,指示它们已将事务的提交记录刷新到持久存储。这确保了除非主服务器和所有同步备用都遭受其数据库存储的损坏,否则不会丢失事务。当设置为remote_write时,提交将等待当前同步备用的回复,指示它们已接收事务的提交记录并将其写入其文件系统。此设置确保数据保留,如果备用的UXsinoDB 实例崩溃,则数据未必已达到备用的持久存储。设置 local会导致提交等待本地刷新到磁盘,但不用于复制。当使用同步复制时,通常不希望这样做,但为了完整性而提供。

此参数可以随时更改;任何一个事务的行为取决于其提交时的设置。因此,有些事务同步提交,有些异步提交是可能的和有用的。例如,要使单个多语句事务在默认设置相反时异步提交,请在事务内发出“SET LOCAL synchronous_commit TO OFF”命令。

下表总结了synchronous_commit设置的功能。

表 同步_提交模式

synchronous_commit settinglocal durable commitstandby durable commit after UX crashstandby durable commit after OS crashstandby query consistency
remote_apply••••
on•••
remote_write••
local•
off

wal_sync_method (enum)

用于强制WAL更新到磁盘的方法。如果fsync关闭,则此设置无关紧要,因为WAL文件更新将根本不会被强制执行。可能的值包括:

  • open_datasync(使用open()选项O_DSYNC写入WAL文件)

  • fdatasync(在每个提交时调用fdatasync())

  • fsync(在每个提交时调用fsync())

  • fsync_writethrough(在每个提交时调用fsync(),强制写入任何磁盘写入缓存)

  • open_sync(使用open()选项O_SYNC写入WAL文件)。

open_*选项还使用O_DIRECT(如果可用)。并非所有这些选择都适用于所有平台。默认值是上述列表中由平台支持的第一种方法,但在Linux和FreeBSD上默认为fdatasync。默认值不一定是理想的;可能需要更改此设置或系统配置的其他方面,以创建崩溃安全的配置或实现最佳性能。这些方面在第11.1节中讨论。这个参数只能在uxsinodb.conf文件或服务器命令行中设置。

full_page_writes (boolean)

当这个参数打开时,UXsinoDB服务器会在检查点之后第一次修改每个磁盘页时将整个内容写入WAL。这是必要的,因为在操作系统崩溃期间正在进行的页面写入可能只完成了部分,导致磁盘上的页面包含旧数据和新数据的混合。通常存储在WAL中的行级更改数据将无法在崩溃后恢复期间完全恢复这样的页面。存储完整页面图像可以保证页面可以正确恢复,但代价是增加必须写入WAL的数据量。(因为WAL重放总是从检查点开始,所以在检查点之后每个页面的第一次更改时执行此操作就足够了。因此,减少全页写入的成本的一种方法是增加检查点间隔参数。)

关闭此参数可以加快正常操作,但可能会在系统故障后导致不可恢复的数据损坏或静默数据损坏。风险类似于关闭fsync,但更小,只有在建议使用该参数的相同情况下才应关闭它。

关闭此参数不会影响使用WAL归档进行时间点恢复(PITR)。

这个参数只能在uxsinodb.conf文件或服务器命令行中设置。默认值为on。

wal_log_hints (boolean)

当这个参数为on时,UXsinoDB服务器会在检查点之后第一次修改每个磁盘页时将整个内容写入WAL,即使是所谓的提示位的非关键修改。

如果启用了数据校验和,则提示位更新始终会被记录在WAL中,忽略此设置。您可以使用此设置测试如果您的数据库启用了数据校验和,会发生多少额外的WAL记录。

此参数只能在服务器启动时设置。默认值为off。

wal_compression (enum)

此参数启用使用指定压缩方法的WAL压缩。启用后,UXsinoDB服务器会在full_page_writes为on或进行基本备份时,压缩写入WAL的完整页面图像。在WAL重放期间,压缩的页面图像将被解压缩。支持的方法是uxlz、lz4(如果UXsinoDB编译时使用了--with-lz4)和zstd(如果UXsinoDB编译时使用了--with-zstd)。默认值为off。只有超级用户和具有适当SET权限的用户才能更改此设置。

启用压缩可以减少WAL卷而不增加不可恢复的数据损坏的风险,但这会增加一些额外的 CPU 负担,用于 WAL 日志记录期间的压缩和 WAL 重放期间的解压缩。

wal_init_zero (boolean)

如果设置为 on(默认值),则此选项会导致新的 WAL 文件填充为零。在某些文件系统上,这可以确保在需要写入 WAL记录之前分配空间。然而,写时复制(COW)文件系统可能无法从此技术中受益,因此提供了跳过不必要工作的选项。如果设置为off,则仅在创建文件时写入最后一个字节,以便其具有预期的大小。

wal_recycle (boolean)

如果设置为 on(默认值),则此选项会通过重命名 WAL 文件来回收它们,避免创建新文件的需要。在 COW文件系统上,创建新文件可能更快,因此提供了禁用此行为的选项。

wal_buffers (integer)

用于尚未写入磁盘的 WAL 数据的共享内存量。默认设置为 -1,选择大小等于shared_buffers 的1/32(约为 3%),但不少于 64kB,也不超过一个 WAL 段的大小,通常为16MB。如果自动选择的值过大或过小,则可以手动设置此值,但任何小于32kB 的正值都将被视为 32kB。如果未指定单位,则将其视为 WAL 块,即 XLOG_BLCKSZ 字节,通常为8kB。此参数只能在服务器启动时设置。

WAL缓冲区的内容在每个事务提交时写入磁盘,因此极大的值不太可能提供显着的好处。但是,在许多客户端同时提交的繁忙服务器上,将此值设置为至少几兆字节可以提高写入性能。默认设置为-1 的自动调整应在大多数情况下给出合理的结果。

wal_writer_delay (integer)

指定 WAL 写入器刷新 WAL 的频率,以时间为单位。刷新 WAL 后,写入器会休眠wal_writer_delay 指定的时间长度,除非被异步提交的事务更早地唤醒。如果上次刷新发生在不到wal_writer_delay 之前,并且自上次刷新以来产生的 WAL 少于 wal_writer_flush_after,则WAL 仅写入操作系统,而不是刷新到磁盘。如果未指定单位,则将其视为毫秒。默认值为 200毫秒(200ms)。请注意,在许多系统上,睡眠延迟的有效分辨率为10 毫秒;将 wal_writer_delay 设置为不是 10 的倍数的值可能会产生与将其设置为下一个更高的 10的倍数相同的结果。此参数只能在 uxsinodb.conf 文件或服务器命令行中设置。

wal_writer_flush_after (integer)

指定 WAL 写入器刷新 WAL 的频率,以容量为单位。 如果上次刷新发生在不到 wal_writer_delay之前,并且自上次刷新以来产生的 WAL 小于 wal_writer_flush_after,则 WAL只会被写入操作系统,而不会被刷新到磁盘。如果将 wal_writer_flush_after 设置为 0,则WAL 数据将立即被刷新。如果未指定单位,则默认为 WAL 块,即 XLOG_BLCKSZ 字节,通常为 8kB。默认值为1MB。此参数只能在 uxsinodb.conf 文件或服务器命令行中设置。

wal_skip_threshold (integer)

当 wal_level 为 minimal且事务在创建或重写永久关系后提交时,此设置确定如何持久化新数据。如果数据小于此设置,则将其写入WAL 日志;否则,使用受影响文件的fsync。根据存储的属性,提高或降低此值可能有助于加速并发事务。如果未指定单位,则默认为千字节。默认值为两兆字节(2MB)。

commit_delay (integer)

设置 commit_delay 可在 WAL刷新启动之前添加时间延迟。如果系统负载足够高,以至于其他事务在给定的时间间隔内准备好提交,则可以通过允许更多的事务通过单个WAL 刷新提交来提高组提交吞吐量。但是,每个 WAL刷新的延迟也会增加延迟时间。因为如果没有其他事务准备好提交,则延迟只是浪费,所以只有在刷新即将启动时至少有commit_siblings 个其他事务处于活动状态时才会执行延迟。如果禁用了fsync,则不执行延迟。如果未指定单位,则默认为微秒。默认值为零(无延迟)。只有超级用户和具有适当SET 权限的用户才能更改此设置。

第一个准备刷新的进程等待配置的时间间隔,而后续进程仅等待直到领导者完成刷新操作。

commit_siblings (integer)

在执行 commit_delay延迟之前要求的最小并发打开事务数。较大的值使得在延迟间隔内至少有一个其他事务准备好提交的概率更大。默认值为五个事务。

3.5.2.检查点

checkpoint_timeout (integer)

自动 WAL 检查点之间的最长时间。 如果未指定单位,则将其视为秒。 有效范围为 30 秒至一天。 默认值为五分钟 (5min)。增加此参数可能会增加崩溃恢复所需的时间。 此参数只能在 uxsinodb.conf 文件或服务器命令行中设置。

checkpoint_completion_target (floating point)

指定检查点完成的目标,作为检查点之间总时间的一部分。默认值为 0.9,几乎将检查点分布在所有可用间隔中,提供相当一致的 I/O负载,同时留出一些时间用于检查点完成开销。不建议降低此参数,因为它会导致检查点完成得更快。这会导致检查点期间的I/O 率更高,然后在检查点完成和下一个计划检查点之间的一段时间内,I/O 率较低。此参数只能在 uxsinodb.conf文件或服务器命令行中设置。

checkpoint_flush_after (integer)

每当在执行检查点时写入的数据量超过此值时,尝试强制操作系统将这些写入发送到底层存储。这样做将限制内核页缓存中的脏数据量,减少在检查点结束时发出fsync 或在后台以更大的批量写回数据时发生停顿的可能性。通常,这将导致事务延迟大大降低,但也有一些情况,特别是对于大于shared_buffers但小于操作系统页缓存的工作负载,性能可能会降低。此设置在某些平台上可能没有效果。如果未指定单位,则将其视为块,即BLCKSZ 字节,通常为 8kB。有效范围为 0(禁用强制写回)至 2MB。在 Linux 上,默认值为256kB,在其他地方为 0。(如果 BLCKSZ 不是8kB,则默认值和最大值按比例缩放。)此参数只能在uxsinodb.conf 文件或服务器命令行中设置。

checkpoint_warning (integer)

如果由于填充 WAL 段文件而发生的检查点之间的时间间隔小于此值(这表明应该提高max_wal_size),则向服务器日志写入消息。如果未指定单位,则将其视为秒。默认值为30 秒 (30s)。零禁用警告。如果未设置 checkpoint_timeout,则不会生成警告。

max_wal_size (integer)

自动检查点期间允许WAL增长的最大大小。这是一个软限制;WAL大小可以在特殊情况下超过max_wal_size,例如重载、失败的archive_command或archive_library,或高wal_keep_size设置。如果未指定单位,则将此值视为兆字节。 默认值为1 GB。 增加此参数可能会增加崩溃恢复所需的时间。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

min_wal_size (integer)

只要WAL磁盘使用率保持在此设置以下,旧的WAL文件就总是在检查点时回收以备将来使用,而不是删除。这可以用于确保保留足够的WAL空间来处理WAL使用率的峰值,例如运行大型批处理作业时。如果未指定单位,则将此值视为兆字节。 默认值为80 MB。 此参数只能在uxsinodb.conf文件或服务器命令行中设置。

3.5.3.归档

archive_mode (enum)

启用archive_mode时,通过设置archive_command或archive_library将完成的WAL段发送到归档存储。除了off以外,还有两种模式:on和always。在正常操作期间,两种模式之间没有区别,但在设置为always时,WAL归档程序也在归档恢复或待机模式下启用。在always模式下,从归档中恢复或通过流复制流式传输的所有文件都将被归档(再次)。

archive_mode是一个单独的设置,与archive_command和archive_library分开,以便可以在不离开归档模式的情况下更改archive_command和archive_library。此参数只能在服务器启动时设置。 当wal_level设置为minimal时,无法启用archive_mode。

archive_command (string)

执行本地shell命令以归档已完成的WAL文件段。字符串中的任何%p都将被文件的路径名替换,任何%f都将被替换为文件名。(路径名相对于服务器的工作目录,即集群的数据目录。)使用%%将实际的%字符嵌入命令中。命令仅在返回零退出状态时才成功。

此参数仅可在uxsinodb.conf文件或服务器命令行中设置。仅当在服务器启动时启用archive_mode并将archive_library设置为空字符串时,才会忽略它。如果archive_command为空字符串(默认值),而archive_mode已启用(并且archive_library设置为空字符串),则WAL归档将暂时禁用,但服务器将继续累积WAL段文件,期望很快提供命令。将archive_command设置为什么都不做但返回true的命令,例如/bin/true(Windows上的REM),可以有效地禁用归档,但也会破坏用于归档恢复所需的WAL文件链,因此应仅在不寻常的情况下使用。

archive_library(string)

用于归档已完成的WAL文件段的库。如果设置为空字符串(默认值),则启用通过shell进行归档,并使用archive_command。否则,将使用指定的共享库进行归档。更改此参数时,uxmaster将重新启动WAL归档器进程。

此参数仅可在uxsinodb.conf文件或服务器命令行中设置。

archive_timeout(integer)

archive_command或archive_library仅在完成WAL段时调用。因此,如果您的服务器生成的WAL流量很少(或者有松弛期间),则在事务完成并安全记录在归档存储中之间可能会有很长时间的延迟。为了限制未存档数据的年龄,可以将archive_timeout设置为强制服务器定期切换到新的WAL段文件。当此参数大于零时,只要自上次段文件切换以来经过了这段时间,并且有任何数据库活动(包括单个检查点,如果没有数据库活动,则跳过检查点),服务器就会切换到新的段文件。请注意,由于强制切换而提前关闭的归档文件仍然与完全满文件相同长度。因此,不明智地使用非常短的archive_timeout,它会膨胀您的归档存储。通常,archive_timeout设置为一分钟左右是合理的。如果您希望将数据更快地从主服务器复制到副本,请考虑使用流复制,而不是归档。如果未指定单位,则将此值视为秒。此参数只能在uxsinodb.conf文件或服务器命令行上设置。

3.5.4.恢复

本节描述了适用于恢复的设置,影响崩溃恢复、流复制和基于归档的复制。

recovery_prefetch (enum)

在恢复期间,是否尝试预取尚未在缓冲池中的WAL中引用的块。有效值为off、on和try(默认值)。如果操作系统提供posix_fadvise函数,则try设置仅启用预取。目前,该函数用于实现预取。请注意,某些操作系统提供该函数,但它不起作用。

预取即将需要的块可以减少某些工作负载下的恢复期间的I/O等待时间。请参阅wal_decode_buffer_size和maintenance_io_concurrency设置,这些设置限制了预取活动。

wal_decode_buffer_size (integer)

服务器可以查找WAL以预取块的最大距离限制。如果未指定单位,则将此值视为字节。默认值为512kB。

3.5.5.归档恢复

本节仅描述恢复期间适用的设置。必须为任何后续要执行的恢复重置这些设置。

“恢复”涵盖将服务器用作备用服务器或执行有针对性的恢复。通常,备用模式将用于提供高可用性或读可扩展性,而有针对性的恢复则用于从数据丢失中恢复。

要在备用模式下启动服务器,请在数据目录中创建一个名为standby.signal的文件。服务器将进入恢复状态,并且当达到归档WAL的末尾时不会停止恢复,而是将继续尝试通过连接到由primary_conninfo设置指定的发送服务器或使用restore_command获取新的WAL段来继续恢复。对于此模式,此部分和备用服务器中的参数是有关的。来自恢复目标的参数也将应用,但通常在此模式下不会有用。

要在有针对性的恢复模式下启动服务器,请在数据目录中创建一个名为recovery.signal的文件。如果同时存在standby.signal和recovery.signal,则服务器将进入备用模式。在有针对性的恢复模式下,此部分和恢复目标中的参数是有关的。recovery.signal文件被创建时,备用模式优先。当归档的 WAL 完全回放或达到 recovery_target 时,目标恢复模式结束。在此模式下,将使用本节和恢复目标的参数。

restore_command (string)

本地 shell 命令,用于检索 WAL 文件系列的归档段。此参数对于归档恢复是必需的,但对于流复制是可选的。 字符串中的任何 %f都将被替换为从归档中检索的文件名,任何 %p都将被替换为服务器上的复制目标路径名(路径名相对于当前工作目录,即集群的数据目录)。任何%r都将被替换为包含最后一个有效重启点的文件的名称。这是必须保留的最早文件,以允许恢复可重新启动,因此此信息可用于将归档截断为仅支持从当前恢复重新启动所需的最小值。%r 通常仅由温备配置使用。写入%% 以嵌入实际的 % 字符。

重要的是,该命令仅在成功时返回零退出状态。该命令将要求返回归档中不存在的文件名;当被要求时,它必须返回非零值。例如:

restore_command = 'cp /mnt/server/archivedir/%f "%p"'
restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"'  # Windows

例外情况是,如果命令被信号(除了用作数据库服务器关闭的一部分的 SIGTERM)或 shell的错误(例如未找到命令)终止,则恢复将中止,服务器将无法启动。

此参数只能在 uxsinodb.conf 文件或服务器命令行中设置。

archive_cleanup_command (string)

此可选参数指定将在每个重启点执行的 shell 命令。 archive_cleanup_command的目的是提供一种机制来清理备用服务器不再需要的旧归档 WAL 文件。任何%r 都将被替换为包含最后一个有效重启点的文件的名称。这是必须保留的最早文件,以允许恢复可重新启动,因此早于 %r的所有文件都可以安全删除。此信息可用于将归档截断为仅支持从当前恢复重新启动所需的最小值。例如,archive_cleanup_command中经常使用ux_archivecleanup模块进行单备用配置:

archive_cleanup_command = 'ux_archivecleanup /mnt/server/archivedir %r'

在相同的归档目录中,您需要确保在任何服务器不再需要WAL文件之前不要删除它们。archive_cleanup_command通常用于温备配置。写入%%以嵌入实际的%字符到命令中。如果命令返回非零退出状态,则会写入警告日志消息。但如果命令被信号或shell错误(例如找不到命令)终止,则会引发致命错误。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

如果命令返回非零退出状态,则会写入警告日志消息,并且数据库将继续启动。但如果命令被信号或shell错误(例如找不到命令)终止,则数据库将不会继续启动。

此参数只能在uxsinodb.conf文件或服务器命令行中设置。

recovery_end_command (string)

此参数指定仅在恢复结束时执行一次的shell命令。这个参数是可选的。recovery_end_command的目的是为复制或恢复后的清理提供一种机制。任何%r都被包含最后一个有效重启点的文件名称替换,就像archive_cleanup_command。

如果该命令返回非零退出状态,则将写入一条警告日志消息,数据库将继续启动。一个例外是,如果命令因信号或shell错误(例如未找到命令)而终止,数据库将无法继续启动。

此参数只能在uxsinodb.conf文件或在服务器命令行中设置。

3.5.6.恢复目标

默认情况下,恢复将恢复到WAL日志的末尾。以下参数可用于指定较早的停止点。最多只能使用一个recovery_target,recovery_target_lsn,recovery_target_name,recovery_target_time或recovery_target_xid;如果在配置文件中指定了多个参数,则会引发错误。这些参数只能在服务器启动时设置。

recovery_target`` = 'immediate'

此参数指定恢复应在达到一致状态时结束,即尽早结束。在从在线备份还原时,这意味着备份结束的点。从技术上讲,这是一个字符串参数,但'immediate'是当前唯一允许的值。

recovery_target_name (string)

此参数指定恢复将进行的命名还原点(使用ux_create_restore_point()创建)。

recovery_target_time (timestamp)

此参数指定恢复将进行的时间戳。确切的停止点也受到以下参数的影响:recovery_target_inclusive。

该参数的值是一个时间戳,格式与timestamp with time zone数据类型相同,但不能使用时区缩写(除非在配置文件中先设置timezone_abbreviations变量)。建议使用与UTC的数字偏移量,或者写全时区名称,例如Europe/Helsinki而不是EEST。

recovery_target_xid (string)

该参数指定了恢复将进行到的事务ID。请记住,虽然事务ID在事务开始时按顺序分配,但事务可以按不同的数字顺序完成。将恢复的事务是那些在指定事务之前(和可选地包括指定事务)提交的事务。精确的停止点也受recovery_target_inclusive的影响。

recovery_target_lsn (ux_lsn)

该参数指定了写入前日志位置的LSN,恢复将进行到该位置。精确的停止点也受recovery_target_inclusive的影响。该参数使用系统数据类型ux_lsn进行解析。

以下选项进一步指定了恢复目标,并影响到达目标时会发生什么:

recovery_target_inclusive (boolean)

指定是否在指定的恢复目标后停止(on),或在恢复目标前停止(off)。适用于指定recovery_target_lsn、recovery_target_time或recovery_target_xid时。此设置控制是否包括恰好具有目标WAL位置(LSN)、提交时间或事务ID的事务在恢复中。默认为on。

recovery_target_timeline (string)

指定恢复到特定时间轴。该值可以是数字时间轴ID或特殊值。值current恢复到在进行基本备份时处于当前状态的时间轴。值latest恢复到存档中找到的最新时间轴,这在备用服务器中很有用。默认为latest。

通常只需要在复杂的重新恢复情况下设置此参数,在这种情况下,您需要返回到在点时间恢复之后达到的状态。

recovery_target_action (enum)

指定服务器在达到恢复目标后应采取的操作。默认值为pause,表示恢复将暂停。promote表示恢复过程将完成,并且服务器将开始接受连接。最后,shutdown将在达到恢复目标后停止服务器。

pause设置的预期用途是允许对数据库执行查询,以检查该恢复目标是否是最理想的恢复点。暂停状态可以通过使用ux_wal_replay_resume()恢复。这将导致恢复结束。如果该恢复目标不是所需的停止点,则关闭服务器,将恢复目标设置更改为更晚的目标,然后重新启动以继续恢复。

shutdown设置对于使实例准备好所需的精确重放点非常有用。实例仍将能够重放更多的WAL记录(实际上,下次启动时将不得不重放自上次检查点以来的WAL记录)。

请注意,因为recovery.signal在将recovery_target_action设置为shutdown时不会被删除,所以除非更改配置或手动删除recovery.signal文件,否则任何后续启动都将以立即关闭结束。

如果未设置恢复目标,则此设置无效。如果未启用hot_standby,则pause设置将与shutdown相同。如果在进行晋升时达到恢复目标,则pause设置将与promote相同。

在任何情况下,如果配置了恢复目标但存档恢复在达到目标之前结束,则服务器将以致命错误关闭。

3.6.复制

这些设置控制内置的流复制功能的行为。服务器将是主服务器或备用服务器。主服务器可以发送数据,而备用服务器始终是复制数据的接收者。当使用级联复制时,备用服务器也可以是发送者和接收者。这些参数主要用于发送和备用服务器,但有些参数仅在主服务器上有意义。如果需要,集群中的设置可以有所不同而没有问题。

3.6.1.发送服务器

这些参数可以在任何要向一个或多个备用服务器发送复制数据的服务器上设置。主服务器始终是发送服务器,因此这些参数必须始终在主服务器上设置。在备用服务器成为主服务器后,这些参数的角色和含义不会改变。

max_wal_senders (integer)

指定从备用服务器或流基本备份客户端(即同时运行的WAL发送进程的最大数量)并发连接的最大数量。默认值为10。值0表示禁用复制。流客户端的突然断开可能会导致主服务器上的日志文件增长,因此应该小心使用此参数。如果要使用流复制,则必须将此参数设置为大于或等于1的值。

max_replication_slots (integer)

指定服务器可以支持的最大复制插槽数量。默认值为10。此参数只能在服务器启动时设置。将其设置为低于当前存在的复制插槽数量的值将阻止服务器启动。此外,wal_level 必须设置为replica 或更高,才允许使用复制插槽。 在订阅者端,指定可以同时跟踪多少个复制源,有效地限制了服务器上可以创建多少个逻辑复制订阅。将其设置为低于当前跟踪的复制源数量的值(反映在ux_replication_origin_status中,而不是ux_replication_origin将阻止服务器启动。

wal_keep_size (integer)

指定在需要为流复制获取它们时,保留在ux_wal目录中的过去日志文件段的最小大小。如果连接到发送服务器的备用服务器落后于超过wal_keep_size兆字节,发送服务器可能会删除备用服务器仍然需要的WAL 段,此时复制连接将被终止。下游连接也将最终失败。 (但是,如果使用 WAL 归档,则备用服务器可以通过从归档中获取该段来恢复。)这仅设置在ux_wal中保留的段的最小大小;系统可能需要保留更多的段以进行 WAL归档或从检查点恢复。如果wal_keep_size为零(默认值),则系统不会为备用目的保留任何额外的段,因此备用服务器可用的旧WAL 段的数量取决于先前检查点的位置和 WAL归档的状态。如果未指定单位,则将其视为兆字节。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

max_slot_wal_keep_size (integer)

指定允许复制插槽在检查点时保留在ux_wal目录中的WAL文件的最大大小。如果max_slot_wal_keep_size为-1(默认值),则复制槽可以保留无限量的WAL文件。否则,如果复制槽的重启LSN落后于当前LSN超过给定大小,则使用该槽的备用服务器可能无法继续复制,因为必需的WAL文件已被删除。您可以在ux_replication_slots中查看复制槽的WAL可用性。如果未指定单位,则将此值视为兆字节。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

wal_sender_timeout (integer)

终止空闲时间超过此时间的复制连接。这对于发送服务器检测备用服务器崩溃或网络故障非常有用。如果未指定单位,则将此值视为毫秒。默认值为60秒。值为零会禁用超时机制。

在分布在多个地理位置的集群中,使用不同的值可以带来更多的集群管理灵活性。较小的值对于具有低延迟网络连接的备用服务器进行更快的故障检测很有用,而较大的值则有助于更好地判断位于远程位置具有高延迟网络连接的备用服务器的健康状况。

track_commit_timestamp (boolean)

记录事务的提交时间。此参数只能在uxsinodb.conf文件或服务器命令行中设置。默认值为off。

3.6.2.主服务器

这些参数可以在将复制数据发送到一个或多个备用服务器的主服务器上设置。请注意,除了这些参数之外,wal_level必须在主服务器上适当设置,还可以启用WAL归档(参见归档)。备用服务器上这些参数的值是无关紧要的,尽管您可能希望在备用服务器上设置它们,以准备备用服务器成为主服务器的可能性。

synchronous_standby_names (string)

指定可以支持同步复制的备用服务器列表。将有一个或多个活动的同步备用服务器;等待提交的事务将在这些备用服务器确认接收其数据后允许继续进行。同步备用服务器将是出现在此列表中的那些服务器,并且当前已连接并实时流式传输数据(如ux_stat_replication视图中的状态streaming所示)。指定多个同步备用服务器可以允许非常高的可用性,但也可能会影响性能可用性和数据丢失保护。

为此目的的备用服务器的名称是备用服务器的连接信息中设置的application_name设置。对于物理复制备用服务器,应在primary_conninfo设置中设置;如果设置了cluster_name,则默认设置为该设置,否则为walreceiver。对于逻辑复制,可以在订阅的连接信息中设置,它的默认值为订阅名称。对于其他复制流消费者,请参阅其文档。

此参数指定使用以下任一语法的备用服务器列表:

[FIRST] num_sync ( standby_name [, ...] )
ANY num_sync ( standby_name [, ...] )
standby_name [, ...]

其中 num_sync 是事务需要等待回复的同步备用服务器的数量, standby_name 是备用服务器的名称。FIRST和ANY指定从列出的服务器中选择同步备用服务器的方法。

关键字FIRST与 num_sync 配合使用,指定基于优先级的同步复制,并使事务提交等待其WAL记录被复制到基于其优先级选择的 num_sync 个同步备用服务器。例如,设置为FIRST 3 (s1, s2, s3,s4)将导致每个提交等待来自备用服务器s1、s2、s3和s4中三个更高优先级的备用服务器的回复。在列表中出现较早的备用服务器具有较高的优先级,并将被视为同步。此列表中稍后出现的其他备用服务器表示潜在的同步备用服务器。如果当前的任何同步备用服务器因任何原因断开连接,它将立即被下一个优先级更高的备用服务器替换。关键字FIRST是可选的。

关键字ANY与 num_sync 配合使用,指定基于法定人数的同步复制,并使事务提交等待其WAL记录被复制到列出的至少 num_sync 个备用服务器。例如,设置为ANY 3(s1, s2, s3, s4)将导致每个提交在s1、s2、s3和s4中的至少三个备用服务器回复后继续进行。

FIRST和ANY不区分大小写。如果将这些关键字用作备用服务器的名称,则其 standby_name 必须用双引号括起来。

特殊的输入*匹配任何备用名称。

没有强制执行备用名称的唯一性机制。如果有重复,匹配的备用中的一个将被视为优先级更高,但是确定哪一个是不确定的。

注意

每个 standby_name 应该具有有效的SQL标识符形式,除非它是*。如果必要,可以使用双引号。但是请注意,无论是否使用双引号, standby_name 都是不区分大小写地与备用应用程序名称进行比较的。

如果没有在此处指定同步备用名称,则未启用同步复制,事务提交将不会等待复制。这是默认配置。即使启用了同步复制,也可以通过将synchronous_commit参数设置为local或off来配置单个事务不等待复制。

此参数只能在uxsinodb.conf文件或服务器命令行中设置。

vacuum_defer_cleanup_age (integer)

指定VACUUM和HOT更新将推迟清除死行版本的事务数量。默认值为零个事务,这意味着死行版本可以尽快被删除,即它们不再对任何打开的事务可见时。您可能希望在支持热备用服务器的主服务器上将其设置为非零值。这允许更多的时间用于在备用上完成查询,而不会因为行的早期清除而产生冲突。但是,由于该值是以主服务器上发生的写事务数量为单位的,因此很难预测可以为备用查询提供多少额外的宽限时间。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

您还应考虑在备用服务器上设置hot_standby_feedback作为使用此参数的替代方法。

这不会阻止已达到old_snapshot_threshold指定的年龄的死行的清理。

3.6.3.备用服务器

这些设置控制接收复制数据的备用服务器的行为。它们在主服务器上的值是无关紧要的。

primary_conninfo (string)

指定用于备用服务器连接发送服务器的连接字符串。如果此字符串中未指定任何选项,则相应的环境将使用默认值。变量将被检查。如果环境变量也没有设置,则使用默认值。

连接字符串应指定发送服务器的主机名(或地址),以及端口号(如果与备用服务器的默认值不同)。还应指定与发送服务器上适当特权角色相对应的用户名。如果发送方要求密码身份验证,则还需要提供密码。它可以在primary_conninfo字符串中提供,也可以在备用服务器上的单独的~/.uxpass文件中提供(使用replication作为数据库名称)。不要在primary_conninfo字符串中指定数据库名称。

此参数只能在uxsinodb.conf文件或服务器命令行中设置。如果在WAL接收器进程运行时更改此参数,则会向该进程发出信号以关闭,并期望使用新设置重新启动该进程(除非primary_conninfo是空字符串)。如果服务器不处于备用模式,则此设置无效。

primary_slot_name (string)

可选地指定要在通过流复制连接到发送服务器时使用的现有复制插槽,以控制上游节点上的资源删除。此参数只能在uxsinodb.conf文件或服务器命令行中设置。如果在WAL接收器进程运行时更改此参数,则会向该进程发出信号以关闭,并期望使用新设置重新启动该进程。如果未设置primary_conninfo或服务器不处于备用模式,则此设置无效。

promote_trigger_file (string)

指定触发器文件,其存在将结束在备用中的恢复。即使未设置此值,您仍然可以使用ux_ctl promote或调用ux_promote()来提升备用。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

hot_standby (boolean)

指定是否可以在恢复期间连接并运行查询。默认值为on。此参数只能在服务器启动时设置。它仅在归档恢复或备用模式下生效。

max_standby_archive_delay (integer)

当热备处于活动状态时,此参数确定备用服务器在取消与即将应用的WAL条目冲突的备用查询之前应等待的时间。max_standby_archive_delay适用于从 WAL 存档中读取 WAL 数据时(因此不是当前的情况)。如果没有指定单位,则将其视为毫秒。默认值为 30 秒。-1的值允许备用服务器永远等待冲突查询完成。此参数只能在 uxsinodb.conf文件或服务器命令行中设置。 请注意,max_standby_archive_delay不是查询在取消之前可以运行的最长时间;相反,它是允许应用任何一个 WAL 段数据的最长总时间。因此,如果一个查询在WAL 段中早期导致了显着的延迟,后续的冲突查询将有更少的宽限时间。

max_standby_streaming_delay (integer)

适用于通过流复制接收 WAL 数据时。如果没有指定单位,则将其视为毫秒。默认值为 30 秒。-1的值允许备用服务器永远等待冲突查询完成。此参数只能在 uxsinodb.conf文件或服务器命令行中设置。 请注意,max_standby_streaming_delay不是查询在取消之前可以运行的最长时间;相反,它是允许一旦从主服务器接收到 WAL 数据,就可以应用 WAL数据的最长总时间。因此,如果一个查询导致了显着的延迟,后续的冲突查询将有更少的宽限时间,直到备用服务器再次赶上。

wal_receiver_create_temp_slot (boolean)

指定当没有配置要使用的永久复制槽(使用primary_slot_name)时,WAL接收器进程是否应在远程实例上创建一个临时复制槽。默认值为 off。此参数只能在 uxsinodb.conf文件或服务器命令行中设置。如果在 WAL接收器进程运行时更改此参数,则会发出信号以关闭该进程,并期望使用新设置重新启动。

wal_receiver_status_interval (integer)

指定备用服务器上的 WAL接收器进程向主服务器或上游备用服务器发送有关复制进度的信息的最小频率,在那里可以使用ux_stat_replication视图查看。备用服务器将报告其已写入的最后一个 WAL日志位置、已刷新到磁盘的最后一个位置以及已应用的最后一个位置。此参数的值是报告之间的最长时间。如果设置为非零值,则每次写入或刷新位置更改时发送更新,或者根据此参数指定的频率发送更新。还有其他情况下会发送更新,同时忽略此参数。例如,在处理现有WAL完成时或当synchronous_commit设置为remote_apply时。因此,应用位置可能略落后于真实位置。如果未指定单位,则将其视为秒。默认值为10秒。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

hot_standby_feedback (boolean)

指定热备是否会向主服务器或上游备机发送有关当前在备机上执行的查询的反馈。此参数可用于消除由清理记录引起的查询取消,但对于某些工作负载可能会导致主服务器的数据库膨胀。反馈消息不会超过每个wal_receiver_status_interval一次。默认值为off。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

如果使用级联复制,则将反馈上传直到最终到达主服务器。备机不会对其接收到的反馈进行其他用途,只会将其上传。

此设置不会覆盖主服务器上old_snapshot_threshold的行为;在备机上超过主服务器的年龄阈值的快照可能会变得无效,从而导致在备机上取消事务。这是因为old_snapshot_threshold旨在为死行贡献到膨胀的时间提供绝对限制,否则由于备机的配置而被违反。

wal_receiver_timeout (integer)

终止空闲时间超过此时间的复制连接。这对于接收备机服务器检测到主节点崩溃或网络中断非常有用。如果未指定单位,则将其视为毫秒。默认值为60秒。值为零会禁用超时机制。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

wal_retrieve_retry_interval (integer)

指定当没有任何来源(流复制、本地ux_wal或WAL存档)提供WAL数据时,备机服务器应等待多长时间,然后再次尝试检索WAL数据。如果未指定单位,则将其视为毫秒。默认值为5秒。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

此参数在需要控制恢复节点等待新WAL数据可用的时间的配置中非常有用。例如,在存档恢复中,可以通过减少此参数的值使恢复更加响应检测到新的WAL日志文件。在WAL活动较低的系统上,增加它可以减少访问WAL存档所需的请求次数,这在云环境中非常有用,因为访问基础架构的次数是被考虑在内的。

recovery_min_apply_delay (integer)

默认情况下,备用服务器会尽快从发送服务器恢复WAL记录。延迟恢复可能有助于提供纠正数据丢失错误的机会。此参数允许您延迟恢复一定的时间。例如,如果将此参数设置为5min,则备用服务器将仅在备用服务器的系统时间至少比主服务器报告的提交时间晚五分钟时才重放每个事务提交。如果未指定单位,则将其视为毫秒。默认值为零,不添加延迟。

可能会出现服务器之间的复制延迟超过此参数的值的情况,在这种情况下不会添加延迟。请注意,延迟是在主服务器上写入的WAL时间戳和备用服务器上的当前时间之间计算的。由于网络延迟或级联复制配置的传输延迟可能会显著降低实际等待时间。如果主服务器和备用服务器上的系统时钟未同步,这可能会导致恢复应用记录比预期早;但这不是一个主要问题,因为此参数的有用设置比服务器之间的典型时间偏差大得多。

延迟仅在事务提交的WAL记录上发生。其他记录尽可能快地重放,这不是问题,因为MVCC可见性规则确保它们的效果在应用相应的提交记录之前不可见。

延迟发生在恢复数据库达到一致状态后,直到备用服务器被提升或触发。之后,备用服务器将在不再等待的情况下结束恢复。

必须在备用服务器上保留WAL记录,直到它们准备好被应用。因此,较长的延迟将导致WAL文件的积累增加,从而增加备用服务器的ux_wal目录的磁盘空间要求。

此参数旨在与流复制部署一起使用;但是,如果指定了该参数,则除崩溃恢复外,它将在所有情况下得到尊重。 使用此功能将延迟hot_standby_feedback,这可能会导致主服务器上的膨胀;请谨慎同时使用两者。

警告

当synchronous_commit设置为remote_apply时,同步复制受此设置的影响;每个COMMIT都需要等待应用。

此参数只能在uxsinodb.conf文件或服务器命令行中设置。

3.6.4.订阅者

这些设置控制逻辑复制订阅者的行为。它们在发布者上的值是无关紧要的。

请注意,wal_receiver_timeout、wal_receiver_status_interval和wal_retrieve_retry_interval配置参数也会影响逻辑复制工作进程。

max_logical_replication_workers (integer)

指定逻辑复制工作进程的最大数量。这包括应用工作进程和表同步工作进程。

逻辑复制工作进程来自由max_worker_processes定义的池。

默认值为4。此参数只能在服务器启动时设置。

max_sync_workers_per_subscription (integer)

每个订阅的最大同步工作进程数。该参数控制订阅初始化或添加新表时初始数据复制的并行度。

目前,每个表只能有一个同步工作进程。

同步工作进程来自由max_logical_replication_workers定义的池。

默认值为2。该参数只能在uxsinodb.conf文件或服务器命令行中设置。

3.7.查询规划

3.7.1.规划器方法配置

这些配置参数提供了一种粗略的方法来影响查询优化器选择的查询计划。如果优化器为特定查询选择的默认计划不是最优的,则可以使用这些配置参数中的一个来强制优化器选择不同的计划,这是一种临时的解决方案。改进优化器选择的计划质量的更好方法包括调整规划器成本常量(参见规划器成本常量)、手动运行ANALYZE、增加default_statistics_target配置参数的值,以及使用ALTER TABLE SET STATISTICS增加特定列的统计信息收集量。

enable_async_append (boolean)

启用或禁用查询规划器使用异步感知附加计划类型。默认值为on。

enable_bitmapscan (boolean)

启用或禁用查询规划器使用位图扫描计划类型。默认值为on。

enable_gathermerge (boolean)

启用或禁用查询规划器使用聚合合并计划类型。默认值为on。

enable_hashagg (boolean)

启用或禁用查询规划器使用哈希聚合计划类型。默认值为on。

enable_hashjoin (boolean)

启用或禁用查询规划器使用哈希连接计划类型。默认值为on。

enable_incremental_sort (boolean)

启用或禁用查询规划器使用增量排序步骤。默认值为on。

enable_indexscan (boolean)

启用或禁用查询规划器使用索引扫描计划类型。默认值为on。

enable_indexonlyscan (boolean)

启用或禁用查询规划器使用仅索引扫描计划类型。默认值为on。

enable_material (boolean)

启用或禁用查询规划器使用材料化。无法完全禁止材料化,但关闭此变量可防止规划器在不需要正确性的情况下插入材料化节点。默认值为on。

enable_memoize (boolean)

启用或禁用查询规划器使用备忘录计划来缓存嵌套循环连接中参数化扫描的结果。此计划类型允许在缓存中已经存在当前参数的结果时跳过对底层计划的扫描。当需要更多空间以容纳新条目时,较少查找的结果可能会从缓存中驱逐出去。默认值为on。

enable_mergejoin (boolean)

启用或禁用查询规划器使用合并连接计划类型。默认值为on。

enable_nestloop (boolean)

启用或禁用查询规划器使用嵌套循环连接计划。无法完全禁止嵌套循环连接,但关闭此变量会阻止规划器在有其他可用方法的情况下使用嵌套循环连接。默认值为on。

enable_parallel_append (boolean)

启用或禁用查询规划器使用并行感知附加计划类型。默认值为on。

enable_parallel_hash (boolean)

启用或禁用查询规划器使用具有并行哈希的哈希连接计划类型。如果未启用哈希连接计划,则无效。默认值为on。

enable_partition_pruning (boolean)

启用或禁用查询规划器消除分区表的分区的能力。这还控制规划器生成的查询计划,允许查询执行器在查询执行期间删除(忽略)分区。默认值为on。

enable_partitionwise_join (boolean)

启用或禁用查询规划器使用分区连接,允许通过连接匹配分区来执行分区表之间的连接。分区连接目前仅适用于连接条件包括所有分区键的情况,这些键必须是相同的数据类型,并具有一对一的匹配子分区集。因为分区连接规划在规划期间可以使用更多的CPU时间和内存,所以默认值为off。

enable_partitionwise_aggregate (boolean)

启用或禁用查询规划器使用分区分组或聚合,允许对分区表进行分别分组或聚合。如果GROUP BY子句不包括分区键,则只能在每个分区上执行部分聚合,并且必须稍后执行最终聚合。因为分区分组或聚合规划在规划期间可以使用更多的CPU时间和内存,所以默认值为off。

enable_seqscan (boolean)

启用或禁用查询规划器使用顺序扫描计划类型。无法完全禁止顺序扫描,但关闭此变量会阻止规划器在有其他可用方法的情况下使用顺序扫描。默认值为on。

enable_sort (boolean)

启用或禁用查询规划器使用显式排序步骤。无法完全禁止显式排序,但关闭此变量会阻止规划器在有其他可用方法的情况下使用显式排序。但是关闭此变量会阻止规划器使用它,如果有其他可用的方法。默认值为on。

enable_tidscan (boolean)

启用或禁用查询规划器使用TID扫描计划类型。默认值为on。

3.7.2.规划器成本常量

本节中描述的成本变量是以任意比例衡量的。只有它们的相对值才有意义,因此将它们全部按相同因子缩放将不会影响规划器的选择。默认情况下,这些成本变量基于顺序页面获取的成本;也就是说,seq_page_cost通常设置为1.0,其他成本变量是以此为参考设置的。但是,如果您愿意,可以使用不同的比例,例如在特定机器上的实际执行时间(以毫秒为单位)。

注意

不幸的是,没有确定成本变量理想值的明确方法。它们最好被视为特定安装将接收到的所有查询的平均值。这意味着仅基于少数实验来更改它们非常危险。

seq_page_cost (floating point)

设置规划器对于顺序获取的磁盘页面获取成本的估计。默认值为1.0。可以通过设置具有相同名称的表空间参数来覆盖特定表和索引的表空间中的此值。

random_page_cost (floating point)

设置规划器对于非顺序获取的磁盘页面的成本估计。默认值为4.0。可以通过设置具有相同名称的表空间参数来覆盖特定表和索引的表空间中的此值。

将此值相对于seq_page_cost降低将导致系统更喜欢索引扫描;将其提高将使索引扫描看起来相对更昂贵。您可以同时提高或降低这两个值,以更改磁盘I/O成本相对于CPU成本的重要性,CPU成本由以下参数描述。

与顺序访问相比,机械磁盘存储的随机访问通常要昂贵得多。但是,使用较低的默认值(4.0)是因为假定大多数随机访问磁盘的操作(例如索引读取)都在缓存中。默认值可以被认为是将随机访问建模为顺序访问的40倍,同时期望90%的随机读取被缓存。

如果您认为90%的缓存率对于您的工作负载是不正确的假设,则可以增加random_page_cost以更好地反映随机存储读取的真实成本。相应地,如果您的数据很可能完全在缓存中,例如当数据库小于总服务器内存时,降低random_page_cost可能是合适的。具有低随机访问成本的存储阅读成本相对于顺序,例如固态硬盘,可能也可以用较低的随机页面成本建模,例如 1.1。

提示

虽然系统允许您将random_page_cost 设置为小于 seq_page_cost,但这是不合理的。但是,如果数据库完全缓存在 RAM中,则将它们设置为相等是有意义的,因为在这种情况下,无需按顺序触摸页面不会受到惩罚。此外,在高度缓存的数据库中,您应该相对于CPU 参数降低两个值,因为获取已在 RAM 中的页面的成本比通常情况下要小得多。

cpu_tuple_cost (floating point)

设置查询期间处理每行的成本的规划器估计值。默认值为 0.01。

cpu_index_tuple_cost (floating point)

设置规划器对索引扫描期间处理每个索引条目的成本的估计值。默认值为 0.005。

cpu_operator_cost (floating point)

设置规划器对查询期间执行的每个运算符或函数的成本的估计值。默认值为 0.0025。

parallel_setup_cost (floating point)

设置规划器启动并行工作进程的成本的估计值。默认值为 1000。

parallel_tuple_cost (floating point)

设置规划器将一个元组从一个并行工作进程传输到另一个进程的成本的估计值。默认值为 0.1。

min_parallel_table_scan_size (integer)

设置必须扫描的最小表数据量,以便考虑并行扫描。对于并行顺序扫描,扫描的表数据量始终等于表的大小,但是当使用索引时,扫描的表数据量通常会更少。如果未指定此值的单位,则将其视为块,即BLCKSZ 字节,通常为 8kB。默认值为 8 兆字节(8MB)。

min_parallel_index_scan_size (integer)

设置必须扫描的最小索引数据量,以便考虑并行扫描。请注意,并行索引扫描通常不会触及整个索引;规划器认为实际上将被扫描的页面数是相关的。此参数还用于决定特定索引是否可以参与并行清理。如果未指定此值的单位,则将其视为块,即 BLCKSZ字节,通常为 8kB。默认值为512千字节(512kB)。

effective_cache_size(integer)

设置规划器对单个查询可用的磁盘缓存的有效大小的假设。这被纳入使用索引的成本估计中;较高的值使索引扫描更可能被使用,较低的值使顺序扫描更可能被使用。在设置此参数时,您应该考虑到UXsinoDB的共享缓冲区和内核磁盘缓存中用于UXsinoDB数据文件的部分,尽管某些数据可能存在于两个位置。此外,考虑到不同表上预期的并发查询数量,因为它们将不得不共享可用空间。此参数对UXsinoDB分配的共享内存大小没有影响,也不保留内核磁盘缓存;它仅用于估计目的。系统还不假定数据在查询之间保留在磁盘缓存中。如果未指定单位,则将其视为块,即BLCKSZ字节,通常为8kB。默认值为4千兆字节(4GB)。(如果BLCKSZ不是8kB,则默认值按比例缩放。)

jit_above_cost(floating point)

设置查询成本高于该值时激活JIT编译(如果启用)。执行JIT成本规划时间,但可以加速查询执行。将其设置为-1将禁用JIT编译。默认值为100000。

jit_inline_above_cost(floating point)

设置查询成本高于该值时JIT编译尝试内联函数和运算符。内联增加了规划时间,但可以提高执行速度。将其设置为小于jit_above_cost没有意义。将其设置为-1将禁用内联。默认值为500000。

jit_optimize_above_cost(floating point)

设置查询成本高于该值时JIT编译应用昂贵的优化。这种优化增加了规划时间,但可以提高执行速度。将其设置为小于jit_above_cost没有意义,将其设置为大于jit_inline_above_cost不太可能有益。将其设置为-1将禁用昂贵的优化。默认值为500000。

3.7.3.遗传查询优化器

遗传查询优化器(GEQO)是一种使用启发式搜索进行查询规划的算法。这降低了复杂查询(连接许多关系的查询)的规划时间,但代价是产生的计划有时比正常的穷举搜索算法找到的计划差。

geqo (boolean)

启用或禁用遗传查询优化器。默认情况下启用。通常最好不要在生产环境中关闭它;geqo_threshold变量提供了更精细的GEQO控制。

geqo_threshold (integer)

使用遗传查询优化器来规划涉及至少这么多FROM项的查询。(注意,一个FULL OUTER JOIN结构只计算为一个FROM项。)默认值为12。对于较简单的查询,通常最好使用常规的穷举搜索规划器,但对于包含许多表的查询,穷举搜索需要太长时间,往往比执行次优计划的惩罚时间更长。因此,查询大小的阈值是管理GEQO使用的一种方便方式。

geqo_effort (integer)

控制GEQO中规划时间和查询计划质量之间的权衡。该变量必须是1到10范围内的整数。默认值为5。较大的值增加了用于查询规划的时间,但也增加了选择高效查询计划的可能性。

geqo_effort实际上并不直接做任何事情;它仅用于计算影响GEQO行为的其他变量的默认值(下面描述)。如果您愿意,可以手动设置其他参数。

geqo_pool_size (integer)

控制GEQO使用的池大小,即遗传种群中的个体数。它必须至少为2,有用的值通常为100到1000。如果将其设置为零(默认设置),则会根据geqo_effort和查询中的表数选择合适的值。

geqo_generations (integer)

控制GEQO使用的代数数量,即算法的迭代次数。它必须至少为1,有用的值与池大小相同。如果将其设置为零(默认设置),则会根据geqo_pool_size选择合适的值。

geqo_selection_bias (floating point)

控制GEQO使用的选择偏差。选择偏差是种群内的选择压力。值可以从1.50到2.00;后者是默认值。

geqo_seed (floating point)

控制GEQO使用的随机数生成器的初始值,以选择通过连接顺序搜索空间的随机路径。该值可以从零(默认值)到一。改变该值会改变探索连接路径的集合,并可能导致找到更好或更差的最佳路径。

3.7.4.其他规划器选项

default_statistics_target(integer)

设置没有通过ALTER TABLE SET STATISTICS设置列特定目标的表列的默认统计目标。较大的值增加执行ANALYZE所需的时间,但可能会提高规划器的估计质量。默认值为100。

constraint_exclusion(enum)

控制查询规划器使用表约束来优化查询。允许的constraint_exclusion值为on(检查所有表的约束),off(从不检查约束)和partition(仅检查继承子表和UNION ALL子查询的约束)。partition是默认设置。它通常与传统继承树一起使用以提高性能。

当此参数允许特定表时,规划器将查询条件与表的CHECK约束进行比较,并省略扫描条件与约束相矛盾的表。例如:

CREATE TABLE parent(key integer, ...);
CREATE TABLE child1000(check (key between 1000 and 1999)) INHERITS(parent);
CREATE TABLE child2000(check (key between 2000 and 2999)) INHERITS(parent);
...
SELECT * FROM parent WHERE key = 2400;

启用约束排除后,此SELECT将根本不扫描child1000,从而提高性能。

目前,仅对经常使用继承树实现表分区的情况默认启用约束排除。对所有表启用它会带来额外的规划开销,在简单查询上非常明显,并且在大多数情况下不会为简单查询带来任何好处。如果您没有使用传统继承进行分区的表,则可能更喜欢完全关闭它。(请注意,分区表的等效功能由单独的参数enable_partition_pruning控制。)

cursor_tuple_fraction(floating point)

设置规划器检索游标行的分数的估计值。默认值为0.1。该设置的较小值会使规划器偏向使用“快速启动”计划。对于游标,它们可以快速检索前几行,但可能需要很长时间才能获取所有行。较大的值更注重总估计时间。在最大设置为1.0时,游标的计划与常规查询完全相同,只考虑总估计时间,而不考虑首行何时可以传递。

from_collapse_limit(integer)

如果结果FROM列表不超过此项,则规划程序将合并子查询到上层查询中。较小的值可以减少计划时间,但可能会产生较差的查询计划。默认值为8。

将此值设置为geqo_threshold或更高值可能会触发使用GEQO规划程序,从而导致非最优计划。

jit(boolean)

确定是否可以使用JIT编译(如果可用)UXsinoDB。默认值为on。

join_collapse_limit(integer)

如果列表不超过此项,则规划程序将显式的JOIN构造(除FULL JOIN之外)重写为FROM项列表。较小的值可以减少计划时间,但可能会产生较差的查询计划。默认情况下,此变量设置为与from_collapse_limit相同,这对大多数用途都是适当的。将其设置为1可以防止重新排序显式的JOIN。因此,查询中指定的显式连接顺序将是连接关系的实际顺序。由于查询规划程序并不总是选择最佳连接顺序,高级用户可以选择将此变量暂时设置为1,然后明确指定所需的连接顺序。将此值设置为geqo_threshold或更高值可能会触发使用GEQO规划程序,从而导致非最优计划。

plan_cache_mode(enum)

可以使用自定义或通用计划执行准备好的语句(显式准备或隐式生成,例如PL/uxSQL)。自定义计划为每个执行使用其特定的参数值集制作,而通用计划不依赖于参数值并且可以在执行之间重复使用。因此,使用通用计划可以节省计划时间,但如果理想计划强烈依赖于参数值,则通用计划可能效率低下。在这些选项之间进行选择通常情况下,会自动创建缓存计划,但可以使用plan_cache_mode进行覆盖。允许的值为auto(默认值)、force_custom_plan和force_generic_plan。此设置在执行缓存计划时考虑,而不是在准备时考虑。

recursive_worktable_factor (floating point)

设置规划器对递归查询的工作表的平均大小的估计,作为查询的初始非递归项的估计大小的倍数。这有助于规划器选择将工作表与查询的其他表连接的最合适方法。默认值为10.0。当递归从一步到另一步的扇出较低时,例如在最短路径查询中,较小的值(如1.0)可能会有所帮助。图形分析查询可能会受益于大于默认值的值。

3.8.错误报告和日志记录

3.8.1.日志记录位置

log_destination (string)

UXsinoDB 支持多种记录服务器消息的方法,包括 stderr、csvlog、 jsonlog 和 syslog。 在Windows 上,还支持 eventlog。 将此参数设置为以逗号分隔的所需日志记录位置列表。 默认值为仅记录到 stderr。此参数只能在 uxsinodb.conf 文件或服务器命令行中设置。

如果在 log_destination 中包含 csvlog,则日志条目将以“逗号分隔值”(CSV)格式输出,这对于将日志加载到程序中非常方便。有关详细信息,请参见使用CSV格式日志输出。必须启用logging_collector才能生成CSV格式的日志输出。

如果log_destination中包含jsonlog,则日志条目将以JSON格式输出,这对于将日志加载到程序中非常方便。有关详细信息,请参见使用JSON格式日志输出。必须启用logging_collector才能生成JSON格式的日志输出。

当包括stderr、csvlog或jsonlog时,将创建文件current_logfiles以记录日志收集器当前使用的日志文件的位置和相关的日志目的地。这提供了一种方便的方法来查找实例当前使用的日志。以下是此文件内容的示例:

stderr log/uxsinodb.log
csvlog log/uxsinodb.csv
jsonlog log/uxsinodb.json

当由于旋转而创建新的日志文件或重新加载log_destination时,将重新创建current_logfiles。如果未在log_destination中包括stderr、csvlog或jsonlog,或者日志收集器已禁用,则将删除它。

注意

在大多数 Unix 系统上,您需要更改系统的syslog守护程序的配置,以便使用log_destination的syslog选项。UXsinoDB可以记录到syslog设施LOCAL0到LOCAL7(请参见syslog_facility),但大多数平台上的默认syslog配置将丢弃所有这些消息。您需要添加类似于以下内容的内容:

local0.*    /var/log/uxsinodb

到syslog守护程序的配置文件中,以使其正常工作。

在 Windows 上,当您使用log_destination的eventlog选项时,应向操作系统注册事件源及其库,以便Windows 事件查看器可以清晰地显示事件日志消息。 有关详细信息,请参见在Windows上注册事件日志。

logging_collector(boolean)

此参数启用日志收集器,它是一个后台进程,捕获发送到stderr的日志消息并将其重定向到日志文件中。这种方法通常比记录到syslog更有用,因为某些类型的消息可能不会出现在syslog输出中。(一个常见的例子是动态链接器失败消息;另一个是由脚本产生的错误消息,例如archive_command。)此参数只能在服务器启动时设置。

注意

可以在不使用日志收集器的情况下记录到 stderr;日志消息将会被发送到服务器的stderr所指向的位置。但是,这种方法只适用于低日志量,因为它没有方便的方法来轮换日志文件。此外,在某些平台上,不使用日志收集器可能会导致丢失或损坏日志输出,因为多个进程同时写入同一个日志文件可能会互相覆盖输出。

注意

日志收集器的设计是永远不会丢失消息。这意味着,在极高的负载情况下,当收集器落后时,服务器进程可能会被阻塞,而尝试发送额外的日志消息。相比之下,syslog更喜欢在无法写入消息时丢弃它们,这意味着在这种情况下它可能无法记录一些消息,但不会阻塞系统的其他部分。

log_directory (string)

当启用 logging_collector时,此参数确定将创建日志文件的目录。它可以指定为绝对路径,也可以相对于集群数据目录。此参数只能在uxsinodb.conf 文件或服务器命令行中设置。默认值为 log。

log_filename (string)

当启用 logging_collector 时,此参数设置所创建的日志文件的文件名。该值被视为 strftime模式,因此可以使用 % 转义符来指定随时间变化的文件名。(请注意,如果有任何依赖于时区的 %转义符,则计算将在由log_timezone指定的时区中进行。)支持的 % 转义符类似于开放组织的 strftime规范中列出的转义符。请注意,不直接使用系统的 strftime,因此平台特定的(非标准)扩展不起作用。默认值为uxsinodb-%Y-%m-%d_%H%M%S.log。

如果指定一个没有转义符的文件名,您应该计划使用日志轮换实用程序来避免最终填满整个磁盘。

如果在 log_destination 中启用了 CSV 格式输出,则会将 .csv 附加到时间戳日志文件名以创建 CSV格式输出的文件名。(如果 log_filename 以 .log 结尾,则会替换后缀。)

如果在 log_destination 中启用了 JSON 格式输出,则会将 .json 附加到时间戳日志文件名以创建 JSON格式输出的文件名。(如果 log_filename 以 .log 结尾,则会替换后缀。)

此参数只能在 uxsinodb.conf 文件或服务器命令行中设置。

log_file_mode (integer)

在 Unix 系统上,当启用 logging_collector 时,此参数设置日志文件的权限。(在 Microsoft Windows 上,此参数被忽略。) 参数值应为数字模式,格式应符合 chmod 和 umask系统调用所接受的格式。(要使用惯用的八进制格式,数字必须以0(零)开头。)

默认权限为 0600,表示只有服务器所有者可以读取或写入日志文件。另一个常用的设置是0640,允许所有者组的成员读取文件。但请注意,要使用这样的设置,您需要更改log_directory,将文件存储在集群数据目录之外的某个位置。无论如何,将日志文件设置为全局可读是不明智的,因为它们可能包含敏感数据。

此参数只能在 uxsinodb.conf 文件或服务器命令行中设置。

log_rotation_age (integer)

当启用 logging_collector时,此参数确定单个日志文件的最长使用时间,之后将创建一个新的日志文件。如果未指定单位,则将其视为分钟。默认值为24 小时。 将其设置为零以禁用基于时间的创建新日志文件。此参数只能在 uxsinodb.conf 文件或服务器命令行中设置。

log_rotation_size (integer)

当启用 logging_collector时,此参数确定单个日志文件的最大大小。在向日志文件中发出此数量的数据后,将创建一个新的日志文件。如果未指定单位,则将其视为千字节。默认值为10 兆字节。 将其设置为零以禁用基于大小的创建新日志文件。此参数只能在 uxsinodb.conf 文件或服务器命令行中设置。

log_truncate_on_rotation (boolean)

当启用 logging_collector 时,此参数将导致 UXDB截断(覆盖)同名的任何现有日志文件,而不是追加到该文件中。但是,截断仅在由于基于时间的轮换而打开新文件时发生,而不是在服务器启动或基于大小的轮换期间发生。当关闭时,所有情况下都将追加到现有文件中。例如,将此设置与类似于uxsinodb-%H.log 的 log_filename 结合使用,将生成二十四个每小时的日志文件,然后循环覆盖它们。此参数只能在 uxsinodb.conf 文件或服务器命令行中设置。

示例:要保留 7 天的日志,每天一个日志文件,命名为 server_log.Mon、server_log.Tue等,并自动用本周的日志覆盖上周的日志,可以使用以下设置:将log_filename设置为server_log.%a,将log_truncate_on_rotation设置为on, 将log_rotation_age设置为1440。

例如:要保留24小时的日志,每小时一个日志文件,但如果日志文件大小超过1GB,也要更早地进行轮换,则将log_filename设置为server_log.%H%M,将log_truncate_on_rotation设置为on,将log_rotation_age设置为60,将log_rotation_size设置为1000000。在log_filename中包含%M允许任何可能发生的大小驱动轮换选择与小时初始文件名不同的文件名。

syslog_facility (enum)

syslog设为启用时,此参数确定要使用的syslog“设备”。您可以从LOCAL0、LOCAL1、LOCAL2、LOCAL3、LOCAL4、LOCAL5、LOCAL6、LOCAL7中选择;默认值为LOCAL0。另请参阅您系统的syslog守护程序的文档。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

syslog_ident (string)

当启用将日志记录到syslog时,此参数确定用于标识UXsinoDB消息的程序名称在syslog日志中使用。默认值为uxdb。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

syslog_sequence_numbers (boolean)

当日志被记录到syslog并且这个设置为 on (默认)时,每一个消息会被加上一个增长的序号作为前缀(例如[2])。这种行为避开了很多 syslog 实现默认采用的“--- 上一个消息重复 N 次 ---”形式。在现代 syslog 实现中,抑制重复消息是可以配置的(例如rsyslog中的$RepeatedMsgReduction),因此这个参数可能不是必需的。此外,如果你真的想抑制重复消息,你可以把这个参数设置为 off。

这个参数只能在uxsinodb.conf文件或者服务器命令行上设置。

syslog_split_messages (boolean)

当启用将日志记录到syslog时,此参数确定如何将消息传递到syslog。当打开时(默认值),消息按行拆分,长行被拆分,因此每个行都是一个单独的syslog消息。如果关闭,则整个消息将作为单个syslog消息发送。此参数只能在uxsinodb.conf文件或服务器命令行中设置。它们将适合1024字节,这是传统syslog实现的典型大小限制。当关闭时,UXsinoDB服务器日志消息将按原样传递到syslog服务,由syslog服务处理潜在的笨重消息。

如果syslog最终记录到文本文件中,则效果将是相同的,最好将设置保留在原样,因为大多数syslog实现无法处理大型消息或需要特殊配置才能处理它们。但是,如果syslog最终写入其他介质,则可能需要或更有用地保持消息逻辑上在一起。

此参数仅可在uxsinodb.conf文件或服务器命令行中设置。

event_source(string)

启用记录到事件日志时,此参数确定用于标识日志中的UXsinoDB消息的程序名称。默认值为UXsinoDB。此参数仅可在uxsinodb.conf文件或服务器命令行中设置。

3.8.2.何时记录

log_min_messages(enum)

控制写入服务器日志的消息级别。有效值为DEBUG5、DEBUG4、DEBUG3、DEBUG2、DEBUG1、INFO、NOTICE、WARNING、ERROR、LOG、FATAL和PANIC。每个级别都包括其后面的所有级别。级别越靠后,发送到日志的消息越少。默认值为WARNING。请注意,在此处,LOG的等级与client_min_messages中的等级不同。只有超级用户和具有适当SET特权的用户才能更改此设置。

log_min_error_statement(enum)

控制记录在服务器日志中的导致错误条件的SQL语句。当前的SQL语句包含在任何指定严重性或更高消息的日志条目中。有效值为DEBUG5、DEBUG4、DEBUG3、DEBUG2、DEBUG1、INFO、NOTICE、WARNING、ERROR、LOG、FATAL和PANIC。默认值为ERROR,这意味着将记录导致错误、日志消息、致命错误或紧急情况的语句。为有效关闭失败语句的日志记录,将此参数设置为PANIC。只有超级用户和具有适当SET权限的用户才能更改此设置。

log_min_duration_statement (integer)

如果语句运行时间至少为指定时间,则记录每个已完成语句的持续时间。例如,如果将其设置为250ms,则所有运行时间为250ms或更长的SQL语句都将被记录。启用此参数可帮助跟踪应用程序中未经优化的查询。如果未指定单位,则将其视为毫秒。将其设置为零会打印所有语句持续时间。-1(默认值)禁用日志记录语句持续时间。只有超级用户和具有适当SET权限的用户才能更改此设置。

这将覆盖log_min_duration_sample,这意味着持续时间超过此设置的查询不会被采样,而始终会被记录。

对于使用扩展查询协议的客户端,解析、绑定和执行步骤的持续时间将独立记录。

注意

当与log_statement一起使用此选项时,由于log_statement而记录的语句文本不会在持续时间日志消息中重复。如果您没有使用syslog,建议您使用log_line_prefix记录PID或会话ID,以便您可以使用进程ID或会话ID将语句消息链接到后来的持续时间消息。

log_min_duration_sample (integer)

允许对运行时间至少为指定时间的已完成语句进行采样持续时间。这会产生与log_min_duration_statement相同类型的日志条目,但仅针对执行的语句子集进行采样,采样率由log_statement_sample_rate控制。例如,如果将其设置为100ms,则所有运行时间为100ms或更长的SQL语句都将被视为采样对象。启用此参数可帮助处理流量过高而无法记录所有查询的情况。如果未指定单位,则将其视为毫秒。将其设置为零会对所有语句持续时间进行采样。-1(默认值)禁用采样语句持续时间。只有超级用户和具有适当SET权限的用户才能更改此设置。

此设置的优先级低于log_min_duration_statement,这意味着持续时间超过log_min_duration_statement的语句不会被采样,而始终会被记录。

其他适用于log_min_duration_statement的注意事项也适用于此设置。

log_statement_sample_rate (floating point)

确定持续时间超过指定时间的语句的分数。log_min_duration_sample,将被记录。抽样是随机的,例如0.5表示 每个语句被记录的统计概率为一半。 默认值为1.0,表示记录所有被抽样的语句。将其设置为零将禁用被抽样语句的持续时间记录,与将log_min_duration_sample设置为 -1相同。 只有超级用户和具有适当SET权限的用户才能更改此设置。

log_transaction_sample_rate (floating point)

设置所有语句都被记录的事务的分数, 除了为其他原因记录的语句。它适用于 每个新事务,无论其语句的持续时间如何。 抽样是随机的,例如0.1表示每个事务被记录的统计概率为十分之一。

log_transaction_sample_rate可以帮助 构建事务样本。默认值为0,表示不记录 来自任何其他事务的语句。将其设置为 1记录所有事务的所有语句。只有超级用户和具有适当SET权限的用户才能更改此设置。

注意

与所有语句记录选项一样,此选项可能会增加显着的开销。

log_startup_progress_interval (integer)

设置启动过程将记录的时间量 仍在进行的长时间操作的消息, 以及该操作的进一步进度消息之间的间隔。 默认值为10秒。设置为0禁用该功能。如果没有单位指定此值, 则将其视为毫秒。该设置分别应用于 每个操作。此参数仅可在uxsinodb.conf 文件或服务器命令行中设置。

例如,如果同步数据目录需要25秒, 然后重置未记录的关系需要8秒, 并且如果此设置具有默认值10秒,则将为同步数据目录记录消息在进行了10秒后,再次在进行了20秒后记录,但不会记录重置未记录的关系。

下表解释了UXsinoDB使用的消息严重级别。如果将日志输出发送到syslog或Windows的 eventlog,则将严重级别翻译为表中所示。

表 消息严重级别

严重性用法syslogeventlog
DEBUG1 .. DEBUG5为开发者提供连续的更详细的信息。DEBUGINFORMATION
INFO提供用户隐式要求的信息,例如来自VACUUM VERBOSE的输出。INFOINFORMATION
NOTICE提供可能对用户有用的信息,例如长标识符截断提示。NOTICEINFORMATION
WARNING提供可能出现的问题的警告,例如在一个事务块外COMMIT。NOTICEWARNING
ERROR报告一个导致当前命令中断的错误。WARNINGERROR
LOG报告管理员可能感兴趣的信息,例如检查点活动。INFOINFORMATION
FATAL报告一个导致当前会话中断的错误。ERRERROR
PANIC报告一个导致所有数据库会话中断的错误。CRITERROR

3.8.3.记录什么到日志

您选择记录的内容可能具有安全隐患; 请参阅日志文件维护。

application_name (string)

application_name可以是任意小于NAMEDATALEN个字符(标准编译中是64个字符)的字符串。这通常由一个应用通过到服务器的连接设置。该名称将被显示在ux_stat_activity视图中并被包括在 CSV 日志项中。它也会被通过log_line_prefix包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。

debug_print_parse (boolean)
debug_print_rewritten (boolean)
debug_print_plan (boolean)

这些参数启用发出各种调试输出。当设置时,它们会打印每个执行的查询的解析树、查询重写器输出或执行计划。这些消息以LOG 消息级别发出,因此默认情况下它们将出现在服务器日志中,但不会发送到客户端。可以通过调整client_min_messages参数来更改此行为。client_min_messages或log_min_messages。这些参数默认关闭。

debug_pretty_print (boolean)

当设置时,debug_pretty_print 缩进由 debug_print_parse、debug_print_rewritten 或 debug_print_plan 产生的消息。这会导致输出更易读,但比关闭时更长。默认情况下,它是开启的。

log_autovacuum_min_duration (integer)

如果自动清理运行的时间达到指定的时间,则记录每个自动清理执行的操作。将其设置为零会记录所有自动清理操作。 -1禁用记录自动清理操作。如果未指定单位,则将此值视为毫秒。 例如,如果将其设置为250ms,则将记录运行时间为 250ms 或更长的所有自动清理和分析。 此外,当将此参数设置为除 -1以外的任何值时,如果由于冲突锁定或并发删除关系而跳过自动清理操作,则会记录消息。默认值为 10min。启用此参数可帮助跟踪自动清理活动。 此参数只能在 uxsinodb.conf文件或服务器命令行中设置;但是可以通过更改表存储参数来覆盖表的设置。

log_checkpoints (boolean)

导致在服务器日志中记录检查点和重启点。日志消息中包括一些统计信息,包括写入的缓冲区数量和写入它们所花费的时间。 此参数只能在uxsinodb.conf 文件或服务器命令行中设置。默认值为开启。

log_connections (boolean)

导致记录每个尝试连接到服务器的连接,以及客户端身份验证(如果需要)和授权的成功完成。 只有超级用户和具有适当 SET特权的用户可以在会话开始时更改此参数,而且不能在会话中更改。 默认值为 off。

注意

某些客户端程序(如uxsql)在确定是否需要密码时会尝试连接两次,因此重复的 “连接已接收” 消息不一定表示问题。

log_disconnections (boolean)

导致记录会话终止。日志输出提供类似于 log_connections 的信息,以及会话的持续时间。 只有超级用户和具有适当 SET特权的用户可以在会话开始时更改此参数,而且不能在会话中更改。默认值为off。而且它在会话中完全无法更改。默认值为off。

log_duration (boolean)

导致记录每个已完成语句的持续时间。 默认值为off。只有超级用户和具有适当SET权限的用户才能更改此设置。

对于使用扩展查询协议的客户端,解析、绑定和执行步骤的持续时间将独立记录。

注意

启用log_duration和将log_min_duration_statement设置为零之间的区别在于,超过log_min_duration_statement会强制记录查询文本,但此选项不会。因此,如果log_duration为on并且log_min_duration_statement具有正值,则所有持续时间都将记录,但仅对超过阈值的语句包括查询文本。这种行为对于在高负载安装中收集统计信息非常有用。

log_error_verbosity (enum)

控制记录每个日志消息时在服务器日志中写入的详细程度。有效值为TERSE、DEFAULT和VERBOSE,每个值都会添加更多字段以显示消息。TERSE排除DETAIL、HINT、QUERY和CONTEXT错误信息的记录。VERBOSE输出包括SQLSTATE错误代码以及生成错误的源代码文件名、函数名和行号。只有超级用户和具有适当SET权限的用户才能更改此设置。

log_hostname (boolean)

默认情况下,连接日志消息仅显示连接主机的IP地址。打开此参数会导致记录主机名。请注意,根据您的主机名解析设置,这可能会带来非常大的性能损失。此参数只能在uxsinodb.conf文件或服务器命令行上设置。

log_line_prefix (string)

这是一个printf样式的字符串,输出在每个日志行的开头。%字符开始“转义序列”,如下所述,将替换为状态信息。未识别的转义将被忽略。其他字符将直接复制到日志行。某些转义仅由会话进程识别,并且将被主服务器进程等后台进程视为空。状态信息可以通过在%之后和选项之前指定数字文字来左对齐或右对齐。负值将导致状态信息填充在左边。使用空格右对齐以给它一个最小宽度,而正值将在左侧填充。填充可以在日志文件中提高人类可读性。

此参数只能在uxsinodb.conf文件或服务器命令行中设置。默认值为'%m [%p] ',它记录时间戳和进程ID。

转义字符效果仅会话
%a应用程序名称是
%u用户名是
%d数据库名称是
%r远程主机名或IP地址和远程端口是
%h远程主机名或IP地址是
%b后端类型否
%p进程ID否
%P并行查询工作进程组的进程ID,如果此进程是并行查询工作者否
%t没有毫秒的时间戳否
%m带有毫秒的时间戳否
%n带有毫秒的时间戳(作为Unix纪元)否
%i命令标记:会话当前命令的类型是
%eSQLSTATE错误代码否
%c会话ID:见下文否
%l每个会话或进程的日志行数,从1开始否
%s进程启动时间戳否
%v虚拟事务ID(backendID/localXID)否
%x事务ID(如果没有分配,则为0)否
%q不产生输出,但告诉非会话进程在此字符串中停止;会话进程忽略否
%Q当前查询的查询标识符。默认情况下不计算查询标识符,因此该字段将为零,除非启用compute_query_id参数或配置计算查询标识符的第三方模块。是
%%字面量%否

后端类型对应于视图ux_stat_activity中的列backend_type,但日志中可能会出现不在该视图中显示的其他类型。

%c转义打印准唯一的会话标识符,由两个4字节十六进制数字(没有前导零)用点分隔组成。这些数字是进程启动时间和进程ID,因此%c也可以用作打印这些项的节省空间的方式。例如,要从ux_stat_activity生成会话标识符,请使用此查询:

SELECT to_hex(trunc(EXTRACT(EPOCH FROM backend_start))::integer) || '.' ||
to_hex(pid)
FROM ux_stat_activity;

提示

如果为log_line_prefix设置非空值, 通常应该使其最后一个字符为空格,以提供与日志行的其余部分的视觉分离。也可以使用标点符号。

提示

Syslog会生成自己的时间戳和进程ID信息,因此如果您正在记录到syslog,则可能不希望包括这些转义字符。

提示

%q转义字符在包含仅在会话(后端)上下文中可用的信息时非常有用,例如用户或数据库名称。例如:

log_line_prefix = '%m [%p] %q%u@%d/%a '

注意

%Q转义字符始终为零标识符报告由log_statement输出的行,因为log_statement在计算标识符之前生成输出,包括无效语句,无法计算标识符的语句。

log_lock_waits (boolean)

控制是否在会话等待超过deadlock_timeout以获取锁时生成日志消息。这对于确定锁等待是否导致性能不佳很有用。默认值为off。只有超级用户和具有适当SET权限的用户才能更改此设置。

log_recovery_conflict_waits (boolean)

控制是否在启动过程等待超过deadlock_timeout以获取恢复冲突时生成日志消息。这对于确定恢复冲突是否阻止恢复应用WAL很有用。

默认值为off。此参数只能在uxsinodb.conf文件或服务器命令行上设置。

log_parameter_max_length (integer)

如果大于零,则将每个绑定参数值记录为非错误语句记录消息时,将其修剪为这么多字节。零禁用非错误语句日志的绑定参数记录。-1(默认值)允许完全记录绑定参数。如果未指定单位,则将此值视为字节。只有超级用户和具有适当SET权限的用户才能更改此设置。

此设置仅影响作为log_statement、log_duration和相关设置的结果打印的日志消息。此设置的非零值会增加一些开销,特别是如果以二进制形式发送参数,则需要转换为文本。

log_parameter_max_length_on_error (integer)

如果大于零,则将每个在错误消息中报告的绑定参数值修剪为这么多字节。零(默认值)禁用在错误消息中包含绑定参数。 -1允许完全打印绑定参数。如果没有指定单位,则将其视为字节。

此设置的非零值会增加开销,因为UXsinoDB需要在每个语句的开头存储参数值的文本表示,无论最终是否发生错误。当绑定参数以二进制形式发送时,开销更大,而当它们以文本形式发送时,开销仅需要复制字符串。

log_statement (enum)

控制记录哪些 SQL 语句。有效值为 none(关闭)、ddl、mod 和 all(所有语句)。ddl记录所有数据定义语句,例如 CREATE、ALTER 和 DROP 语句。 mod记录所有 ddl 语句,以及数据修改语句,例如 INSERT、UPDATE、DELETE、TRUNCATE 和COPY FROM。如果包含的命令是适当类型的,则还会记录 PREPARE、EXECUTE 和 EXPLAIN ANALYZE语句。对于使用扩展查询协议的客户端,在接收 Execute 消息时记录日志,并包括绑定参数的值(任何嵌入的单引号都会加倍)。

默认值为 none。 只有超级用户和具有适当的 SET 权限的用户才能更改此设置。

注意

不会记录包含简单语法错误的语句,即使设置为 log_statement = all,因为仅在基本解析确定语句类型后才发出日志消息。对于扩展查询协议,此设置同样不会记录在执行阶段之前失败的语句(即在解析分析或计划期间)。将log_min_error_statement 设置为 ERROR(或更低)以记录此类语句。

记录的语句可能会显示敏感数据,甚至包含明文密码。

log_replication_commands (boolean)

导致在服务器日志中记录每个复制命令。默认值为off。 只有超级用户和具有适当的 SET 权限的用户才能更改此设置。

log_temp_files (integer)

控制临时文件名和大小的日志记录。可以为排序、哈希和临时查询结果创建临时文件。如果启用此设置,则在删除每个临时文件时会发出日志记录。值为零时记录所有临时文件信息,而正值仅记录大小大于或等于指定的数据量。如果没有指定单位,则默认为千字节。 默认设置为-1,表示禁用此类日志记录。 只有超级用户和具有适当SET权限的用户才能更改此设置。

log_timezone (string)

设置用于在服务器日志中写入时间戳的时区。与TimeZone不同,此值是集群范围的,因此所有会话都将一致报告时间戳。 内置默认值为GMT,但通常会在uxsinodb.conf中覆盖;initdb将在那里安装与其系统环境对应的设置。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

3.8.4.使用CSV格式日志输出

在log_destination列表中包含csvlog提供了一种方便的方法将日志文件导入数据库表中。此选项以逗号分隔值(CSV)格式发出日志行, 具有以下列: 带毫秒的时间戳、 用户名、数据库名称、 进程ID、 客户端主机:端口号、 会话ID、 每个会话的行号、 命令标记、 会话开始时间、 虚拟事务ID、常规事务ID、 错误严重性、 SQLSTATE代码、 错误消息、 错误消息详细信息、 提示、导致错误的内部查询(如果有)的字符计数位置、 错误上下文、导致错误的用户查询(如果启用了log_min_error_statement)、其中的字符计数位置、UXsinoDB源代码中的错误位置(如果log_error_verbosity设置为verbose)、应用程序名称、后端类型、并行组长的进程ID和查询ID。 以下是用于存储CSV格式日志输出的示例表定义:

CREATE TABLE uxdb_log
(
log_time timestamp(3) with time zone,
user_name text,
database_name text,
process_id integer,
connection_from text,
session_id text,
session_line_num bigint,
command_tag text,
session_start_time timestamp with time zone,
virtual_transaction_id text,
transaction_id bigint,
error_severity text,
sql_state_code text,
message text,
detail text,
hint text,
internal_query text,
internal_query_pos integer,
context text,
query text,
query_pos integer,
location text,
application_name text,
backend_type text,
leader_pid integer,
query_id bigint,
PRIMARY KEY (session_id, session_line_num)
);

要将日志文件导入此表,请使用COPY FROM命令:

COPY uxdb_log FROM '/full/path/to/logfile.csv' WITH csv;

还可以使用提供的file_fdw模块将文件作为外部表访问。

有几件事情需要做以简化导入CSV日志文件:

  1. 设置log_filename和log_rotation_age以提供一致、可预测的命名方案,用于日志文件。这使您可以预测文件名,并知道单个日志文件何时完成,因此可以导入。

  2. 将log_rotation_size设置为0以禁用基于大小的日志轮换,因为它使日志文件名难以预测。

  3. 将log_truncate_on_rotation设置为on,以便旧的日志数据不会与新的数据混合在同一个文件中。

  4. 上面的表定义包括一个主键规范。这对于防止意外导入相同的信息非常有用。COPY命令一次性提交导入的所有数据,因此任何错误都会导致整个导入失败。如果您导入部分日志文件,并在文件完整时再次导入文件,则主键冲突将导致导入失败。在日志完整且关闭之前等待导入。此过程还将防止意外导入未完全编写的部分行,这也会导致COPY失败。

3.8.5.使用JSON格式日志输出

在log_destination列表中包含jsonlog提供了一种方便的方式将日志文件导入到许多不同的程序中。此选项以JSON格式发出日志行。

具有空值的字符串字段将从输出中排除。将来可能会添加其他字段。处理jsonlog输出的用户应忽略未知字段。

每个日志行都被序列化为一个JSON对象,其中包含下表显示的键和它们的关联值。

表 JSON日志条目的键和值

键名类型描述
timestamp字符串带毫秒的时间戳
user字符串用户名
dbname字符串数据库名称
pid数字进程ID
remote_host字符串客户端主机
remote_port数字客户端端口
session_id字符串会话ID
line_num数字每个会话的行号
ps字符串当前ps显示
session_start字符串会话开始时间
vxid字符串虚拟事务ID
txid字符串常规事务ID
error_severity字符串错误严重程度
state_code字符串SQLSTATE代码
message字符串错误消息
detail字符串错误消息详细信息
hint字符串错误消息提示
internal_query字符串导致错误的内部查询
internal_position数字指向内部查询的游标索引
context字符串错误上下文
statement字符串客户端提供的查询字符串
cursor_position数字指向查询字符串的游标索引
func_name字符串错误位置函数名称
file_name字符串错误位置的文件名
file_line_num数字错误位置的文件行号
application_name字符串客户端应用程序名称
backend_type字符串后端类型
leader_pid数字活动并行工作者的领导进程ID
query_id数字查询ID

3.8.6.进程标题

这些设置控制服务器进程的进程标题如何被修改。进程标题通常使用像ps或在Windows上使用Process Explorer等程序查看。有关详细信息,请参见标准Unix工具。

cluster_name (string)

设置进程标题中的集群名称。默认值为空字符串。这个设置只有在编译时启用了进程标题支持时才有效。

设置标识此数据库集群(实例)的名称,以供各种用途。该集群名称出现在此集群中所有服务器进程的进程标题中。此外,它是备用连接的默认应用程序名称(请参见synchronous_standby_names)。

名称可以是任何少于NAMEDATALEN个字符的字符串(在标准构建中为64个字符)。只能在cluster_name值中使用可打印的ASCII字符。其他字符将被替换为问号(?)。如果将此参数设置为空字符串''(默认值),则不显示名称。此参数只能在服务器启动时设置。

update_process_title (boolean)

每次服务器接收到新的SQL命令时,启用更新进程标题。此设置在大多数平台上默认为on,但在Windows上默认为off,因为该平台更新进程标题的开销较大。只有超级用户和具有适当的SET权限的用户才能更改此设置。

3.9.运行时统计信息

3.9.1.累积查询和索引统计信息

这些参数控制服务器范围内的累积统计信息系统。启用后,可以通过ux_stat和ux_statio系统视图访问收集的数据。有关更多信息,请参见监控数据库活动。

track_activities (boolean)

启用对每个会话当前执行的命令、其标识符以及该命令开始执行的时间的信息收集。此参数默认为开启状态。请注意,即使启用,此信息也仅对超级用户、具有ux_read_all_stats角色特权的角色以及报告的会话所有者(包括属于他们特权的角色的会话)可见,因此不应构成安全风险。只有超级用户和具有适当SET特权的用户才能更改此设置。

track_activity_query_size (integer)

指定为ux_stat_activity.query字段中每个活动会话保留的当前执行命令文本的内存量。如果未指定单位,则将其视为字节。默认值为1024字节。

此参数只能在服务器启动时设置。

track_counts (boolean)

启用收集数据库活动统计信息。此参数默认为开启状态,因为自动清理守护进程需要收集信息。只有超级用户和具有适当的 SET权限的用户才能更改此设置。

track_io_timing (boolean)

启用数据库 I/O 调用的计时。此参数默认为关闭状态,因为它会重复查询操作系统的当前时间,这可能会在某些平台上造成重大开销。您可以使用ux_test_timing 工具来测量系统计时的开销。I/O计时信息显示在ux_stat_database中,在使用 BUFFERS 选项的 EXPLAIN 输出中,在使用VERBOSE 选项的 VACUUM输出中,在自动清理和自动分析的自动清理程序中,在设置log_autovacuum_min_duration时以及由ux_stat_statements显示。只有超级用户和具有适当的 SET 权限的用户才能更改此设置。

track_wal_io_timing (boolean)

启用 WAL I/O 调用的计时。此参数默认为关闭状态,因为它会重复查询操作系统的当前时间,这可能会在某些平台上造成重大开销。您可以使用ux_test_timing 工具来测量系统计时的开销。I/O 计时信息显示在ux_stat_wal中。只有超级用户和具有适当的 SET 权限的用户才能更改此设置。

track_functions (enum)

启用跟踪函数调用次数和使用时间。指定 pl 以仅跟踪过程语言函数,指定 all 以跟踪 SQL 和 C 语言函数。默认值为none,禁用函数统计信息跟踪。只有超级用户和具有适当的 SET 权限的用户才能更改此设置。

注意

简单到可以“内联”到调用查询中的 SQL 语言函数将不会被跟踪,无论此设置如何。

stats_fetch_consistency (enum)

确定在事务中多次访问累积统计信息时的行为。当设置为none时,每次访问都会重新从共享内存中获取计数器。当设置为cache时,对于对象的统计信息的第一次访问会将这些统计信息缓存,直到事务结束,除非调用ux_stat_clear_snapshot()。当设置为snapshot时,第一次访问统计信息会将当前数据库中所有可访问的统计信息缓存,直到事务结束,除非调用ux_stat_clear_snapshot()。默认值为cache。

注意

none最适合用于监控系统。如果只访问一次值,则它是最有效的。cache确保重复访问产生相同的值,这对于涉及自连接的查询非常重要。snapshot在交互式检查统计信息时可能很有用,但开销较大,特别是如果存在许多数据库对象。

3.9.2.统计监控

compute_query_id (enum)

启用查询标识符的内核计算。查询标识符可以在ux_stat_activity视图中显示,使用EXPLAIN,或者如果通过log_line_prefix参数进行配置,则在日志中发出。ux_stat_statements 扩展还需要计算查询标识符。请注意,如果内核查询标识符计算方法不可接受,则可以使用外部模块。在这种情况下,必须始终禁用内核计算。有效值为off(始终禁用),on(始终启用),auto,让诸如 ux_stat_statements 之类的模块自动启用它,以及regress,它与auto具有相同的效果,但不会在EXPLAIN输出中显示查询标识符,以便促进自动回归测试。默认值为auto。

注意

为确保仅计算并显示一个查询标识符,计算查询标识符的扩展应在已计算查询标识符的情况下抛出错误。

log_statement_stats (boolean)
log_parser_stats (boolean)
log_planner_stats (boolean)
log_executor_stats (boolean)

对于每个查询,输出相应的性能统计信息。该模块将查询统计信息记录到服务器日志中。这是一种粗略的分析工具,类似于Unix操作系统的getrusage()功能。log_statement_stats报告总语句统计信息,而其他选项报告每个模块的统计信息。不能同时启用log_statement_stats和任何一个模块选项。所有这些选项默认都是禁用的。只有超级用户和具有适当SET权限的用户才能更改这些设置。

3.10.自动清理

这些设置控制自动清理功能的行为。更多信息请参见自动清理守护进程。请注意,许多这些设置可以在每个表上被覆盖。

autovacuum (boolean)

控制服务器是否运行自动清理守护进程。默认情况下,此项为开启状态;但是,track_counts也必须启用才能使自动清理工作。此参数只能在uxsinodb.conf文件或服务器命令行上设置;但是,可以通过更改表存储参数来禁用单个表的自动清理。

请注意,即使禁用了此参数,系统也会在必要时启动自动清理进程以防止事务ID环绕。有关更多信息,请参见防止事务ID环绕故障。

autovacuum_max_workers (integer)

指定除自动清理启动器之外,可能同时运行的自动清理进程的最大数量。默认值为3。此参数只能在服务器启动时设置。

autovacuum_naptime (integer)

指定在任何给定数据库上运行自动清理的最小延迟。在每一轮中,守护进程检查数据库并发出VACUUM和ANALYZE命令。如果需要,可以为该数据库中的表设置自动清理。如果未指定单位,则将其视为秒。默认值为一分钟(1min)。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

autovacuum_vacuum_threshold (integer)

指定在任何一个表中触发VACUUM所需的最小更新或删除元组数。默认值为50个元组。此参数只能在uxsinodb.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。

autovacuum_vacuum_insert_threshold (integer)

指定在任何一个表中触发VACUUM所需的插入元组数。默认值为1000个元组。如果指定为-1,则autovacuum不会基于插入数量触发VACUUM操作。此参数只能在uxsinodb.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。

autovacuum_analyze_threshold (integer)

指定在任何一个表中触发ANALYZE所需的最小插入、更新或删除元组数。默认值为50个元组。此参数只能在uxsinodb.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。

autovacuum_vacuum_scale_factor(floating point)

指定在决定是否触发VACUUM时,要添加到autovacuum_vacuum_threshold的表大小的一部分。默认值为0.2(表大小的20%)。此参数只能在uxsinodb.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。

autovacuum_vacuum_insert_scale_factor(floating point)

指定在决定是否触发VACUUM时,要添加到autovacuum_vacuum_insert_threshold的表大小的一部分。默认值为0.2(表大小的20%)。此参数只能在uxsinodb.conf文件或服务器命令行中设置;但可以通过更改表存储参数来覆盖单个表的设置。

autovacuum_analyze_scale_factor(floating point)

指定在决定是否触发ANALYZE时,要添加到autovacuum_analyze_threshold的表大小的一部分。默认值为0.1(表大小的10%)。此参数只能在uxsinodb.conf文件或服务器命令行中设置; 但是可以通过更改表存储参数来覆盖单个表的设置。

autovacuum_freeze_max_age(integer)

指定表的ux_class。relfrozenxid字段在强制执行VACUUM操作之前可以达到的最大事务数,以防止表内的事务ID环绕。请注意,即使禁用了自动清理,系统也会启动自动清理进程以防止环绕。

清理还允许从ux_xact子目录中删除旧文件,这就是为什么默认值相对较低的2亿个事务。此参数只能在服务器启动时设置,但可以通过更改表存储参数来降低设置。有关更多信息防止事务ID环绕故障。

autovacuum_multixact_freeze_max_age(integer)

指定表的ux_class。relminmxid字段在强制执行VACUUM操作之前可以达到的最大multixacts数,以防止表内的multixact ID环绕。请注意,即使禁用了自动清理,系统也会启动自动清理进程以防止环绕。

清理multixacts还允许从ux_multixact/members和ux_multixact/offsets子目录中删除旧文件,这就是为什么默认值相对较低的4亿个multixacts。此参数只能在服务器启动时设置,但可以通过更改表存储参数来降低设置。有关更多信息,请参见多事务和回卷。

autovacuum_vacuum_cost_delay(floating point)

指定在自动VACUUM操作中将使用的成本延迟值。如果指定-1,则使用常规vacuum_cost_delay值。如果未指定单位,则将其视为毫秒。 默认值为2毫秒。 此参数只能在uxsinodb.conf文件或服务器命令行中设置;但是可以通过更改表存储参数来覆盖单个表的设置。

autovacuum_vacuum_cost_limit(integer)

指定在自动VACUUM操作中将使用的成本限制值。如果指定-1(默认值),则使用常规vacuum_cost_limit值。请注意,如果有多个运行的自动清理工作程序,则该值将在这些工作程序之间按比例分配,以使限制的总和为每个工作进程都不超过此变量的值。此参数只能在uxsinodb.conf文件或服务器命令行中设置; 但可以通过更改表存储参数来覆盖单个表的设置。

3.11.客户端连接默认值

3.11.1.语句行为

client_min_messages (enum)

控制发送给客户端的表 消息严重级别。有效值为DEBUG5、DEBUG4、DEBUG3、DEBUG2、DEBUG1、LOG、NOTICE、WARNING和ERROR。每个级别都包括其后面的所有级别。级别越高,发送的消息越少。默认值为NOTICE。注意,LOG在这里的等级与log_min_messages中的等级不同。

INFO级别的消息始终发送给客户端。

search_path (string)

此变量指定在引用对象(表、数据类型、函数等)时使用简单名称且未指定模式时搜索模式的顺序。当存在多个具有相同名称的对象时,将使用第一个找到的对象。默认情况下,搜索路径包括"$user"和public模式。在不同模式中具有相同名称的对象,将使用搜索路径中找到的第一个对象。不在搜索路径中的对象只能通过指定其包含模式的限定(点分)名称来引用。

search_path 的值必须是逗号分隔的模式名称列表。任何不是现有模式的名称,或者是用户没有USAGE权限的模式,都会被静默忽略。

如果列表项之一是特殊名称$user,则将替换具有由CURRENT_USER返回的名称的模式,如果存在这样的模式并且用户对其具有USAGE权限。(如果没有,则忽略$user。)

系统目录模式ux_catalog始终被搜索,无论它是否在路径中被提及。如果它在路径中被提及,则将按指定顺序搜索它。如果ux_catalog不在路径中,则将在搜索任何路径项之前搜索它。

同样,如果存在当前会话的临时表模式ux_temp_nnn,则始终会搜索它。可以通过使用别名ux_temp将其明确列在路径中。如果它没有列在路径中,则首先搜索它(甚至在ux_catalog之前)。但是,临时模式仅用于搜索关系(表、视图、序列等)和数据类型名称。它永远不会搜索函数或运算符名称。

当创建对象而没有指定特定目标模式时,它们将放置在search_path中命名的第一个有效模式中。如果搜索路径为空,则报告错误。

此参数的默认值为"$user",public。此设置支持数据库的共享使用(其中没有用户具有私有模式,所有用户共享使用public)、每个用户私有模式以及这些组合。可以通过全局或每个用户更改默认搜索路径设置来获得其他效果。

默认配置仅适用于数据库具有单个用户或少数相互信任的用户的情况。

可以通过SQL函数current_schemas检查搜索路径的当前有效值。这与检查search_path的值不完全相同,因为current_schemas显示了如何解析出现在search_path中的项。

row_security (boolean)

此变量控制是否在应用行安全策略之前引发错误。当设置为on时,策略正常应用。当设置为off时,查询将失败,否则至少会应用一个策略。默认值为on。在可能导致不正确结果的有限行可见性的情况下,更改为off;例如,ux_dump默认进行更改。此变量对绕过行安全策略的角色没有影响。每行安全策略,即超级用户和具有BYPASSRLS 属性的角色。

default_table_access_method (string)

此参数指定在创建表或物化视图时使用的默认表访问方法,如果 CREATE 命令没有明确指定访问方法,或者使用不允许指定表访问方法的SELECT ... INTO 命令。默认值为 heap。

default_tablespace (string)

此变量指定在没有明确指定表空间的情况下创建对象(表和索引)时要使用的默认表空间。

该值可以是表空间的名称,也可以是空字符串,以指定使用当前数据库的默认表空间。如果该值与任何现有表空间的名称不匹配,则 UXDB将自动使用当前数据库的默认表空间。如果指定了非默认表空间,则用户必须具有该表空间的 CREATE 权限,否则创建尝试将失败。

此变量不用于临时表;对于它们,将使用temp_tablespaces。

此变量在创建数据库时也不使用。默认情况下,新数据库继承其从中复制的模板数据库的表空间设置。

如果在创建分区表时将此参数设置为非空字符串,则分区表的表空间将设置为该值,该值将用作将来创建的分区的默认表空间,即使default_tablespace 自那时以来已更改。

有关表空间的更多信息,请参见 表空间。

default_toast_compression (enum)

此变量设置可压缩列的默认TOAST压缩方法。(可以通过在 CREATE TABLE 或 ALTER TABLE 中设置 COMPRESSION 列选项来覆盖单个列。)支持的压缩方法是 uxlz 和(如果UXsinoDB 是使用 --with-lz4 编译的)lz4。默认值为 uxlz。

temp_tablespaces (string)

此变量指定在没有明确指定表空间的情况下创建临时对象(临时表和临时表上的索引)时要使用的表空间。用于排序大型数据集等目的的临时文件也在这些表空间中创建。

该值是表空间名称列表。当列表中有多个名称时,UXsinoDB每次创建临时对象时会随机选择列表中的一个成员;但在事务内,连续创建的临时对象会按照列表中的顺序依次放置在连续的表空间中。如果列表中选择的元素是空字符串,则UXsinoDB会自动使用当前数据库的默认表空间。当交互式设置temp_tablespaces时,指定不存在的表空间会导致错误,指定用户没有CREATE权限的表空间也是如此。但是,使用先前设置的值时,不存在的表空间会被忽略,用户缺少CREATE权限的表空间也是如此。特别是在使用在uxsinodb.conf中设置的值时,此规则适用。默认值是空字符串,这将导致所有临时对象都在当前数据库的默认表空间中创建。另请参见default_tablespace。

check_function_bodies (boolean)

该参数通常为开启状态。当设置为off时,它会禁用在CREATE FUNCTION和CREATE PROCEDURE期间对例程体字符串的验证。禁用验证可以避免验证过程的副作用,特别是防止由于前向引用等问题导致的误报。在代表其他用户加载函数之前将此参数设置为off;ux_dump会自动执行此操作。

default_transaction_isolation (enum)

每个SQL事务都有一个隔离级别,可以是“读未提交”、“读已提交”、“可重复读”或“可串行化”。该参数控制每个新事务的默认隔离级别。默认值为“读已提交”。

default_transaction_read_only (boolean)

只读SQL事务不能更改非临时表。该参数控制每个新事务的默认只读状态。默认值为off(读/写)。

default_transaction_deferrable (boolean)

当运行在 serializable 隔离级别时, 可延迟的只读 SQL 事务可能会被延迟,直到允许它继续执行。但是,一旦它开始执行,它就不会产生任何保证串行性所需的开销;因此,串行化代码将没有理由因为并发更新而强制它中止, 使得这个选项适用于长时间运行的只读事务。

该参数控制每个新事务的默认可延迟状态。 它目前对于读写事务或低于 serializable 隔离级别的事务没有影响。 默认值为 off。

transaction_isolation (enum)

该参数反映当前事务的隔离级别。 在每个事务开始时,它被设置为default_transaction_isolation的当前值。 任何后续尝试更改它都相当于一个 SET TRANSACTION 命令。

transaction_read_only (boolean)

该参数反映当前事务的只读状态。 在每个事务开始时,它被设置为default_transaction_read_only的当前值。 任何后续尝试更改它都相当于一个 SET TRANSACTION 命令。

transaction_deferrable (boolean)

该参数反映当前事务的可延迟状态。 在每个事务开始时,它被设置为default_transaction_deferrable的当前值。 任何后续尝试更改它都相当于一个 SET TRANSACTION 命令。

session_replication_role (enum)

控制当前会话的复制相关触发器和规则的触发。 可能的值为 origin(默认值)、replica 和 local。设置此参数会导致丢弃任何先前缓存的查询计划。 只有超级用户和具有适当的 SET权限的用户才能更改此设置。

此设置的预期用途是,逻辑复制系统在应用复制更改时将其设置为replica。这将导致触发器和规则(未从其默认配置更改)不会在副本上触发。有关更多信息,请参见ALTER TABLE子句ENABLE TRIGGER和ENABLE RULE。UXsinoDB在内部将origin和local设置视为相同。第三方复制系统可以将这两个值用于其内部目的,例如使用local来指定不应复制其更改的会话。由于外键是作为触发器实现的,因此将此参数设置为replica也会禁用所有外键检查,如果不正确使用,可能会导致数据处于不一致状态。

statement_timeout (integer)

中止任何超过指定时间的语句。如果log_min_error_statement设置为ERROR或更低,则超时的语句也将被记录。如果未指定单位,则将其视为毫秒。值为零(默认值)禁用超时。

超时是从命令到达服务器的时间开始计算的,直到服务器完成为止。如果单个简单查询消息中出现多个SQL语句,则超时将分别应用于每个语句。(UXDB 2113之前的版本通常将超时视为应用于整个查询字符串。)在扩展查询协议中,超时在任何查询相关消息(Parse、Bind、Execute、Describe)到达时开始运行,并在Execute或Sync消息完成时取消。

不建议在uxsinodb.conf中设置statement_timeout,因为它会影响所有会话。

lock_timeout (integer)

在尝试获取表、索引、行或其他数据库对象的锁时,中止等待时间超过指定时间的语句。时间限制分别应用于每个锁获取尝试。限制适用于显式锁定请求(例如LOCK TABLE或SELECT FOR UPDATE而不是NOWAIT)和隐式获取的锁。如果未指定单位,则将其视为毫秒。值为零(默认值)禁用超时。

与statement_timeout不同,此超时仅在等待锁时发生。请注意,如果statement_timeout为非零值,则将lock_timeout设置为相同或更大的值相当无意义,因为语句超时总是会先触发。如果log_min_error_statement设置为ERROR或更低,则将记录超时的语句。

不建议在uxsinodb.conf中设置lock_timeout,因为它会影响所有会话。

idle_in_transaction_session_timeout (integer)

如果一个处于打开事务状态下的会话在等待客户端查询时空闲时间超过指定的时间,则终止该会话。如果未指定单位,则将其视为毫秒。值为零(默认值)表示禁用超时。

此选项可用于确保空闲会话不会持有锁太长时间。即使没有持有重要锁,打开的事务也会阻止清除最近死亡的元组,这些元组可能仅对该事务可见;因此,长时间保持空闲状态可能会导致表膨胀。有关详细信息,请参见常规清理。

idle_session_timeout (integer)

如果一个处于空闲状态(即等待客户端查询),但未处于打开事务状态下的会话空闲时间超过指定的时间,则终止该会话。如果未指定单位,则将其视为毫秒。值为零(默认值)表示禁用超时。

与打开事务的情况不同,没有事务的空闲会话对服务器没有太大的成本,因此不太需要启用此超时,比起idle_in_transaction_session_timeout。

在强制执行此超时时,要注意连接池软件或其他中间件所建立的连接,因为这样的层可能无法很好地处理意外的连接关闭。可能有助于仅为交互式会话启用此超时,例如仅将其应用于特定用户。

vacuum_freeze_table_age (integer)

如果表的ux_class.relfrozenxid字段的年龄达到此设置的值,则VACUUM执行一次激进的扫描。激进扫描与常规VACUUM的区别在于,它访问可能包含未冻结的XID或MXID的每个页面,而不仅仅是可能包含死元组的页面。默认值为1.5亿个事务。尽管用户可以将此值设置为零到20亿,但VACUUM将默默地将有效值限制为autovacuum_freeze_max_age的95%,以便在为表启动反转包装自动清理之前,定期手动VACUUM有机会运行。有关更多信息,请参见防止事务ID环绕故障。

vacuum_freeze_min_age (integer)

指定VACUUM在扫描表时应使用的截止年龄(以事务为单位),以决定是否冻结行版本。默认值为5千万个事务。尽管用户可以将此值设置为零到10亿,但VACUUM将默默地将有效值限制为autovacuum_freeze_max_age值的一半,以便在强制自动清理之间没有不合理的短时间。有关更多信息,请参见防止事务ID环绕故障。

vacuum_failsafe_age (integer)

指定表的ux_class.relfrozenxid字段在达到的最大事务数(transactions)之前,VACUUM会采取特殊措施以避免系统范围的事务ID环绕故障。这是VACUUM的最后一道防线。故障安全通常会在防止事务ID环绕的自动清理运行一段时间后触发,尽管在任何VACUUM期间都有可能触发故障安全。

当触发故障安全时,任何生效的基于成本的延迟都将不再应用,并且进一步的非必要维护任务(例如索引清理)将被绕过。

默认值为16亿个事务。尽管用户可以将此值设置为从零到21亿的任何值,VACUUM将默默地将有效值调整为不少于autovacuum_freeze_max_age的105%。

vacuum_multixact_freeze_table_age (integer)

如果表的ux_class.relminmxid字段达到此设置指定的年龄,则VACUUM将执行一次激进的扫描。激进扫描与常规VACUUM不同之处在于,它访问可能包含未冻结XID或MXID的每个页面,而不仅仅是可能包含死元组的页面。默认值为1.5亿个多重事务(multixacts)。尽管用户可以将此值设置为从零到20亿的任何值,VACUUM将默默地将有效值限制为autovacuum_multixact_freeze_max_age的95%,以便在启动表的防环绕之前,定期手动VACUUM有机会运行。有关更多信息,请参见多事务和回卷。

vacuum_multixact_freeze_min_age (integer)

指定VACUUM在扫描表时应使用的截止年龄(以多重事务(multixacts)为单位),以决定是否将多重事务ID替换为新的事务ID或多重事务ID。默认值为500万个多重事务。尽管用户可以将此值设置为从零到10亿的任何值,VACUUM将默默地将有效值限制为autovacuum_multixact_freeze_max_age值的一半,以避免在强制自动清理之间出现不合理的短时间。有关更多信息,请参见多事务和回卷。

vacuum_multixact_failsafe_age (integer)

指定表的ux_class.relminmxid字段在达到的最大多重事务数(multixacts)之前,VACUUM会采取特殊措施以避免系统范围的多重事务ID环绕故障。这是VACUUM的最后一道防线。

VACUUM采取特殊措施避免系统范围内的多事务ID环绕故障之前,字段可以达到的最大值。这是VACUUM的最后一道防线。故障安全通常在自动清理以防止事务ID环绕已经运行了一段时间后触发,尽管在任何VACUUM期间触发故障安全也是可能的。

当触发故障安全时,任何正在生效的基于成本的延迟都将不再应用,并且进一步的非必要维护任务(如索引清理)将被绕过。

默认值为16亿个多事务。尽管用户可以将此值设置为从零到21亿的任何值,VACUUM将默默地将有效值调整为不少于autovacuum_multixact_freeze_max_age的105%。

bytea_output (enum)

设置类型为bytea的值的输出格式。有效值为hex(默认值)和escape(传统的UXsinoDB格式)。无论此设置如何,bytea类型始终接受输入中的两种格式。

xmlbinary (enum)

设置在XML中编码二进制值的方式。例如,当bytea值通过xmlelement或xmlforest函数转换为XML时,将应用此设置。可能的值为base64和hex,两者都在XML Schema标准中定义。默认值为base64。

实际选择在很大程度上是品味问题,仅受客户端应用程序可能的限制约束。两种方法都支持所有可能的值,尽管十六进制编码将比base64编码略大。

xmloption (enum)

设置在XML和字符字符串值之间转换时是否隐含DOCUMENT或CONTENT。有效值为DOCUMENT和CONTENT。默认值为CONTENT。

根据SQL标准,设置此选项的命令为

SET XML OPTION { DOCUMENT | CONTENT };

此语法在UXsinoDB中也可用。

gin_pending_list_limit (integer)

设置GIN索引的挂起列表的最大大小,该列表在启用fastupdate时使用。如果列表增长超过此最大大小,则通过批量将其中的条目移动到索引的主GIN数据结构来清理它。

如果未指定单位,则将此值视为千字节。 默认值为四兆字节(4MB)。可以通过更改索引存储参数来覆盖单个GIN索引的此设置。

3.11.2.区域设置和格式

设置日期和时间值的显示格式,以及解释模糊日期输入值的规则。由于历史原因,此变量包含两个独立的组件:输出格式规范(ISO、Uxdb、SQL或German)和年/月/日排序的输入/输出规范(DMY、MDY或YMD)。这些可以单独或一起设置。关键字Euro和European是DMY的同义词;关键字US、NonEuro和NonEuropean是MDY的同义词。内置默认值为ISO,MDY,但initdb将使用与所选lc_time区域设置的行为相对应的设置初始化配置文件。

IntervalStyle (enum)

设置间隔值的显示格式。 值sql_standard将生成与SQL标准间隔文字相匹配的输出。值uxdb(默认值)将生成与设置为ISO的DateStyle参数之前的UXsinoDB相匹配的输出。值uxdb_verbose将生成与设置为非ISO输出的DateStyle参数之前的UXsinoDB相匹配的输出。 值iso_8601将生成与ISO 8601的时间间隔“带有指示符的格式”相匹配的输出。

IntervalStyle参数还会影响模糊间隔输入的解释。

TimeZone (string)

设置用于显示和解释时间戳的时区。内置默认值为GMT,但通常在uxsinodb.conf中覆盖;initdb会在那里安装与其系统环境相对应的设置。

timezone_abbreviations (string)

设置服务器用于日期时间输入的时区缩写集合。默认值为'Default',适用于大部分世界地区;还有'Australia'和'India',也可以为特定安装定义其他集合。

extra_float_digits (integer)

此参数调整用于浮点值(包括float4、float8和几何数据类型)的文本输出中使用的数字位数。

如果值为1(默认值)或更高,则浮点值以最短精确格式输出。生成的实际数字位数仅取决于输出的值,而不取决于此参数的值。对于float8值,最多需要17位数字,而对于float4值,最多需要9位数字。此格式既快速又精确,正确读取时完全保留原始二进制浮点值。出于历史兼容性考虑,允许使用最多3个值。

如果值为零或负数,则输出将四舍五入到给定的小数精度。使用的精度是类型的标准数字位数(根据需要适当使用FLT_DIG或DBL_DIG)根据此参数的值进行减少。(例如,指定-1将导致float4值输出四舍五入到5个有效数字,float8值四舍五入到14个数字。)此格式较慢,不能保留二进制浮点值的所有位,但可能更易于阅读。

client_encoding (string)

设置客户端编码(字符集)。默认值为使用数据库编码。由UXsinoDB服务器支持的字符集在支持的字符集中描述。

lc_messages (string)

设置显示消息的语言。可接受的值取决于安装的语言环境。有关更多信息,请参见本地化支持。如果将此变量设置为空字符串(默认值),则该值将以系统相关的方式从服务器的执行环境继承。

在某些系统上,此语言环境类别不存在。设置此变量仍将起作用,但不会产生任何效果。此外,所需语言的翻译消息可能不存在。在这种情况下,您将继续看到英文消息。

只有超级用户和具有适当的SET权限的用户才能更改此设置。

lc_monetary (string)

设置用于格式化货币金额的语言环境,例如使用to_char函数族。可接受的值是系统相关的;有关更多信息,请参见本地化支持。如果将此变量设置为空字符串(默认值),则该值将以系统相关的方式从服务器的执行环境继承。

lc_numeric (string)

设置用于格式化数字的语言环境,例如使用to_char函数族。可接受的值是系统相关的;有关更多信息,请参见本地化支持。如果将此变量设置为空字符串(默认值),则该值将以系统相关的方式从服务器的执行环境继承。

lc_time (string)

设置用于格式化日期和时间的语言环境,例如使用to_char函数族。可接受的值是系统相关的;有关更多信息,请参见本地化支持。如果将此变量设置为空字符串(默认值),则该值将以系统相关的方式从服务器的执行环境继承。

default_text_search_config (string)

选择由那些没有显式参数指定配置的文本搜索函数的变体使用的文本搜索配置。内置默认值为ux_catalog.simple,但如果可以识别与所选lc_ctype语言环境相匹配的配置,则initdb将使用配置文件初始化。

注意

Windows环境下client_encoding (string)、lc_messages (string)、lc_monetary (string)、lc_numeric (string)、lc_time (string)仅支持ux_collation系统表所罗列的语言。

3.11.3.共享库预加载

有几个设置可用于预加载共享库到服务器,以加载其他功能或实现性能优势。例如'$libdir/mylib'设置可能会导致mylib.so(或者某些平台上的mylib.sl)从安装的标准库目录被预装载。设置之间的区别在于它们何时生效以及更改它们所需的特权。

可以通过使用语法'$libdir/plXXX'来预加载UXsinoDB过程语言库,其中XXX是uxsql、perl、tcl或python。

只有专门用于与UXsinoDB一起使用的共享库才能以这种方式加载。每个受UXsinoDB支持的库都有一个“魔术块”,用于保证兼容性。因此,非UXsinoDB库不能以这种方式加载。您可能可以使用操作系统设施,例如LD_PRELOAD。

通常,有关特定模块的推荐加载方式,请参阅该模块的文档。

local_preload_libraries (string)

此变量指定要在连接启动时预加载的一个或多个共享库。它包含一个逗号分隔的库名称列表,其中每个名称的解释方式与LOAD命令相同。条目之间的空格将被忽略;如果需要在名称中包含空格或逗号,请使用双引号将库名称括起来。参数值仅在连接开始时生效。随后的更改不会产生影响。如果找不到指定的库,则连接尝试将失败。

任何用户都可以设置此选项。因此,可以加载的库被限制为出现在安装的标准库目录的plugins子目录中的库。(数据库管理员有责任确保只安装了“安全”的库。)local_preload_libraries中的条目可以显式指定此目录,例如$libdir/plugins/mylib,也可以只指定库名称——mylib将具有与$libdir/plugins/mylib相同的效果。

此功能的目的是允许非特权用户在特定会话中加载调试或性能测量库,而无需显式使用LOAD命令。为此,通常使用UXOPTIONS环境变量在客户端上设置此参数,或使用ALTER ROLE SET。

但是,除非模块专门设计为由非超级用户使用,否则通常不是正确的设置。请查看session_preload_libraries。

session_preload_libraries (string)

此变量指定要在连接启动时预加载的一个或多个共享库。它包含一个逗号分隔的库名称列表,其中每个名称的解释方式与LOAD命令相同。条目之间的空格将被忽略;如果需要在名称中包含空格或逗号,请使用双引号将库名称括起来。参数值仅在连接开始时生效。后续更改无效。如果找不到指定的库,则连接尝试将失败。只有超级用户和具有适当SET 权限的用户才能更改此设置。

此功能的目的是允许将调试或性能测量库加载到特定会话中,而无需给出显式的LOAD命令。例如,可以通过使用ALTER ROLE SET设置此参数来为给定用户名下的所有会话启用auto_explain。此外,可以在不重新启动服务器的情况下更改此参数(但仅在启动新会话时才生效),因此即使应用于所有会话,也更容易以这种方式添加新模块。

与 shared_preload_libraries不同,将库加载到会话开始时而不是首次使用时并没有太大的性能优势。但是,当使用连接池时,确实有一些优势。

shared_preload_libraries (string)

变量指定要在服务器启动时预加载的一个或多个共享库。它包含一个逗号分隔的库名称列表,其中每个名称的解释与LOAD命令相同。条目之间的空格将被忽略;如果需要在名称中包含空格或逗号,则用双引号括起来。此参数只能在服务器启动时设置。如果找不到指定的库,则服务器将无法启动。

某些库需要执行某些只能在uxmaster启动时进行的操作,例如分配共享内存、保留轻量级锁或启动后台工作进程。这些库必须通过此参数在服务器启动时加载。有关详细信息,请参阅每个库的文档。

其他库也可以预加载。通过预加载共享库,可以避免在首次使用库时启动库。但是,即使该进程从未使用该库,每个新服务器进程启动的时间可能会略微增加。因此,此参数仅建议用于将在大多数会话中使用的库。此外,更改此参数需要重新启动服务器,因此这不是用于短期调试任务的正确设置。请改用session_preload_libraries。

注意

在 Windows主机上,预加载库不会减少启动每个新服务器进程所需的时间;每个服务器进程将重新加载所有预加载库。但是,shared_preload_libraries对于需要在 uxmaster 启动时执行操作的库仍然在 Windows 主机上有用。

jit_provider (string)

变量是要使用的JIT提供程序库的名称。默认值为llvmjit。此参数只能在服务器启动时设置。

如果设置为不存在的库,则JIT 将不可用,但不会引发错误。这种特性允许在主PostgreSQL包之外单独安装JIT支持。

3.11.4.其他默认值

dynamic_library_path (string)

如果需要打开一个动态加载的模块,并且在 CREATE FUNCTION 或 LOAD命令中指定的文件名没有目录组件(即,名称不包含斜杠),则系统将在此路径中搜索所需的文件。

dynamic_library_path 的值必须是由冒号(或 Windows上的分号)分隔的绝对目录路径列表。如果列表元素以特殊字符串$libdir 开头,则编译的 UXDB 包库目录将替换为 $libdir;这是标准 UXDB发行版提供的模块安装的位置。(使用 ux_config --pkglibdir查找此目录的名称。)例如:

dynamic_library_path = '/usr/local/lib/uxsinodb:/home/my_project/lib:$libdir'

或在 Windows环境中:

dynamic_library_path = 'C:\tools\uxsinodb;H:\my_project\lib;$libdir'

此参数的默认值为 '$libdir'。如果将值设置为空字符串,则自动路径搜索将关闭。

此参数可以由超级用户和具有适当的 SET特权的用户在运行时更改,但是以这种方式进行的设置仅持续到客户端连接结束,因此此方法应保留用于开发目的。建议设置此参数的方法是在uxsinodb.conf 配置文件中设置。

gin_fuzzy_search_limit (integer)

GIN 索引扫描返回的集合大小的软上限。

3.12.锁管理

deadlock_timeout (integer)

这是等待锁定的时间,在检查是否存在死锁条件之前。检查死锁是相对昂贵的,因此服务器不会每次等待锁定时都运行它。我们乐观地假设在生产应用程序中死锁不常见,只是在等待一段时间后才检查死锁。增加此值会减少在不必要的死锁检查中浪费的时间,但会减慢实际死锁错误的报告速度。如果未指定单位,则将其视为毫秒。默认值为一秒钟(1s),这可能是您在实践中想要的最小值。在高负载服务器上,您可能需要将其提高。理想情况下,该设置应超过您的典型事务时间,以提高在等待者决定检查死锁之前释放锁的几率。只有超级用户和具有适当的 SET 权限的用户才能更改此设置。

当设置了log_lock_waits时,此参数还确定在发出有关锁定等待的日志消息之前等待的时间。如果您正在尝试调查锁定延迟,您可能希望设置比正常更短的deadlock_timeout。

max_locks_per_transaction (integer)

共享锁表跟踪max_locks_per_transaction*(max_connections+max_prepared_transactions)个对象(例如表)的锁定;因此,不能锁定超过这么多个不同的对象。任何时候,此参数控制为每个事务分配的平均对象锁定数;只要所有事务的锁适合锁表中,单个事务可以锁定更多的对象。这不是可以锁定的行数;该值是无限制的。默认值为64,历史上已经被证明足够使用,但如果您有查询在单个事务中涉及许多不同的表,例如具有许多子项的父表的查询,则可能需要提高此值。此参数只能在服务器启动时设置。在运行备用服务器时,您必须将此参数设置为与主服务器相同或更高的值。否则,将不允许在备用服务器中进行查询。

max_pred_locks_per_transaction (integer)

共享谓词锁表跟踪对max_pred_locks_per_transaction*(max_connections+max_prepared_transactions)个对象(例如表)的锁定;因此,在任何时候,不能锁定更多的不同对象。此参数控制为每个事务分配的平均对象锁定数;只要所有事务的锁适合锁表中,单个事务可以锁定更多的对象。这不是可以锁定的行数;该值是无限制的。默认值为64,在测试中通常已经足够,但如果您有客户端在单个可串行化事务中触及许多不同的表,则可能需要提高此值。此参数只能在服务器启动时设置。

max_pred_locks_per_relation (integer)

此参数控制在锁定整个关系之前可以谓词锁定单个关系的页面或元组的数量。大于或等于零的值表示绝对限制,而负值表示max_pred_locks_per_transaction除以此设置的绝对值。默认值为-2,保持了以前版本的UXsinoDB的行为。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

max_pred_locks_per_relation (integer)

此参数控制在锁定整个页面之前可以谓词锁定单个页面上的多少行。默认值为2。此参数只能在uxsinodb.conf文件或服务器命令行中设置。

3.13.错误处理

exit_on_error (boolean)

如果设置为开启,任何错误都将终止当前会话。默认情况下,此项设置为关闭,因此只有致命错误才会终止会话。

restart_after_crash (boolean)

当设置为开启时,即默认情况下,UXsinoDB将在后端崩溃后自动重新初始化。保持此值为开启通常是最大化数据库可用性的最佳方式。但是,在某些情况下,例如当UXsinoDB被集群软件调用时,禁用重启可能是有用的,以便集群软件可以获得控制并采取任何它认为适当的操作。

此参数只能在uxsinodb.conf文件或服务器命令行中设置。

data_sync_retry (boolean)

当设置为关闭时,即默认情况下,UXsinoDB在无法将修改后的数据文件刷新到文件系统时会引发PANIC级别的错误。这会导致数据库服务器崩溃。此参数只能在服务器启动时设置。

在某些操作系统上,写回失败后内核页面缓存中数据的状态是未知的。在某些情况下,它可能已经完全被遗忘,使得重试不安全;第二次尝试可能被报告为成功,但实际上数据已经丢失。在这些情况下,避免数据丢失的唯一方法是在报告任何故障后从WAL恢复,最好在调查故障根本原因并更换任何有故障的硬件后进行恢复。

如果设置为开启,UXsinoDB将报告错误但继续运行,以便可以在稍后的检查点中重试数据刷新操作。仅在需要时将其设置为开启。在调查操作系统对缓冲数据的处理方式后,如果写回失败,可以设置。

recovery_init_sync_method (enum)

参数。当设置为fsync时,这是默认设置,UXsinoDB将在崩溃恢复开始之前递归地打开和同步数据目录中的所有文件。寻找文件将遵循WAL目录和每个配置的表空间的符号链接(但不包括任何其他符号链接)。这旨在确保在重放更改之前,所有WAL和数据文件都被持久地存储在磁盘上。这适用于启动未正常关闭的数据库集群,包括使用ux_basebackup创建的副本。

在Linux上,可以使用syncfs,要求操作系统同步包含数据目录、WAL文件和每个表空间的整个文件系统(但不包括通过符号链接可达的任何其他文件系统)。这可能比fsync设置快得多,因为它不需要逐个打开每个文件。另一方面,如果一个文件系统被其他修改了很多文件的应用程序共享,那么它可能会更慢,因为这些文件也将被写入磁盘。

此参数只能在uxsinodb.conf文件或服务器命令行中设置。

3.14.预设选项

以下的“参数”是只读的。因此,它们已被排除在示例uxsinodb.conf文件之外。这些选项报告了UXsinoDB行为的各个方面,这可能对某些应用程序特别是管理前端很有兴趣。它们中的大多数是在编译或安装UXsinoDB时确定的。

block_size (integer)

报告磁盘块的大小。它由构建服务器时BLCKSZ的值确定。默认值为8192字节。一些配置变量(如shared_buffers)的含义受block_size的影响。有关信息,请参见资源消耗。

data_checksums (boolean)

报告此集群是否启用了数据校验和。有关更多信息,请参见数据校验和。

data_directory_mode (integer)

在Unix系统上,此参数报告数据目录(由data_directory定义)在服务器启动时的权限。(在Microsoft Windows上,此参数将始终显示0700。)

debug_assertions (boolean)

报告UXsinoDB是否启用了断言。如果在构建UXsinoDB时定义了宏USE_ASSERT_CHECKING(例如通过configure选项--enable-cassert),则为启用了断言。默认情况下,UXsinoDB是没有启用断言的。

integer_datetimes (boolean)

报告UXsinoDB是否支持64位整数日期和时间。默认为on。

in_hot_standby (boolean)

报告服务器当前是否处于热备模式。当此选项为on时,所有事务都被强制为只读。在会话中,只有在服务器被提升为主服务器时才能更改此选项。

lc_collate (string)

报告文本数据排序所使用的区域设置。有关更多信息,请参见本地化支持。此值在创建数据库时确定。

lc_ctype (string)

报告确定字符分类的区域设置。有关更多信息,请参见本地化支持。此值在创建数据库时确定。通常,此值与lc_collate相同,但对于特殊应用程序,可能会设置为不同的值。

max_function_args (integer)

报告函数参数的最大数量。它由构建服务器时的FUNC_MAX_ARGS的值确定。默认值为100个参数。

max_identifier_length (integer)

报告标识符的最大长度。它被确定为构建服务器时NAMEDATALEN的值减1。默认值NAMEDATALEN为64;因此,默认的max_identifier_length为63个字节,当使用多字节编码时,可能小于63个字符。

max_index_keys (integer)

报告索引键的最大数量。它由构建服务器时的INDEX_MAX_KEYS的值确定。默认值为32个键。

segment_size (integer)

报告可以存储在文件中的块(页)数量。段。它由构建服务器时的RELSEG_SIZE值确定。段文件的最大大小(以字节为单位)等于segment_size乘以block_size;默认值为1GB。

server_encoding (string)

报告数据库编码(字符集)。它在创建数据库时确定。通常,客户端只需要关注client_encoding的值。

server_version (string)

报告服务器的版本号。它由构建服务器时的UX_VERSION值确定。

server_version_num (integer)

报告服务器版本号的整数值。它由构建服务器时的UX_VERSION_NUM值确定。

shared_memory_size (integer)

报告主共享内存区域的大小,向上舍入到最近的兆字节。

shared_memory_size_in_huge_pages (integer)

根据指定的huge_page_size,报告主共享内存区域所需的巨大页面数。如果不支持巨大页面,则为-1。

此设置仅在Linux上受支持。在其他平台上,它始终设置为-1。有关在Linux上使用巨大页面的更多详细信息,请参见Linux 大页面。

ssl_library (string)

报告此UXsinoDB服务器构建时使用的SSL库的名称(即使在此实例上未配置或未使用SSL),例如OpenSSL,如果没有则为空字符串。

wal_block_size (integer)

报告WAL磁盘块的大小。它由构建服务器时的XLOG_BLCKSZ值确定。默认值为8192字节。

wal_segment_size (integer)

报告预写式日志段的大小。默认值为16MB。有关更多信息,请参见WAL 配置。

3.15.自定义选项

此功能旨在允许附加模块(如过程语言)添加通常未知的参数。这允许扩展模块以标准方式进行配置。

自定义选项有两部分名称:扩展名,然后是参数名称本身,类似于 SQL中的限定名称。例如,pluxsql.variable_conflict。

由于可能需要在未加载相关扩展模块的进程中设置自定义选项,UXsinoDB将接受任何两部分参数名称的设置。这些变量被视为占位符,没有任何功能,直到定义它们的模块被加载。当扩展模块被加载时,它将添加其变量定义并根据这些定义转换任何占位符值。如果有任何以其扩展名开头的未识别占位符,则会发出警告并删除这些占位符。

3.16.短选项

为了方便起见,某些参数还提供了单个字母的命令行选项开关。下表进行了描述。其中一些选项存在历史原因,它们作为单个字母选项的存在并不一定表示支持大量使用该选项。

表 短选项键

短选项等效选项
-B xshared_buffers = x
-d xlog_min_messages = DEBUGx
-edatestyle = euro
-fb, -fh, -fi, -fm, -fn, -fo, -fs, -ftenable_bitmapscan = off, enable_hashjoin = off, enable_indexscan = off, enable_mergejoin = off, enable_nestloop = off, enable_indexonlyscan = off, enable_seqscan = off, enable_tidscan = off
-Ffsync = off
-h xlisten_addresses = x
-ilisten_addresses = '*'
-k xunix_socket_directories = x
-lssl = on
-N xmax_connections = x
-Oallow_system_table_mods = on
-p xport = x
-Pignore_system_indexes = on
-slog_statement_stats = on
-S xwork_mem = x
-tpa, -tpl, -telog_parser_stats = on, log_planner_stats = on, log_executor_stats = on
-W xpost_auth_delay = x

4.客户端认证

当客户端应用程序连接到数据库服务器时,它指定要连接的UXsinoDB数据库用户名,就像在Unix计算机上以特定用户登录一样。在SQL环境中,活动的数据库用户名确定对数据库对象的访问权限——有关更多信息,请参见数据库角色。因此,限制哪些数据库用户可以连接是必要的。

注意

正如在数据库角色中所解释的那样,UXsinoDB实际上是以“角色”的术语进行特权管理的。在本章中,我们使用“数据库用户”一词来表示这些角色。

一贯使用数据库用户来表示具有LOGIN特权的角色。

认证是数据库服务器建立客户端身份的过程,通过该过程,还可以确定客户端应用程序(或运行客户端应用程序的用户)是否被允许连接到请求的数据库用户名。

UXDB提供了许多不同的客户端认证方法。可以基于(客户端)主机地址、数据库和用户选择用于认证特定客户端连接的方法。

UXsinoDB数据库用户名在逻辑上与服务器运行的操作系统的用户名是分开的。如果特定服务器的所有用户也在服务器的机器上拥有帐户,则将数据库用户名分配给与其操作系统用户名匹配的用户是有意义的。但是,接受远程连接的服务器可能有许多没有本地操作系统帐户的数据库用户,在这种情况下,数据库用户名和操作系统用户名之间不需要有任何连接。

4.1.ux_hba.conf 文件

客户端认证由一个配置文件控制,传统上这个文件被命名为 ux_hba.conf,并存储在数据库 集群的数据目录中。 (HBA代表基于主机的认证。) 当数据 目录由 initdb初始化时,会安装一个默认的 ux_hba.conf 文件。然而,也可以将认证配置文件放在其他位置; 请参阅hba_file 配置参数。

ux_hba.conf 文件的一般格式是 一组记录,每行一个。空行被忽略,以及任何 在 # 注释字符之后的文本。可以通过在行末使用反斜杠将记录继续到下一行。 (反斜杠只在行末才有特殊意义。)记录由多个字段组成,这些字段由空格或制表符分隔。 如果字段值是双引号括起来的,则字段可以包含空格。在数据库、用户或地址字段中引用其中一个关键字 (例如, all 或 replication) 会使该单词失去其特殊含义,并仅与具有该名称的数据库、用户或主机匹配。 反斜杠行续行符甚至适用于引号文本或注释。

每个记录指定一个连接类型、客户端 IP 地址范围 (如果与连接类型相关),数据库名称、用户名,以及用于匹配这些参数的认证方法。第一个具有匹配的连接类型、客户端地址、请求的数据库和用户名的记录用于执行认证。 没有“fall-through”或 “backup”:如果选择了一个记录并且认证失败,则不考虑后续记录。如果没有记录匹配,则拒绝访问。

记录可以有多种格式:

local         database  user  auth-method [auth-options]
host          database  user  address     auth-method  [auth-options]
hostssl       database  user  address     auth-method  [auth-options]
hostnossl     database  user  address     auth-method  [auth-options]
hostgssenc    database  user  address     auth-method  [auth-options]
hostnogssenc  database  user  address     auth-method  [auth-options]
host          database  user  IP-address  IP-mask      auth-method  [auth-options]
hostssl       database  user  IP-address  IP-mask      auth-method  [auth-options]
hostnossl     database  user  IP-address  IP-mask      auth-method  [auth-options]
hostgssenc    database  user  IP-address  IP-mask      auth-method  [auth-options]
hostnogssenc  database  user  IP-address  IP-mask      auth-method  [auth-options]

字段的含义如下:

local
此记录匹配使用 Unix 域套接字的连接尝试。如果没有此类型的记录,则禁止 Unix 域套接字连接。

host
该记录匹配使用TCP/IP进行的连接尝试。host记录匹配使用SSL或非SSL连接尝试以及GSSAPI加密或非GSSAPI加密连接尝试。

注意

除非服务器使用适当的listen_addresses配置参数启动,否则将无法进行远程TCP/IP连接,因为默认行为仅在本地回环地址localhost上监听TCP/IP连接。

hostssl
该记录仅匹配使用TCP/IP进行的使用SSL加密的连接尝试。

要使用此选项,必须使用SSL支持构建服务器。此外,必须通过设置ssl配置参数启用SSL(有关更多信息,请参见使用 SSL 进行安全的 TCP/IP 连接)。否则,除了记录警告无法匹配任何连接之外,将忽略hostssl记录。

hostnossl
该记录类型与hostssl的行为相反;它仅匹配不使用SSL的TCP/IP连接尝试。

hostgssenc
该记录仅匹配使用TCP/IP进行的使用GSSAPI加密的连接尝试。

要使用此选项,必须使用GSSAPI支持构建服务器。否则,将忽略hostgssenc记录,除了记录警告无法匹配任何连接之外。

hostnogssenc
该记录类型与hostgssenc的行为相反;它仅匹配不使用GSSAPI加密的TCP/IP连接尝试。

database
指定此记录匹配的数据库名称。值all指定它匹配所有数据库。值sameuser指定如果请求的数据库与请求的用户具有相同的名称,则记录匹配。值samerole指定请求的用户必须是与请求的数据库具有相同名称的角色的成员(samegroup是samerole的过时但仍被接受的拼写)。对于samerole,超级用户不被视为角色的成员,除非他们明确地是角色的成员,直接或间接地,而不仅仅是超级用户的身份。值replication指定如果请求物理复制连接,则记录匹配,但它不与逻辑复制连接匹配。请注意,物理复制连接不指定任何特定的数据库,而逻辑复制连接确实指定它。否则,这是特定的UXsinoDB数据库的名称。可以通过用逗号分隔它们来提供多个数据库名称。逗号。可以通过在文件名前加上@来指定包含数据库名称的单独文件。

user
指定此记录匹配的数据库用户名。值all表示匹配所有用户。否则,这是特定数据库用户的名称,或者是以+开头的组名。(请注意,在UXsinoDB中,用户和组之间没有真正的区别;+标记实际上意味着“匹配直接或间接成员的任何角色”,而没有+标记的名称仅匹配特定角色。)为此,只有明确成为角色成员的超级用户才被视为角色的成员,而不是仅仅因为是超级用户而被视为成员。可以通过用逗号分隔它们来提供多个用户名。可以通过在文件名前加上@来指定包含用户名的单独文件。

address
指定此记录匹配的客户端机器地址。此字段可以包含主机名、IP地址范围或下面提到的特殊关键字之一。

使用范围的起始地址的标准数字表示法指定IP地址范围,然后是斜杠(/)和一个CIDR掩码长度。掩码长度指示必须匹配的客户端IP地址的高位比特数。在给定的IP地址中,右侧的位应为零。 IP地址、/和CIDR掩码长度之间不能有任何空格。

以这种方式指定的IPv4地址范围的典型示例是172.20.143.89/32表示单个主机,或172.20.143.0/24表示小型网络,或10.6.0.0/16表示较大的网络。IPv6地址范围可能看起来像::1/128表示单个主机(在这种情况下是IPv6环回地址),或fe80::7a31:c1ff:0000:0000/96表示小型网络。0.0.0.0/0表示所有IPv4地址,::0/0表示所有IPv6地址。要指定单个主机,请使用IPv4的掩码长度32或IPv6的掩码长度128。在网络地址中,不要省略尾随的零。

以IPv4格式给出的条目仅匹配IPv4连接,以IPv6格式给出的条目仅匹配IPv6连接,即使表示的地址在IPv4-in-IPv6范围内也是如此。请注意,如果系统的C库不支持IPv6地址,则以IPv6格式给出的条目将被拒绝。

您还可以写all以匹配任何IP地址,samehost以匹配服务器自己的任何IP地址,或samenet以匹配服务器直接连接到的任何子网中的任何地址。

如果指定了主机名(任何不是IP地址范围或特殊关键字的内容都被视为主机名),则将该名称与客户端IP地址的反向名称解析的结果进行比较(例如,如果使用DNS,则进行反向DNS查找)。主机名比较不区分大小写。如果匹配,则在主机名上执行正向名称解析(例如,正向DNS查找),以检查它解析为的任何地址是否等于客户端的IP地址。如果两个方向都匹配,则认为该条目匹配。(在ux_hba.conf中使用的主机名应该是如果客户端的IP地址的地址到名称解析返回,则该行将匹配。一些主机名数据库允许将IP地址与多个主机名关联,但是操作系统在被要求解析IP地址时只返回一个主机名。

以点(.)开头的主机名规范匹配实际主机名的后缀。因此,.example.com将匹配foo.example.com(但不仅仅是example.com)。

在ux_hba.conf中指定主机名时,应确保名称解析速度合理快速。可以设置本地名称解析缓存,例如nscd。此外,您可能希望启用配置参数log_hostname,以在日志中看到客户端的主机名而不是IP地址。

这些字段不适用于本地记录。

注意

用户有时会想知道为什么主机名以这种看似复杂的方式处理,包括两个名称解析,包括客户端IP地址的反向查找。这使得在客户端的反向DNS条目未设置或产生某些不良主机名的情况下使用该功能变得复杂。这主要是为了效率而做的:这样,连接尝试最多需要两个解析器查找,一个反向和一个正向。如果某个地址存在解析器问题,则只成为该客户端的问题。假设的另一种只进行正向查找的替代实现将不得不在每次连接尝试期间解析ux_hba.conf中提到的每个主机名。如果列出了许多名称,则这可能会非常慢。如果其中一个主机名存在解析器问题,则它将成为每个人的问题。

此外,反向查找对于实现后缀匹配功能是必要的,因为需要知道实际客户端主机名才能将其与模式匹配。

请注意,此行为与其他流行的基于主机名的访问控制实现一致,例如Apache HTTP Server和TCP Wrappers。

IP-address IP-mask
这两个字段可以用作IP地址/掩码长度表示法的替代方法。不需要指定掩码长度,而是在单独的列中指定实际掩码。例如,255.0.0.0表示IPv4 CIDR掩码长度为8,而255.255.255.255表示CIDR掩码长度为32。 这些字段不适用于本地记录。

auth-method
指定连接匹配此记录时要使用的身份验证方法。可能的选择在此处概述;详细信息在认证方法中。所有选项都是小写的,大小写敏感,因此即使是缩写词(例如ldap)也必须指定为小写。

trust
允许无条件连接。此方法允许任何可以连接到UXsinoDB数据库服务器的人以任何他们希望的UXsinoDB用户登录,而无需密码或任何其他身份验证。有关详细信息,请参见信任认证。

reject
无条件拒绝连接。这对于从组中“过滤掉”某些主机非常有用,例如,reject行可以阻止特定主机的连接,而稍后的行允许特定网络中的其余主机连接。

scram-sha-256
执行SCRAM-SHA-256身份验证以验证用户的密码。有关详细信息,请参见密码认证。

md5
执行SCRAM-SHA-256或MD5身份验证以验证用户的密码。有关详细信息,请参见密码认证。

sm3
执行SM3认证来验证用户的口令。有关详细信息,请参见密码认证。

password
要求客户端提供未加密的密码进行身份验证。由于密码以明文形式通过网络发送,因此不应在不受信任的网络上使用。有关详细信息,请参见密码认证。

gss
使用GSSAPI对用户进行身份验证。这仅适用于TCP/IP连接。有关详细信息,请参见GSSAPI认证。它可以与GSSAPI加密一起使用。

sspi
使用SSPI对用户进行身份验证。这仅适用于Windows。有关详细信息,请参见SSPI认证。

ident
通过联系客户端上的ident服务器获取客户端的操作系统用户名,并检查它是否与请求的数据库用户名匹配。Ident身份验证仅适用于TCP/IP连接。当为本地连接指定时,将改用对等身份验证。有关详细信息,请参见Ident认证。

peer
从操作系统获取客户端的操作系统用户名,并检查它是否与请求的数据库用户名匹配。这仅适用于本地连接。有关详细信息,请参见Peer认证。

ldap
使用LDAP服务器进行身份验证。有关详细信息,请参见LDAP认证。

radius
使用RADIUS服务器进行身份验证。有关详细信息,请参见RADIUS认证。

cert
使用SSL客户端证书进行身份验证。有关详细信息,请参见证书认证。

pam
使用操作系统提供的可插拔身份验证模块(PAM)服务进行身份验证。有关详细信息,请参见PAM认证。

bsd
使用提供的BSD身份验证服务进行身份验证操作系统。有关详细信息,请参见BSD认证。

auth-options
在 auth-method 字段之后,可以有以下形式的字段: name = value ,用于指定身份验证方法的选项。有关可用于哪些身份验证方法的选项的详细信息,请参见下面的内容。

除了下面列出的特定于方法的选项之外,还有一个独立于方法的身份验证选项clientcert,可以在任何hostssl记录中指定。此选项可以设置为verify-ca或verify-full。这两个选项都要求客户端提供有效(受信任的)SSL证书,而verify-full还强制要求证书中的cn(公共名称)与用户名或适用的映射相匹配。这种行为类似于cert身份验证方法(请参见证书认证),但使得可以将客户端证书的验证与支持hostssl条目的任何身份验证方法配对使用。

在使用客户端证书身份验证的任何记录上(即使用cert身份验证方法或使用clientcert选项的记录),可以使用clientname选项指定要匹配的客户端证书凭据的哪个部分。此选项可以有两个值。如果指定clientname=CN,这是默认值,则用户名与证书的Common Name (CN)匹配。如果您指定clientname=DN,则用户名与证书的整个Distinguished Name (DN)匹配。这个选项最好与用户名映射一起使用。比较使用RFC 2253格式中的DN进行。要以此格式查看客户端证书的DN,请执行以下操作:

openssl x509 -in myclient.crt -noout --subject -nameopt RFC2253 | sed "s/^subject=//"

在使用此选项时需要注意,特别是在使用正则表达式匹配DN时。

通过@结构包含的文件被读取为名称列表,可以用空格或逗号分隔。注释与ux_hba.conf中一样,由#引入,允许嵌套的@结构。除非@后面的文件名是绝对路径,否则它将被视为相对于包含引用文件的目录。

由于ux_hba.conf记录对于每个连接尝试进行顺序检查,因此记录的顺序很重要。通常,早期记录将具有紧密的连接匹配参数和较弱的身份验证方法,而后期记录将具有较松的匹配参数和较强的身份验证方法。例如,可能希望对本地TCP/IP连接使用trust身份验证,但对远程TCP/IP连接需要密码。在这种情况下,指定对来自127.0.0.1的连接进行trust身份验证的记录将比较合适。出现在记录中,指定密码认证的更广泛范围的允许客户端IP地址。

ux_hba.conf文件在启动时和主服务器进程接收到SIGHUP信号时被读取。如果您在活动系统上编辑文件,则需要向uxmaster发出信号(使用ux_ctl reload,调用SQL函数ux_reload_conf()或使用kill -HUP)以使其重新读取文件。

注意

前面的说明在Microsoft Windows上不为真:在Windows上,ux_hba.conf文件中的任何更改会立即被应用到后续的新连接上。

系统视图 ux_hba_file_rules 可用于预测试对ux_hba.conf文件的更改,或者在加载文件未产生所需效果时诊断问题。视图中具有非空error字段的行表示文件中相应行中的问题。

提示

要连接到特定数据库,用户不仅必须通过ux_hba.conf检查,还必须具有数据库的CONNECT权限。如果您希望限制哪些用户可以连接到哪些数据库,通常更容易通过授予/撤销CONNECT权限来控制,而不是将规则放在ux_hba.conf条目中。

ux_hba.conf条目的示例如下。有关不同身份验证方法的详细信息,请参见认证方法。

示例ux_hba.conf项

# 允许本地系统上的任何用户使用Unix域套接字(本地连接的默认值)连接到任何数据库,使用任何数据库用户名。
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             all                                     trust

# 使用本地回环TCP/IP连接的相同方式。
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             127.0.0.1/32            trust

# 与上一行相同,但使用单独的netmask列
#
# TYPE  DATABASE        USER            IP-ADDRESS      IP-MASK             METHOD
host    all             all             127.0.0.1       255.255.255.255     trust

# 通过IPv6进行相同的操作。
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             ::1/128                 trust

# 使用主机名进行相同的操作(通常涵盖IPv4和IPv6)。
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             localhost               trust

# 允许来自IP地址为192.168.93.x的任何主机上的任何用户连接到数据库“uxdb”,作为ident报告的相同用户名(通常是操作系统用户名)。
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    uxdb        all             192.168.93.0/24         ident

# 如果正确提供了用户的密码,则允许来自主机192.168.12.10的任何用户连接到数据库“uxdb”。
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    uxdb        all             192.168.12.10/32        scram-sha-256# 允许来自 example.com 域中的任何主机的用户连接到任何数据库,如果用户正确提供密码。
#
# 对于大多数用户,要求使用 SCRAM 认证,但对于使用不支持 SCRAM 认证的旧客户端的用户“mike”进行例外处理。
#
# 类型  数据库        用户            地址                 方法
host    all             mike            .example.com            md5
host    all             all             .example.com            scram-sha-256

# 在没有前面的“host”行的情况下,这三行将拒绝来自 192.168.54.1 的所有连接(因为该条目将首先匹配),但允许来自互联网的任何其他地方的 GSSAPI 加密连接。 零掩码不考虑主机 IP 地址的任何位,因此它匹配任何主机。 允许未加密的 GSSAPI 连接(因为“hostgssenc”仅匹配加密的 GSSAPI 连接而“落入”第三行),但仅允许来自 192.168.12.10。
#
# 类型  数据库        用户            地址                 方法
host    all             all             192.168.54.1/32         reject
hostgssenc all          all             0.0.0.0/0               gss
host    all             all             192.168.12.10/32        gss

# 如果来自 192.168.x.x 主机的用户通过 ident 检查,则允许他们连接到任何数据库。 例如,如果 ident 表示用户是“bryanh”,并且他请求连接为 UXDB 用户“guest1”,则仅当 ux_ident.conf 中有一个映射“omicron”的条目,该条目表示“bryanh”被允许作为“guest1”连接时,才允许连接。
#
# 类型  数据库        用户            地址                 方法
host    all             all             192.168.0.0/16          ident map=omicron

# 如果这是本地连接的唯一三行,则仅允许本地用户连接到自己的数据库(与其数据库用户名相同的数据库),除了管理员和角色“support”的成员,他们可以连接到所有数据库。 文件 $UXDATA/admins 包含管理员名称列表。 在所有情况下都需要密码。
#
# 类型  数据库        用户            地址                 方法
local   sameuser        all                                     md5
local   all             @admins                                 md5
local   all             +support                                md5

# 上面的最后两行可以合并为一行:
local   all             @admins,+support                        md5

# 数据库列也可以使用列表和文件名:
local   db1,db2,@demodbs  all                                   md5

4.2.用户名映射

当使用诸如 Ident 或 GSSAPI等外部认证系统时,发起连接的操作系统用户的名称可能与要使用的数据库用户(角色)名称不同。在这种情况下,可以应用用户名映射将操作系统用户名映射到数据库用户。要使用用户名映射,请在ux_hba.conf 中的选项字段中指定map= map-name 。此选项支持所有接收外部用户名的认证方法。由于不同的连接可能需要不同的映射,因此在ux_hba.conf 中指定要使用的映射的名称以指示每个单独连接要使用哪个映射。

用户名映射在 ident 映射文件中定义,默认情况下该文件名为ux_ident.conf,存储在群集的数据目录中。(但是,可以将映射文件放在其他位置;请参见ident_file配置参数。)ident 映射文件包含以下一般形式的行:

map-name system-username database-username

注释、空格和行续行符的处理方式与 ux_hba.conf 中的处理方式相同。 map-name 是一个任意名称,将用于在ux_hba.conf 中引用此映射。另外两个字段指定操作系统用户名和匹配的数据库用户名。同一个 map-name 可以重复使用,以指定单个映射中的多个用户映射。

没有关于给定操作系统用户可以对应多少个数据库用户或反之的限制。因此,映射中的条目应被视为意味着“此操作系统用户被允许作为此数据库用户连接”,而不是“此操作系统用户只能作为此数据库用户连接”。如果存在任何映射条目将从外部认证系统获取的用户名与用户请求连接的数据库用户名配对,则允许连接。

如果 system-username 字段以斜杠(/)开头,则该字段的其余部分将被视为正则表达式。正则表达式可以包含单个捕获或括号子表达式,然后可以在 database-username 字段中引用为\1(反斜杠一)。这允许在单个行中映射多个用户名,这对于简单的语法替换特别有用。例如,这些条目:

mymap   /^(.*)@mydomain\.com$      \1
mymap   /^(.*)@otherdomain\.com$   guest

将删除以@mydomain.com结尾的系统用户名的域部分,并允许以@otherdomain.com结尾的任何用户作为guest登录。

请记住,默认情况下,正则表达式可以匹配字符串的一部分。通常最好使用^和$,如上例所示,以强制匹配整个系统用户名。

ux_ident.conf文件在启动时和主服务器进程接收到SIGHUP信号时读取。如果在活动系统上编辑文件,则需要向uxmaster发送信号(使用ux_ctl reload,调用SQL函数ux_reload_conf()或使用kill -HUP)以使其重新读取文件。系统视图 ux_ident_file_mappings 可用于预测试对ux_ident.conf文件的更改,或者在加载文件没有产生预期效果时进行诊断。视图中具有非空error字段的行指示文件中相应行中的问题。

可以与示例ux_hba.conf项中的ux_hba.conf文件一起使用的ux_ident.conf文件如ux_ident.conf文件示例所示。在此示例中,未登录到192.168网络上没有操作系统用户名bryanh、ann或robert的任何人都将不被授予访问权限。只有当Unix用户robert尝试作为UXsinoDB用户bob而不是作为robert或其他任何人时,才允许访问robert。只有ann被允许作为ann连接。用户bryanh将被允许作为bryanh或guest1连接。

ux_ident.conf文件示例

# MAPNAME       SYSTEM-USERNAME         UX-USERNAME
omicron         bryanh                  bryanh
omicron         ann                     ann
# bob has user name robert on these machines
omicron         robert                  bob
# bryanh can also connect as guest1
omicron         bryanh                  guest1

4.3.认证方法

UXsinoDB 提供了多种认证用户的方法:

  • 信任认证,简单地相信用户所说的身份。

  • 密码认证,要求用户发送密码。

  • GSSAPI认证,依赖于 GSSAPI兼容的安全库。通常用于访问认证服务器,如 Kerberos 或 MicrosoftActive Directory 服务器。

  • SSPI认证,使用类似于 GSSAPI 的 Windows 特定协议。

  • Ident认证,依赖于客户端机器上的“身份验证协议”(RFC1413)服务。(在本地 Unix 套接字连接中,这被视为对等身份验证。)

  • Peer认证,依赖于操作系统的功能来识别本地连接另一端的进程。不支持远程连接。

  • LDAP认证,依赖于 LDAP 认证服务器。

  • RADIUS认证,依赖于 RADIUS 认证服务器。

  • 证书认证,需要 SSL 连接,并通过检查用户发送的 SSL证书来认证用户。

  • PAM认证,依赖于PAM(可插入身份验证模块)库。

  • BSD认证,依赖于BSD身份验证框架(目前仅在OpenBSD上可用)。

对于本地连接,通常建议使用对等身份验证,尽管在某些情况下信任身份验证可能足够。密码身份验证是远程连接的最简单选择。所有其他选项都需要某种外部安全基础设施(通常是身份验证服务器或用于发行SSL证书的证书颁发机构),或者是特定于平台的。

以下各节详细描述了每种身份验证方法。

4.4.信任认证

当指定trust认证时,UXsinoDB假定任何能够连接到服务器的人都被授权使用任何数据库用户名(甚至是超级用户名称)访问数据库。当然,database和user列中的限制仍然适用。只有在连接到服务器的操作系统级别保护足够时才应使用此方法。

trust认证适用于单用户工作站上的本地连接,非常方便。但是,在多用户机器上,通常不适合仅使用trust认证。但是,如果使用文件系统权限限制对服务器的Unix域套接字文件的访问,则可以在多用户机器上使用trust。为此,请按照连接和身份验证中所述设置unix_socket_permissions(以及可能的unix_socket_group)配置参数。或者,您可以设置unix_socket_directories配置参数,将套接字文件放置在适当受限制的目录中。

仅设置文件系统权限有助于Unix套接字连接。本地TCP/IP连接不受文件系统权限限制。因此,如果要使用文件系统权限进行本地安全,请从ux_hba.conf中删除host ... 127.0.0.1...行,或将其更改为非trust认证方法。

如果信任允许连接到服务器的每个机器上的每个用户,则trust认证仅适用于TCP/IP连接。除来自localhost(127.0.0.1)的连接外,很少有理由在任何TCP/IP连接中使用trust。

4.5.密码认证

有几种基于密码的认证方法。这些方法的操作方式类似,但在服务器上存储用户密码的方式以及客户端提供的密码在连接中的传输方式不同。

scram-sha-256
方法scram-sha-256执行SCRAM-SHA-256认证,如RFC 7677所述。这是一种挑战-响应方案,可以防止在不受信任的连接上嗅探密码,并支持在服务器上以加密哈希形式存储密码,被认为是安全的。

这是目前提供的最安全的方法,但旧的客户端库不支持它。

md5
方法md5使用自定义的不太安全的挑战-响应机制。它可以防止密码嗅探,并避免以明文形式在服务器上存储密码,但如果攻击者成功窃取服务器上的密码哈希,则无法提供保护。此外,MD5哈希算法现在不再被认为是安全的,容易受到有决心的攻击。

md5方法不能与db_user_namespace功能一起使用。

为了方便从md5方法过渡到较新的SCRAM方法,如果在ux_hba.conf中指定了md5方法,但服务器上的用户密码已加密为SCRAM(见下文),则将自动选择基于SCRAM的认证。

sm3
sm3是中华人民共和国政府采用的一种密码散列函数标准,相关标准为“GM/T0004-2012《sm3密码杂凑算法》”。当进行口令认证时,会在传输前结合用户名和salt(服务器发送给客户端的随机数)对密码进行单向sm3加密,以增加安全性。用户认证方式为sm3时,仅支持加密方式为sm3的用户可登录。

password
方法password以明文形式发送密码,因此容易受到密码“嗅探”攻击。如果可能,应始终避免使用它。如果连接受到SSL保护,则可以使用它。

如果进行了加密,password 就可以安全使用,但是如果依赖于使用 SSL,则 SSL 证书认证可能是更好的选择。

UXsinoDB 数据库密码与操作系统用户密码是分开的。每个数据库用户的密码存储在 ux_authid 系统目录中。密码可以使用 SQL命令 CREATE ROLE 和 ALTER ROLE 进行管理,例如 CREATE ROLE foo WITH LOGIN PASSWORD 'secret' 或 uxsql 命令 \password。如果没有为用户设置密码,则存储的密码为null,该用户的密码身份验证将始终失败。

不同基于密码的身份验证方法的可用性取决于服务器上用户密码的加密方式(或更准确地说,哈希方式)。这由在设置密码时的配置参数password_encryption控制。如果使用 scram-sha-256 设置加密密码,则可以将其用于身份验证方法 scram-sha-256 和password(但在后一种情况下,密码传输将以明文形式进行)。身份验证方法规范 md5 将自动切换到使用scram-sha-256 方法,如上所述,因此它也可以工作。如果使用 md5 设置加密密码,则只能将其用于 md5 和password 身份验证方法规范(同样,在后一种情况下,密码以明文形式传输)。要检查当前存储的密码哈希,请参阅系统目录ux_authid。

要从 md5 升级到 scram-sha-256 的现有安装,必须确保所有正在使用的客户端库都足够新以支持 SCRAM,在uxsinodb.conf 中设置 password_encryption ='scram-sha-256',使所有用户设置新密码,并将 ux_hba.conf中的身份验证方法规范更改为 scram-sha-256。

4.6.GSSAPI认证

GSSAPI 是一个安全认证的行业标准协议,定义在RFC 2743 中。 UXDB 支持 GSSAPI用于认证、通信加密或两者兼备。 GSSAPI 提供了支持它的系统的自动认证(单点登录)。 认证本身是安全的。 如果使用了 GSSAPI加密或 SSL 加密,则沿数据库连接发送的数据将被加密;否则,它将不会被加密。

必须在构建 UXDB 时启用 GSSAPI 支持。

当 GSSAPI 使用 Kerberos 时,它使用格式为servicename/hostname@realm 的标准服务主体(认证身份)名称。 特定安装使用的主体名称不会以任何方式编码在 UXDB服务器中;而是在服务器读取以确定其身份的 keytab 文件中指定。 如果 keytab文件中列出了多个主体,则服务器将接受其中任何一个。 服务器的领域名称是服务器可访问的 Kerberos配置文件中指定的首选领域。

在连接时,客户端必须知道要连接到的服务器的主体名称。 主体的 servicename 部分通常为 uxdb,但可以通过libuxsql 的 krbsrvname连接参数选择另一个值。 hostname 部分是完全限定的主机名,libuxsql被告知要连接到该主机。

领域名称是客户端可访问的Kerberos配置文件中指定的首选领域。客户端还将拥有自己身份的主体名称(并且必须拥有此主体的有效票证)。要使用GSSAPI进行身份验证,客户端主体必须与UXsinoDB数据库用户名相关联。可以使用ux_ident.conf配置文件将主体映射到用户名;例如,uxusername@realm可以映射到uxusername。或者,您可以在UXsinoDB中使用完整的username@realm主体作为角色名,而无需进行任何映射。

UXsinoDB还支持通过仅从主体中删除领域来将客户端主体映射到用户名。此方法支持向后兼容性,但强烈不建议使用,因为这样就无法区分来自不同领域但具有相同用户名的不同用户。要启用此功能,请将include_realm设置为0。对于简单的单领域安装,结合设置krb_realm参数(检查主体的领域是否与krb_realm参数中的完全匹配)仍然是安全的;但与在ux_ident.conf中指定显式映射相比,这是一种功能较弱的方法。

服务器的keytab文件位置由krb_server_keyfile配置参数指定。出于安全原因,建议为UXsinoDB服务器使用单独的keytab文件,而不是允许服务器读取系统keytab文件。确保您的服务器keytab文件可被UXsinoDB服务器帐户读取(最好只读,不可写)。

keytab文件是使用Kerberos软件生成的;有关详细信息,请参见Kerberos文档。以下示例显示了使用MIT兼容的Kerberos5实现的kadmin工具执行此操作:

kadmin% addprinc -randkey uxdb/server.my.domain.org
kadmin% ktadd -k krb5.keytab uxdb/server.my.domain.org

以下身份验证选项支持GSSAPI身份验证方法:

include_realm
如果设置为0,则通过用户名映射传递之前,将从经过身份验证的用户主体中剥离领域名称。这是不安全的,主要是为了向后兼容性,除非也使用krb_realm在多领域环境中使用。建议将include_realm保留为默认值(1),并在ux_ident.conf中提供显式映射以将主体名称转换为UXsinoDB用户名称。

map
允许从客户端主体映射到数据库用户名。有关详细信息,请参见用户名映射。对于GSSAPI /Kerberos身份验证,可以使用此选项。例如,username@EXAMPLE.COM(或者更少见的username/hostbased@EXAMPLE.COM)等主体,用于映射的用户名为username@EXAMPLE.COM(或者分别为username/hostbased@EXAMPLE.COM),除非将include_realm设置为0,在这种情况下,映射时所看到的系统用户名为username(或者username/hostbased)。

krb_realm
设置要匹配用户主体名称的领域。如果设置了此参数,则仅接受该领域的用户。如果未设置,则可以连接任何领域的用户,但要根据所做的任何用户名映射进行。

除了这些设置外,对于不同的ux_hba.conf条目,还有服务器范围的krb_caseins_users配置参数。如果将其设置为true,则客户端主体与用户映射条目不区分大小写匹配。如果设置了krb_realm,则也不区分大小写匹配。

4.7.SSPI认证

SSPI是一种用于单点登录的安全身份验证技术,适用于Windows系统。在“协商”模式下,UXsinoDB将使用Kerberos进行身份验证,如果不行,则自动回退到NTLM。只有在服务器和客户端都运行在Windows系统上,或在非Windows平台上,GSSAPI可用时,才能使用SSPI身份验证。

使用Kerberos身份验证时,SSPI的工作方式与GSSAPI相同;有关详细信息,请参见GSSAPI认证。

下列被支持的配置选项用于SSPI:

include_realm
如果设置为0,则通过用户名映射传递之前,将从已验证的用户主体中剥离领域名称。这是不安全的,主要是为了向后兼容而提供的,除非也使用了krb_realm,否则在多领域环境中不安全。建议将include_realm设置为默认值(1),并在ux_ident.conf中提供显式映射,将主体名称转换为UXsinoDB用户名称。

compat_realm
如果被设置为 1,该域的 SAM 兼容名称(也被称为 NetBIOS 名称)被用于include_realm选项。这是默认值。如果被设置为 0,会使用来自 Kerberos 用户主名的真实realm名称。

不要禁用这个选项,除非你的服务器运行在一个域账号(这包括一个域成员系统上的虚拟服务账号)下并且所有通过 SSPI 认证的所有客户端也在使用域账号,否则认证将会失败。

upn_username
如果启用了此选项以及 compat_realm,则使用 Kerberos UPN 的用户名进行身份验证。如果禁用它(默认情况下),则使用SAM 兼容的用户名。默认情况下,这两个名称对于新用户帐户是相同的。

请注意,如果未指定显式用户名,则 libuxsql 使用 SAM 兼容名称。如果您使用 libuxsql或基于它的驱动程序,则应禁用此选项或在连接字符串中明确指定用户名。

map
允许在系统用户和数据库用户名称之间进行映射。有关详细信息,请参见用户名映射。对于 SSPI/Kerberos 主体,例如username@EXAMPLE.COM(或较少见的 username/hostbased@EXAMPLE.COM),用于映射的用户名是username@EXAMPLE.COM(或 username/hostbased@EXAMPLE.COM),除非将include_realm 设置为 0,在这种情况下,当进行映射时,所看到的系统用户名是 username(或username/hostbased)。

krb_realm
设置要与用户主体名称匹配的领域。如果设置了此参数,则仅接受该领域的用户。如果未设置,则可以连接任何领域的用户,视情况进行用户名映射。

4.8.Ident认证

ident 认证方法通过从 ident 服务器获取客户端操作系统用户名并将其用作允许的数据库用户名(带有可选的用户名映射)来工作。这仅支持TCP/IP 连接。

注意

当为本地(非 TCP/IP)连接指定 ident 时,将使用对等身份验证(参见Peer认证)。

下列被支持的配置选项用于ident:

map
允许在系统和数据库用户名之间进行映射。有关详细信息,请参见用户名映射。

“Identification Protocol”在RFC 1413中有描述。几乎每个类 Unix的操作系统都默认安装了一个在 TCP 端口 113 上监听的 ident 服务器。ident服务器的基本功能是回答类似于“你的端口 X 上发出的连接连接到我的端口 Y 的用户是谁?”这样的问题。因为当建立物理连接时,UXsinoDB 知道 X 和 Y ,所以它可以在连接客户端的主机上查询 ident服务器,并理论上确定任何给定连接的操作系统用户。

这种过程的缺点是它依赖于客户端的完整性:如果客户端机器不受信任或被攻击,攻击者可以在端口 113上运行几乎任何程序并返回任何他们选择的用户名。因此,此身份验证方法仅适用于每个客户端机器都受到严格控制且数据库和系统管理员密切联系的封闭网络。换句话说,您必须信任运行ident 服务器的机器。请注意警告:

身份验证协议不是授权或访问控制协议。 --RFC 1413

一些标识服务器具有非标准选项,该选项会导致返回的用户名被加密,使用只有原始机器管理员知道的密钥。当使用标识服务器与UXsinoDB时,不得使用此选项,因为UXsinoDB没有任何方法解密返回的字符串以确定实际用户名。

4.9.Peer认证

对等身份验证方法通过从内核获取客户端的操作系统用户名并将其用作允许的数据库用户名(具有可选的用户名映射)来工作。此方法仅在本地连接上受支持。

以下配置选项支持peer:

map
允许在系统和数据库用户名之间进行映射。有关详细信息,请参见用户名映射。

对等身份验证仅在提供getpeereid()函数、SO_PEERCRED套接字参数或类似机制的操作系统上可用。目前包括Linux、大多数BSD,包括macOS和Solaris。

4.10.LDAP认证

此身份验证方法与密码类似,但它使用LDAP作为密码验证方法。LDAP仅用于验证用户名/密码对。因此,在使用LDAP进行身份验证之前,用户必须已经存在于数据库中。

LDAP身份验证可以在两种模式下运行。在第一种模式下,我们将其称为简单绑定模式,服务器将绑定到构造的区分名称,如 prefix username suffix 。通常, prefix 参数用于指定cn=或 DOMAIN\在Active Directory环境中。在非Active Directory环境中, suffix 用于指定DN的其余部分。

在第二种模式下,我们将其称为搜索+绑定模式,服务器首先使用指定的固定用户名和密码(使用 ldapbinddn 和 ldapbindpasswd )绑定到LDAP目录,并搜索尝试登录到数据库的用户。如果未配置用户和密码,则将尝试匿名绑定到目录。搜索将在 ldapbasedn 的子树上执行,并尝试精确匹配 ldapsearchattribute 中指定的属性。一旦在此搜索中找到用户,服务器将断开连接并重新绑定到目录作为此用户,使用客户端指定的密码验证登录是否正确。此模式与其他软件中使用的LDAP身份验证方案(例如Apache mod_authnz_ldap和pam_ldap)相同。此方法允许用户对象在目录中的位置更加灵活,但将导致对LDAP服务器进行两个单独的连接。

以下配置选项在两种模式下均可使用:

ldapserver
连接的LDAP服务器的名称或IP地址。可以指定多个服务器,用空格分隔。

ldapport
连接的LDAP服务器的端口号。如果未指定端口,则使用LDAP库的默认端口设置。

ldapscheme
设置为ldaps以使用LDAPS。这是一种非标准的使用LDAP over SSL的方式,由一些LDAP服务器实现支持。另请参见ldaptls选项以获取另一种选择。

ldaptls
设置为1以使UXsinoDB和LDAP服务器之间的连接使用TLS加密。这使用RFC 4513的StartTLS操作。另请参见ldapscheme选项以获取另一种选择。

请注意,仅使用ldapscheme或ldaptls仅加密UXsinoDB服务器和LDAP服务器之间的流量。除非在此处也使用SSL,否则UXsinoDB服务器和UXsinoDB客户端之间的连接仍将未加密。

以下选项仅在简单绑定模式下使用:

ldapprefix
在形成要绑定的DN时,要添加到用户名前面的字符串,以进行简单绑定身份验证。

ldapsuffix
在形成要绑定的DN时,要添加到用户名后面的字符串,以进行简单绑定身份验证。

以下选项仅在搜索+绑定模式下使用:

ldapbasedn
进行搜索+绑定身份验证时要开始搜索用户的根DN。

ldapbinddn
要绑定到目录以执行搜索的用户的DN,当进行搜索+绑定身份验证时。

ldapbindpasswd
要绑定到目录以执行搜索的用户的密码,当进行搜索+绑定身份验证时。

ldapsearchattribute
在搜索+绑定身份验证中匹配用户名称的属性。如果未指定属性,则使用uid属性。

ldapsearchfilter
进行搜索+绑定身份验证时要使用的搜索过滤器。$username的出现将替换为用户名。这允许使用比ldapsearchattribute更灵活的搜索过滤器。

ldapurl
RFC 4516 LDAPURL。这是一种以更紧凑和标准的形式编写某些其他LDAP选项的替代方法。格式为

ldap[s]://host[:port]/basedn[?[attribute][?[scope][?[filter]]]]

scope 必须是 base、one 或 sub 中的一个,通常是最后一个(默认值为base,在此应用程序中通常无用)。 attribute 可以指定单个属性,此时它将用作 ldapsearchattribute的值。如果 attribute 为空,则 filter 可以用作 ldapsearchfilter 的值。

URL 方案 ldaps 选择使用 LDAPS 方法通过 SSL 进行 LDAP 连接,相当于使用ldapscheme=ldaps。要使用使用 StartTLS 操作进行加密的 LDAP 连接,请使用普通的 URL 方案ldap,并除了 ldapurl 之外还指定 ldaptls 选项。

对于非匿名绑定,必须将 ldapbinddn 和 ldapbindpasswd 指定为单独的选项。

LDAP URL 目前仅受OpenLDAP支持,不支持 Windows。

将简单绑定的配置选项与搜索+绑定的选项混合使用是错误的。

在使用搜索+绑定模式时,可以使用单个属性指定搜索,该属性由 ldapsearchattribute 指定,或者使用由ldapsearchfilter 指定的自定义搜索过滤器。指定 ldapsearchattribute=foo 等效于指定ldapsearchfilter="(foo=$username)"。如果未指定任何选项,则默认值为ldapsearchattribute=uid。

如果UXsinoDB使用OpenLDAP作为 LDAP 客户端库进行编译,则可以省略 ldapserver设置。在这种情况下,将通过RFC 2782DNS SRV 记录查找主机名和端口列表。查找名称为 _ldap._tcp.DOMAIN,其中 DOMAIN 是从ldapbasedn 中提取的。

以下是简单绑定 LDAP配置的示例:

host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"

当请求以数据库用户 someuser 的身份连接到数据库服务器时,UXsinoDB 将尝试使用由客户端提供的密码绑定到 LDAP服务器,使用 DN cn=someuser, dc=example,dc=net。如果该连接成功,则授予数据库访问权限。

以下是搜索+绑定配置的示例:

host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid

当请求以数据库用户 someuser 的身份连接到数据库服务器时,UXsinoDB 将尝试匿名绑定(因为未指定ldapbinddn)到 LDAP 服务器,使用指定基本 DN 下的 (uid=someuser)进行搜索。如果找到条目,则尝试使用找到的信息和客户端提供的密码进行绑定。如果第二个连接成功,则授予数据库访问权限。

以下是相同的搜索+绑定配置,以 URL形式编写:

host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub"

一些其他支持针对 LDAP进行身份验证的软件使用了该配置。相同的URL格式,因此共享配置将更容易。

以下是一个搜索+绑定配置的示例,它使用ldapsearchfilter而不是ldapsearchattribute,以允许通过用户ID或电子邮件地址进行身份验证:

host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchfilter="(|(uid=$username)(mail=$username))"

以下是一个搜索+绑定配置的示例,它使用DNS SRV发现来查找域名example.net的LDAP服务的主机名和端口:

host ... ldap ldapbasedn="dc=example,dc=net"

提示

由于LDAP通常使用逗号和空格来分隔DN的不同部分,因此在配置LDAP选项时通常需要使用双引号括起来的参数值,如示例所示。

4.11.RADIUS认证

此认证方法类似于password,但它使用 RADIUS 作为密码验证方法。RADIUS 仅用于验证用户名/密码对。因此,在使用RADIUS 进行身份验证之前,用户必须已经存在于数据库中。

使用 RADIUS 认证时,将向配置的 RADIUS 服务器发送访问请求消息。此请求将是Authenticate Only类型,并包括user name、password(加密)和NAS Identifier参数。请求将使用与服务器共享的密钥进行加密。RADIUS服务器将以Access Accept或Access Reject响应此请求。不支持 RADIUS accounting。

可以指定多个 RADIUS服务器,此时它们将按顺序尝试。如果从服务器收到负面响应,则身份验证将失败。如果没有收到响应,则将尝试列表中的下一个服务器。要指定多个服务器,请使用逗号将服务器名称分隔开,并用双引号括起整个列表。如果指定了多个服务器,则还可以将其他RADIUS 选项指定为逗号分隔的列表,以为每个服务器提供单独的值。它们也可以指定为单个值,在这种情况下,该值将适用于所有服务器。

支持以下 RADIUS 配置选项:

radiusservers
要连接的 RADIUS 服务器的 DNS 名称或 IP 地址。此参数是必需的。

radiussecrets
在与 RADIUS 服务器进行安全通信时使用的共享密钥。在 UXDB 和 RADIUS服务器上必须具有完全相同的值。建议使用至少 16个字符的字符串。此参数是必需的。

注意

只有在构建了支持 OpenSSL 的 UXDB 时,所使用的加密向量才具有加密强度。在其他情况下,传输到 RADIUS 服务器应该只被认为是模糊的,而不是安全的,如果需要,应该应用外部安全措施。

radiusports
要连接到RADIUS服务器的端口号。如果没有指定端口,则将使用默认的RADIUS端口(1812)。

radiusidentifiers
要在RADIUS请求中用作NAS Identifier的字符串。例如,可以使用此参数来标识用户尝试连接的数据库集群,这对于在RADIUS服务器上进行策略匹配非常有用。如果未指定标识符,则将使用默认值uxsinodb。

如果需要在RADIUS参数值中有逗号或空格,可以通过在值周围放置双引号来实现,但这很繁琐,因为现在需要两层双引号。将空格放入RADIUS密钥字符串的示例是:

host ... radius radiusservers="server1,server2" radiussecrets="""secret one"",""secret two"""

4.12.证书认证

此认证方法使用 SSL 客户端证书进行认证。因此,它仅适用于 SSL连接。使用此认证方法时,服务器将要求客户端提供有效的、可信任的证书。不会向客户端发送密码提示。证书的“通用名称”属性将与请求的数据库用户名进行比较,如果它们匹配,则允许登录。用户名映射可用于允许“通用名称”与数据库用户名不同。

支持以下 SSL证书认证的配置选项:

map
允许在系统和数据库用户名之间进行映射。有关详细信息,请参见用户名映射。

对证书认证使用clientcert选项是多余的,因证书认证实际上是使用clientcert=valid-full进行信任身份验证。

4.13.PAM认证

此认证方法与password类似,但它使用 PAM(可插拔认证模块)作为认证机制。默认的 PAM 服务名称是uxsinodb。PAM 仅用于验证用户名/密码对以及可选的连接远程主机名或 IP 地址。因此,在使用 PAM进行认证之前,用户必须已经存在于数据库中。有关 PAM的更多信息,请阅读Linux-PAM页面。

以下是 PAM 支持的配置选项:

pamservice
PAM 服务名称。

pam_use_hostname
确定是否通过 PAM_RHOST 项将远程 IP 地址或主机名提供给 PAM 模块。默认情况下,使用 IP 地址。将此选项设置为1,以改为使用已解析的主机名。主机名解析可能会导致登录延迟。(大多数 PAM 配置不使用此信息,因此只有在专门创建 PAM配置以使用此信息时才需要考虑此设置。)

注意

如果 PAM 设置为读取 /etc/shadow,则认证将失败,因为 UXDB 服务器是由非 root 用户启动的。但是,当PAM 配置为使用 LDAP 或其他认证方法时,这不是问题。

4.14.BSD认证

此身份验证方法与password类似,但它使用BSD身份验证来验证密码。BSD身份验证仅用于验证用户名/密码对。因此,在使用BSD身份验证进行身份验证之前,用户的角色必须已经存在于数据库中。BSD身份验证框架目前仅在OpenBSD上可用。

在UXsinoDB中,BSD身份验证使用auth-uxsinodb登录类型,并使用uxsinodb登录类进行身份验证,如果在login.conf中定义了该类。默认情况下,该登录类不存在,UXsinoDB将使用默认登录类。

注意

要使用BSD身份验证,必须首先将UXsinoDB用户帐户(即运行服务器的操作系统用户)添加到auth组中。在OpenBSD系统上,默认存在auth组。

4.15.认证问题

认证失败及相关问题通常会通过以下错误消息表现出来:

FATAL:  no ux_hba.conf entry for host "123.123.123.123", user "andym", database "testdb"

如果您成功连接了服务器但它不想与您通信,那么您最有可能得到的就是这个。正如消息所示,服务器拒绝了连接请求,因为在其 ux_hba.conf配置文件中找不到匹配的条目。

FATAL:  password authentication failed for user "andym"

像这样的消息表明您已经联系了服务器,它愿意与您交流,但前提是您必须通过 ux_hba.conf文件中指定的授权方法。请检查您提供的密码,或者如果投诉中提到了Kerberos 或 ident 认证类型,请检查您的 Kerberos 或 ident 软件。

FATAL:  user "andym" does not exist

指定的数据库用户名未找到。

FATAL:  database "testdb" does not exist

您尝试连接的数据库不存在。请注意,如果您没有指定数据库名称,则默认为数据库用户名,这可能是正确的,也可能不是正确的。

提示

服务器日志可能包含有关认证失败的更多信息,而不是向客户端报告的信息。如果您对失败的原因感到困惑,请检查服务器日志。

5.数据库角色

UXDB使用角色的概念管理数据库访问权限。一个角色可以被看成是一个数据库用户或者是一个数据库用户组,这取决于角色被怎样设置。角色可以拥有数据库对象(例如,表和函数)并且能够把那些对象上的权限赋予给其他角色来控制谁能访问哪些对象。此外,还可以把一个角色中的成员资格授予给另一个角色,这样允许成员角色使用被赋予给另一个角色的权限。

角色的概念把“用户”和“组”的概念都包括在内。任意角色都可以扮演用户、组或者两者。

本章描述如何创建和管理角色。

5.1.数据库角色

数据库角色在概念上与操作系统用户完全分离。实际上,保持对应关系可能很方便,但这不是必需的。数据库角色在整个数据库集群安装中是全局的(而不是每个单独的数据库)。要创建角色,请使用 CREATE ROLESQL命令:

CREATE ROLE name;

name 遵循SQL标识符的规则:要么是没有特殊字符的未装饰标识符,要么是双引号括起来的标识符。(实际上,您通常会想要添加其他选项,例如LOGIN,以便更详细的信息出现在下面。)要删除现有角色,请使用类似的 DROP ROLE 命令:

DROP ROLE name;

为了方便起见,提供了 createuser 和 dropuser 程序作为这些可以从shell命令行调用的SQL命令的包装器:

createuser name
dropuser name

要确定现有角色集,请检查ux_roles系统目录,例如:

SELECT rolname FROM ux_roles;

uxsql 程序的\du元命令也有助于列出现有角色。

为了引导数据库系统,新初始化的系统始终包含一个预定义的角色。此角色始终是一个“超级用户”,默认情况下(除非在运行initdb时更改),它将与初始化数据库集群的操作系统用户具有相同的名称。通常,此角色将被命名为uxdb。要创建更多角色,您首先必须连接到此初始角色。

每个连接到数据库服务器的连接都是使用某个特定角色的名称进行的,该角色确定了该连接中发出的命令的初始访问权限。用于特定数据库连接的角色名称由发起连接请求的客户端以应用程序特定的方式指示。例如,uxsql程序使用-U命令行选项指示要连接的角色。许多应用程序默认情况下假定当前操作系统用户的名称(包括createuser和uxsql)。因此,通常方便维护角色和操作系统用户之间的命名对应关系。

给定客户端连接可以连接的数据库角色集由客户端身份验证设置确定,如客户端认证所述。(因此,客户端不限于连接与其操作系统用户匹配的角色,就像一个人的登录名不必与他或她的真实姓名匹配一样。)由于角色身份确定连接的客户端可用的特权集,因此在设置多用户环境时重要仔细配置特权。

5.2.角色属性

数据库角色可以具有多个属性,这些属性定义了其权限并与客户端身份验证系统交互。

login privilege
只有具有 LOGIN 属性的角色才能用作数据库连接的初始角色名称。具有 LOGIN属性的角色可以被视为“数据库用户”。要创建具有登录权限的角色,请使用以下任一命令:

CREATE ROLE name LOGIN;
CREATE USER name;

(CREATE USER 等同于 CREATE ROLE,只是 CREATE USER 默认包括 LOGIN,而CREATE ROLE不包括。)

superuser status
数据库超级用户可以绕过所有权限检查,除了登录权限。这是一种危险的特权,不应轻率使用;最好将大部分工作作为非超级用户角色完成。要创建新的数据库超级用户,请使用CREATE ROLE name SUPERUSER。您必须以已经是超级用户的角色身份执行此操作。

database creation
必须明确授予角色创建数据库的权限(超级用户除外,因为它们绕过所有权限检查)。要创建此类角色,请使用 CREATE ROLE name CREATEDB。

role creation
必须明确授予角色创建更多角色的权限(超级用户除外,因为它们绕过所有权限检查)。要创建此类角色,请使用 CREATE ROLE name CREATEROLE。具有 CREATEROLE权限的角色也可以更改和删除其他角色,并授予或撤销其成员资格。然而,要创建、更改、删除或更改超级用户角色的成员身份,需要超级用户状态;CREATEROLE是不够的。

initiating replication
除了超级用户(因为超级用户绕过所有权限检查),必须明确授予角色启动流式复制的权限。用于流式复制的角色必须也具有LOGIN权限。要创建这样的角色,请使用 CREATE ROLE name REPLICATION LOGIN。

password
密码仅在客户端身份验证方法要求用户在连接到数据库时提供密码时才有意义。 password和md5身份验证方法使用密码。数据库密码与操作系统密码分开。在角色创建时指定密码,使用CREATE ROLE name PASSWORD 'string'。

inheritance of privileges
默认情况下,角色被授予继承其成员身份的权限。但是,要创建没有权限的角色,请使用CREATE ROLE name NOINHERIT。

bypassing row-level security
必须明确授予角色绕过每个行级安全(RLS)策略的权限(除超级用户外,因为超级用户绕过所有权限检查)。要创建这样的角色,请使用CREATE ROLE name BYPASSRLS作为超级用户。

connection limit
连接限制可以指定角色可以进行多少并发连接。-1(默认值)表示没有限制。在角色创建时指定连接限制,使用CREATE ROLE name CONNECTION LIMIT 'integer'。

可以使用ALTER ROLE在创建后修改角色的属性。

提示

创建具有CREATEDB和CREATEROLE特权但不是超级用户的角色,然后将此角色用于所有例行数据库和角色管理,这是一个好习惯。这种方法避免了在不需要的任务上作为超级用户操作的危险。

角色还可以具有针对服务器配置中描述的许多运行时配置设置的角色特定默认值。例如,如果出于某种原因您想要在任何时候禁用索引扫描(提示:不是一个好主意),可以使用:

ALTER ROLE myname SET enable_indexscan TO off;

这将保存设置(但不立即设置)。在此角色的后续连接中,似乎已经在会话开始前执行了SET enable_indexscan TO off。您仍然可以在会话期间更改此设置;它只会成为默认设置。要删除特定角色的默认设置,请使用ALTER ROLE rolename RESET varname 。请注意,附加到没有LOGIN权限的角色的特定角色默认设置相当无用,因为它们永远不会被调用。

5.3.角色成员

通常为了方便管理权限,将用户分组是很方便的:这样,可以将权限授予或从整个组中撤销。在UXsinoDB中,通过创建表示组的角色,然后将组角色的成员身份授予个人用户角色来实现这一点。

要设置组角色,首先创建角色:

CREATE ROLE name;

通常用作组的角色不会有LOGIN属性,但如果您愿意,可以设置它。

一旦组角色存在,您可以使用GRANT和REVOKE命令添加和删除成员:

GRANT group_role TO role1, ... ;
REVOKE group_role FROM role1, ... ;

您也可以将成员身份授予其他组角色(因为组角色和非组角色之间没有真正的区别)。数据库不会让您设置循环成员身份循环。此外,不允许将成员身份授予PUBLIC。

组角色的成员可以以两种方式使用角色的权限。首先,组的每个成员都可以显式地执行SET ROLE,以临时“成为”组角色。在此状态下,数据库会话可以访问组角色的权限,而不是原始登录角色的权限,并且创建的任何数据库对象都被视为由组角色而不是登录角色拥有。其次,具有INHERIT属性的成员角色自动具有其成员身份的角色的权限,包括由这些角色继承的任何权限。例如,假设我们已经执行了以下操作:

CREATE ROLE joe LOGIN INHERIT;
CREATE ROLE admin NOINHERIT;
CREATE ROLE wheel NOINHERIT;
GRANT admin TO joe;
GRANT wheel TO admin;

连接为角色 joe 后,数据库会话将直接使用授予 joe 的特权以及授予 admin 的任何特权,因为 joe “继承”了admin 的特权。但是,授予 wheel 的特权不可用,因为尽管 joe 是间接成员,但成员是通过具有 NOINHERIT属性的 admin 进行的。执行以下操作后:

SET ROLE admin;

会话将仅使用授予 admin 的特权,而不是授予 joe 的特权。执行以下操作后:

SET ROLE wheel;

会话将仅使用授予 wheel 的特权,而不是授予 joe 或 admin 的特权。可以使用以下任何一种方法恢复原始特权状态:

SET ROLE joe;
SET ROLE NONE;
RESET ROLE;

注意

SET ROLE 命令始终允许选择原始登录角色直接或间接成员的任何角色。因此,在上面的示例中,在成为 wheel 之前不需要成为admin。

注意

在 SQL 标准中,用户和角色之间有明确的区别,用户不会自动继承特权,而角色会。可以通过为用作 SQL 角色的角色赋予 INHERIT属性,为用作 SQL 用户的角色赋予 NOINHERIT 属性来获得此行为。但是,UXsinoDB 默认为所有角色提供INHERIT 属性,以向后兼容用户始终可以使用授予给他们所属组的权限。

角色属性 LOGIN、SUPERUSER、CREATEDB 和 CREATEROLE可以被视为特殊特权,但它们永远不会像普通特权一样继承到数据库对象上。您必须实际上使用具有这些属性之一的特定角色来使用该属性。继续上面的示例,我们可以选择将CREATEDB 和 CREATEROLE 授予 admin 角色。然后,作为角色 joe连接的会话将不会立即拥有这些特权,只有在执行 SET ROLEadmin 后才会拥有。

要销毁组角色,请使用 DROP ROLE:

DROP ROLE name;

任何组角色的成员身份都将自动撤销(但成员角色不受影响)。

5.4.删除角色

由于角色可以拥有数据库对象并持有访问其他对象的权限,因此删除角色通常不仅仅是一个快速的DROP ROLE命令。角色拥有的任何对象必须首先被删除或重新分配给其他所有者;并且必须撤销授予角色的任何权限。

可以使用ALTER命令逐个转移对象的所有权,例如:

ALTER TABLE bobs_table OWNER TO alice;

或者,可以使用REASSIGN OWNED命令将待删除角色拥有的所有对象的所有权重新分配给单个其他角色。由于REASSIGN OWNED无法访问其他数据库中的对象,因此需要在包含待删除角色拥有对象的每个数据库中运行它。(请注意,第一个REASSIGN OWNED将更改任何由待删除角色拥有的跨数据库共享的对象,即数据库或表空间的所有权。)

一旦任何有价值的对象已转移到新所有者,任何仍由待删除角色拥有的对象都可以使用DROP OWNED命令删除。同样,此命令无法访问其他数据库中的对象,因此需要在包含待删除角色拥有对象的每个数据库中运行它。此外,DROP OWNED不会删除整个数据库或表空间,因此如果角色拥有任何未转移给新所有者的数据库或表空间,则需要手动执行此操作。

DROP OWNED还会删除授予目标角色但不属于它的对象的任何权限。由于REASSIGN OWNED不会触及这些对象,因此通常需要依次运行REASSIGN OWNED和DROP OWNED(按此顺序!)以完全删除待删除角色的依赖项。

简而言之,删除用于拥有对象的角色的最通用的方法是:

REASSIGN OWNED BY doomed_role TO successor_role;
DROP OWNED BY doomed_role; 
-- 在集群的每个数据库中重复上述命令
DROP ROLE doomed_role;

当不是所有拥有的对象都要转移到同一个继承者所有者时,最好手动处理异常,然后执行上述步骤来清理。

如果尝试DROP ROLE时仍存在依赖对象,则会发出标识需要重新分配或删除哪些对象的消息。

5.5.预定义角色

UXsinoDB 提供了一组预定义角色,这些角色提供了访问某些常用的特权功能和信息的权限。管理员(包括具有 CREATE ROLE权限的角色)可以将这些角色授予用户或其他角色,从而使这些用户可以访问指定的功能和信息。

下表预定义角色进行了描述。请注意,每个角色的具体权限可能会随着添加其他功能而发生更改。管理员应该监视发布说明以了解更改。

表 预定义角色

角色允许访问
ux_read_all_data读取所有数据(表、视图、序列),就像对这些对象具有 SELECT 权限和所有模式的 USAGE 权限一样,即使没有明确授予。此角色没有设置角色属性 BYPASSRLS。如果使用了 RLS,则管理员可能希望在授予此角色的角色上设置 BYPASSRLS。
ux_write_all_data写入所有数据(表、视图、序列),就像对这些对象具有 INSERT、UPDATE 和 DELETE 权限和所有模式的 USAGE 权限一样,即使没有明确授予。此角色没有设置角色属性 BYPASSRLS。如果使用了 RLS,则管理员可能希望在授予此角色的角色上设置 BYPASSRLS。
ux_read_all_settings读取所有配置变量,即使这些变量通常只对超级用户可见。
ux_read_all_stats读取所有 ux_stat_* 视图并使用各种与统计相关的扩展,即使是通常只对超级用户可见的那些。
ux_stat_scan_tables执行可能需要 ACCESS SHARE 表上的锁的监视函数, 可能需要很长时间。
ux_monitor读取/执行各种监视视图和函数。 此角色是 ux_read_all_settings, ux_read_all_stats 和 ux_stat_scan_tables 的成员。
ux_database_owner无。成员隐含地包括当前数据库所有者。
ux_signal_backend信号另一个后端以取消查询或终止其会话。
ux_read_server_files允许从数据库可以访问的服务器上的任何位置读取文件,使用 COPY 和 其他文件访问函数。
ux_write_server_files允许在数据库可以访问的服务器上的任何位置写入文件,使用 COPY 和 其他文件访问函数。
ux_execute_server_program允许以数据库运行的用户身份在数据库服务器上执行程序, 使用 COPY 和其他允许执行服务器端程序的函数。
ux_checkpoint允许执行 CHECKPOINT 命令。

ux_monitor,ux_read_all_settings, ux_read_all_stats 和 ux_stat_scan_tables 角色旨在允许管理员轻松配置用于监视数据库服务器的角色。它们授予一组常见的特权允许角色读取各种有用的配置设置、统计信息和 其他系统信息,通常只限于超级用户。

ux_database_owner 角色有一个隐含的、情况相关的成员,即当前数据库的所有者。像任何角色一样,它可以拥有对象或接收访问权限的授予。因此,一旦 ux_database_owner 在一个模板数据库中拥有权利,从该模板实例化的每个数据库所有者都将行使这些权利。ux_database_owner 不能是 任何角色的成员,也不能有非隐含成员。最初, 此角色拥有 public模式,因此每个数据库所有者管理模式的本地使用。

ux_signal_backend 角色旨在允许管理员启用受信任但非超级用户的角色向其他后端发送信号。目前,此角色启用发送信号取消另一个后端上的查询或终止其会话。用户授予此角色的权限,但不能向超级用户拥有的后端发送信号。

ux_read_server_files,ux_write_server_files 和 ux_execute_server_program 角色旨在允许管理员拥有 受信任但非超级用户的角色,能够访问文件并在上运行程序数据库服务器作为数据库运行的用户。由于这些角色能够访问服务器文件系统上的任何文件,它们在直接访问文件时绕过了所有数据库级别的权限检查,因此它们可能被用于获得超级用户级别的访问权限,因此在授予这些角色给用户时应该非常小心。

在授予这些角色时应该小心,确保它们仅在需要时使用,并理解这些角色授予访问特权 受限信息。

管理员可以使用以下方式向用户授予这些角色的访问权限例如,GRANT命令:

GRANT ux_signal_backend TO admin_user;

5.6.函数安全性

函数、触发器和行级安全策略允许用户将代码插入到后端服务器中,其他用户可能会无意中执行该代码。因此,这些机制允许用户相对容易地对其他用户进行“特洛伊木马”攻击。最强的保护是对谁可以定义对象进行严格控制。如果这是不可行的,请编写只引用具有受信任所有者的对象的查询。从search_path中删除任何允许不受信任的用户创建对象的模式。

函数在后端服务器进程中运行,具有数据库服务器守护程序的操作系统权限。如果用于函数的编程语言允许未经检查的内存访问,则可以更改服务器的内部数据结构。因此,在很多其他事情中,这些函数可能绕开任何系统访问控制。允许这种访问的函数语言被认为是“不受信任的”,UXsinoDB只允许超级用户创建使用这些语言编写的函数。

6.管理数据库

每个运行的UXsinoDB服务器实例都管理着一个或多个数据库。因此,数据库是组织SQL对象(“数据库对象”)的最高层次结构。本章描述了数据库的属性,以及如何创建、管理和销毁它们。

6.1.概述

在集群级别上,定义了一些对象,如角色、数据库和表空间名称,并存储在ux_global表空间中。集群内有多个数据库,它们相互隔离,但可以访问集群级别的对象。每个数据库内有多个模式,其中包含表和函数等对象。因此,完整的层次结构是:集群、数据库、模式、表(或其他类型的对象,如函数)。

连接到数据库服务器时,客户端必须在其连接请求中指定数据库名称。一个连接无法访问多个数据库。但是,客户端可以打开到同一数据库或不同数据库的多个连接。数据库级别的安全性有两个组成部分:访问控制(参见ux_hba.conf文件),在连接级别进行管理;授权控制,通过授权系统进行管理。外部数据封装器允许一个数据库内的对象充当其他数据库或集群中对象的代理。旧的dblink模块提供了类似的功能。默认情况下,所有用户都可以使用所有连接方法连接到所有数据库。

如果计划将一个UXsinoDB服务器集群包含无关的项目或用户,这些项目或用户在很大程度上应该不知道彼此,建议将它们放入单独的数据库中,并相应地调整授权和访问控制。如果项目或用户是相互关联的,因此应该能够使用彼此的资源,则应将它们放入同一个数据库中,但可能是不同的模式;这提供了具有命名空间隔离和授权控制的模块化结构。

虽然可以在单个集群中创建多个数据库,但建议仔细考虑其利弊和限制。

特别是共享WAL(请参见可靠性和预写式日志)对备份和恢复选项的影响。尽管从用户的角度来看,集群中的各个数据库是隔离的,但从数据库管理员的角度来看,它们是紧密相连的。使用CREATE DATABASE命令(请参见创建数据库)创建数据库,并使用DROP DATABASE命令(请参见销毁数据库)销毁数据库。要确定现有数据库集,请检查ux_database系统目录,例如:

SELECT datname FROM ux_database; 

uxsql程序的\l元命令和-l命令行选项也有助于列出现有数据库。

注意

SQL标准将数据库称为“catalogs”,但实际上没有区别。

6.2.创建数据库

要创建数据库,必须启动 UXDB 服务器(参见启动数据库服务器)。

使用 SQL 命令 CREATE DATABASE创建数据库:

CREATE DATABASE name;

其中 name 遵循 SQL标识符的常规规则。当前角色自动成为新数据库的所有者。数据库所有者有权稍后删除它(即使其中的对象具有不同的所有者)。

创建数据库是一项受限操作。有关如何授予权限,请参见 角色属性。

由于需要连接到数据库服务器才能执行 CREATE DATABASE 命令,因此问题在于如何创建任何给定站点的 第一个数据库。第一个数据库总是由 initdb 命令在初始化数据存储区时创建的(参见创建数据库集群)。该数据库称为 uxdb。因此,要创建第一个“普通”数据库,可以连接到 uxdb。

还会在数据库集群初始化期间创建两个其他数据库:template1 和template0。每当在集群内创建新数据库时,template1会被克隆。这意味着您在 template1中所做的任何更改都会传播到随后创建的所有数据库。因此,除非您希望它们在所有数据库中都存在,否则请避免在template1 中创建对象。传播到每个新创建的数据库。 template0 旨在作为原始内容的原始副本template1。当需要创建一个没有任何这样的本地站点添加的数据库时,可以克隆它而不是 template1。更多细节在模板数据库中出现。

为方便起见,有一个程序可以 从 shell 中执行以创建新数据库, createdb。

createdb dbname

createdb 连接到 uxdb 数据库并发出 CREATE DATABASE 命令, 正如上面所述。请注意,没有任何参数的createdb 将创建 一个具有当前用户名的数据库。

注意

客户端认证包含有关如何限制谁可以连接到给定数据库的信息。

有时您想为其他人创建一个数据库,并让他们 成为新数据库的所有者,以便他们可以 自己配置和管理它。为了实现这一点,请使用以下命令之一:

CREATE DATABASE dbname OWNER rolename;

从 SQL 环境中,或者:

createdb -O rolename dbname

从 shell 中。 只有超级用户被允许为其他人创建数据库 (也就是说,对于您不是成员的角色)。

6.3.模板数据库

CREATE DATABASE 实际上是通过复制现有数据库来工作的。默认情况下,它会复制名为 template1 的标准系统数据库。因此,该数据库是新数据库的“模板”。如果您向 template1添加对象,则这些对象将被复制到随后创建的用户数据库中。这种行为允许对数据库中标准对象集进行现场修改。例如,如果您在template1 中安装过程语言 PL/Perl,则在创建这些数据库时无需采取任何额外操作,它将自动可用于用户数据库。

还有一个名为 template0 的标准系统数据库。 该数据库包含与 template1 的初始内容相同的数据,即仅包含由您的UXsinoDB 版本预定义的标准对象。在数据库集群初始化后,template0 不应更改。通过指示 CREATE DATABASE复制 template0 而不是template1,可以创建一个“原始”的用户数据库(其中不存在用户定义的对象,系统对象也未被更改),其中不包含template1 中的现场添加。这在恢复 ux_dump转储时特别方便:应将转储脚本恢复到原始数据库中,以确保重新创建转储数据库的正确内容,而不会与后来添加到template1 的对象冲突。

复制 template0 而不是 template1 的另一个常见原因是,可以在复制 template0时指定新的编码和区域设置,而复制 template1 必须使用与其相同的设置。

这是因为template1可能包含特定于编码或语言环境的数据,而template0则不包含这些数据。

要通过复制template0来创建数据库,请使用:

CREATE DATABASE dbname TEMPLATE template0;

从SQL环境,或者:

createdb -T template0 dbname

从shell。

可以创建其他模板数据库,实际上可以通过将其名称指定为CREATE DATABASE的模板来复制集群中的任何数据库。但是,重要的是要理解,这不是(尚未)旨在作为通用的“COPY DATABASE”工具。主要限制是在复制时不能连接到源数据库的任何其他会话。 如果在启动时存在任何其他连接,则CREATE DATABASE将失败。在复制操作期间,将防止对源数据库的新连接。

ux_database中存在两个有用的标志,用于每个数据库:列datistemplate和datallowconn。可以将datistemplate设置为指示数据库旨在用作CREATE DATABASE的模板。如果设置了此标志,则任何具有CREATEDB特权的用户都可以克隆数据库;如果未设置,则只有超级用户和数据库所有者可以克隆它。如果datallowconn为false,则不允许对该数据库进行新连接(但是仅通过将标志设置为false不会终止现有会话)。通常将template0数据库标记为datallowconn = false以防止其修改。template0和template1都应始终标记为datistemplate = true。

注意

template1和template0除了名称template1是CREATE DATABASE的默认源数据库名称之外,没有任何特殊状态。例如,可以删除template1并从template0重新创建它而不会产生任何不良影响。如果不小心在template1中添加了一堆垃圾,则可能建议采取此措施。(要删除template1,必须将ux_database.datistemplate = false。)

uxdb数据库也在初始化数据库集群时创建。 该数据库旨在作为用户和应用程序连接的默认数据库。它只是template1的副本,如果需要,可以删除并重新创建。

6.4.数据库配置

回想一下服务器配置,UXsinoDB服务器提供了大量的运行时配置变量。您可以为许多这些设置设置特定于数据库的默认值。

例如,如果出于某种原因,您想要禁用给定数据库的GEQO优化器,您通常必须将其禁用所有数据库,或者确保每个连接的客户端小心地发出SET geqo TO off。为了使这个设置成为特定数据库中的默认设置,您可以执行以下命令:

ALTER DATABASE mydb SET geqo TO off;

这将保存设置(但不会立即设置)。在随后连接到这个数据库时,它将出现在会话开始之前就执行了SET geqo TO off;。请注意,用户仍然可以在他们的会话期间更改此设置;它只是默认值。要撤消任何此类设置,请使用ALTER DATABASE dbname RESET varname 。

6.5.销毁数据库

使用命令DROP DATABASE销毁数据库:

DROP DATABASE name;

只有数据库的所有者或超级用户才能销毁数据库。销毁数据库将删除数据库中包含的所有对象。销毁数据库是无法撤消的。

您不能在连接到受害数据库时执行DROP DATABASE命令。但是,您可以连接到任何其他数据库,包括template1数据库。template1将是删除给定集群的最后一个用户数据库的唯一选项。

为了方便起见,还有一个用于删除数据库的shell程序dropdb:

dropdb dbname

(与createdb不同,删除具有当前用户名的数据库不是默认操作。)

6.6.表空间

在UXsinoDB中,表空间允许数据库管理员定义文件系统中表示数据库对象的文件存储位置。创建后,可以在创建数据库对象时通过名称引用表空间。

通过使用表空间,管理员可以控制UXsinoDB安装的磁盘布局。这至少有两种用途。首先,如果初始化群集的分区或卷用尽空间并且无法扩展,则可以在不同的分区上创建表空间并使用,直到系统可以重新配置。

其次,表空间允许管理员使用数据库对象的使用模式知识来优化性能。例如,可以将非常频繁使用的索引放置在非常快速、高可用的磁盘上,例如昂贵的固态设备。同时,可以将存储归档数据的表(很少使用或不重要)存储在较便宜、较慢的磁盘系统上。

警告

尽管位于主要的UXsinoDB数据目录之外,表空间是数据库群集的一个组成部分,因此不能将其视为一个独立的数据文件集合。它们依赖于主数据目录中包含的元数据,因此不能附加到不同的数据库群集或单独备份。同样,如果丢失表空间(文件删除、磁盘故障等),数据库群集可能会变得无法读取或无法启动。将表空间放置在临时文件系统(如RAM磁盘)上会影响整个群集的可靠性。

6.6.1.关于表空间

UXDB数据库中的表空间允许数据库管理员在文件系统中定义用来存放表示数据库对象的文件的位置。一旦被创建,表空间就可以在创建数据库对象时通过名称引用。

6.6.2.查看表空间信息

当初始化数据库实例时,UXDB数据库会自动创建三个表空间,ux_default和ux_global和main。

ux_global表空间被用于共享系统目录。ux_default表空间是template1和template0数据库的默认表空间(因此也是所有其他数据库的默认表空间,除非在使用CREATE DATABASE创建数据库时被其中的TABLESPACE子句覆盖)。

main表空间类似于ux_default表空间,可以通过手动指定默认空间。用户可通过检查系统表ux_tablespace,确定现有表空间的集合。

uxdb=# SELECT spcname FROM ux_tablespace;
  spcname   
------------
 ux_default
 ux_global
 main
(3 行记录)

uxsql程序的db元命令也可以用来列出现有的表空间。

uxdb=# \db
          表空间列表
    名称    | 拥有者 | 所在地 
------------+--------+--------
 main       | uxdb   | 
 ux_default | uxdb   | 
 ux_global  | uxdb   | 
(3 行记录)

要定义一个表空间,使用CREATE TABLESPACE命令,如下所示。

CREATE TABLESPACE fastspace LOCATION '/ssd1/uxsino/data';

这个位置必须是一个已有的空目录,并且属于UXDB操作系统用户。所有后续在该表空间中创建的对象都将被存放在这个目录下的文件中。该位置不能放在可移动或者瞬时存储上,因为如果表空间丢失会导致集簇无法工作。

注意

  • 通常在每个逻辑文件系统上创建多于一个表空间没有什么意义,因为你无法控制在一个逻辑文件系统中特定文件的位置。不过,UXDB不强制任何这样的限制,并且事实上它不会注意你的系统上的文件系统边界。它只是在你告诉它要使用的目录中存储文件。
  • 表空间的创建本身必须作为一个数据库超级用户完成,但在创建完之后之后你可以允许普通数据库用户来使用它。要这样做,给数据库普通用户授予表空间上的CREATE权限。

表、索引和整个数据库都可以被分配到特定的表空间。想这么做,在给定表空间上有CREATE权限的用户必须把表空间的名字以一个参数的形式传递给相关的命令。例如,下面的命令在表空间space1中创建一个表:

CREATE TABLE foo(i int) TABLESPACE space1;

另外,还可以使用default_tablespace参数:

SET default_tablespace = space1;
CREATE TABLE foo(i int);

当default_tablespace被设置为非空字符串,那么它就为没有显式TABLESPACE子句的CREATE TABLE和CREATE INDEX命令提供一个隐式TABLESPACE子句。

6.6.3.表空间设置

  • 大纲

    ALTER TABLESPACE name RENAME TO new_name
    ALTER TABLESPACE name OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
    ALTER TABLESPACE name SET ( tablespace_option = value [, ... ] )
    ALTER TABLESPACE name RESET ( tablespace_option [, ... ] )
    
  • 描述

    ALTER TABLESPACE用于更改一个表空间的定义。

    注意

    1. 更改一个表空间的定义,必须拥有它。
    2. 修改拥有者,还必须是新拥有角色的一个直接或间接成员(注意数据库管理员自动拥有这些特权)。
  • 参数

    temp_tablespaces参数,决定临时表和索引的位置,以及用于大数据集排序等目的的临时文件的位置。这可以是一个表空间名的列表,而不是只有一个。因此,与临时对象有关的负载可以散布在多个表空间上。每次要创建一个临时对象时,将从列表中随机取一个成员来存放它。

    与一个数据库相关联的表空间用来存储该数据库的系统目录。此外,如果没有给出TABLESPACE子句并且没有在default_tablespace或temp_tablespaces(如适用)中指定其他选择,它还是在该数据库中创建的表、索引和临时文件的默认表空间。如果一个数据库被创建时没有指定表空间,它会使用其模板数据库相同的表空间。

  • 示例

    如重命名表空间,如下所示。

    uxdb=# ALTER TABLESPACE workplace RENAME TO jobplace;
    ALTER TABLESPACE
    uxdb=# \db
                表空间列表
        名称    | 拥有者 |   所在地   
    ------------+--------+------------
     jobplace   | uxdb   | /home/uxdb
     main       | uxdb   | 
     ux_default | uxdb   | 
     ux_global  | uxdb   | 
    (4 行记录)
    

6.6.4.表空间删除

表空间一旦被创建,就可以被任何数据库使用,前提是请求的用户具有足够的权限。这也意味着,一个表空间只有在所有使用它的数据库中所有对象都被删除掉之后才可以被删掉。

删除一个空的表空间,使用DROP TABLESPACE命令。

注意

  1. 一个表空间只能被其拥有者或数据库管理员删除。
  2. 在一个表空间能被删除前,其中必须没有任何数据库对象。即使当前数据库中没有对象正在使用该表空间,也可能有其他数据库的对象存在于其中。
  3. 如果该表空间被列在任何活动会话的temp_tablespaces设置中,DROP也可能会失败,因为可能有临时文件存在其中。

7.模式管理

7.1.关于模式

一个数据库可以包含一个或多个命名的模式(SCHEMA),一个模式内可以包含多个表。不同的模式中的表名可以相同,例如,schema1和schema2中可以分别包含名称为mytable的表,但是同一个模式中的表不能同名。模式类似于操作系统级的目录,但模式不能嵌套。

用户只要有权限就可以访问所连接数据库中的任何模式中的对象。

在创建数据库时,UXDB会默认创建两个模式:ux_catalog和public。

ux_catalog模式用于存放系统表和所有内置的数据类型、函数和操作符。

当用户没有自己的模式并且其创建或使用数据库对象没有指定模式时,默认使用public模式。

模式通常在如下情况中使用。

  1. 多个用户使用同一个数据库而不会相互影响。

  2. 对数据库中的对象进行逻辑分组,更便于管理。

  3. 各个应用分别使用各自的模式,以避免命名冲突。

7.2.查看模式

通过检查系统表sys_namespace,可以确定现有模式的集合。

uxdb=# select nspname from ux_namespace ;
     nspname     
-----------------
 ux_toast
 ux_temp_1
 ux_toast_temp_1
 ux_catalog
 public
 schame1
(6 行记录)

uxsql程序的dn命令行选项也可以用来列出已有的模式。

uxdb=# \dn
   架构模式列表
  名称   | 拥有者 
---------+--------
 public  | uxdb
 schame1 | uxdb
(2 行记录)

7.3.CREATE SCHEMA

  • 大纲

    CREATE SCHEMA
    
  • 描述

    CREATE SCHEMA创建一个新模式到当前数据库中。

    注意

    1. 要创建一个模式,创建用户必须拥有当前数据库的CREATE特权,或者是数据库管理员。
    2. 所创建模式的模式名必须与当前数据库中任何现有模式的名称不同。

    如果希望创建属于UserName的模式SchemaName,可以使用下面的语句。

    CREATE SCHEMA SchemaName AUTHORIZATION UserName;
    

    使用CREATE SCHEMA语句创建模式,在模式中创建数据库对象或访问模式中的对象时,对象名前使用指定的模式名。

  • 示例

    创建一个模式并且在其中创建一个表和视图,如下所示。

    CREATE SCHEMA hollywood
    CREATE TABLE films (title text, release date, awards text[])
    CREATE VIEW winners AS
    SELECT title, release FROM films WHERE awards IS NOT NULL;
    

7.4.ALTER SCHEMA

  • 大纲

    ALTER SCHEMA SchemaName RENAME TO new_ SchemaName
    ALTER SCHEMA SchemaName OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
    
  • 描述

    ALTER SCHEMA更改一个模式的定义。

    注意

    1. 使用ALTER SCHEMA,必须拥有该模式。
    2. 重命名一个模式,必须拥有该数据库的CREATE特权。
    3. 更改拥有者,必须是新拥有角色的一个直接或者间接成员,并且该角色必须具有该数据库上的CREATE特权。

7.5.DROP SCHEMA

  • 大纲

    DROP SCHEMA [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
    
  • 描述

    DROP SCHEMA从数据库中删除模式。

  • 参数

    表 DROP SCHEMA参数说明

    参数说明
    IF EXISTS如果该模式不存在,将不会抛出一个错误,而是发出一个提示。
    name模式的名称。
    CASCADE自动删除包含在该模式中的对象(表、函数等),然后删除所有依赖于那些对象的对象。
    RESTRICT如果该模式含有任何对象,则拒绝删除,是默认值。

    注意

    1. 一个模式只能由其拥有者或一个超级用户删除。  
    2. 即使拥有者不拥有该模式中的某些对象,也能删除该模式(以及所有含有的对象)。
    
  • 示例

    删除一个空模式(模式中的所有数据库对象已经删除),如下所示。

    DROP SCHEMA SchemaName;
    

    如果模式中还有数据库对象,则使用CASCADE子句,删除模式及其中的所有数据库对象,如下所示。

    DROP SCHEMA SchemaName CASCADE;
    

8.表管理

8.1.表

表是为数据库中数据存储的基本单位,其数据按行、列存储。

表中列的个数和顺序是固定的。在创建基本表时,要对表中的所有列进行说明,要说明它的名称、数据类型、宽度或精度等。已经说明的列也可以使用SQL语句修改。

列的数据类型限制了该列的可能取值以及说明了该列进行计算时,存储在该列上的数据的语义。例如,一个列声明为INTEGER类型,则其中就不能存放字符串数据,该列的数据可以进行数学运算。同样,一个列声明为字符串类型,则其中可以存放任何数据,但该列的数据不可以进行数学运算。

列的值是可以随时发生变化的。同一列中的所有值具有相同的数据类型,而且这些值必须属于同一个表。列中的一个值是在表中进行检索和更新的最小数据单位。

行是对应单个记录的列信息的集合。同一表中每一行包含表中每一列的一个值,表中每行的第i个值即是该表第i列的一个值。行是在表中进行插入和删除操作的最小数据单位。

表中的数据行是无序的。因此,对表进行查询时,数据行的顺序是随机的,除非查询语句中具有ORDER BY子句。

示例

  1. 通过ux_tables,可以查看数据库中每个表的信息。

    uxdb=# select tablename from ux_tables;
            tablename        
    -------------------------
     t
     ux_statistic
     ux_statistic_ext_data
     ux_user_mapping
     ux_type
     ux_authid
     .
     .
     .
    
  2. 通过uxsql程序的dt命令行选项查看表。

    uxdb=# \dt
            List of relations
     Schema |  Name   | Type  | Owner 
    --------+---------+-------+-------
     public | student | table | uxdb
     public | t       | table | uxdb
     public | test    | table | uxdb
    (3 rows)
    
  3. 通过uxsql程序的d命令行选项查看某个表的结构。

    示例:查看表ux_type的结构( 加 "+" 获取更多信息:d+)。

    uxdb=# \d+ ux_type
                                           Table "ux_catalog.ux_type"
         Column     |     Type     | Collation | Nullable | Default | Storage  | Stats target | Description 
    ----------------+--------------+-----------+----------+---------+----------+--------------+-------------
     oid            | oid          |           | not null |         | plain    |              | 
     typname        | name         |           | not null |         | plain    |              | 
     typnamespace   | oid          |           | not null |         | plain    |              | 
     typowner       | oid          |           | not null |         | plain    |              | 
     typlen         | smallint     |           | not null |         | plain    |              | 
     typbyval       | boolean      |           | not null |         | plain    |              | 
     typtype        | "char"       |           | not null |         | plain    |              | 
     typcategory    | "char"       |           | not null |         | plain    |              | 
     typispreferred | boolean      |           | not null |         | plain    |              | 
     typisdefined   | boolean      |           | not null |         | plain    |              | 
     typdelim       | "char"       |           | not null |         | plain    |              | 
     typrelid       | oid          |           | not null |         | plain    |              | 
     typelem        | oid          |           | not null |         | plain    |              | 
     typarray       | oid          |           | not null |         | plain    |              | 
     typinput       | regproc      |           | not null |         | plain    |              | 
     typoutput      | regproc      |           | not null |         | plain    |              | 
     typreceive     | regproc      |           | not null |         | plain    |              | 
     typsend        | regproc      |           | not null |         | plain    |              | 
     typmodin       | regproc      |           | not null |         | plain    |              | 
     typmodout      | regproc      |           | not null |         | plain    |              | 
     typanalyze     | regproc      |           | not null |         | plain    |              | 
     typalign       | "char"       |           | not null |         | plain    |              | 
     typstorage     | "char"       |           | not null |         | plain    |              | 
     typnotnull     | boolean      |           | not null |         | plain    |              | 
     typbasetype    | oid          |           | not null |         | plain    |              | 
     typtypmod      | integer      |           | not null |         | plain    |              | 
     typndims       | integer      |           | not null |         | plain    |              | 
     typcollation   | oid          |           | not null |         | plain    |              | 
     typdefaultbin  | ux_node_tree | C         |          |         | extended |              | 
     typdefault     | text         | C         |          |         | extended |              | 
     typacl         | aclitem[]    |           |          |         | extended |              | 
    Indexes:
        "ux_type_oid_index" UNIQUE, btree (oid)
        "ux_type_typname_nsp_index" UNIQUE, btree (typname, typnamespace)
    Access method: heap)
    
  4. 系统初始化的时候会自动在ux_catalog模式下创建dual表。该表只有一列,列名是dummy,数据类型是varchar(1),并且该表只包含一条记录'X'。该表可以被所有的用户访问,但只有数据库管理员才可以删除、增加、修改表dual的内容,普通用户只能查询该表。可以通过查询表dual来计算一个常量表达式的值,因为dual只有一条记录,所以只返回一次结果。

    查询dual表,如下所示。

    uxdb=# select * from dual;
     dummy 
    -------
     X
    (1 row)
    

8.2.CREATE TABLE

  • 大纲

    CREATE TABLE tablename ...
    
  • 描述

    数据库中的表由CREATE TABLE语句定义。

    详细参数请参见《优炫数据库管理系统SQL命令手册》的“CREATE TABLE”。

    注意

    1. 在该语句中必须对基表命名,并且说明该表中每个列的列名、数据类型等。
    2. 创建一个表,必须分别具有所有列类型或OF子句中类型的USAGE特权。
  • 示例

    创建表my_first_table,如下所示。

    CREATE TABLE my_first_table(
      first_column TEXT,
      second_column INTEGER
      );
    

8.3.ALTER TABLE

  • 大纲

    ALTER TABLE ...
    
  • 描述

    表创建后,可以使用ALTER TABLE语句修改表的定义。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“ALTER TABLE”。

  • 示例

    • 给表增加一列、删除表中的列、修改表名、列名等。

      • 向一个表增加一个类型为varchar的列。

        ALTER TABLE my_first_table ADD COLUMN address varchar(30);
        
      • 从表中删除一列。

        ALTER TABLE my_first_table DROP COLUMN address RESTRICT;
        
      • 在一个操作中更改两个现有列的类型。

        ALTER TABLE my_first_table
        ALTER COLUMN first_column TYPE varchar(80),
        ALTER COLUMN second_column TYPE varchar(100);
        
      • 重命名表。

        ALTER TABLE my_first_table RENAME TO my_table;
        
    • 使用INSERT、DELETE、UPDATE语句对表中数据进行增、删、改操作。

      • 把表films的列kind中的单词Drama改成Dramatic。

        UPDATE films SET kind = 'Dramatic' WHERE kind = 'Drama';
        
      • 删除表films中Musical。

        DELETE FROM films WHERE kind <> 'Musical';
        
      • 向films中插入一行。

        INSERT INTO films VALUES ('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes');
        

8.4.DROP TABLE

  • 大纲

    DROP TABLE
    
  • 描述

    当不再使用一个表时,可以将其删除。删除表时,将产生以下结果:

    1. 表的结构信息从数据字典中删除,表中的数据不可访问。

    2. 表上的所有索引和触发器被一起清除。

    3. 所有建立在该表上的同义词、视图和存储过程变为无效。

    4. 所有分配给表的簇标记为空闲,可被分配给其他的数据库对象。

    一般情况下,普通用户只能删除自己模式下的表。若要删除其他模式下的表,则必须具有DROP TABLE的数据库权限。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“DROP TABLE”。

  • 示例

    • 删除表my_first_table。

      DROP TABLE my_first_table;
      
    • 如果要删除的表被其他表引用,即其他表的外键引用了表的任何主键或唯一键,则需要在DROP TABLE语句中包含CASCADE选项,如下所示。

      DROP TABLE my_first_table CASCADE;
      

8.5.清空表

某些情况下,当表的数据不再使用时,需要删除表的所有行,即清空该表。UXDB支持以下方式来删除表中的所有的行。

  1. 使用DELETE语句。

  2. 使用DROP和CREATE语句。

  3. 使用truncate语句。

8.5.1.使用DELETE

  • 大纲

    DELETE FROM my_first_table;
    
  • 描述

    使用DELETE语句删除表中的行。下面的语句将删除my_first_table表中的所有行:

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“DELETE”。

    但当表有很多行时,使用DELETE清空表会消耗过多的系统资源。

8.5.2.使用DROP和CREATE

  • 大纲

    DROP TABLE my_first_table;
    CREATE TABLE my_first_table (…);
    
  • 描述

    使用DROP删除一个表,然后创建一个同名的表,也可以达到清空表的效果。例如,下面的语句先删除my_first_table表,之后再重新创建。

    当删除和重新创建表时,所有与之相关联的索引、完整性约束和触发器也被删除。同样,所有针对被删除表的授权也会被删除。

8.5.3.使用truncate

  • 大纲

    truncate TABLE my_first_table;
    
  • 描述

    使用truncate语句能删除表中的所有行。下面的语句清空my_first_table表。

    truncate语句提供了一种快速、有效地删除表所有行的方法。并且truncate是一个DDL语句,不会产生任何回滚信息。执行truncate会立即提交,而且不能回滚。

    详细信息请参见《SQL命令手册》的“TRUNCATE”。

    truncate语句并不影响与被删除的表相关联的任何结构、约束、触发器或者授权。另外,UXDB数据库truncate表后,原来分配给该表的空间会被释放,供其他数据库对象使用,大大提高空间的利用效率。

    注意

    一般情况下,普通用户只能truncate自己模式下的表。若要truncate其他模式下的表,则必须具有DROP TABLE的数据库权限。
    如果要清空的表被其他表引用,即其他表的外键引用了表的任何主键或唯一键,并且子表不为空或子表的外键约束未被禁用,则不能truncate该表。

8.6.查询表信息

表创建后,可以使用SELECT语句对表中数据进行查询操作。

查询DUAL表,如下所示。

SELECT * FROM DUAL;
DUMMY
-------
X
(1 row)

9.视图

9.1.关于视图

视图是CREATE VIEW语句定义的导出表,由一个或多个表(或其他视图)中的数据的一种定制的表示,是用一个查询定义的。所以视图可认为是一个存储的查询或是一个虚表(virtual table)。视图几乎可在任何使用表的地方使用。

由于视图是由表导出的,所以视图和表存在许多类似。视图可以被查询,而在修改、插入或删除时具有一定的限制。例如,在视图上执行的操作影响了视图的基本表中的数据时,该操作应受到基本表的完整性约束和触发器的限制。

视图与表不同。一个视图不分配任何存储空间,不真正地包含数据。由查询定义的视图对应于视图引用表中的数据。视图只在数据字典中存储其定义。

引入视图可以通过限制对表的预定义行集合的存取,为表提供附加的安全性;可以为用户简化命令;可用于保存复杂查询等。

视图是一个虚拟表,其内容由查询语句(SELECT)定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。

物化视图是查询结果集的一份持久化存储,所以它与普通视图完全不同,而非常趋近于表。可以是基础表中部分数据的一份简单拷贝,也可以是多表join之后产生的结果或其子集,或者原始数据的聚合指标等等。所以,物化视图不会随着基础表的变化而变化,所以它也称为快照(snapshot)。

9.2.查看视图

  1. 通过检查系统表ux_views,用户可以确定现有视图的集合。

    uxdb=# select viewname from ux_views;
                   viewname                
    ---------------------------------------
     ux_shadow
     ux_settings
     ux_file_settings
     ux_hba_file_rules
     ux_config
     ux_replication_origin_status
    
     .
    
  2. uxsql程序的dv命令行选项可以用来列出现有视图。

    uxdb=# \dv
           List of relations
     Schema |  Name  | Type | Owner 
    --------+--------+------+-------
     public | myview | view | uxdb
    (1 row)
    

9.3.CREATE VIEW

  • 大纲

    CREATE VIEW ...
    
  • 描述

    CREATE VIEW定义一个查询的视图。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“CREATE VIEW”。

    注意

    如果给定了一个模式名(例如CREATE VIEW myschema.myview...),那么该视图会被创建在指定的模式中。否则,它会被创建在当前模式中。
    视图的名称不能与同一模式中任何其他视图、表、序列、索引或外部表同名。

  • 示例

    在student表中创建一个查询视图,如下所示。

    create view myview as select * from student ;
    

9.4.ALTER VIEW

  • 大纲

    ALTER VIEW [ IF EXISTS ] name ALTER [ COLUMN ] column_name SET DEFAULT expression
    ALTER VIEW [ IF EXISTS ] name ALTER [ COLUMN ] column_name DROP DEFAULT
    ALTER VIEW [ IF EXISTS ] name OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
    ALTER VIEW [ IF EXISTS ] name RENAME TO new_name
    ALTER VIEW [ IF EXISTS ] name SET SCHEMA new_schema
    ALTER VIEW [ IF EXISTS ] name SET ( view_option_name [= view_option_value] [, ... ] )
    ALTER VIEW [ IF EXISTS ] name RESET ( view_option_name [, ... ] )
    
  • 描述

    ALTER VIEW更改一个视图的多种辅助属性。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“ALTER VIEW”。

    注意

    1. 使用ALTER VIEW,必须拥有该视图。
    2. 更改一个视图的模式,必须具有新模式上的CREATE特权。
    3. 更改拥有者,必须是新拥有角色的一个直接或者间接成员,并且该角色必须具有该视图的模式上的CREATE特权。(这些限制强制修改拥有者不能做一些通过删除和重建视图做不到的事情。但是,数据库管理员能够更改任何视图的所有权。)

9.5.DROP VIEW

  • 大纲

    DROP VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
    
  • 描述

    DROP VIEW删除一个现有的视图。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“DROP VIEW”。

    注意

    视图的拥有者才有权限执行这个命令。

10.索引

10.1.关于索引

索引是与表相关的一种数据结构,是为了提高数据检索的性能而建立的。利用它可快速地确定指定的信息。但是,索引在总体上也增加数据库的负担,因此,创建索引要谨慎。

UXDB索引为表数据提供快速存取路径。索引适用于一范围的行查询或指定行的查询。

任何时候都可以在表上创建和删除索引。索引逻辑地和物理地独立于数据,它们的建立或删除对表没有影响。

索引可建立在一个表的一列或多列上。一旦建立,将由UXDB自动维护和使用,对用户是完全透明的。系统的优化器会根据统计信息确定是否使用索引来提高系统性能。

索引一旦创建,系统则必须维护索引与表之间的同步。因此,当一个表上存在许多索引时,修改、删除和插入操作的性能会下降。所以,一些不是很必要的索引应该删除。

索引有唯一索引和非唯一索引。唯一索引保证表中没有两行在定义索引的列上具有重复值。在唯一码上自动地定义唯一索引实施UNIQUE完整性约束。

10.2.查看索引

  1. 通过检查系统表ux_indexes,用户可以确定现有索引的集合。

    uxdb=# select indexname from ux_indexes;
                       indexname                   
    -----------------------------------------------
     ux_aggregate_fnoid_index
     ux_am_name_index
     ux_am_oid_index
     ux_amop_fam_strat_index
     ux_amop_opr_fam_index
     ux_amop_oid_index
    .
    
    
  2. uxsql程序的di命令行选项也可以用来列出所有索引。

10.3.CREATE INDEX

  • 大纲

    CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] name ] ON [ ONLY ] table_name [ USING method ]
    ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
    [ INCLUDE ( column_name [, ...] ) ]
    [ WITH ( storage_parameter = value [, ... ] ) ]
    [ TABLESPACE tablespace_name ]
    [ WHERE predicate ]
    
  • 描述

    使用CREATE INDEX语句可以创建索引。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“CREATE INDEX”。

    注意

    1. 缺省情况下,CREATE INDEX语句创建B-树索引。
    2. CREATE FULLTEXT INDEX语句创建GIN索引。
    3. 使用USING method子句可以选择创建B-树索引、HASH索引或GIN索引。
  • 示例

    1. 在表films中的列title上创建一个B-树索引。

      CREATE UNIQUE INDEX title_idx ON films (title);
      

      函数索引是根据表的一个或多个列上的函数结果建立的索引。

    2. 函数索引可以提高基于函数调用结果的数据的访问效率。

      #如果创建了下面的索引:
      CREATE INDEX emp_lower_ename_idx ON scott.emp (lower(ename));
      #则下面的查询就可以通过该索引提高查询速度:
      SELECT * FROM scott.emp WHERE lower(ename) = 'value';
      

      函数索引定义中引用的函数可以具有多个参数变量,但是它们必须是表中的列。函数索引总是单列索引(函数结果值)。

10.4.ALTER INDEX

  • 大纲

    ALTER INDEX [ IF EXISTS ] name RENAME TO new_name
    ALTER INDEX [ IF EXISTS ] name SET TABLESPACE tablespace_name
    ALTER INDEX name ATTACH PARTITION index_name
    ALTER INDEX name DEPENDS ON EXTENSION extension_name
    ALTER INDEX [ IF EXISTS ] name SET ( storage_parameter = value [, ... ] )
    ALTER INDEX [ IF EXISTS ] name RESET ( storage_parameter [, ... ] )
    ALTER INDEX [ IF EXISTS ] name ALTER [ COLUMN ] column_number
    SET STATISTICS integer
    ALTER INDEX ALL IN TABLESPACE name [ OWNED BY role_name [, ... ] ]
    SET TABLESPACE new_tablespace [ NOWAIT ]
    
  • 描述

    ALTER INDEX更改一个索引的定义。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“ALTER INDEX”。

    注意

    1. 使用ALTER TABLE可以实现ALTER INDEX操作相同的效果。实际上,ALTER INDEX只是ALTER TABLE应用在索引上的形式的别名。
    2. 一个索引的拥有者不能与其基表的拥有者不同。更改基表的拥有者会自动地更改索引的拥有者。
    3. 不允许更改系统目录索引的任何部分。
  • 示例

    重命名一个现有索引。

    ALTER INDEX distributors RENAME TO suppliers;
    

10.5.REINDEX

  • 大纲

    REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [CONCURRENTLY ] name
    
  • 描述

    当一个表经过大量的增删改操作后,表的数据在物理文件中可能存在大量碎片,从而影响访问速度。此外,当删除表的大量数据后,若不再对表执行插入操作,索引所处的段可能占用了大量并不使用的簇,从而浪费了存储空间。

    因此,可以使用重建索引来对索引的数据进行重组,使数据更加紧凑,并释放不需要的空间,从而提高访问效率和空间效率。

    UXDB提供REINDEX重建索引。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“REINDEX”。

  • 示例

    uxdb
    - 重建单个索引,如下所示。
    
      ```sql
      REINDEX INDEX my_index;
    
    • 重建表my_table上的所有索引,如下所示。

      REINDEX TABLE my_table;
      

10.6.DROP INDEX

  • 大纲

    DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
    
  • 描述

    当用户不再需要该索引,或者该索引没有为针对其相关的表所发布的查询提供所期望的性能改善时。需要删除一个索引。

    UXDB提供DROP INDEX重建索引。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“DROP INDEX”。

    注意

    要想删除索引,则该索引必须包含在用户的模式中或用户必须具有DROP INDEX的数据库权限。

  • 参数

    表 DROP INDEX 参数说明

    参数描述
    CASCADE自动删除依赖于该索引的对象,然后删除所有依赖于那些对象的对象。
    RESTRICT如果有任何对象依赖于该索引,则拒绝删除它,是默认值。
  • 示例

    删除索引title_idx,如下所示。

    DROP INDEX title_idx;
    

11.存储过程/函数

11.1.关于存储过程/函数

存储过程/函数是由过程化语言(PL/SQL)书写,经编译和优化后存储在数据库服务器中的过程/函数。UXDB的存储过程/函数结合了SQL的数据操作能力和过程化语言的数据处理能力,方便程序开发人员设计出更加灵活的应用系统。

存储过程/函数相当于数据库中的一个对象,用户在使用存储过程/函数时首先使用CREATE PROCEDURE/FUNCTION语句创建存储过程/函数。在其它的存储过程/函数或用户的应用程序中可以使用CALL语句执行存储过程。用户创建的函数可以和其他系统内置的函数一样使用。当存储过程/函数不再需要时,可以使用DROP PROCEDURE/FUNCTION删除存储过程/函数。

11.2.查看存储过程/函数

  • 通过检查系统表ux_proc,用户可以确定有关函数、过程、聚集函数以及窗口函数的信息。

  • uxsql程序的df命令行选项也可以用来列出(只包括聚合/常规/程序/触发器/窗口)函数。

  • uxsql程序的dL命令行选项也可以用来列出所有过程语言。

11.3.CREATE PROCEDURE

  • 大纲

    CREATE OR REPLACE PROCEDURE
    
  • 描述

    创建一个新过程或者替换一个已有的定义。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“CREATE PROCEDURE”。

    注意

    1. 用户必须具有所使用的语言上的USAGE特权。
    2. 如果这个命令中包括了一个方案名称,则该存储过程将被创建在该方案中。否则存储过程将被创建在当前的方案中。新存储过程的名称不能匹配同一方案中具有相同输入参数类型的任何现有存储过程或函数。但是,具有不同参数类型的存储过程和函数可以共享同一个名称(这被称为重载)。
    3. 替换一个已有存储过程的当前定义,请使用CREATE OR REPLACE PROCEDURE。但不能采用这种方式更改存储过程的名称或者参数类型(如果尝试这样做,实际上会创建一个新的、不同的存储过程)。
    4. 当CREATE OR REPLACE PROCEDURE被用来替换一个现有的存储过程时,该存储过程的拥有关系和权限保持不变。所有其他的存储过程属性会被赋予这个命令中指定的或者暗示的值。必须拥有(包括成为拥有角色的成员)该存储过程才能替换它。
    5. 创建存储过程的用户将成为该存储过程的拥有者。
  • 示例

    简单存储过程示例,如下所示。

    uxdb=# create table tbl(id int);
    CREATE TABLE
    uxdb=# CREATE PROCEDURE insert_data(a integer, b integer)
    LANGUAGE SQL
    AS $$
    INSERT INTO tbl VALUES (a);
    INSERT INTO tbl VALUES (b);
    $$;
    CREATE PROCEDURE
    uxdb=# CALL insert_data(1, 2);
    CALL
    uxdb=# select * from tbl ;
     id 
    ----
      1
      2
    (2 rows)
    
    CREATE OR REPLACE PROCEDURE increment1(i INTEGER)
    AS $$
    BEGIN
    RAISE NOTICE '%', i + 1;
    END;
    $$ LANGUAGE pluxsql;
    

11.4.ALTER PROCEDURE

  • 大纲

    ALTER PROCEDURE
    
  • 描述

    UXDB使用ALTER PROCEDURE更改一个过程的定义。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“ALTER PROCEDURE”。

    注意

    1. 必须拥有该过程。
    2. 更改一个存储过程的方案,必须有新方案上的CREATE特权。
    3. 要更改拥有者,你还必须是新拥有角色的直接或间接成员,并且那个角色在该存储过程的方案上拥有CREATE特权(这些限制强制更新拥有者无法做到通过删除和重建该存储过程无法做到的事情。超级用户总是能够更改任何存储过程的拥有关系)。
  • 示例

    • 重命名具有两个integer类型参数的过程insert_data为insert_record。

      ALTER PROCEDURE insert_data(integer, integer) RENAME TO insert_record;
      
    • 将具有两个integer类型参数的过程insert_data的拥有者改为joe。

      ALTER PROCEDURE insert_data(integer, integer) OWNER TO joe;
      
    • 将具有两个integer类型参数的过程insert_data的方案改为accounting。

      ALTER PROCEDURE insert_data(integer, integer) SET SCHEMA accounting;
      

11.5.DROP PROCEDURE

  • 大纲

    DROP PROCEDURE
    
  • 描述

    删除一个现有存储过程的定义。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“DROP PROCEDURE”。

    注意

    该存储过程的拥有者才有权限执行此命令。该存储过程的参数类型必须指定,因为可能存在多个不同的存储过程具有相同名称和不同参数列表。

  • 示例

    DROP PROCEDURE do_db_maintenance();
    

11.6.CREATE FUNCTION

  • 大纲

    CREATE OR REPLACE FUNCTION
    
  • 描述

    创建一个新函数或者替换一个现有的函数。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“CREATE FUNCTION”。

    注意

    1. 要定义一个函数,用户必须具有该语言上的USAGE特权。
    2. 创建该函数的用户将成为该函数的拥有者。
  • 示例

    1. 创建一个函数,如下所示。

      CREATE FUNCTION add(integer, integer) RETURNS integer
      AS 'select $1 + $2;'
      LANGUAGE SQL
      IMMUTABLE
      RETURNS NULL ON NULL INPUT;
      
    2. 调用一个函数,如下所示。

      select add(1,1);
      

11.7.ALTER FUNCTION

  • 大纲

    ALTER FUNCTION
    
  • 描述

    更改一个函数的定义。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“ALTER FUNCTION”。

    注意

    1. 函数的拥有者才有权限执行此命令。
    2. 更改一个函数的模式,必须具有新模式上的CREATE特权。
    3. 更改拥有者,必须是新拥有角色的一个直接或者间接成员,并且该角色必须具有在该函数的模式上的CREATE特权(这些限制强制修改拥有者不能做一些通过删除和重建该函数做不到的事情。但是,数据库管理员能够更改任何函数的所有权)。
  • 示例

    1. 把用于类型integer的函数sqrt 重命名为square_root,如下所示。

      ALTER FUNCTION sqrt(integer) RENAME TO square_root;
      
    2. 把用于类型integer的函数sqrt 的拥有者改为joe,如下所示。

      ALTER FUNCTION sqrt(integer) OWNER TO joe;
      
    3. 把用于类型integer的函数sqrt 的模式改为maths,如下所示。

      ALTER FUNCTION sqrt(integer) SET SCHEMA maths;
      

11.8.DROP FUNCTION

  • 大纲

    DROP FUNCTION
    
  • 描述

    删除一个已有函数的定义。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“DROP FUNCTION”。

    注意

    1. 要执行这个命令用户必须是该函数的拥有者。
    2. 该函数的参数类型必须被指定,因为多个不同的函数可能会具有相同的函数名和不同的参数列表。
  • 示例

    1. 删除平方根函数,如下所示。

      DROP FUNCTION sqrt(integer);
      
    2. 在一个命令中删除多个函数,如下所示。

      DROP FUNCTION sqrt(integer), sqrt(bigint);
      

12.触发器

12.1.关于触发器

触发器是一种特殊的存储过程。它在插入、删除或修改特定表和视图中的数据时触发执行,它比数据库本身标准的功能有更精细和更复杂的数据控制能力。

触发器是一种特殊类型的存储过程,不由用户直接调用。创建触发器时需要对其进行定义,以便在对特定表或列作特定类型的数据修改时执行。

与存储过程相同,触发器也存储在数据库中,使用SQL和PL/SQL语句编写。存储过程和触发器最主要的区别在于它们运行的方式不同。存储过程由用户、应用程序或触发器显式调用,而触发器则是当触发事件发生时由系统触发执行。

触发器按照所触发动作的间隔尺寸可以分为语句级触发器和行级触发器,CREATE TRIGGER语句的FOR EACH子句定义了触发动作的间隔尺寸,它既可以是FOR EACH STATEMENT,也可以是FOR EACH ROW。

12.2.表级触发器

表级触发器是依赖于已存在的表、对特定表的相关操作会引动发触发器调用相应的触发器函数。

12.2.1.CREATE TRIGGER

  • 描述

    CREATE TRIGGER创建一个新触发器。该触发器将被关联到指定的表、视图或者外部表并且在表上发生特定操作时将执行指定的函数function_name。

  • 示例

    只要表accounts的一行即将要被更新时会执行函数check_account_update,如下所示。

    CREATE TRIGGER check_update
    BEFORE UPDATE ON accounts
    FOR EACH ROW
    EXECUTE FUNCTION check_account_update();
    

12.2.2.ALTER TRIGGER

  • 描述

    ALTER TRIGGER更改一个现有触发器的属性。

    RENAME子句更改给定触发器的名称而不更改其定义。

    DEPENDS ON EXTENSION子句把该触发器标记为依赖于一个扩展,这样如果扩展被删除,该触发器也会被自动删除。

    要更改一个触发器的属性,必须拥有该触发器所作用的表。

  • 示例

    重命名一个现有的触发器,如下所示。

    ALTER TRIGGER emp_stamp ON emp RENAME TO emp_track_chgs;
    

12.2.3.DROP TRIGGER

  • 描述

    DROP TRIGGER删除一个现有的触发器定义。要执行这个命令,当前用户必须是触发器基表的拥有者。

  • 示例

    销毁表films上的触发器if_dist_exists,如下所示。

    DROP TRIGGER if_dist_exists ON films;
    

12.2.4.表级触发器的禁止和开启

表级触发器的禁止或者开启功能由ALTER TABLE提供,而非ALTER TRIGGER,因为ALTER TRIGGER无法针对性启用或者禁止一个表上的触发器。

详细信息请参见《优炫数据库管理系统SQL命令手册》的“ALTER TABLE”中的DISABLE TRIGGER选项和ENABLE TRIGGER选项。

12.3.事件触发器

UXDB中的事件触发器和表级触发器(依赖于表上并且只捕捉DML事件)不同,事件触发器对数据库来说是全局的,并且可以捕捉DDL事件。

和表级触发器一样,可以用任何事件触发器支持的过程语言编写事件触发器,目前UXDB不支持用纯SQL编写事件触发器。

只要一个与事件触发器相关的事件在事件触发器所在的数据库中发生,该事件触发器就会被触发。UXDB当前支持的事件有ddl_command_start、ddl_command_end、table_rewrite和sql_drop。

12.3.1.CREATE EVENT TRIGGER

  • 描述

    CREATE EVENT TRIGGER创建一个新的事件触发器。只要指定的事件发生并且与该触发器相关的WHEN条件(如果有)被满足,该触发器的函数将被执行。创建事件触发器的用户会成为它的拥有者。

    只有数据库管理员能创建事件触发器。

    在单用户模式(见uxdb)中事件触发器被禁用。如果一个错误的事件触发器禁用了数据库让你甚至无法删除它,可以重启到单用户模式,这样就能删除它。

  • 示例

    禁止执行任何DDL命令,如下所示。

    CREATE OR REPLACE FUNCTION abort_any_command()
    RETURNS event_trigger
    LANGUAGE plsql
    AS $$
    BEGIN
    RAISE EXCEPTION 'command % is disabled', tg_tag;
    END;
    $$;
    CREATE EVENT TRIGGER abort_ddl ON ddl_command_start
    EXECUTE FUNCTION abort_any_command();
    

12.3.2.ALTER EVENT TRIGGER

  • 大纲

    ALTER EVENT TRIGGER name DISABLE
    ALTER EVENT TRIGGER name ENABLE [ REPLICA | ALWAYS ]
    ALTER EVENT TRIGGER name OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
    ALTER EVENT TRIGGER name RENAME TO new_name
    
  • 描述

    ALTER EVENT TRIGGER更改一个现有事件触发器的属性。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“ALTER EVENT TRIGGER”。

    注意

    只有数据库管理员有权限更改一个时间触发器。

12.3.3.DROP EVENT TRIGGER

  • 描述

    DROP EVENT TRIGGER删除一个已有的事件触发器。要执行这个命令,当前用户必须是事件触发器的拥有者。

  • 示例

    销毁触发器snitch,如下所示。

    DROP EVENT TRIGGER snitch;
    

12.3.4.事件触发器使用示例

这里是一个用 C 编写的事件触发器函数的简单例子。

函数noddl在每一次被调用时抛出一个异常。事件触发器定义把该函数和 ddl_command_start事件关联在了一起。其效果就是所有DDL 命令都被阻止运行。

  1. 编写触发器函数的源代码。

    #include "uxdb.h"
    #include "commands/event_trigger.h"
    
    UX_MODULE_MAGIC;
    UX_FUNCTION_INFO_V1(noddl);
    Datum
    noddl(UX_FUNCTION_ARGS)
    {
        EventTriggerData *trigdata;
    
        if (!CALLED_AS_EVENT_TRIGGER(fcinfo))  /* internal error */
            elog(ERROR, "not fired by event trigger manager");
    
        trigdata = (EventTriggerData *) fcinfo->context;
    
        ereport(ERROR,
            (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                     errmsg("command \"%s\" denied", trigdata->tag)));
    
        UX_RETURN_NULL();
    }
    
  2. 在编译了源代码后,声明函数和触发器。

    CREATE FUNCTION noddl() RETURNS event_trigger
        AS 'noddl' LANGUAGE C;
    
  3. 创建触发器。

    CREATE EVENT TRIGGER noddl ON ddl_command_start
        EXECUTE FUNCTION noddl();
    
  4. 执行触发器的操作。

    \dy
                         List of event triggers
     Name  |       Event       | Owner | Enabled | Function | Tags
    -------+-------------------+-------+---------+----------+------
     noddl | ddl_command_start | dim   | enabled | noddl    |
    (1 row)
    
    CREATE TABLE foo(id serial);
    ERROR:  command "CREATE TABLE" denied
    

    在这种情况下,为了在需要时能运行某些 DDL 命令,你必须删除该事件触发器 或者禁用它。只在一个事务期间禁用该触发器会比较方便:

    BEGIN;
    ALTER EVENT TRIGGER noddl DISABLE;
    CREATE TABLE foo (id serial);
    ALTER EVENT TRIGGER noddl ENABLE;
    COMMIT;
    

13.序列管理

13.1.序列发生器

通过序列发生器,可以自动产生按一定规律(增加或减小)变化的序列的数值。用户可以根据需要定义每次序列变化的步长,序列能达到的极限值,当达到极限值时是否再从初始值重新开始。一旦定义了序列发生器,用户可取出序列值,取出序列值后,序列发生器自动变为下一序列值。序列发生器在很大程度上方便了用户的操作。不用对序列发生器进行维护,数据库会自动完成序列值的变化。序列发生器还可以与其它数据库对象结合使用。如:将某一字段的缺省值与某一序列发生器相关联,从而实现自动增长序列字段的功能。序列作为一种独立的模式对象存在,它的功能与自增长数据类型相同。可以在表数据的默认值中利用序列操作函数对序列进行使用。

13.2.CREATE SEQUENCE

  • 大纲

    CREATE SEQUENCE
    
  • 描述

    创建一个新的序列数发生器。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“CREATE SEQUENCE”。

  • 示例

    创建一个称作serial的上升序列,从101开始,如下所示。

    CREATE SEQUENCE serial START 101;
    

13.3.ALTER SEQUENCE

  • 大纲

    ALTER SEQUENCE
    
  • 描述

    更改一个现有序列的参数。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“ALTER SEQUENCE”。

    注意

    1. 使用`ALTER SEQUENCE`,必须拥有该序列。      
    2. 更改一个序列的模式,必须拥有新模式上的`CREATE`特权。      
    3. 更改拥有者,必须是新拥有角色的一个直接或者间接成员,并且该角色必须具有该域的模式上的`CREATE`特权(这些限制强制修改拥有者不能做一些通过删除和重建该序列做不到的事情。但是,数据库管理员能够更改任何序列的所有权。)。
    

13.4.DROP SEQUENCE

  • 大纲

    DROP SEQUENCE
    
  • 描述

    删除序列。

    详细信息请参见《优炫数据库管理系统SQL命令手册》的“DROP SEQUENCE”。

注意

一个序列只能被其拥有者或数据库管理员删除。

  • 示例

    删除序列serial,如下所示。

    DROP SEQUENCE serial;
    

14.事务管理

同大多数的商业数据库一样,UXDB数据库也引入了事务的概念。本章介绍UXDB中的事务以及事务的管理。

14.1.事务的概念

数据库中的事务一个独立的逻辑单元。它包括了一个或多个 SQL语句。数据库工作的基本单位是事务,事务是不能被拆分的。一个事务执行的结果只可能有两个:事务内的语句都成功执行,事务执行成功,即事务提交;或事务执行失败,本事务不对数据造成任何影响,即事务回滚。为了更形象的描述事务,举一个简单的例子:银行数据库如何处理客户转账。一个客户有这样的要求:把一笔钱从A帐户转到B帐户。这个要求可以拆分为三个独立的部分:

  • 帐户A划走这笔钱

  • 帐户B增加这笔钱

  • 记录这笔交易

整个交易过程数据库确保最终达到如下两种状态中的一个:

  • 三条语句都成功执行,达到转账目的并且做交易记录。整个事务提交,数据应用到数据库。

  • 其中一条语句执行过程发生错误,比如A帐户资金不足,B帐户不存在,或者在整个交易过程中发生硬件故障,数据库停机。整个事务回滚,执行成功的语句被撤销,执行失败的语句不对数据造成影响,还未执行的语句不再执行。数据回滚到此事务未开始的状态。无论什么原因,整个业务逻辑不允许出现诸如帐户A上的钱被划走,而却没有到达帐户B,或者这个交易没有被记录这样的中间结果,整个交易必须是原子性的,要么整个操作成功,要么整个操作失败。数据库的事务概念正是吻合了此要求。

一条SQL语句成功执行标志着:

  • SQL语句被解析,语法正确。

  • SQL语句是有效的,语义正确。

  • 一些数据可能被更改,但是这些更改不是永久性的,在此语句所在事务提交前,数据的更改并没有在整个数据库生效。

对于事务的执行结果,只能有提交和回滚。

  • 提交操作意味着:事务内的语句对数据的改变被数据库接受。这将造成数据对于整个数据库发生永久性的改变。

  • 回滚操作意味着:这个事务内所有对数据造成的更改全部被撤销。

一条SQL语句执行失败会回滚整个事务。

14.2.事务的特性

为了保证数据库中的数据一致性,确保UXDB能够在并发访问和系统发生故障时对数据进行维护,事务作为数据库工作的基本单位,具有下列四个特性,称为事务的ACID特性。

  • 原子性(Atomicity)

    一个事务对数据库的所有操作,是一个不可分割的工作单元。这些操作要么全部执行,要么什么也不做。

  • 一致性(Consistency)

    一个事务独立执行的结果应保持数据库的一致性,即数据不会因为事务的执行而遭受破坏。例如事务的概念里银行转账的例子,保证了数据的一致性。

  • 隔离性(Isolation)

    在多个事务并发执行时,系统应保证与这些事务先后单独执行时的结果一样,此时称事务达到了隔离性的要求,也就是在多个并发事务执行时,保证执行结果是正确的,如同单用户环境一样。隔离性是由UXDB的并发控制子系统实现的。

  • 持久性(Durability)

    一个事务一旦完成全部操作后,它对数据库的所有更新应永久地反映在数据库中。即使以后系统发生故障,也应保留这个事务执行的痕迹。

事务是恢复和并发控制的基本单位。UXDB能够保证事务的ACID特性不被破坏,分为以下几种情况:

  • 多个事务并发运行时,不同事务的操作交叉执行。UXDB保证多个事务的交叉运行不影响这些事务的原子性。

  • 事务在运行过程中被强行终止。UXDB保证被强行终止的事务对数据库和其他事务没有任何影响。

14.3.数据库对事务的管理

对于事务的管理,UXDB支持事务的隐式和显式提交,即自动提交和非自动提交。

  • 自动提交事务

    默认一个SQL语句为一个事务,当此语句执行成功后,由系统隐式提交。数据更改被数据库接受。当SQL执行失败,自然视做回滚,不对数据造成影响。UXDB默认提交事务方式为自动提交。

  • 非自动提交事务

    事务的开始为第一个SQL语句。事务的结束必须用户显式的使用COMMIT语句提交整个事务或者使用ROLLBACK语句回滚整个事务。如果客户端连接断开,那么未提交的事务做回滚操作。

    当用户想自己控制事务的执行,可以显式的用BEGIN语句开始一个事务,然后在事务结束时应该使用COMMIT或ROLLBACK语句显式提交。

    接口中也有对事务提交方式的控制,配置相应的配置文件可以使会话处于自动提交或非自动提交模式。

一个事务的提交和回滚对数据库实例造成的影响如下所示。

  • 一个事务提交对数据库实例造成的影响

    • 所有数据库更改对整个数据库生效。

    • 保证此事务产生的日志写到磁盘。

    • 释放所有此事务进行过程中申请的锁。

    • 数据库标记此事务结束。

  • 一个事务回滚对数据库实例造成的影响

    • 撤销所有对数据的更改到此事务开始之前的状态。

    • 释放所有此事务进行过程中申请的锁。

    • 数据库标记此事务结束。

14.4.数据的一致性和并发控制

在实际应用中数据库资源对用户是共享的,不同的用户在不同或相同的时刻使用数据库,这就是数据库的并发操作。在多用户数据库环境中,并发操作提高了数据库资源的使用效率,但若对这种并发操作不加限制就会破坏数据的完整性和一致性问题。

由于数据库工作的基本单位是事务,针对事务并发操作中的各类问题,SQL标准提出了事务的隔离级别概念。

14.4.1.事务的隔离级别

并发操作虽然可以改善系统的资源利用率和短事务的响应时间,但是在运行中必须对并发事务加以控制,否则会引发一些问题,SQL92标准对这些情况进行了分类,以及提出了解决办法。

由于一个事务可能包含多个SQL语句,SQL语句是顺序执行的。T1和T2两个事务在一个数据库上并发执行,可能有如下类型的问题:

  1. 读“脏”数据(Dirty Read)

    事务T1更新了一个数据,并且在T1提交或者回滚前,另外一个事务T2读取了那个数据。如果T1这个时候回滚,那么T2就读取了一个未提交的虚假的值,即“脏”数据。

  2. 不可重复读(Non-Repeatable 或 Fuzzy Read)

    事务T1读取了一个数据。这个时候另外一个事务T2修改或者删除了这个数据并且提交了。如果T1尝试再读取一次这个数据,就会发现再次读到的数据与之前不一致或不存在。

  3. 幻象读(Phantom Read)

    事务T1读取了若干个满足某个查询条件的数据。这个时候事务T2创建了一个数据恰好也满足T1的这个查询条件。如果这个时候T1再次根据这个查询条件进行读取,它会发现会多出了部分数据。

很显然,高并发度带来了数据的不一致,这些情况一些是用户不愿意见到,一些则是无法接受的。用户需要在高并发带来的高性能和数据的一致性之间做取舍。SQL92标准提出了事务隔离级别,来解决上面的问题。

事务的隔离级别

隔离级别读脏数据不可重复读读幻象数据
读未提交(Read uncommitted)可能可能可能
读已提交(Read committed)不可能可能可能
可重复的读(Repeatable read)不可能不可能可能
可串行化(Serializable)不可能不可能不可能

四个隔离级别从上到下对事务执行的并发程度进行了不同程度的限制,更加严格的限制在带来更好的数据一致性的同时,也会损失更多并发带来的高性能。

实际使用中,隔离级别并不是越高就越好,大多数情况下应用并不需要很高的数据一致性。相反的,在多用户环境下,更强调的是并发度。所以综合考虑选取一个折中的办法往往能达到最优的效果。

  • 读已提交 (Read committed)

    READ COMMITTED是UXDB默认的事务隔离级别。在运行在该隔离级别的事务中,查询语句只能看到该查询开始执行之前提交的数据,而不会看到任何未提交的数据或查询执行期间并发的其它事务提交的数据,但是该查询可以看到本事务中查询之前执行的数据更新。

    在READ COMMITTED隔离级别下,对于事务T1中的更新和删除语句,与查询语句相同,只能看到语句开始执行时提交的数据行,但是,这些数据行可能已经被同时并发的另一个事务B更新,在这种情况下,事务T1将等待事务T2回滚或提交。如果事务 T2回滚,则事务T1在原来的数据上继续更新,如果事务T2提交了,将分两种情况,1):如果事务T2删除了该行,则事务T1 忽略该行,2):如果事务T2对该行进行了更新,则事务T1判断该行的新值是否还满足条件,如果满足条件,则事务T1在新数据行上进行更新,如果不满足条件,则忽略该行。

    在READ COMMITTED隔离级别下,同一个事务的不同查询看到的可能是不同的数据,因此会出现不可重复读的问题。这种隔离级别对于大多数的应用已经能够满足要求,但有些应用需要提供更加严格的数据一致性。

    为了避免同样的查询得到不同的结果,在READ COMMITTED隔离级别下,应用程序在同一事务内应该尽量避免重复的查询。

  • 可串行化(Serializable)

    SERIALIZABLE提供了更加严格的事务隔离级别,在该事务隔离级别下,事务并发执行,其结果与某个串行执行顺序的结果完全相同。

    在运行在SERIALIZABLE隔离级别的事务中,查询语句只能看到该事务开始执行之前已经提交的数据,而不会看到任何未提交的数据或事务执行期间,并发的其它事务提交的数据,但是该查询可以看到本事务中查询之前执行的数据更新。

    在SERIALIZABLE隔离级别下,对于事务 T1中更新和删除语句,与查询语句相同,只能看到事务开始执行时提交的数据行,但是,这些数据行可能已经被同时并发的另一个事务T2 更新(事务 T2 开始的时间在事务 T1前),在这种情况下,事务T1将等待事务T2回滚或提交。如果事务T2回滚,则事务T1在原来的数据上继续更新,如果事务T2提交了,则事务T1就会出错回滚,因为一个串行事务不能修改在该事务开始后被其它事务修改的数据。

    SERIALIZABLE隔离级别可以确保每个事务看到一个完全一致的数据,但是当出现并发更新时,后更新的事务必须回滚,只能在之前的更新提交后再重新执行。

    在SERIALIZABLE隔离级别下,应用程序如果碰到更新语句回滚,应该重执行更新语句所在的整个事务。

14.4.2.并发控制的实现

UXDB在多用户环境的并发访问,是通过多版本并发控制和封锁机制共同实现的。

14.4.2.1.多版本并发控制

多版本并发控制,即MVCC(Multi-version concurrency control)。对于表里的某个一行R,多版本并发控制通过每个写R的操作建立R的一个新版本,当执行一个读R的操作时,针对操作所在的事务,系统选择R的一个正确版本来进行操作。多版本并发控制的一个显著好处是读操作和写操作并不互斥。

例如:如果用户A希望读取表T上的所有数据,而此时用户B正在更新表T上的某行数据r。对于多版本并发控制系统,B用户的更新操作对于r生成新的版本r(i)进行修改,而不是直接修改数据。用户A读操作同样获取一个版本的数据r(j)。所以利用区分版本的方式,用户A不必等待B的完成。

这里的版本概念也称作快照(snapshot)。一个快照就是在某个时刻的数据库映像。比如,当事务开始时,系统为对应的时间点的数据生成一个快照。在这个快照中包含的数据十分关键,可能包含了那个时刻未提交的事务所产生的数据,还可能包含了那个时刻已经提交的事务产生的数据。换句话说一些数据在这个快照中是可见的,另一些是不可见的。毫无疑问,这影响到了数据的一致性。

可以用快照对数据的可见性,定义数据库的隔离级别。

  • 读已提交 (Read committed)

    当一个事务隔离级别为读已提交时,在事务里每个SQL语句开始时,按规则生成一个快照,对于还没有提交的数据,认为不可见,否则可见。

  • 可串行化 (Serializable)

    当一个事务隔离级别为可串行化时,事务开始时生成一个快照,如果在这个事务开始时还没有提交的数据,认为它们不可见,否则可见。

多版本控制带来的巨大好处是最大可能的支持并发的查询操作,即使修改数据时也不会阻塞读。

14.4.2.2.锁

除了多版本并发控制,锁机制也是实现并发访问的必不可少的手段。

表 锁

编号锁模式(LOCKMODE)对应操作与之冲突的模式
1AccessShareLockSELECT8
2RowShareLockSELECT FOR UPDATE7,8
3RowExclusiveLockINSERT, UPDATE, DELETE5,6,7,8
4ShareUpdateExclusiveLockVACUUM4,5,6,7,8
5ShareLockCREATE INDEX3,4,6,7,8
6ShareRowExclusiveLocklike ExclusiveLock, but allows ROW SHARE3,4,5,6,7,8
7ExclusiveLockblocks ROW SHARE2,3,4,5,6,7,8
8AccessExclusiveLockDROP TABLE, ALTER TABLE全部

UXDB使用锁控制用户对数据库对象,包括:表、页面、元组、事务、非表对象(函数,触发器等)的并发访问。

如果一个对象被加上了一种模式的锁,那么其他用户如果想加上和此模式相冲突的锁,就会发生冲突。这个用户必须等待,直到加上的锁被释放。

两到多个事务相互争用资源时,可能发生死锁。UXDB支持自动检测死锁,并且自动处理。例如:事务T1已经获得表A上的排它锁(如成功更新表A上的列a:update A set a = 1;),事务T2已经获得表B 上的排它锁(如成功更新表B行的列a:update B set a = 1;),现在T1申请表B上的排它锁(如尝试更新表B上的列 a:update B set a = 1;),由于冲突,发生锁等待,这时T2申请表A上的排它锁(如尝试更新表A上的列a:update A set a = 1;),也冲突,形成死锁。这时UXDB检测到T1和T2发生死锁,强制回滚T2,解决死锁。