Итак, подведем итоги нашего обсуждения Slack, вот в чем была проблема. Я резюмирую его здесь, поскольку он может быть полезен другим, сталкивающимся с аналогичной проблемой.
TD; DR. У вас были проблемы со всеми расширениями на этом компьютере, не только с TimescaleDB, и проблема оказалась связана с созданием новых функций C, которые выполняло расширение. .
Когда функции определены, 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 pg_languages
SET lanvalidator = (SELECT oid FROM pg_proc WHERE proname = 'fmgr_c_validator')
WHERE lanname = 'c'
Обратите внимание, что это объясняет, почему вы получаете ошибку, но не объясняет, почему pg_languages
содержит неправильный OID для столбца lanvalidator
. Мы предположили, что это могло произойти во время аварийного переключения, поскольку у вас было несколько рекламных акций, но в конечном итоге это чистая догадка.
person
Mats Kindahl
schedule
31.10.2019
select name, installed_version from pg_available_extensions where name = 'timescaledb'
? - person Mats Kindahl   schedule 30.10.2019shared_preload_libraries
, так и без него, и это сработало в обоих случаях. Если у некоторых столбцов был неправильный тип, это могло вызвать эту ошибку, поэтому вы используете совпадающие версии PostgreSQL и TimescaleDB? - person Mats Kindahl   schedule 30.10.2019