标签

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

PostgreSQL 10.0 preview 功能增强 - 后台运行(pg_background)相关推荐

  1. PostgreSQL 10.0 preview 功能增强 - 更强可靠性, 过去式事务状态可查(杜绝unknown事务)...

    标签 PostgreSQL , 10.0 , 2PC , txid_status , unknown事务 背景 在一些极端情况下,例如当客户端发出事务提交SQL后,客户端收到数据库返回的提交状态前,如 ...

  2. PostgreSQL 10.0 preview 功能增强 - 支持EUI-64格式MAC地址类型

    标签 PostgreSQL , 10.0 , eui-64 , mac 背景 PostgreSQL 是全球最先进的开源数据库,所谓先进,体现在很多方面: 支持扩展类型 支持扩展操作符 支持扩展函数 支 ...

  3. PostgreSQL 10.0 preview 主动防御 - 禁止执行全表删除、更新(可配置)

    标签 PostgreSQL , 10.0 , 主动防御 , 是否允许执行不带where条件的update\delete 背景 你是否曾经被不带where 条件的SQL误伤过呢? 比如 update t ...

  4. 元旦技术大礼包 - 2017金秋将要发布的PostgreSQL 10.0已装备了哪些核武器?

    标签 PostgreSQL , 10.0 , 金秋 , 元旦 , 大礼包 , commitfest 背景 早上送给大家的新年大礼包,一年一个大版本是PostgreSQL社区的传统,虽然发布时间通常为秋 ...

  5. PostgreSQL · 实现分析 · PostgreSQL 10.0 并行查询和外部表的结合

    前言 大家都知道,PostgreSQL 近几大版本中加入了很多 OLAP 相关特性.9.6 的并行扫描应该算最大的相关特性.在今年发布的 10.0 中,并行扫描也在不断加强,新增了并行的索引扫描. 我 ...

  6. 修改rcS启动定制功能,后台运行脚本,新建子SHELL进程。

    除了在rcS中编写了启动所需的必须功能命令后,我们还可以添加自己的定制功能.方法如下: 首先,在/usr/bin下,编写各个定制功能的脚本.注意修改权限 chmod a+x myscript 在脚本里 ...

  7. [惊!] IE 10.0,你没看错! IE10 Platform Preview 1出来啰~

    你还没安装上 IE 9.0吗?那真的逊! 因为..... IE 10.0已经有 Preview版本给人下载啰!!!!! 下载 IE10 Platform Preview 1    (2011/4/12 ...

  8. aelf Enterprise 1.0.0 Preview 2 版正式发布!

    4月27日,aelf Enterprise 1.0.0 Preview 2 版正式发布.aelf Enterprise 1.0.0 Preview 2 版是基于aelf Enterprise 1.0. ...

  9. Windows和Linux下apache-artemis-2.10.0安装配置

    window下安装配置 一.官网下载 http://activemq.apache.org/artemis/download.html 二.百度网盘下载 链接:https://pan.baidu.co ...

最新文章

  1. Ubuntu14.04 LTS中安装Ruby 2.4源码操作步骤
  2. wcf ria中主从表绑定treeview
  3. C#根据execl批量修改图片名称
  4. linux的驱动开发——内核模块的编译
  5. Python 列表List - Python零基础入门教程
  6. python购物程序_Python学习:购物程序
  7. C++新特性探究(十三):右值引用(r-value ref)探究
  8. JQuery 选择器总结
  9. linux fread函数的用法,fread和fwrite用法详解
  10. navicat for mysql 10.0.11 简体免安装中文破解版
  11. 三维空间点到直线的距离C++实现
  12. [C++] 最小生成树
  13. Log4j.properties 属性详解以及 LOG4J日志级别详解
  14. 我的回忆和有趣的故事 by李维(台湾)
  15. R语言:rJava包的安装
  16. elasticsearch query里面的slop选项
  17. IC-二进制, 自然数, 有符号数
  18. 大数据24小时:九章云极宣布获近亿元B轮融资,我国成功研发智能辅助驾驶系统
  19. android开发——RecycleView
  20. mysql-server-5.6 deb_linux下安装mysql-server-5.6的问题

热门文章

  1. jdbcTemplate 调用存储过程。 入参 array 返回 cursor
  2. Python写各大聊天系统的屏蔽脏话功能原理
  3. Bootstrap-table学习笔记(一)
  4. nginx下后端realserver健康检测模块ngx_http_upstream_check_module
  5. JVMTOP JVM 监视工具
  6. 学习笔记---取得枚举项的2种方法: Enum.GetValues()-Array.GetValue()和Enum.GetNames()-Enum.Parse()...
  7. 18不使用委托实现能自动侦测车距的智能汽车
  8. P1339 热浪 最短路径模板题
  9. SystemCenter2012SP1实践(5)SCVMM管理HyperV
  10. Office 2016 for Mac 15.24已推送至Office Insider慢速更新通道