PostgreSQL 10.0 preview 功能增强 - 后台运行(pg_background)

简介:

标签

PostgreSQL , 10.0 , 后台运行 , pg_background_launch , pg_background_result , pg_background_detach , pg_background


背景

当用户在管理数据库时,如果要在交互式界面跑一些QUERY,但是不知道QUERY要运行多久,担心网络问题或者其他问题导致终端断开,QUERY执行情况不明的话。就需要后台运行这个功能了。

后台运行在LINUX中也很常见,比如

nohup ls -la / >/tmp/result 2>&1 &  

这样的话,即使断开会话也没关系,这条命令会在后台运行,并将标准输出存入/tmp/result,标准错误也重定向到标准输出。

对于PostgreSQL数据库,在10.0的这个特性出来之前,用户可以使用dblink的异步调用,达到类似的目的,但是不能断开会话,注意了。

dblink异步调用

使用dblink异步调用,可以达到后台运行的目的,但是别忘了,dblink连接是当前会话建立的,当前会话退出,连接也会退出。

postgres=# create extension dblink;  
CREATE EXTENSION  
  
创建测试表  
postgres=# create table t(id int);  
CREATE TABLE  
  
建立连接  
postgres=# select dblink_connect('digoal','host=127.0.0.1 port=1921 user=postgres dbname=postgres');  
 dblink_connect   
----------------  
 OK  
(1 row)  
  
开始事务(你也可以使用autocommit)  
postgres=# select * from dblink_send_query('digoal', 'begin');  
 dblink_send_query   
-------------------  
                 1  
