PostgreSQL plpgsql中不借助第三方扩展如何实现函数/存储过程并行运行?
PostgreSQL 原生实现脚本并发运行的方案
PostgreSQL 无需依赖pg_cron等第三方扩展,完全可以通过官方自带能力实现plpgsql函数、存储过程的并行运行,常用方案如下:
方案1:基于多数据库连接实现并行
PostgreSQL服务端原生支持多连接并发处理,每个独立的数据库连接会对应独立的服务端进程,请求天然并行执行(仅在出现资源竞争、锁冲突时才会互相阻塞)。
- 实操方式:你可以用任意支持多线程/多进程的客户端发起请求,比如你熟悉的Java,直接写多线程逻辑创建多个独立JDBC连接,每个连接调用对应的存储过程/函数即可,和你平时写Java多线程逻辑的思路完全一致。如果是轻量场景,也可以用Shell、Python等脚本开启多个
psql客户端连接执行任务。 - 注意点:并发连接数不要超过数据库
max_connections配置的上限,避免连接占满影响正常业务。
方案2:使用官方内置dblink模块在数据库内部实现并发
dblink是PostgreSQL官方发行版自带的功能模块,不属于第三方扩展,支持在SQL/存储过程内部创建跨连接请求,不需要依赖外部客户端即可实现并发逻辑。
开启方式
只需在数据库中执行一次如下语句启用模块即可:
CREATE EXTENSION IF NOT EXISTS dblink;
并发调用示例
如果需要并行执行func_a()和func_b()两个函数,可参考如下写法:
-- 建立第一个独立连接,异步执行func_a SELECT dblink_connect('conn_a', 'dbname=' || current_database()); SELECT dblink_send_query('conn_a', 'SELECT func_a();'); -- 建立第二个独立连接,异步执行func_b,不会被前一个任务阻塞 SELECT dblink_connect('conn_b', 'dbname=' || current_database()); SELECT dblink_send_query('conn_b', 'SELECT func_b();'); -- 可选:等待两个任务执行完成,获取返回结果 SELECT * FROM dblink_get_result('conn_a') AS res_a(result text); SELECT * FROM dblink_get_result('conn_b') AS res_b(result text); -- 关闭连接释放资源 SELECT dblink_disconnect('conn_a'); SELECT dblink_disconnect('conn_b');
该方案适合将并发逻辑完全封装在数据库内部,不需要依赖外部调度工具。
方案3:结合操作系统原生定时任务实现定时并发
如果你的维护任务需要定时触发,不想用pg_cron的话,可以直接用操作系统自带的定时调度能力:
- Linux/Unix系统使用原生
cron,编写多个独立的Shell脚本调用psql执行存储过程,配置相同的触发时间即可实现定时并发运行。 - Windows系统使用自带的任务计划程序,配置多个同时启动的
psql调用任务即可。
通用注意事项
- 并发任务要提前规避锁冲突:如果多个任务同时操作同一张表的同一行数据,会触发行锁阻塞,严重时可能出现死锁,需要提前做好逻辑隔离。
- 控制并行任务数量:不要一次性发起过多并行任务,避免占满数据库CPU、内存、IO资源,影响正常业务运行。
- 如果你需要的是单个大查询的内部并行执行,不需要额外编写逻辑:PostgreSQL 9.6及以上版本已经原生支持查询并行执行,只要配置好
max_parallel_workers_per_gather等相关参数,数据库会自动对符合条件的大查询启用多进程并行加速。
内容的提问来源于stack exchange,提问作者PainIsAMaster
相关产品推荐
相关产品推荐

