PG12:Postgres Professional的数十个补丁

很高兴在PostgreSQL 12官方发行版的“致谢”列表中看到熟悉的名称,我们决定将开发人员所从事的创新和一些错误修复汇总在一起。

1. JSONPath支持


(在发行说明中,这听起来像是添加了对SQL / JSON路径语言的支持(Nikita Glukhov,Teodor Sigaev,Alexander Korotkov,Oleg Bartunov,Liudmila Mantrova)

该修补程序本身,JSONPath功能和此问题的历史记录在中心上的另一篇文章中进行了详细讨论。 JSONPath是Postgres Professional的一项重大成就,也是PostgreSQL 12的主要创新之一。

2014年,A。Korotkov,O。Bartunov和F. Sigaev开发了jsquery扩展,该扩展被包含在Postgres Pro Standard 9.5(以及后来的Standard和Enterprise版本)中。 它提供了用于处理json(b)的其他非常广泛的功能。

当标准SQL:2016出现时,事实证明它的语义与jsquery扩展名中的语义没有太大不同。 该标准的作者甚至可能浏览了jsquery并发明了JSONPath。 我们的团队必须实施一些与现有产品有所不同的东西,当然,还有很多新事物。

尽管尚未提交具有功能的特殊修补程序,但是JSONPath修补程序已经具有用于处理JSON(B)的关键功能,例如:

jsonb_path_query('{"a": [1,2,3,4,5]}', '$.a[*] ? (@ > 2)')  3, 4, 5 jsonb_path_query('{"a": [1,2,3,4,5]}', '$.a[*] ? (@ > 5)')  0  

此外, 还优化了一些以前可用于JSON的功能。 这是Nikita Glukhov成功完成的。

例如,与函数jsonb_each_text()jsonb_array_elements_text()相对应的运算符#>>用于快速将JsonbValue转换为文本,但与其他类型的转换却很慢。 现在一切都在快速进行。

2.支持在SP-GiST(KNN)索引中快速搜索最近的邻居


(增加了对SP-GiST索引的最近邻(KNN)搜索的支持。Nikita Glukhov,Alexander Korotkov,Vlad Sterzhanov)

我公司的Nikita Glukhov和Alexander Korotkov继续了明斯克(又名Quadrocube)的Vlad Sterzhanov开始的工作。 Postgres是第一个以更直接,更方便的方式搜索其最近邻居(以前是Oracle和MS)的DBMS,这要归功于Oleg Bartunov及其团队。 这种搜索的思想是在原始的树遍历算法中进行的,该算法在大多数情况下会带来巨大的收益。 寻找最近的邻居的地方很多,但在GIS中尤为常见。

当将平面分为固定大小的正方形和KD树(即k维树)时,Vlad制作了一个KNN搜索补丁,用于处理四叉树的空间索引SP-GiST。

Vlad的GSoC指导者(Google Summer of Code)的Alexander Korotkov与来自Postgres专业人士Nikita Glukhov的同事一起继续开发。 功能得到了极大的丰富:遍历树时改进了内部数据缓存,添加了按距离排序的圆形和多边形的运算符类。

要使用最近的邻居搜索算法,只需编写ORDER BY [, ] ,然后优化器将自动连接该算法。 举个例子

 SELECT * FROM polygons ORDER BY poly <-> point '(0,0)'; 

可以在github上看到Nikita Glukhov的补丁。

3.优化锁以加速插入B-Tree索引


(在发行说明中,这是通过减少锁定开销来提高btree索引插入的速度。Alexander Korotkov)

Postgres Professional的首席系统架构师Alexander Korotkov在插入B树索引时设法提出了一种更合理的锁定算法。 在插入或多或少“连续”发生的情况下,应用此补丁后的增益非常明显。 在72核服务器上的测量表明,在这种情况下,增益达到50%。 在插入混乱的情况下,增益并不是那么明显。

4.经济的WAL


(减少了GiST,GIN和SP-GiST索引创建的WAL写入开销。Anastasia Lubennikova,Andrey V. Lepikhov)

这一系列补丁可减少创建GiST,GIN和SP-GiST索引时生成的WAL流量 。 现在,您只能记录一次此类索引的页面-最后,当索引已建立时。 并且,如果在WAL中建立条目索引时发生错误,则根本不会出现不成功的尝试。 以前,这仅在创建B树和RUM时才可行。 修补程序使用通用的WAL机制。

xlog脚本以检查xlog大小。 在IMDB数据库(JSON格式)上进行的测试(其中4M +记录占用4GB)显示:

 CREATE INDEX ON imdb USING gin(jb jsonb_path_ops); 

旧方法执行205秒,WAL 3.2 GB,而新算法执行133秒,WAL 0.4 GB。

5.在多列的情况下优化仅索引扫描。


(允许仅索引扫描在具有许多列的索引上更加有效。Konstantin Knizhnik)

在分析我们公司的一个客户的数据库的操作时, 发现在某些情况下,使用仅索引扫描比使用索引扫描(enable_indexonlyscan = off)执行同一查询的时间要长25%。
在许多字段上执行SELECT时会发生这种情况,这些字段大多数是bytea类型的,并且不缓存其偏移量,因为此类字段没有固定的偏移量(另请参见Nikolai Shaplov的报告“ What's Inside It” )。 要解压缩第k个属性,必须解压缩先前的k-1。 通过一个属性解压缩记录需要O(N * N)时间,其中N是字段数。 这25%已经发生在10个领域。

康斯坦丁·尼兹尼克(Konstantin Knizhnik)使用了处理臀部时使用的算法:访问第k个属性时,前面的k-1被记录并记住,时间随着场的数量线性增长。 应用补丁后,带有索引扫描和仅索引扫描的运行时几乎是相同的。

6.控制将WAL段转储到磁盘


(为WAL段的fsync添加一个等待事件。Konstantin Knizhnik)

PostgreSQL内核监视对WAL的写入,但不监视WAL段从内存到磁盘的刷新,即fsync 。 K. Knizhnik制作了一个修补程序,该修补程序创建了一种新型事件,现在称为WALSync(变量的内部名称为WAIT_EVENT_WAL_SYNC)。 您可以在PG事件标签中看到它,其解释为“等待将WAL文件转储到可靠的存储区”。 在黑客邮件列表中讨论了此问题。

重置需要多长时间通常是未知的:标准PostgreSQL不知道如何汇总此类统计信息。 但是有一个用Postgres Professional编写的pg_wait_sampling扩展 。 它可以谈论Postgres花时间在哪些事件上。 现在添加了事件,您可以关注fsync

7.支持词干词典中的新语言


(更新了Snowball词干词典,增加了对新语言的支持。ArthurZakirov)

由于Postgres会议是在尼泊尔举行的,因此尼泊尔语添加到数据库中会变得更加自然! 完成了 多亏了Arthur Zakirov的努力,您现在可以在Snowball上使用尼泊尔语词干词典。

8.函数to_timestamp()/ to_date()的数据容忍度更高


(调整to_timestamp()/ to_date()函数以更宽容模板不匹配,Artur Zakirov,Alexander Korotkov,Ludmila Mantrova)

如果格式字符串用多余的空格处理,则to_timestamp()函数不起作用。 对to_timestamp()中的错误的讨论导致了冗长的讨论 ,即to_timestamp()函数to_timestamp()to_timestamp()哪些行为视为正确。 为了每个人的利益,这两个功能都变得更宽容了格式行和输入行中的多余空格。

9.日志可以通过pg_ctl旋转


(允许通过pg_ctl来控制日志文件的旋转。Horiguchi Kyotaro,Alexander Kuzmenkov,Alexander Korotkov)

换句话说, pg_ctl实用程序获得了一个新选项:

 pg_ctl logrotate [-D _] [-s] 

执行此命令后,服务器将切换到新的日志文件或重新打开现有的日志文件,具体取决于日志记录配置 。 在紧急情况下,这可能是必要的,尤其是当需要传输庞大,快速增长的日志文件进行诊断时。

10.具有创建新型表的能力(可插拔存储)


(添加CREATE ACCESS METHOD命令以创建新表类型。AndresFreund,Haribabu Kommi,ÁlvaroHerrera,Alexander Korotkov,Dmitry Dolgov)

此重要补丁是可插拔存储API基础结构的重要组成部分,因此是补丁开发人员的国际组成部分。 自9.6版以来,CREATE ACCESS METHOD命令已在Postgres上运行。 但是直到12日,您只能创建索引访问方法。 这是第11版的文档

 CREATE ACCESS METHOD  TYPE __ HANDLER _ < ... > __       .      INDEX. 

并且在第12个文档中已经阅读当前仅支持TABLE和INDEX。 顺便说一句,在第11个CREATE ACCESS METHOD命令由Postgres Pro扩展提供,而在第12个已经由PostgreSQL提供。

操作的执行取决于访问方法的类型。 如果它是TABLE类型,则table_am_handler将对其进行table_am_handler ;如果它是INDEX类型,则将处理index_am_handler (先前:对于INDEX类型的访问方法,它应该是index_am_handler )。 整章都出现在有关表方法的文档中。

现在,在创建表时,可以指定其类型:

 CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] _ ( [ < ... > [ USING  ] 

该方法的类型为TABLE-这是对可插入存储的引用。 现在默认情况下是heap ,而实际上不是。 关于此处的运算符类

default_table_access_method (string)

如果未在CREATE命令中显式指定访问方法,或者在执行SELECT ... INTO命令时无法显式设置访问方法,则此参数设置在创建表或实例化视图时将使用的默认表访问方法。 默认值为heap黑客的大讨论有助于弄清细节。

在此之前,我们一直在谈论创新。 但是,错误修复也吞噬了程序员的时间。 主要的是:

11.错误:结构之一中的错误


_dumpOptions中的多余quote_all_identifiers。 亚瑟·扎基罗夫(Arthur Zakirov)

通常,没有什么特别的,在pg_dump使用的结构之一中发现了一个错误-编译器忽略了该错误。 但是布鲁斯·莫姆延(Bruce Momjyan)自己为这一发现称赞

DumpOptions其他问题可以在这里找到。

12.复制中的错误:


(xlogreader:不要两次读取文件块。ArthurZakirov)

我们公司的另一名员工pg_probackup开发人员Grigory Smolkin发现,当xlogreader读取zlib归档文件时,我们的一个实用程序速度变慢。 原来,有时他会两次读取WAL文件块。

如果归档读取不一致,则性能会很差。 重复读取该块始终是不一致的,因为您必须通过调用gzseek()函数返回到通过的位置。 现在不会发生不必要的重新读取。

PS I我不会拆解:一打补丁(严格来说是一打补丁)并不是与Postgres版本号的偶然巧合。 该列表很可能是数量不足或过多的。 我认为它将变得更加美丽,而美丽部分是编程的引擎,更不用说人类活动的其他领域了。

Source: https://habr.com/ru/post/zh-CN472072/


All Articles