本文介绍了PolarDB PostgreSQL 11版升级至PolarDB PostgreSQL 14版后的变化点。
概述
PolarDB PostgreSQL版作为一款企业级关系型数据库管理系统,具有广泛的应用和强大的社区支持。每个新版本的发布都带来了许多改进和新特性,以提高性能、可用性和安全性。目前,升级到PolarDB PostgreSQL14版本可以显著提升数据库性能与使用体验。
PolarDB PostgreSQL 14版本(简称PG 14版本)引入了新的查询优化算法和存储引擎,提高了查询速度和并发处理能力,能够更快地处理大量数据,提升数据库的响应能力和性能。此外,该版本还引入了许多新的功能和增强功能,提供更好的用户体验和开发者工具。例如,改进了对JSON数据类型的支持,使处理和查询JSON数据更加便捷;丰富的监控和诊断工具,帮助您更好地理解和优化数据库的性能;加强了数据库的安全性和可靠性,引入了更严格的访问控制策略和权限管理功能,保护您的数据免受潜在的安全威胁;改进了备份和恢复功能,使您能够更轻松地保护和恢复数据。
升级到PolarDB PostgreSQL 14版本还意味着您可以与PostgreSQL社区保持同步,提供更多的资源和支持,帮助您解决问题并学习数据库的最佳实践。建议您升级到PolarDB PostgreSQL 14版本。
在PolarDB PostgreSQL 11版本(简称PG 11版本)升级到PolarDB PostgreSQL 14版本的过程中,大部分的数据类型、内置函数、表列和对象都没有发生显著变化,大多数变化属于细节改进。通过逻辑复制等方式(推荐使用DTS工具)可以实现接近100%的兼容性,而具体的变化细节如下所示。
系统表和内置列
移除oid列的特殊行为。PG 11版本,在表创建过程中可以使用
WITH OIDS
来指定一个通常不可见的oid列,PG 14版本已经移除了该能力。但仍然可以显式声明列的数据类型为oid。对于使用WITH OIDS
创建的列的操作需要进行调整。PG 11版本中,系统目录中隐藏的oid列现在变成普通的oid列。因此,SELECT *
现在会输出这些列,而PG 11版本只有在显式选择时才会显示这些列。将类型为name的表列默认标记为
C
排序规则。数据类型为name的比较运算符现在可以使用任何排序规则,而不仅仅使用C
排序规则。为了保持查询的先前语义,现在明确将类型为name的表列标记为具有C
排序规则。这个副作用是,name列上的正则表达式运算符现在默认使用C
排序规则,而不是数据库的排序规则,以确定与区域相关的正则表达式模式(例如\w
)的行为。如果想在name列上的正则表达式中使用非C
行为,请附加一个明确的COLLATE
子句。(对于用户定义的name列,另一种可能性是在创建表时指定不同的排序规则,但这只是将不向后兼容性移动到比较运算符。)将
information_schema
视图中的对象名称列视为name
类型而不是varchar
类型。根据SQL标准,information_schema
视图中的对象名称列被声明为domain
类型sql_identifier
。在PostgreSQL中,底层目录列的类型实际上是name
类型。这个更改使sql_identifier
成为name
的domain
,而不是之前的varchar
。这消除了比较和排序行为中的语义不匹配,可以极大地改善对限制对象名称列的information_schema
视图的查询的性能。说明不等式限制:例如,
SELECT ... FROM information_schema.tables WHERE table_name < 'foo';
现在默认使用C
区域的比较语义,而不是之前的数据库默认排序规则。对这些列进行排序也将遵循C
排序规则,可以通过添加COLLATE "default"
子句来强制使用之前的行为(和低效性)。删除过时的
pg_constraint.consrc
列。该列已经被废弃很长时间,因为它没有根据其他目录更改(例如,列重命名)进行更新。从pg_constraint获取检查约束表达式的文本版本的推荐方法是pg_get_expr(conbin, conrelid)
。pg_get_constraintdef()
也是一个有用的替代方法。删除过时的
pg_attrdef.adsrc
列。该列已经被废弃很长时间了,因为它没有根据其他目录更改(例如,列重命名)进行更新。从pg_attrdef获取默认值表达式的文本版本的推荐方法是pg_get_expr(adbin, adrelid)
。
操作符和正则表达式
删除阶乘运算符
!
、!!
以及函数numeric_fac( )
,但仍然支持阶乘函数。删除对后缀(右一元)操作符的支持。如果正在转储后缀操作符,则
pg_dump
和pg_upgrade
将发出告警。防止
intarray
的包容运算符(<@
和@>
)使用GiST索引。之前需要进行完整的GiST索引扫描,所以避免进行完整的GiST索引扫描并扫描堆,这样操作速度更快,应删除为此目的创建的索引。重构几何函数和运算符的代码。可能会导致与PG 11版本相比更准确但稍有不同的结果。
说明与NaN、下溢、溢出和除零有关的情况的处理比以前更加一致。
允许
\D
和\W
通配符在正则表达式对换行符敏感模式中匹配换行符。在此模式下,之前它们不匹配换行符,但这与其他常见的正则表达式引擎的行为不一致,可以使用[^[:digit:]]
或[^[:word:]]
来获得旧行为。忽略正则表达式反向引用时的限制。例如,在
(^\d+).*\1
中,^
约束应在字符串的开头应用,但在匹配\1
时不应用。在正则表达式字符类中禁止将
\w
用作范围的起始或结束。
函数与表达式
不允许在负数的情况下使用
factorial
函数。PG 11版本中,该情况返回1。通过使用新算法改进了
real
和double precision
值的输出性能。PG 11版本中,显示的浮点数值默认情况下会四舍五入到6位(对于real
)或15位(对于double precision
),根据extra_float_digits
的值进行调整。在PG 14版本,只有在extra_float_digits
大于零时(默认情况),才会仅输出保留精确二进制值所需的最少位数。当extra_float_digits
设置为零或更小时,行为与PG 11版本相同。此外,浮点数指数的格式现在在各个平台上是统一的:除非需要三位数,否则使用两位数。当输入为单个NaN值时,将
var_samp()
和stddev_samp()
的numeric
参数返回NULL,PG 11版本中返回NaN。random()
和setseed()
在各个平台上的行为在PG 11版本中是统一的。在使用特定种子值进行setseed()
调用后生成的random()
值序列可能与PG 11版本中的不同。但是,它也是可重复的,在PG 11版本中无法保证,因为服务器内部的其他随机数使用可能会干扰。SQL的random()
函数现在具有自己的私有会话状态,以防止这种情况发生。将
EXTRACT()
的返回类型从float8更改为numeric。这样可以避免某些用法中的精度丢失问题。旧行为仍然可以通过使用旧的底层函数date_part()
来获得。此外,在PG 14版本中,EXTRACT(date)
对于不是date数据类型的单位会抛出错误。将SQL风格的
substring()
改为具有标准兼容的贪婪行为。在模式可以有多种匹配方式的情况下,在PG 14版本中,初始子模式被视为匹配最少可能的文本,而不是最多的。例如,模式%#"aa*#"
会选择输入中的第一个a组,而不是最后一个。引用某些内置数组函数及其参数类型的用户定义对象必须重新创建。具体来说,
array_append()
、array_prepend()
、array_cat()
、array_position()
、array_positions()
、array_remove()
、array_replace()
和width_bucket()
在PG 11版本中接受anyarray
参数,但在PG 14版本中接受anycompatiblearray
。因此,在升级之前必须删除引用这些数组函数签名的聚合和操作符等用户定义对象,并在升级完成后重新创建。在使用属性编号时,对于不存在或已删除的列进行
has_column_privilege()
检查时返回false。在PG 11版本中,此类属性编号会返回无效列错误。修复
to_tsquery()
和websearch_to_tsquery()
以正确解析包含已丢弃令牌的查询文本。某些已丢弃的令牌(如下划线)导致这些函数的输出产生不正确的tsquery
输出。例如,websearch_to_tsquery('"pg_class pg"')
和to_tsquery('pg_class <-> pg')
在PG 11版本中输出( 'pg' & 'class' ) <-> 'pg'
,但在PG 14版本中两者都输出'pg' <-> 'class' <-> 'pg'
。修复
websearch_to_tsquery()
以正确解析带有多个相邻已丢弃令牌的引号内文本。在PG 11版本中,包含多个相邻已丢弃令牌的引号内文本被视为多个令牌,导致输出不正确的tsquery
。例如,websearch_to_tsquery('"aaa: bbb"')
在PG 11版本输出'aaa' <2> 'bbb'
,但在PG 14版本输出'aaa' <-> 'bbb'
。修复无限窗口函数范围的处理。在PG 11版本中,像
'inf' PRECEDING AND 'inf' FOLLOWING
这样的窗口帧子句会返回不正确的结果。防止
tablefunc
的函数normal_rand()
接受负值。负值会产生不良结果。将
SIMILAR TO ... ESCAPE NULL
更改为返回NULL。这种新行为符合SQL规范。在PG 11版本中,空的ESCAPE值被认为是使用默认的转义字符串(反斜杠字符)。对于substring(text FROM pattern ESCAPE text)
也适用相同规则。通过保持原始函数不变,在PG 11版本中的行为在旧视图中得到保留。使
json[b]_to_tsvector()
完全检查其string
选项的拼写。删除
pretty-print
作用xpath()
或XMLTABLE
构造的结果。在某些情况下,这些函数会在节点集值中插入额外的空白(换行符和/或空格)。因为根据使用情况,空白可能被认为是重要的语义。
查询优化
更改非默认的
effective_io_concurrency
值对并发性的影响方式。在PG 11版本中,在设置并发请求数量之前会对该值进行调整,而在PG 14版本中可以直接使用该值。可以使用以下方法将旧值转换为新值:SELECT round(sum(OLDVALUE / n::float)) AS newvalue FROM generate_series(1, OLDVALUE) s(n);
。在
ltree
中,当lquery
模式包含带括号的相邻星号,例如*{2}.{3}
,正确解释为{5}
。在新的btree索引中,最大索引条目的长度减少了八个字节,以改善对重复条目的处理。这意味着对从PG 11版本进行
pg_upgrade
的索引进行REINDEX
操作可能会出现故障。
DDL数据操作
修复
ALTER FOREIGN TABLE ... RENAME COLUMN
以返回更合适的命令标记。在PG 11版本中返回ALTER TABLE
,在PG 14版本中返回ALTER FOREIGN TABLE
。修复
ALTER MATERIALIZED VIEW ... RENAME COLUMN
以返回更合适的命令标记。在PG 11版本中返回ALTER TABLE
,在PG 14版本中返回ALTER MATERIALIZED VIEW
。禁止在
CREATE
/DROP LANGUAGE
命令中对语言名称使用单引号。如果没有提供参数列表并且存在多个匹配的对象,则使用
DROP IF EXISTS FUNCTION/PROCEDURE/AGGREGATE/ROUTINE
时会产生错误,还改进了这种情况下的错误消息。
插件和工具
不允许在psql的
\pset format
命令中使用非唯一的缩写。在PG 11版本中,例如,\pset format a
选择的是aligned
;在PG 14版本中则会失败,因为这样写同样可以表示asciidoc
。移除
timetravel
扩展,移除数据类型abstime
、reltime
和tinterval
,这些类型已被SQL标准类型(例如timestamp
)所取代。防止在
pg_stat_ssl
和pg_stat_gssapi
系统视图中显示辅助进程。如果查询将这些视图与pg_stat_activity
连接,并希望看到辅助进程,将需要使用左连接。