GUCS 大修

来自 PostgreSQL wiki
跳转到导航跳转到搜索

问题

目前,postgresql.conf 和我们的 GUC 配置集存在一些重大问题

  1. 大多数人不知道如何设置这些参数。
  2. 当前的 postgresql.conf 文件是一个包含 194 个选项的巨大混乱,其中绝大多数是大多数用户永远不会触碰的。
  3. GUCS 列表保存在 3 个不同的位置(guc.c、postgresql.conf 和 settings.sgml),它们之间只能手动同步。
  4. 我们似乎离自动调优越来越远了。

目标

  • 至关重要的是,GUCS 用户端的任何大修都必须在一个版本中完成,以最大限度地减少所涉及的痛苦。
  • 文件格式应以易于解析和生成的方式进行标准化。
  • 内部数据和 pg_settings 视图应包含输出新的 postgresql.conf 所需的一切,该文件在功能上与原始文件相同
    • 在涉及包含文件的情况下,这将更加困难。
  • 通过从 postgresql.conf 作为文档格式和手动编辑的模型转变为机器生成的模型,编写简单的实用程序来管理这些设置变得容易得多。现在,像 SET PERSISTENT 这样的东西最大的“障碍”是“如何保留文件中手动编辑的注释”——答案是我们不需要。不会
  • 缺乏通过端口访问 PostgreSQL 来管理设置的简单方法是 PostgreSQL 在具有大量服务器的环境中采用的重要阻碍因素。使此功能可用将使其更容易集成到像 CPANEL 这样的工具中,进而扩展 PostgreSQL 网站托管的可用性。

陷阱

  • 不可能将所有设置都推送到数据库本身以完全消除 postgresql.conf,因为在读取数据库之前需要相当多的 GUC 参数;特别是那些关于文件位置和共享内存大小的参数。
  • 远程操作的工具必须考虑它们可能会进行会导致服务器无法启动的更改。假设您以一种破坏数据库的方式更改了一个参数(例如,将 shared_buffers 设置为超过内核允许的值),然后尝试重启。数据库无法启动。如果您只有在数据库启动后才能通过端口 5432 访问数据库,并且您无法通过直接编辑文件来更改该参数,那么您就完蛋了。
    • 为了支持托管服务器目标,也许可以生成一个备用的“已知良好”备份文件,并在主文件无法工作时使用。
    • 正在探索的另一个选择是编写一个配置文件检查器。目前尚不清楚它如何才能知道使用新配置所需的共享内存块是否足够大。

设计方案

更新 pg_settings (已完成)

公开一些在 pg_settings 中可用但不可见的信息

  • 默认值。需要支持 pg_generate_conf,以及对调优工具作者非常有用。
  • 设置在源文件中显示的方式。您可以使用 current_setting(name) 获取有用的重新缩放设置,这可能就足够了,而不是再提供另一种方法。
  • 设置的来源,用于区分来自主文件和来自包含文件的设置。这仅在重新生成包含其他文件的复杂 postgresql.conf 文件时需要。

这项工作已于 2008 年 10 月 6 日完成。

推荐一个区分用户和系统生成的注释的标准

现在 postgresql.conf 有这样的行

max_connections = 100           # (change requires restart)
# Note:  Increasing max_connections costs ~400 bytes of shared memory per
# connection slot, plus lock space (see max_locks_per_transaction).  You might
# also need to raise shared_buffers to support more connections.

在现场管理员最终采用了一些常见的习语来处理这个文件,以便他们可以区分自己的更改和关于这些更改的注释,以及最初存在的文本。提供一种标准的方式来处理这个问题,而不必真正更改任何服务器代码,只需要提供一个新的 postgresql.conf 即可。以下是一个关于如何将此参数重新处理成新形式的建议,其中系统生成的注释以 #! 区分;还包含一个关于更改控制的良好用户注释的示例

#! Note:  Increasing max_connections costs ~400 bytes of shared memory per
#! connection slot, plus lock space (see max_locks_per_transaction).  You might
#! also need to raise shared_buffers to support more connections. 
#! (change requires restart)
# 2008-09-16 Increased to 200
max_connections = 200

如果采用这种方法,它将使操作 postgresql.conf 文件的代码更容易管理。一个简单的程序可以在管理员请求时将文件转换为不同级别的详细程度。

编写一个注释转换工具

给定一个正常 postgresql.conf 中出现的库存注释列表,一个简单的脚本可以删除这些行或部分行,同时保留用户评论和更改。这将允许具有现有 postgresql.conf 文件的用户轻松采用新标准,同时保留其当前注释。

添加 pg_settings_info

