Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tracing the cause of "could not open relation with OID" error

Tags:

postgresql

Quite recently my PostgreSQL 8.2.4 logs such errors:

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

The error is always caused by the same scenario: an update to table A causes trigger to fire, which inserts data to table B, which fires another trigger, which (among many other things) does select on table C. That select on table C is then reported as CONTEXT of the problem above. The sequence of queries that cause the error message to appear is executed every day, and everyday it complains about the same OID missing.

Quite naturally the OID mentioned in error message doesn't exists when querying pg_class. Executing problematic SQL (that is, select on table C) doesn't cause any problems. I've tried to figure out the OIDs and connections between all the tables involved, to figure out where that reference to non-existent OID is, but i have failed. I started with table A and got its OID (pg_class.reltype) and verified, that it has trigger attached. The problems start when i query pg_trigger using pg_trigger.tgrelid = pg_class.reltype as a condition. The query yelds 0 rows, but when i query tables just by relname/tgname i get different OIDs, just like the trigger is on a different table. I did a quick test and it appears, that creating a simple table with a trigger on it produces the same result.

So my questions are:

  1. How do i navigate pg_trigger (and other pg tables like pg_attribute, pg_shdepend) tables when i can locate table in pg_class?

  2. If somehow I manage to find a reference to problematic OID, am I safe to simple remove the reference by doing direct updates/deletes on pg_class tables?

like image 288
Jacek Prucia Avatar asked Feb 17 '11 15:02

Jacek Prucia


People also ask

How do I get oid in PostgreSQL?

To get a table OID, cast to the object identifier type regclass (while connected to the same DB): SELECT 'mytbl'::regclass::oid; This finds the first table (or view, etc.) with the given name along the search_path or raises an exception if not found.

What is oid in PostgreSQL?

Object identifiers (OIDs) are used internally by PostgreSQL as primary keys for various system tables. OIDs are not added to user-created tables, unless WITH OIDS is specified when the table is created, or the default_with_oids configuration variable is enabled. Type oid represents an object identifier.

What is OIDs false in PostgreSQL?

Without OIDS – This is defined as creating the table without using OIDS, if we define OIDs value as false then OID will not generate to the row in PostgreSQL. OID –This is defined as an object identifier is defined to every row in PostgreSQL. This is a unique identifier of every row.


1 Answers

Note that 'reltype' is the OID of the table's rowtype- the OID of the table itself is pg_class.oid (which is a system column, so doesn't show up in \d or select * output, you need to select it explicitly).

Hopefully that will solve some mysteries of how the catalogue tables relate to each other! The same pattern is repeated with quite a few other tables using oid as their primary key.

It looks like quite a serious problem, possibly indicating some sort of catalogue corruption? You can modify pg_class et al directly, but obviously there is some risk involved in doing that. I can't think of much generic advice to give here- what to do will vary greatly depending on what you find.

like image 131
araqnid Avatar answered Oct 11 '22 21:10

araqnid