2016-06-17 3 views
0

У меня есть требование выполнить операцию запроса в указанный срок в postgresql. Если запрос не выполняется в этом временном лимите, нам нужно поймать исключение/действие и нужно убить все другие операции, которые блокируют эту операцию запроса, и выполнить нашу операцию обновления. Для этого прототипа, как был создан следующим образом:Как мы можем заставить «statement_timeout» работать внутри функции?

CREATE OR REPLACE FUNCTION execute_upgrade_statement(upgrade_stat text) RETURNS int as $$ 
BEGIN 
EXECUTE upgrade_stat; 
return 1; 
END; 
$$ 
LANGUAGE plpgsql; 


CREATE OR REPLACE FUNCTION upgrade_function(upgrade_statement text,upgrading_table text) RETURNS void as $$ 
DECLARE 
    pid INTEGER; 
    return_value INTEGER; 
    pid_values INTEGER[]; 
BEGIN 
SET statement_timeout TO 6000; 
LOOP 
BEGIN 
select execute_upgrade_statement(upgrade_statement) into return_value; 
if return_value = 1 THEN 
raise notice 'Upgrade query performed'; 
return; 
else 
continue; 
end if; 
END; 
END LOOP; 
exception when query_canceled then 
select into pid_values array_agg(p1.pid) from pg_locks p1 LEFT JOIN pg_stat_activity psa on p1.pid=psa.pid where p1.relation=(select relid from pg_stat_all_tables where relname=upgrading_table) and p1.pid <> pg_backend_pid(); 
FOREACH pid IN ARRAY pid_values 
LOOP 
raise notice 'pid value : %',pid; 
perform pg_terminate_backend(pid); 
END LOOP; 
END; 
$$ 
LANGUAGE plpgsql; 


begin; 
select upgrade_function('statement','table_name'); 
commit; 

Здесь statement_timeout не получает выполняется, когда функция вызывается из стороны сервера, но это становится выполняется при вызове со стороны клиента. Есть ли другой способ заставить statement_timeout работать с вызовом на стороне сервера или есть ли другой способ выполнить мою операцию обновления в заданный лимит времени?

ответ

0

Действительно, невозможно эффективно изменить statement_timeout с помощью функции сервера, это должно выполняться с клиентской стороны перед отправкой внешнего запроса.

См аналогичный вопрос о DBA.SE: Why “SET LOCAL statement_timeout” does not work as expected with PostgreSQL functions?

или эту тему в Postgres список рассылки, который датируется с 2007 года, но отрицательный ответ до сих пор применяется в текущей версии:

statement_timeout doesnt work within plpgsql by design?

0

Действительно, невозможно эффективно изменить statement_timeout с помощью функции сервера, она должна быть выполнена на стороне клиента перед отправкой запроса верхнего уровня.

См аналогичный вопрос о DBA.SE: Why “SET LOCAL statement_timeout” does not work as expected with PostgreSQL functions?

или эту тему в Postgres список рассылки, который датируется с 2007 года, но отрицательный ответ до сих пор применяется в текущей версии:

statement_timeout doesnt work within plpgsql by design?