отслеживание причины ошибки «не удалось открыть связь с OID» - PullRequest
4 голосов
/ 17 февраля 2011

Совсем недавно мой PostgreSQL 8.2.4 регистрирует такие ошибки:

ERROR:  could not open relation with OID nnnnnnnnn
CONTEXT: SELECT a,b,c FROM table_C

Ошибка всегда вызывается одним и тем же сценарием: обновление таблицы A вызывает срабатывание триггера, который вставляет данные в таблицу B, который запускает другой триггер, который (среди прочего) выбирает в таблице C. Этот выбор затем в таблице С указывается КОНТЕКСТ проблемы, описанной выше. Последовательность запросов, приводящих к появлению сообщения об ошибке, выполняется каждый день, и каждый день жалуется на отсутствие одного и того же OID.

Вполне естественно OID, упомянутый в сообщении об ошибке, не существует при запросе pg_class. Выполнение проблемного SQL (то есть выбор в таблице C) не вызывает никаких проблем. Я попытался выяснить OID и соединения между всеми задействованными таблицами, чтобы выяснить, где находится эта ссылка на несуществующий OID, но мне не удалось. Я начал с таблицы A и получил ее OID (pg_class.reltype) и убедился, что к ней подключен триггер. Проблемы начинаются, когда я запрашиваю pg_trigger, используя pg_trigger.tgrelid = pg_class.reltype в качестве условия. Запрос выдает 0 строк, но когда я запрашиваю таблицы только по relname / tgname, я получаю разные OID, точно так же, как триггер находится в другой таблице. Я провел быструю проверку, и оказалось, что создание простой таблицы с триггером приводит к тому же результату.

Итак, мои вопросы:

  1. Как мне перемещаться по таблицам pg_trigger (и другим таблицам pg, таким как pg_attribute, pg_shdepend), когда я могу найти таблицу в pg_class?

  2. Если мне как-то удается найти ссылку на проблемный OID, могу ли я просто удалить ссылку, выполнив прямые обновления / удаления в таблицах pg_class?

Ответы [ 2 ]

4 голосов
/ 17 февраля 2011

Обратите внимание, что reltype - это OID типа строки таблицы - OID самой таблицы равен pg_class.oid (это системный столбец, поэтому он не отображается в \d или select * выходныхнужно выбрать его явно).

Надеюсь, это решит некоторые загадки о том, как таблицы каталога связаны друг с другом!Тот же шаблон повторяется с несколькими другими таблицами, использующими oid в качестве своего первичного ключа.

Это выглядит как довольно серьезная проблема, возможно, указывающая на какое-то повреждение каталога?Вы можете изменить pg_class и др. Напрямую, но, очевидно, в этом есть определенный риск.Я не могу придумать много общих советов, чтобы дать здесь - что делать будет сильно различаться в зависимости от того, что вы найдете.

0 голосов
/ 28 марта 2016

Если это появляется при выполнении операторов внутри функции SQL, измените язык с SQL на plpgsql.Причиной может быть кэшированный план.Функция plpgsql делает недействительным план между запусками, в то время как функция sql пропускает этот шаг.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...