Невозможно расширить базу данных postgresql с помощью timescaledb - PullRequest
0 голосов
/ 24 октября 2019

Я создал кластер PostgreSQL с 3 узлами, используя Patroni.

Я использую Ubuntu 18.04, Postgresql-10 и Timescaledb 1.4.2.

В postgresql.conf файле, который я включилshared_preload_libraries = 'timescaledb'

При расширении postresql с помощью timescaledb с помощью команды

CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE; 

выдается ошибка

ОШИБКА: не удалось выполнить поиск в кешефункция 1

1 Ответ

0 голосов
/ 31 октября 2019

Итак, подведем итог нашей дискуссии о 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. Мы выдвинули гипотезу, что это могло произойти во время аварийного переключения, поскольку у вас было несколько повышений в должности, но в конечном итоге это просто догадки.

...