Getting problem when taking backup on database contains around 50 schema with each schema having around 100 tables.
pg_dump throwing below error suggesting that to increase max_locks_per_transaction.
pg_dump: WARNING: out of shared memory
pg_dump: SQL command failed
pg_dump: Error message from server: ERROR: out of shared memory
HINT: You might need to increase max_locks_per_transaction.
pg_dump: The command was: SELECT tableoid, oid, prsname, prsnamespace, prsstart::oid, prstoken::oid, prsend::oid, prsheadline::oid, prslextype::oid FROM pg_ts_parser
An updated of max_locks_per_transaction to 256 in postgresql.conf did not solve the problem.
Are there any possibilities which can cause this problem?
Edited:(07 May, 2016)
Postgresql version = 9.1
Operating system = Ubuntu 14.04.2 LTS
shared_buffers in postgresql.conf = 2GB
Edited:(09 May, 2016)
My postgres.conf
maintenance_work_mem = 640MB
wal_buffers = 64MB
shared_buffers = 2GB
max_connections = 100
max_locks_per_transaction=10000
Getting problem when taking backup on database contains around 50 schema with each schema having around 100 tables.
pg_dump throwing below error suggesting that to increase max_locks_per_transaction.
pg_dump: WARNING: out of shared memory
pg_dump: SQL command failed
pg_dump: Error message from server: ERROR: out of shared memory
HINT: You might need to increase max_locks_per_transaction.
pg_dump: The command was: SELECT tableoid, oid, prsname, prsnamespace, prsstart::oid, prstoken::oid, prsend::oid, prsheadline::oid, prslextype::oid FROM pg_ts_parser
An updated of max_locks_per_transaction to 256 in postgresql.conf did not solve the problem.
Are there any possibilities which can cause this problem?
Edited:(07 May, 2016)
Postgresql version = 9.1
Operating system = Ubuntu 14.04.2 LTS
shared_buffers in postgresql.conf = 2GB
Edited:(09 May, 2016)
My postgres.conf
maintenance_work_mem = 640MB
wal_buffers = 64MB
shared_buffers = 2GB
max_connections = 100
max_locks_per_transaction=10000
У меня есть две таблицы: таблица с названием companies_display с информацией о публично торгуемых компаниях, таких как тикер, рыночная капитализация и т. Д., И разделенная таблица stock_prices с историческими ценами на акции для каждой Компания. Я хочу рассчитать бета-версию каждой акции и записать ее в companies_display . Для этого я написал функцию calculate_beta (ticker) , которая его вычисляет:
CREATE OR REPLACE FUNCTION calculate_beta (VARCHAR)
RETURNS float8 AS $beta$
DECLARE
beta float8;
BEGIN
WITH weekly_returns AS (
WITH RECURSIVE
spy AS (
SELECT time, close FROM stock_prices WHERE ticker = 'SPY'
),
stock AS (
SELECT time, close FROM stock_prices WHERE ticker = $1
)
SELECT
spy.time,
stock.close / LAG(stock.close) OVER (ORDER BY spy.time DESC) AS stock,
spy.close / LAG(spy.close) OVER (ORDER BY spy.time DESC) AS spy
FROM stock
JOIN spy
ON stock.time = spy.time
WHERE EXTRACT(DOW FROM spy.time) = 1
ORDER BY spy.time DESC
LIMIT 52
)
SELECT
COVAR_SAMP(stock, spy) / VAR_SAMP(spy) INTO beta
FROM weekly_returns
;
RETURN beta;
END;
$beta$ LANGUAGE plpgsql;
Функция работает только для нескольких компаний, но когда я попытался обновить всю таблицу
UPDATE companies_display SET beta = calculate_beta(ticker);
Я получаю сообщение об ошибке нехватки разделяемой памяти, и в нем говорится, что max_locks_per_transaction слишком мало. Я предполагаю, что функция создает блокировку для таблицы stock_prices для каждой компании и не сбрасывает их, пока не завершится. Я пытался создать петлю
DO
$do$
DECLARE
ticker_ VARCHAR;
BEGIN
FOR ticker_ IN SELECT ticker FROM companies_display
LOOP
UPDATE companies_display
SET beta = calculate_beta(ticker_)
WHERE ticker = ticker_
;
END LOOP;
END
$do$;
Но я столкнулся с той же проблемой. Есть ли способ снять блокировку stock_prices после каждого расчета бета-версии или выполнять обновление партиями? Мой метод работает одновременно примерно с 5 компаниями.
1 ответ
Лучший ответ
Если кто-то столкнется с той же проблемой, я избежал ошибки, вызвав свою функцию sql с сервера, который я использую для обновления своей базы данных. Таким образом, у меня будет одна транзакция на компанию, и я не получу много блокировок.
0
Tim Berti
24 Июн 2021 в 14:06
У меня есть запрос, который вставляет заданное количество тестовых записей. Это выглядит примерно так:
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?
Есть идеи?