发布日期:. 2021-11-11
本次发布包含来自 13.4 的多项修复。 有关 13 主版本新特性的说明,请参见 Section E.24.
对于运行 13.X 的用户,不需要执行导出/恢复。
但是,请注意使用物理复制的安装应先更新备库再更新主库, 如下面第三个变更日志条目所述。
此外,已发现若干可能导致索引损坏的错误, 如接下来几个变更日志条目所述。如果存在上述任一情况, 建议在更新后重建可能受影响的索引。
此外,如果是从早于 13.2 的版本升级,请参见 Section E.22。
使服务器在 SSL 或 GSS 加密握手后拒绝多余的数据(Tom Lane) §
能够向 TCP 连接注入数据的中间人攻击者可以在本应受加密保护的数据库会话开始时 塞入一些明文数据。 这可以被用来向服务器发送伪造的 SQL 命令, 不过只有在服务器不要求任何认证数据时才能生效。 (然而,依赖 SSL 证书认证的服务器很可能不会要求认证数据。)
PostgreSQL 项目感谢 Jacob Champion 报告此问题。 (CVE-2021-23214)
使 libpq 在 SSL 或 GSS 加密握手后拒绝多余的数据(Tom Lane) §
能够向 TCP 连接注入数据的中间人攻击者可以在本应受加密保护的数据库会话开始时 塞入一些明文数据。 这可能被用来向客户端注入伪造的响应, 不过 libpq 行为的其他细节使得这比听起来更难实现。另一种攻击方式是 窃取客户端的密码或其他可能在会话早期发送的敏感数据。已证明 在受 CVE-2021-23214 漏洞影响的服务器上这是可能的。
PostgreSQL 项目感谢 Jacob Champion 报告此问题。 (CVE-2021-23222)
修复在主库发送以不完整 WAL 记录结尾的 WAL 段后崩溃时的物理复制问题 (Álvaro Herrera) § § §
如果主库未能存活足够长的时间来完成写入不完整 WAL 记录的剩余部分, 则之前的崩溃恢复逻辑会回退并从不完整 WAL 记录的开头处重新覆盖写入 WAL。 这是有问题的,因为备库可能已有该 WAL 段的副本。 它们随后会看到不一致的下一个段,将无法在没有人工干预的情况下恢复。 为修复此问题,在崩溃后重新启动时不再跨越 WAL 段边界回退。 而是在下一个 WAL 段的开头写入一种新类型的 WAL 记录, 通知读取器不完整的 WAL 记录将永远不会被完成且必须被忽略。
应用此更新时,最好先更新备库再更新主库, 这样如果主库发生崩溃,备库就已准备好处理这种新类型的 WAL 记录。
修复 CREATE INDEX CONCURRENTLY 以等待最新的预备事务(Andrey Borodin) §
刚刚预备的事务插入的行可能会从新索引中遗漏, 导致依赖该索引的查询错过此类行。 之前对此类问题的修复未能考虑到在 CREATE INDEX CONCURRENTLY 检查时仍在进行中的 PREPARE TRANSACTION 命令。 与之前一样,在启用了预备事务(max_prepared_transactions > 0)的安装中,建议重建所有并发构建的索引, 以防在构建时发生了此问题。
避免竞态条件导致后端无法将新行的条目添加到正在并发构建的索引中(Noah Misch,Andrey Borodin) §
虽然此情况在实际环境中似乎很少发生,但它可能影响 使用 CONCURRENTLY 选项构建或重建的任何索引。 建议重建此类索引以确保其正确性。
修复 float4 和 float8 的哈希函数,使其对 NaN 产生一致的结果(Tom Lane) § § §
由于 PostgreSQL 的浮点类型将所有 NaN 视为相等,哈希函数必须为所有按 IEEE 754 标准表示 NaN 的位模式生成相同的哈希值。以前没有做到这一点,因此对于非规范的 NaN 值,哈希索引和基于哈希的查询计划可能产生错误结果。(在大多数机器上,'-NaN'::float8 就是产生此类值的一种方法。)如果浮点列的哈希索引有任何可能包含此类值,建议重建这些索引。
修复 REINDEX CONCURRENTLY 以保留附加到目标索引上的操作符类参数 (Michael Paquier) §
防止在 wal_level = minimal 时,对 CREATE TABLESPACE 进行崩溃恢复导致数据丢失(Noah Misch) §
如果服务器在 CREATE TABLESPACE 与下一次检查点之间崩溃,重放会完全删除新表空间目录中的内容,并依靠后续 WAL 重放来恢复目录中的一切。这与跳过 WAL 写入的优化配合不当(例如向刚创建的表执行 COPY)。此类优化仅在 wal_level 为 minimal 时应用,而这并非 v10 及更新版本的默认设置。
确保在将表附加到分区表或从分区表中分离时正确地使关系缓存失效(Amit Langote,Álvaro Herrera) §
此疏忽可能导致直接对该分区进行后续插入/更新时出现错误行为, 但仅在当前已存在的会话中。
确保将分区表添加到发布或从发布移除时,使其所有分区的关系缓存失效(Hou Zhijie,Vignesh C) §
这一疏漏可能导致不正确的复制行为,直到所有当前已存在的会话都退出。
确保创建或删除 FOR ALL TABLES 发布时使关系缓存失效(Hou Zhijie,Vignesh C) §
这一疏漏可能导致不正确的复制行为,直到所有当前已存在的会话都退出。
不要丢弃未指定类型修饰符的同类型转换(Tom Lane) §
例如,如果列 f1 的类型为 numeric(18,3),解析器以前会直接丢弃 f1::numeric 这样的类型转换,理由是它在运行时没有任何作用。这一点没错,但表达式对外呈现的类型仍应视为普通的 numeric,而非 numeric(18,3)。这对于正确确定更大结构的类型很重要,例如递归 UNION。
修复复合类型上域的数组中元素字段的更新问题(Tom Lane) §
如果数组的元素是域而不是普通复合类型,则类似 UPDATE tab SET fld[1].subfld = val 这样的命令会失败。
禁止 FETCH FIRST WITH TIES 和 FOR UPDATE SKIP LOCKED 的组合(David Christensen) §
FETCH FIRST WITH TIES 必然会多获取一行, 因为在找到非并列行之前它无法停止。在我们当前的实现中, 如果使用了 FOR UPDATE,那么该行也会被锁定,即使它不会被返回。 如果指定了 SKIP LOCKED 选项,则会导致不期望的行为。 在不引入另一组不期望行为的情况下很难改变这一点,因此目前禁止此组合。
如果当前数据库的编码不支持某个 ICU 排序规则,则禁止创建该排序规则(Tom Lane) §
以前允许这样做,但由于排序规则查找的工作方式,之后无法引用该排序规则;既不能使用它,甚至也不能删除它。
禁止 ALTER INDEX index ALTER COLUMN col SET (options)(Nathan Bossart,Michael Paquier) §
虽然解析器接受此语法,但它没有文档记录且实际上不起作用。
修复 numeric power() 在边界情况下的精度损失(Dean Rasheed) §
当第一个参数非常接近 1 时,结果可能不准确。
避免 {0} 内部存在捕获括号时出现正则表达式错误(Tom Lane) §
(.){0}...\1 这样的正则表达式会产生 “invalid backreference number” 错误。但 Perl 等其他正则表达式引擎不会报错,而且在一些非常相近的情况下,我们的引擎也不会报错。更糟的是,它还可能触发断言失败。现在修复为不抛出错误,而是静默地将该反向引用视为永不匹配。
防止正则表达式的反向引用有时在不应匹配的情况下匹配(Tom Lane) §
正则表达式引擎在拒绝一个部分匹配后,没有仔细清除捕获括号的匹配数据。这可能使后续的反向引用在本应因没有已定义的引用对象而失败的位置匹配成功。
修复迭代节点内部反向引用的正则表达式性能缺陷(Tom Lane) §
错误的回溯逻辑可能使寻找匹配所花费的时间呈指数级增长。幸运的是,其他优化在大多数情况下掩盖了此问题。
修复对 time with time zone 值应用 AT TIME ZONE 时产生的错误结果(Tom Lane) §
如果目标时区通过动态时区缩写指定(即定义为等价于完整时区名称,而非固定 UTC 偏移量的缩写),结果就会不正确。
修复将子查询表达式上拉到函数范围表条目时的规划器错误(Tom Lane) §
如果 FROM 中的函数横向引用了 FROM 子句中 较早出现的某个子 SELECT 的输出, 并且我们能够将该子 SELECT 展平到外层查询中, 则复制到函数表达式中的表达式未被完全处理。 这可能导致执行时崩溃。
修复将 PlaceHolderVars 转换到继承子关系时的错误(Tom Lane) §
此错误可能导致断言失败,或使外连接可空一侧含有分区表或继承表的查询得到错误的计划。
避免仅使用 MCV 统计信息来估计列的范围(Tom Lane) §
在某些边界情况下,ANALYZE 会构建高频值(MCV)列表 但不构建直方图,即使 MCV 列表并未包含所有观测值。 在这种情况下,防止规划器仅使用 MCV 列表来估计列值的范围。
修复子事务内部 Portal 快照的恢复(Bertrand Drouvot) §
如果过程提交或回滚了一个事务,然后其下一个重要操作在新的子事务内部, 快照管理会出错,导致悬挂指针和可能的崩溃。 PL/pgSQL 中的一个典型示例是 COMMIT 紧跟一个执行查询的 BEGIN ... EXCEPTION 块。
确保在事务导出快照后失败时正确清理(Dilip Kumar) §
此疏忽仅在同一会话再次尝试导出快照时才会导致问题。 最可能的场景是创建复制槽(随后回滚)然后再创建另一个复制槽。
防止备库上溢出子事务跟踪的回卷(Kyotaro Horiguchi,Alexander Korotkov) §
此疏忽可能导致备库上显著的性能下降 (表现为过多的 SubtransSLRU 流量)。
确保在备库提升期间正确地将预备事务纳入考虑(Michael Paquier,Andres Freund) §
存在一个很窄的窗口,预备事务可能从并发运行的会话获取的快照中被遗漏。 如果该会话随后使用该快照执行数据更新, 可能导致错误的结果或数据损坏。
禁止在后台工作进程中使用 LISTEN(Tom Lane) §
没有支持此功能的基础设施,因此如果有人这样做,只会导致 NOTIFY 队列无法清理。
在事务提交期间向其他后端发送 NOTIFY 信号,而不在服务器的空闲循环中发送(Artur Zakirov,Tom Lane) §
此项修改使通知可以在过程内部执行 COMMIT 后立即送达,也允许逻辑复制工作进程发送通知。
如果标记为 NO SCROLL 的游标因 WITH HOLD 选项而从上一个事务保留下来,则拒绝将其退回起点(Tom Lane) §
我们早已禁止从 NO SCROLL 游标向后获取数据,但由于历史原因,这一禁令没有涵盖将整个查询退回起点后再向前重新获取的情况。这一例外会导致不一致,尤其是对于跨事务保留的游标,它们可能没有存储退回起点所需的全部数据。现在禁止不可滚动的保留游标退回起点,以避免最严重的不一致。(v15 将完全移除这一例外。)
修复事务结束时保存已读取完毕的 WITH HOLD 游标可能发生的失败(Tom Lane) §
修复对已增长到最大允许长度的关系的检测(Tom Lane) §
虽然尝试将表或索引扩展到超过 2^32-1 个块的限制会被拒绝,但拒绝得不够早,未能防止产生不一致的内部状态。
展开 DO INSTEAD 规则时,正确跟踪是否存在修改数据的 CTE(Greg Nancarrow,Tom Lane) §
以前未能做到这一点,可能导致不安全地选择并行计划等问题。
修复对扩展统计对象权限检查失败的不正确报告(Tomas Vondra) § §
代码通常会产生 “cache lookup error”,而非预期的消息。
修复并行工作进程中不正确的快照处理(Greg Nancarrow) §
如果事务隔离级别低于 REPEATABLE READ,这一疏漏可能导致并行查询行为异常。
修复逻辑解码,使其正确忽略短暂表的 TOAST 表变更(Bertrand Drouvot) §
逻辑解码通常会忽略短暂表中的变更,例如 ALTER TABLE 堆重写期间创建的表。但这一过滤没有应用于其关联的 TOAST 表(如果存在),因而在重写正在发布的表时可能出错。
修复逻辑解码的内存用量统计,使其正确处理 TOAST 数据(Bertrand Drouvot) §
确保 WAL 接收进程 进程在退出前创建所有必需的归档通知文件(Fujii Masao) §
如果 WAL 接收进程 恰好在 WAL 段边界处退出,它就不会为最后接收的段创建通知文件,从而延迟该段在备库上的归档。
避免尝试锁定使用 SELECT FOR UPDATE 的规则中的 OLD 和 NEW 伪关系(Masahiko Sawada,Tom Lane) §
修复解析器对聚合 FILTER 子句的处理(Tom Lane) §
如果 FILTER 表达式是普通的布尔列,聚合的语义层级可能被错误判定,从而产生不符合规范的行为。如果 FILTER 表达式本身是返回布尔值的聚合,本应抛出错误却没有,因而很可能在执行时崩溃。
确保在重命名表时使用正确的锁级别(Nathan Bossart,Álvaro Herrera) § §
由于历史原因,ALTER INDEX ... RENAME 可以应用于任何类型的关系。重命名索引所需的锁级别低于 重命名表或其他类型关系所需的锁级别,但代码在此处出错, 每当命令拼写为 ALTER INDEX 时都会使用较弱的锁级别。
防止 ALTER TYPE/DOMAIN/OPERATOR ... SET 改变扩展成员关系(Tom Lane) §
扩展脚本执行 ALTER ... SET 时,如果目标对象尚不属于该扩展,就会使其成为扩展成员。这本身并不太令人困扰,因为扩展脚本几乎没有理由操作不属于该扩展的对象。但 ALTER TYPE SET 会递归处理依赖它的域,从而使这些域也成为扩展成员。如果扩展升级脚本使用该命令调整属于扩展的某个基础类型的属性,就会产生不希望的副作用。通过重新定义这些 ALTER 操作,使其永不改变扩展成员关系来修复此问题。
避免在 LLVM 内部发生错误后尝试清理 LLVM 状态(Andres Freund,Justin Pryzby) §
这可以防止 LLVM 发生致命错误后,后端退出时很可能出现的崩溃。
避免在删除拥有正在被并发删除的对象的角色时出现空指针解引用崩溃(Álvaro Herrera) §
防止当 lo_export() 或相关函数失败时出现 “snapshot reference leak” 警告(Heikki Linnakangas) § §
确保统计视图会计入对 SP-GiST 索引的扫描(Tom Lane) §
SP-GiST 代码遗漏了递增索引扫描次数计数器的操作,虽然逐元组计数器已被正确递增。
修复 CoerceToDomain 表达式节点的低效代码生成(Ranier Vilela) §
如果在恢复期间修改 recovery_min_apply_delay,则重新计算相关等待间隔(Soumyadeep Chakraborty,Ashwin Agrawal) §
修复 simplehash.h 哈希表达到 2^32 个元素时的无限循环(Yura Sokolov) §
此缺陷似乎不太可能在实践中被触发,因为就 simplehash.h 的现有用途而言,需要将 work_mem 设置为数百 GB 才会出现。
避免某些列表操作中的 O(N^2) 行为(Nathan Bossart,Tom Lane) § § §
这些更改修复了多个场景中的慢处理问题,包括: 当备库重放主库上持有许多排他锁的事务时; 当检查点后有许多文件需要取消链接时; 当哈希聚合涉及许多批次时;以及当 pg_trgm 从复杂正则表达式中提取可索引条件时。 仅第一种场景实际上已在实际环境中被报告,但它们都似乎是 低效列表删除的合理后果。
增加更多围绕 B-树 posting list 分裂的防御性检查(Peter Geoghegan) § §
此更改应有助于检测涉及重复表 TID 的索引损坏。
当 shared_memory_type 为 sysv 时,禁止将 huge_pages 设置为 on(Thomas Munro) §
之前此设置会被接受,但由于缺乏实现而不起作用。
修复 AIX 上缺失的 libpq 函数(Tony Reix) §
代码重组导致 AIX 上的 libpq 没有导出以下已记录在文档中的函数:pg_encoding_to_char()、pg_utf_mblen()、pg_char_to_encoding()、pg_valid_server_encoding() 和 pg_valid_server_encoding_id()。现在恢复这些函数的可见性。
修复 ecpg,使其在建立连接期间 malloc() 失败后能够正确恢复(Michael Paquier) §
修复 PL/pgSQL CALL 语句参数中调用的稳定函数被错误求值的问题(Tom Lane) §
这些函数调用时使用了过期的快照,因此无法看到自会话顶层命令开始以来的任何数据库变更。
允许使用 EXIT 退出 PL/pgSQL 例程的最外层块(Tom Lane) §
如果例程不要求显式 RETURN,这种用法应该有效,但以前会被拒绝。
移除 pg_ctl 对生成命令总长度的硬编码限制(Phil Krylov) §
例如,这移除了对可传递给 postmaster 的命令行选项数量的限制。pg_ctl 处理的单个路径名,例如 postmaster 可执行文件名或数据目录名,在大多数情况下仍限制为 MAXPGPATH 字节。
修复 pg_dump 以正确导出非全局默认权限(Neil Chen,Masahiko Sawada) §
如果全局(不受限的)ALTER DEFAULT PRIVILEGES 命令撤销了某个默认存在的权限,例如函数的 EXECUTE,然后受限的 ALTER DEFAULT PRIVILEGES 命令又为选定的角色或模式重新授予了该权限, 则 pg_dump 无法正确导出受限的权限授予。
使 pg_dump 对要导出的分区表获取共享锁(Tom Lane) §
此疏忽通常是相当无害的,因为一旦 pg_dump 锁定了任何叶分区,就足以阻止对分区表本身的重大 DDL。 但是,在导出没有子分区的分区表时可能出现问题,因为不会持有相关的锁。
避免逐表查询 RLS 策略和重复调用 format_type(),从而提高 pg_dump 的性能(Tom Lane) § §
这些修改在从本地服务器转储时只能带来小幅提升,但从远程服务器转储时,可以因网络往返次数减少而获益显著。
修复 pg_dump 在尝试从 8.3 之前版本的服务器导出触发器定义时的崩溃(Tom Lane) §
修复 pg_restore 关于无效大对象 TOC 文件的错误消息中的不正确文件名(Daniel Gustafsson) §
确保 pgbench 在套接字级别失败后以非零状态退出(Yugo Nagata,Fabien Coelho) § §
期望的行为是完成运行但随后以状态 2 退出。同时修复了此类错误的报告。
修复对 "char" 列(而非 char( 列)的 n)contrib/btree_gin 索引使用 < 或 <= 操作符进行索引扫描时的失败(Tom Lane) §
这样的索引扫描无法返回所有应返回的条目。
改变 contrib/pg_stat_statements 以最大 1GB 为单位读取其 “查询文本” 文件(Tom Lane) §
如此大的查询文本文件非常不常见,但如果确实出现, 之前的代码在 Windows 64 上会失败(因为它拒绝超过 2GB 的单次读取请求)。
修复 contrib/postgres_fdw 尝试报告数据转换错误时的空指针崩溃(Tom Lane) §
增加对 RISC-V 架构的自旋锁支持(Marek Szuba) §
这对于在该平台上获得合理的性能至关重要。
支持 OpenSSL 3.0.0(Peter Eisentraut,Daniel Gustafsson,Michael Paquier) § § § §
为 PostgreSQL 创建的 OpenSSL BIO(I/O 抽象)对象设置正确的类型标识符(Itamar Gafni) §
这一疏漏可能只对执行审计 OpenSSL 安装等任务的代码有影响。但严格来说,这违反了 OpenSSL API,因此予以修复。
修复我们的 pkg-config 文件,使其重新支持静态链接 libpq(Peter Eisentraut) §
使 pg_regexec() 能够稳健地处理超出范围的 search_start 参数(Tom Lane) §
当 search_start 超过字符串末尾时,返回 REG_NOMATCH,而不再可能崩溃。核心 PostgreSQL 中可能不会出现这种情况,但扩展可能对参数值不够谨慎。
确保 GetSharedSecurityLabel() 可以在尚未构建关键 关系缓存条目的新启动会话中使用(Jeff Davis) §
使用 CLDR 项目的数据将 Windows 时区名称映射到 IANA 时区(Tom Lane) § § §
在 Windows 上运行时,initdb 尝试将新集簇的 timezone 参数设置为与系统当前时区匹配的 IANA 时区。 我们使用的是多年前生成的映射表,并且只是零星地更新; 不出所料,它包含许多错误以及遗漏了最近添加的时区。 事实证明 CLDR 一直在跟踪最合适的映射,所以开始使用他们的数据。 此更改不会影响任何现有安装,仅影响新初始化的集簇。
将时区数据文件更新至 tzdata release 2021e,包含斐济、约旦、巴勒斯坦和萨摩亚的夏令时法律变更, 以及巴巴多斯、库克群岛、圭亚那、纽埃、葡萄牙和汤加的历史更正。(Tom Lane) §
此外,Pacific/Enderbury 时区已重命名为 Pacific/Kanton。 同时,以下时区已合并到附近的、人口更多的时区中, 因为它们的时钟自 1970 年以来一直与之一致:Africa/Accra、 America/Atikokan、America/Blanc-Sablon、America/Creston、 America/Curacao、America/Nassau、America/Port_of_Spain、 Antarctica/DumontDUrville 和 Antarctica/Syowa。 在所有这些情况下,之前的时区名称仍作为别名保留。