如何在PostgreSQL中像运行作业一样异步执行代码块?
结论
PostgreSQL 原生内核未直接内置会话外异步执行代码的功能,但可以通过官方生态的扩展实现和 Oracle dbms_job.submit 等价的能力,无需依赖外部操作系统层面的 Cron 工具。
可用实现方案
方案1:使用 pg_background 扩展实现即时异步任务提交
该扩展专门用于在独立后台会话中异步执行 SQL 逻辑,提交任务后不会阻塞当前会话,完全匹配你的需求:
- 首先安装扩展(需要超级用户权限,且需提前在
postgresql.conf的shared_preload_libraries参数中添加pg_background后重启数据库生效):
CREATE EXTENSION pg_background;
- 提交长耗时代码块到后台执行的写法:
SELECT pg_background_launch($$ DO $do$ begin FOR i IN 1..1000000 loop -- 长耗时插入逻辑 insert into my_table(x) values (i); commit; end loop; end $do$; $$);
- 执行后会立即返回后台任务ID,你可以继续操作当前会话,后续也可以通过
pg_background_result(任务ID)获取任务执行结果。
方案2:使用 pg_cron 扩展实现定时/一次性异步任务
如果你的场景允许极小的执行延迟,或者需要定时调度能力,可以使用 PostgreSQL 官方维护的 pg_cron 扩展:
- 首先安装扩展(需要超级用户权限,且需提前在
postgresql.conf的shared_preload_libraries参数中添加pg_cron后重启数据库生效):
CREATE EXTENSION pg_cron;
- 提交一次性后台任务(提交后立刻异步执行):
SELECT cron.schedule( '一次性批量插入任务', NOW(), $$ DO $do$ begin FOR i IN 1..1000000 loop insert into my_table(x) values (i); commit; end loop; end $do$; $$ );
- 任务执行完成后如果不需要保留调度记录,可以调用
cron.unschedule(任务ID)删除对应记录。
注意事项
- 上述两个扩展的异步任务执行权限和提交任务的用户权限一致,事务逻辑完全独立于当前会话。
- 若你没有数据库超级用户权限,无法安装扩展,才需要考虑操作系统层面的 Cron 调度、外部应用异步调用等方案。
内容的提问来源于stack exchange,提问作者diziaq
相关产品推荐
相关产品推荐