注意:枚举列表目标已在 8.4 开发过程中添加到 pg_settings 视图中。但是,该实现只是一个简单的字符串。如果它是一个 text[],则它将与这里其他内容更正交。Greg Smith 自愿在 8.4 时间线中进行该更改。

添加一个新表(pg_settings_info),其中包含 GUC 操作不需要的附加信息,其中包含以下字段的子集

  • 当前 postgresql.conf 样例中的系统注释。这是启用 pg_generate_conf 所需的主要内容;此列表中的以下项都是可选的。
  • 保存的用户注释
  • 子类别
  • 更多文档
    • 更长的描述,也许是该选项的全部文档?
    • 指向此选项完整文档的 Web 链接?
      • 手头有一个系统 postgresql.conf,也许每个部分都首选文档的相应部分。那里的 URL 可以根据已知的文档映射方式进行构建,而不是显式设置。
  • 建议
  • 枚举列表
  • 如果查看 pg_settings 可以获得人们对 带注释的 postgresql.conf 的所有喜爱,那将是一件好事。

以下是一些支持以下目标的最小实现的 DDL

CREATE TABLE pg_settings_info (
    name text,
    system_comments text[],
    user_comments text[],
    UNIQUE(name)
);

该领域的一些剩余问题

  • 即使使用所有导入的信息重建原始文件,一个问题是用户可能在配置文件中设置了一组特定的参数,也许是为了以与默认值不同的方式对它们进行分组。最近补丁中添加的源文件行号允许处理这种情况。
  • 这里一个棘手的问题是,在现实世界中,人们倾向于在文件的顶部或底部放置一个标题,其中包含有关此主机等的注释,这些注释实际上与任何特定参数无关。

将 postgresql.conf 样例中的注释移动到系统注释列

当前出现在 postgresql.conf 中的所有特定于参数的注释都需要移到 pg_settings_info.system_comments 区域。

编写 pg_generate_conf

pg_generate_conf 将使用以下开关

  • -b , --basic — 简短的 conf 文件,仅列出 15-18 个最常更改的选项
  • -a , --advanced — 列出所有 196+ 个选项的 conf 文件
  • -t, --terse — conf 文件仅列出类别标题和实际设置,没有注释
  • -n, --normal — conf 文件具有类别和子类别设置,并附带简短的描述性注释
  • -v, --verbose — conf 文件在每个选项的注释中列出完整描述和建议
  • -c "option = value" 在文件中将特定选项设置为特定值
  • -f "filename" — 从文件“filename”中获取选项和值

默认值为“-b, -n”,shared_buffers 和 wal_sync_method 的设置特定。当前的 postgresql.conf 更像是“-a, -v”文件。

这将以以下方式帮助我们

  • 通过拥有一个生成的 postgresql.conf 和一个简单的方法来生成它,编写自动配置脚本(以及像 SET PERSISTENT 这样的快捷方式)变得容易得多。
  • 大多数用户只需要处理有限的 15-20 个配置变量。
  • 维护 GUCS 列表的 3 个地方将是:文档、guc.c 和用于填充 pg_settings_info 的文件

pg_generate_conf 应该能够读取它自己的输出作为输入,并生成一个具有相同参数但具有不同详细程度的新文件。

这里另一种方法是在数据库服务器本身中包含一些易于阅读的基于文本的文档,然后在 postgresql.conf 中引用它(以及官方文档)。

移除 postgresql.conf.sample

  • 删除 postgresql.conf.sample 文件
  • initdb 现在可以调用 pg_generate_conf 来基于 guc.c 和命令行开关生成 postgresql.conf,而不是基于 postgresql.conf.sample。

相关项目

服务器端更改

需要有一种方法来修改底层设置并将这些设置保存到新的机器生成的 postgresql.conf 文件中。实现 SET PERSISTENT 是否足以满足此要求?

调优向导

想象一个 GUI 或 Web 应用程序,它连接到端口 5432 上的服务器,找出有关服务器的一些基本信息,然后给出类似于以下内容的信息

Parameter               Current Recommended     Change?
shared_buffers          32MB    1024MB          [X]
effective_cache_size    128MB   3000MB          [ ]
work_mem                1MB     16MB            [ ]

保存参数更改历史记录

许多 IT 部门希望在更新参数时进行某种形式的历史记录。以下内容将满足大多数此类要求

# 2008-03-02 : 32MB : postgres : Database default
# 2008-05-02 : 512MB : pg_autotune : Wizard update
# 2008-05-15 : 1024MB : gsmith : Increased after benchmark tests
shared_buffers = 1024MB

调优向导应该以这种方式标记其注释。希望如果这种格式得到推荐并且有效,其他人也会将其作为进行手动编辑的事实标准。

调优信息来源