В настоящее время я работаю над базой данных PostgreSQL 9.2.x с большим количеством клиентов, а также таблиц и функций. Мы постоянно развертываем код, и иногда из-за этого развертывания необходимо даже отказаться от типа или функции.Postgres drop type XX000 "cache lookup failed for type"
Пример:
1.Script создать необходимые функции в первую очередь
CREATE TYPE tmp._myEnum AS ENUM ('OLD', 'NEW', 'BOTH');
CREATE OR REPLACE FUNCTION tmp._get_status()
RETURNS tmp._myEnum AS
$BODY$
BEGIN
RETURN 'OLD'::tmp._myEnum;
END;
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER COST 10;
CREATE OR REPLACE FUNCTION tmp._my_testfunction()
RETURNS VOID AS
$BODY$
BEGIN
CASE tmp._get_status()
WHEN 'OLD'::tmp._myEnum THEN
RAISE INFO 'myEnum is OLD';
WHEN 'NEW'::tmp._myEnum THEN
RAISE INFO 'myEnum is NEW';
WHEN 'BOTH'::tmp._myEnum THEN
RAISE INFO 'myEnum is BOTH';
ELSE
RAISE INFO 'myEnum has an unexpected value';
END CASE;
FOR i IN 1..10 LOOP
RAISE INFO 'Step [%]',i;
END LOOP;
RETURN;
END;
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER COST 10;
2.Scenario, что приводит к исключению:
а) один клиент постоянно с помощью ТМП ._my_testfunction()
SELECT tmp._my_testfunction()
b) Чтобы развернуть изменение на t он Композитный тип я исполняю в другой сессии
DROP FUNCTION IF EXISTS tmp._get_status();
DROP TYPE IF EXISTS tmp._myEnum;
CREATE TYPE tmp._myEnum AS ENUM ('OLD', 'NEW', 'BOTH','NOTHING');
CREATE OR REPLACE FUNCTION tmp._get_status()
RETURNS tmp._myEnum AS
$BODY$
BEGIN
RETURN 'OLD'::tmp._myEnum;
END;
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER COST 10;
с) Клиент, который постоянно используя tmp._my_testfunction() imidiatly бросает
ERROR: cache lookup failed for type 386318
CONTEXT: PL/pgSQL function tmp._my_testfunction() line 3 at CASE
Как я могу предотвратить это?
Мы уже развертываем только часы с низким трафиком, но из-за потребительского трафика на нашем продукте его все еще, похоже, много для чистого развертывания. Нет ли какой-либо команды или способа уведомлять Postgres, чтобы очистить все сеансовые кеши? проблема заключалась в том, что исключение было выброшено через 20 минут после развертывания и остановлено только после того, как все соединения db были закрыты и снова открыты. – RootOfProblem
Вы можете использовать консультативную блокировку, но тогда вам придется поместить это на каждую (несколько блоков) функцию (ы), и каждый запрос, используя любую такую функцию, должен был бы получить консультативную блокировку до вызова функции. Мне кажется, это слишком много. Лучшее предложение, которое у меня есть, - это взять ваш вопрос на форум DBA, так как именно там вы можете встретить фотовспытателей. – Patrick
Спасибо, я попробую удачу там. Спасибо, в любом случае. – RootOfProblem