You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

循环调用PostgreSQL存储过程异常:CPU占满超时问题排查

问题描述

编写了如下PostgreSQL存储过程insert_into_tableAv2,用于从tableA批量插入100条未存在于tableAv2的记录:

CREATE OR REPLACE PROCEDURE insert_into_tableAv2(inout rows_affected INT) LANGUAGE 'plpgsql' AS $$ BEGIN
    INSERT INTO insert_into_tableAv2 (serial, aaa, ooo, UPDATED)
        SELECT id, aaa, ooo, UPDATED
        FROM tableA
        WHERE NOT EXISTS (
            SELECT 1
            FROM tableAv2
            WHERE tableA.id = tableAv2.serial AND tableA.aaa = tableAv2.aaa
        )
        LIMIT 100;

        GET DIAGNOSTICS rows_affected = ROW_COUNT;
        RETURN;

END; $$;

DEV环境中tableA仅含9000条数据,属于小型表,但通过如下DO块循环调用该存储过程时,出现RDS CPU占用100%、无法插入且超时的问题:

DO $$
DECLARE
    result int := 0; -- Initialize with a starting value
BEGIN
    LOOP
        result := 0;
        -- Call the procedure and update the result
        CALL insert_into_tableAv2(result);

        -- Exit the loop if the result is 0
        EXIT WHEN result = 0;
    END LOOP;
END $$;

该存储过程是为后续在更大表中执行类似批量操作编写的,请问调用异常的原因是什么?

异常原因分析
  • 存储过程插入目标表错误:存储过程里的INSERT INTO insert_into_tableAv2 (...)写错了目标表,应该是tableAv2却写成了存储过程自身的名称。这会导致每次调用时尝试往错误的对象插入数据,触发大量无效操作或异常,直接拉高CPU占用。
  • 缺失索引引发重复全表扫描:tableAv2未创建(serial, aaa)复合索引,每次执行NOT EXISTS子查询时都会对tableAv2做全表扫描。循环调用时,随着tableAv2数据量增加,全表扫描的开销持续累积,即使小型表也会很快导致CPU饱和。
  • 循环无间隔持续施压:DO块的循环是不间断执行的,没有任何延迟或合理的事务控制,数据库被持续的批量请求占满资源,进一步加剧CPU负载。

内容的提问来源于stack exchange,提问作者ahmet gül

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 15:12:05