2013-05-10 6 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; 

Похоже, что ошибка является результатом памяти bu когда я создаю временную таблицу, использую ее и сразу убираю (таким образом, чтобы понять, что я освобождаю память), я не вижу, как это будет возможно.

Update

Я обновил функцию prcStatsUpdate представлять реальную функцию, которая у меня есть. Я просто заменил имена таблиц и столбцов на что-то общее. Причина, по которой я не публиковал это в первый раз, состоит в том, что это в основном очень простые операции с sql, и я предположил, что с ним не может быть никаких проблем.

Кроме того, где вы начинаете подсчет строк? Он говорит, что ошибка указана в строке 25, но это просто не может быть правдой, поскольку строка 25 является условием в предложении where, если вы начинаете считать с начала. Вы начинаете считать с begin?

Любые идеи?

+0

Я обновил свой вопрос. Спасибо за предложение поместить весь код. – Dmitry

+0

Вы пытались увеличить max_locks_per_transaction? –

+0

Я еще не был. Прежде чем я это сделаю, я подумал, что спрошу, может ли кто-нибудь указать на ошибку, которую я, возможно, пропустил. Я хотел бы понять, что вызывает это. – Dmitry

ответ

2

Замки не освобождаются до конца транзакции, когда временная таблица отбрасывается.

Посмотрите, что related answer.

Если возможно, вы должны реорганизовать код, чтобы создать временную таблицу за пределами функции и усечь/заполнить ее внутри функции.

Смежные вопросы