Итак, подведем итог нашей дискуссии о Slack, вот в чем проблема. Я суммирую это здесь, так как это может быть полезно для других, которые сталкиваются с подобной проблемой.
TD; DR. У вас были проблемы с всеми расширениями на этоммашина, а не только TimescaleDB, и проблема оказалась связана с созданием новых функций языка Си, которые выполняло расширение.
Когда функции определены, PostgreSQL принимает участие после LANGUAGE
(в данном случае C
) и найдите валидатор языка в pg_languages
. Код для этого находится в CreateFunction
в файле functioncmds.c
.
В вашем случае pg_languages
содержит:
SELECT * FROM pg_languages;
lanname | lanowner | lanispl | lanpltrusted | lanplcallfoid | laninline | lanvalidator | lanacl
----------+----------+---------+--------------+---------------+-----------+--------------+--------
internal | 10 | f | f | 0 | 0 | 2246 |
sql | 10 | f | t | 0 | 0 | 2248 |
plpgsql | 10 | t | t | 13005 | 13006 | 13007 |
c | 10 | f | f | 0 | 0 | 1 |
(4 rows)
Из таблицы выше, OID для валидатора языка (что является нашей причиной) равно 1.
Как только это будет сделано, PostgreSQL вызовет валидатор с определяемой функцией и позволит валидатору проверить, что функция определена правильно. Это делается в ProcedureCreate
в файле pg_proc.c
.
Это происходит путем поиска OID функции в таблице pg_proc
, которая в вашем случае содержала:
SELECT oid, proname FROM pg_proc WHERE oid = 1;
oid | proname
-----+---------
(0 rows)
Итак, процедура для валидатора языка не найдена, и онагенерирует ошибку здесь (это внутри fmgr_info_cxt_security
в fmgr.c
):
/* Otherwise we need the pg_proc entry */
procedureTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
if (!HeapTupleIsValid(procedureTuple))
elog(ERROR, "cache lookup failed for function %u", functionId);
procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
Это можно исправить, посмотрев правильный валидатор языка для использования. Все встроенные валидаторы имеют имя fmgr_<lang>_validator
, поэтому мы можем найти их, используя:
SELECT oid, proname FROM pg_proc WHERE proname LIKE '%fmgr%validator%';
oid | proname
------+-------------------------
2246 | fmgr_internal_validator
2247 | fmgr_c_validator
2248 | fmgr_sql_validator
(3 rows)
Итак, этот запрос обновит столбец lanvalidator
для использования правильного валидатора.
UPDATE foo
SET lanvalidator = (SELECT oid FROM pg_proc WHERE proname = 'fmgr_c_validator')
WHERE lanname = 'c'
Обратите внимание, что это объясняет, почему вы получаете ошибку, но не объясняет, почему pg_languages
содержал неправильный OID для столбца lanvalidator
. Мы выдвинули гипотезу, что это могло произойти во время аварийного переключения, поскольку у вас было несколько повышений в должности, но в конечном итоге это просто догадки.