2013-05-10 126 views
0

我有一个插入给定数量的测试记录的查询。 它看起来是这样的:错误:共享内存不足

CREATE OR REPLACE FUNCTION _miscRandomizer(vNumberOfRecords int) 
RETURNS void AS $$ 
declare 
    -- declare all the variables that will be used 
begin 
    select into vTotalRecords count(*) from tbluser; 
    vIndexMain := vTotalRecords; 

    loop 
     exit when vIndexMain >= vNumberOfRecords + vTotalRecords; 

     -- set some other variables that will be used for the insert 
     -- insert record with these variables in tblUser 
     -- insert records in some other tables 
     -- run another function that calculates and saves some stats regarding inserted records 

     vIndexMain := vIndexMain + 1; 
     end loop; 
    return; 
end 
$$ LANGUAGE plpgsql; 

当我运行此查询300点的记录它会引发以下错误:

********** Error ********** 

ERROR: out of shared memory 
SQL state: 53200 
Hint: You might need to increase max_locks_per_transaction. 
Context: SQL statement "create temp table _counts(...)" 
PL/pgSQL function prcStatsUpdate(integer) line 25 at SQL statement 
SQL statement "SELECT prcStatsUpdate(vUserId)" 
PL/pgSQL function _miscrandomizer(integer) line 164 at PERFORM 

功能prcStatsUpdate看起来是这样的:

CREATE OR REPLACE FUNCTION prcStatsUpdate(vUserId int) 
RETURNS void AS 
$$ 
declare 
    vRequireCount boolean; 
    vRecordsExist boolean; 
begin 
    -- determine if this stats calculation needs to be performed 
    select into vRequireCount 
     case when count(*) > 0 then true else false end 
    from tblSomeTable q 
    where [x = y] 
     and [x = y]; 

    -- if above is true, determine if stats were previously calculated 
    select into vRecordsExist 
     case when count(*) > 0 then true else false end 
    from tblSomeOtherTable c 
    inner join tblSomeTable q 
     on q.Id = c.Id 
    where [x = y] 
     and [x = y] 
     and [x = y] 
     and vRequireCount = true; 

    -- calculate counts and store them in temp table 
    create temp table _counts(...); 
    insert into _counts(x, y, z) 
    select uqa.x, uqa.y, count(*) as aCount 
    from tblSomeOtherTable uqa 
    inner join tblSomeTable q 
     on uqa.Id = q.Id 
    where uqa.Id = vUserId 
     and qId = [SomeOtherVariable] 
     and [x = y] 
     and vRequireCount = true 
    group by uqa.x, uqa.y; 

    -- if stats records exist, update them; else - insert new 
    update tblSomeOtherTable 
    set aCount = c.aCount 
    from _counts c 
    where c.Id = tblSomeOtherTable.Id 
     and c.OtherId = tblSomeOtherTable.OtherId 
     and vRecordsExist = true 
     and vRequireCount = true; 

    insert into tblSomeOtherTable(x, y, z) 
    select x, y, z 
    from _counts 
    where vRecordsExist = false 
     and vRequireCount = true; 

    drop table _counts; 
end; 
$$ LANGUAGE plpgsql; 

它看起来像错误是一个内存埠的结果因为我创建临时表,使用它并立即下降(因此我理解释放内存),但我不明白这怎么可能。

更新

我更新prcStatsUpdate函数来表示我有实际的功能。我只是将表名和列名替换为通用名。 我第一次没有发布的原因是它主要是非常简单的SQL操作,我认为它不会有任何问题。

另外,你从哪里开始线计数?它表示错误在第25行,但如果从头开始计数,则第25行是where子句中的条件,但这不是真的。你是否从begin开始计数?

任何想法?

+0

我更新了我的问题。感谢您提供整个代码的建议。 – Dmitry 2013-05-10 23:29:51

+0

您是否尝试增加max_locks_per_transaction? – 2013-05-11 00:56:17

+0

我还没有。在我这样做之前,我想我会问是否有人可以指出我可能错过的错误。我想了解是什么导致了这种情况发生。 – Dmitry 2013-05-11 02:31:01

回答

2

直到事务结束时才释放锁定,临时表被删除。

看到related answer

如果可能,您应该重新组织代码以在函数外部创建临时表并在函数内截断/填充它。