(1 row  
  
获取异步调用结果  
postgres=# select * from dblink_get_result('digoal') as t(res text);  
  res    
-------  
 BEGIN  
(1 row)  
  
获取异步调用结果为0时,才能对这个连接进行下一次异步调用。  
postgres=# select * from dblink_get_result('digoal') as t(res text);  
 res   
-----  
(0 rows)  
  
异步插入数据  
postgres=# select * from dblink_send_query('digoal', 'insert into t values (1)');  
 dblink_send_query   
-------------------  
                 1  
(1 row)  
  
获取异步调用结果  
postgres=# select * from dblink_get_result('digoal') as t(res text);  
    res       
------------  
 INSERT 0 1  
(1 row)  
  
postgres=# select * from dblink_get_result('digoal') as t(res text);  
 res   
-----  
(0 rows)  
  
查看数据是否插入,因为异步事务没有提交,所以看不到数据  
postgres=# select * from t;  
 id   
----  
(0 rows)  
  
提交异步事务  
postgres=# select * from dblink_send_query('digoal', 'commit');  
 dblink_send_query   
-------------------  
                 1  
(1 row)  
  
查看数据,有了  
postgres=# select * from t;  
 id   
----  
  1  
(1 row)  

断开本地会话,异步会话也会断开,未提交的异步事务自动回滚。

postgres=# select dblink_connect('digoal','host=127.0.0.1 port=1921 user=postgres dbname=postgres');  
-[ RECORD 1 ]--+---  
dblink_connect | OK  
  
postgres=# select * from dblink_send_query('digoal', 'begin');  
-[ RECORD 1 ]-----+--  
dblink_send_query | 1  
  
postgres=# select * from dblink_get_result('digoal') as t(res text);  
-[ RECORD 1 ]  
res | BEGIN  
  
postgres=# select * from dblink_get_result('digoal') as t(res text);  
(0 rows)  
  
postgres=# select * from dblink_send_query('digoal', 'insert into t values (2)');  
-[ RECORD 1 ]-----+--  
dblink_send_query | 1  
  
退出当前会话  
postgres=# \q  
  
重新连接,异步会话已断开,并回滚。  
postgres=# select * from t;  
 id   
----  
  1  
(1 row)  

使用dblink异步接口,可以完成一些后台运行的功能,但是比较繁琐,也不完美(比如当前会话不能退出)

https://www.postgresql.org/docs/9.6/static/contrib-dblink-get-result.html

PostgreSQL 10.0 新增了background session的功能,这个功能可以对标类似Oracle的自治事务的功能。(是plsql函数或存储过程迁移到PostgreSQL plpgsql的有利兼容性,此前需要使用dblink模拟自治事务)

基于background session,开发了一个后台运行的管理接口。可以方便的执行后台事务了。

PostgreSQL 10.0 background session(自治事务)功能

参考

《PostgreSQL 10.0 preview 功能增强 - 匿名、自治事务(Oracle 兼容性)》

PostgreSQL 10.0 后台运行接口功能

一开始的设计比较简单,提供了三个API函数

• pg_background_launch : 开启后台work进程与会话,执行用户提供的SQL,返回后台会话的PID  
  
• pg_background_result   : 根据提供的PID,返回这个后台会话执行SQL的结果  
  
• pg_background_detach : 根据提供的PID,返回这个后台会话执行SQL的结果,同时关闭这个后台进程。  

最开始的讨论细节如下

Hi All,  
  
I would like to take over pg_background patch and repost for  
discussion and review.  
  
Initially Robert Haas has share this for parallelism demonstration[1]  
and abandoned later with  
summary of open issue[2] with this pg_background patch need to be  
fixed, most of them seems to be  
addressed in core except handling of type exists without binary  
send/recv functions and documentation.  
I have added handling for types that don't have binary send/recv  
functions in the attach patch and will  
work on documentation at the end.  
  
One concern with this patch is code duplication with  
exec_simple_query(), we could  
consider Jim Nasby’s patch[3] to overcome this,  but  certainly we  
will end up by complicating  
exec_simple_query() to make pg_background happy.  
  
As discussed previously[1] pg_background is a contrib module that lets  
you launch arbitrary command in a background worker.  
  
• VACUUM in background  
• Autonomous transaction implementation better than dblink way (i.e.  
no separate authentication required).  
• Allows to perform task like CREATE INDEX CONCURRENTLY from a  
procedural language.  
  
This module comes with following SQL APIs:  
  
• pg_background_launch : This API takes SQL command, which user wants  
to execute, and size of queue buffer.  
  This function returns the process id of background worker.  
• pg_background_result   : This API takes the process id as input  
parameter and returns the result of command  
  executed thought the background worker.  
• pg_background_detach : This API takes the process id and detach the  
background process which is waiting for  
 user to read its results.  
  
  
Here's an example of running vacuum and then fetching the results.  
Notice that the  
notices from the original session are propagated to our session; if an  
error had occurred,  
it would be re-thrown locally when we try to read the results.  
  
postgres=# create table foo (a int);  
CREATE TABLE  
postgres=# insert into foo values(generate_series(1,5));  
INSERT 0 5  
  
postgres=# select pg_background_launch('vacuum verbose foo');  
pg_background_launch  
----------------------  
              65427  
(1 row)  
  
postgres=# select * from pg_background_result(65427) as (x text);  
INFO:  vacuuming "public.foo"  
INFO:  "foo": found 0 removable, 5 nonremovable row versions in 1 out of 1 pages  
DETAIL:  0 dead row versions cannot be removed yet.  
There were 0 unused item pointers.  
Skipped 0 pages due to buffer pins.  
0 pages are entirely empty.  
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.  
 x  
--------  
VACUUM  
(1 row)  
  
  
Thanks to Vibhor kumar, Rushabh Lathia and Robert Haas for feedback.  
  
Please let me know your thoughts, and thanks for reading.  
  
[1]. https://www.postgresql.org/message-id/CA%2BTgmoam66dTzCP8N2cRcS6S6dBMFX%2BJMba%2BmDf68H%3DKAkNjPQ%40mail.gmail.com  
[2]. https://www.postgresql.org/message-id/CA%2BTgmobPiT_3Qgjeh3_v%2B8Cq2nMczkPyAYernF_7_W9a-6T1PA%40mail.gmail.com  
[3]. https://www.postgresql.org/message-id/54541779.1010906%40BlueTreble.com  
  
Regards,  
Amul  

社区讨论后,这个架构改成了这样的,架构更优雅一些。

• pg_background_launch : 这个接口只是用来fork一个后台进程,并返回PID  
  
• pg_background_run : 根据提供的PID,让这个后台进程执行提供的SQL。  
  
• pg_background_result : 根据提供的PID,获取执行SQL的结果。  
  
• pg_background_detach : 关闭后台进程与会话。  

讨论细节如下

Hi all,  
  
As we have discussed previously, we need to rework this patch as a client of  
Peter Eisentraut's background sessions code[1].  
  
Attaching trial version patch to discussed possible design and api.  
We could have following APIs :  
  
• pg_background_launch : This function start and stores new background  
session, and returns the process id of background worker.  
  
• pg_background_run : This API takes the process id and SQL command as  
input parameter. Using this process id, stored worker's session is  
retrieved and give SQL command is executed under it.  
  
• pg_background_result : This API takes the process id as input  
parameter and returns the result of command executed thought the  
background worker session.  Same as it was before but now result can  
be fetch in LIFO order i.e. result of last executed query using  
pg_background_run will be fetched first.  
  
• pg_background_detach : This API takes the process id and detach the  
background process. Stored worker's session is not dropped until this  
called.  
  
• TBC : API to discard result of last query or discard altogether?  
  
• TBC : How about having one more api to see all existing sessions ?  
  
  
Kindly share your thoughts/suggestions.  Note that attach patch is WIP  
version, code, comments & behaviour could be vague.  
  
------------------  
Quick demo:  
------------------  
Apply attach patch to the top of Peter Eisentraut's  
0001-Add-background-sessions.patch[1]  
  
postgres=# select pg_background_launch();  
 pg_background_launch  
----------------------  
                21004  
(1 row)  
  
postgres=# select pg_background_run(21004, 'vacuum verbose foo');  
 pg_background_run  
-------------------  
  
(1 row)  
  
postgres=# select * from pg_background_result(21004) as (x text);  
INFO:  vacuuming "public.foo"  
INFO:  "foo": found 0 removable, 5 nonremovable row versions in 1 out of 1 pages  
DETAIL:  0 dead row versions cannot be removed yet.  
There were 0 unused item pointers.  
Skipped 0 pages due to buffer pins.  
0 pages are entirely empty.  
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.  
   x  
--------  
 VACUUM  
(1 row)  
  
postgres=# select pg_background_run(21004, 'select * from foo');  
 pg_background_run  
-------------------  
  
(1 row)  
  
postgres=# select * from pg_background_result(21004) as (x int);  
 x  
---  
 1  
 2  
 3  
 4  
 5  
(5 rows)  
  
postgres=# select pg_background_detach(21004);  
 pg_background_detach  
----------------------  
  
(1 row)  
  
  
References :  
[1] https://www.postgresql.org/message-id/e1c2d331-ee6a-432d-e9f5-dcf85cffaf29%402ndquadrant.com.  
  
  
Regards,  
Amul Sul  

后面的讨论又改成了这样,还是朝着优雅的方向在改进

The following review has been posted through the commitfest application:  
make installcheck-world:  tested, passed  
Implements feature:       tested, passed  
Spec compliant:           tested, passed  
Documentation:            tested, failed  
  
I’ll summarize here my thoughts as a reviewer on the current state of the pg_background:  
1. Current version of a code [1] is fine, from my point of view. I have no suggestions on improving it. There is no documentation, but code is commented.  
2. Patch is dependent on background sessions from the same commitfest.  
3. There can exist more features, but for v1 there is surely enough features.  
4. There is some controversy on where implemented feature shall be: in separate extension (as in this patch), in db_link, in some PL API, in FDW or somewhere else.   
I think that new extension is an appropriate place for the feature. But I’m not certain.  
Summarizing these points, appropriate statuses of the patch are ‘Ready for committer’ or ‘Rejected’.   
Between these two I choose ‘Ready for committer’, I think patch is committable (after bg sessions).  
  
Best regards, Andrey Borodin.  
  
The new status of this patch is: Ready for Committer  

这个patch在commit前,还有一些变数,比如可能将这个功能合并到dblink里面。而不是新开一个extension插件.

这个patch的讨论,详见邮件组,本文末尾URL。

PostgreSQL社区的作风非常严谨,一个patch可能在邮件组中讨论几个月甚至几年,根据大家的意见反复的修正,patch合并到master已经非常成熟,所以PostgreSQL的稳定性也是远近闻名的。

参考

https://commitfest.postgresql.org/13/893/

https://www.postgresql.org/message-id/flat/CAAJ_b97FRO+Y_-SOgXGj-WPwtuWrmifgfgPvbXMAvUKQykvNvA@mail.gmail.com#CAAJ_b97FRO+Y_-SOgXGj-WPwtuWrmifgfgPvbXMAvUKQykvNvA@mail.gmail.com

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
关系型数据库 Serverless 分布式数据库
【公测】PolarDB PostgreSQL版Serverless功能免费使用​!
【公测】PolarDB PostgreSQL版Serverless功能免费使用​,公测于2024年3月28日开始,持续三个月,公测期间可以免费使用!
|
存储 关系型数据库 数据库
深入了解 PostgreSQL:功能、特性和部署
PostgreSQL,通常简称为Postgres,是一款强大且开源的关系型数据库管理系统(RDBMS),它在数据存储和处理方面提供了广泛的功能和灵活性。本文将详细介绍 PostgreSQL 的功能、特性以及如何部署和使用它。
1362 1
深入了解 PostgreSQL:功能、特性和部署
|
关系型数据库 Serverless 分布式数据库
PolarDB PostgreSQL版Serverless功能上线公测啦,公测期间免费使用!
Serverless数据库能够使得数据库集群资源随客户业务负载动态弹性扩缩,将客户从复杂的业务资源评估和运维工作中解放出来。PolarDB PostgreSQL版 Serverless提供了CPU、内存、存储、网络资源的实时弹性能力,构建计算与存储分离架构下的 PolarDB PostgreSQL版产品新形态。
|
SQL 关系型数据库 分布式数据库
在PolarDB for PostgreSQL中,你可以使用LIKE运算符来实现类似的查询功能,而不是使用IF函数
在PolarDB for PostgreSQL中,你可以使用LIKE运算符来实现类似的查询功能,而不是使用IF函数
221 7
|
SQL 关系型数据库 分布式数据库
在PolarDB for PostgreSQL中,你可以使用LIKE运算符来实现类似的查询功能
在PolarDB for PostgreSQL中,你可以使用LIKE运算符来实现类似的查询功能【1月更文挑战第13天】【1月更文挑战第65篇】
167 2
|
关系型数据库 Linux Shell
Centos系统上安装PostgreSQL和常用PostgreSQL功能
Centos系统上安装PostgreSQL和常用PostgreSQL功能
|
SQL 关系型数据库 MySQL
功能强大的PostgreSQL没有MySQL流行的10个原因
本篇文章总结了为什么功能强大的PostgreSQL没有像MySQL一样流行的10个原因。玖章算术CEO叶正盛从产品功能、技术架构、生态、品牌商业等多个方面进行了分析,并指出了MySQL在流行度上的优势。文章还讨论了数据库在不同领域的竞争力和展望,并提到了PostgreSQL在中国信创产业发展中可能迎来新的机会。总体而言,这篇文章提供了关于MySQL和PostgreSQL的综合比较和评估。
497 0
功能强大的PostgreSQL没有MySQL流行的10个原因
|
存储 SQL NoSQL
PostgreSQL列存增加更新和删除功能
PostgreSQL列存增加更新和删除功能
627 0
|
SQL 存储 运维
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB PostgreSQL版解析与实践(上)——四、核心功能解析与实践
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB PostgreSQL版解析与实践(上)——四、核心功能解析与实践

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版
  • 推荐镜像

    更多