Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgresql object ID and tuples

Tags:

postgresql

I sometimes see messages like

Process 12990 waits for ExclusiveLock on tuple (889,66) of relation 17720 of database 17607; blocked by process 12992.

So of course the 'process' part is quite clear, but I don't know how to correlate between the relation ID and a human readable name. I also don't really know what to make of the tuple bit.

Anyone know how to read these messages and how to glean useful data from them?

Thanks!

like image 470
user431221 Avatar asked Aug 25 '10 21:08

user431221


People also ask

What is a tuple ID?

A tuple ID is a pair (block number, tuple index within block) that identifies the physical location of the row within its table.

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 an object in PostgreSQL?

In Postgres, Large Objects (also known as BLOBs) are used to hold data in the database that cannot be stored in a normal SQL table. They are stored in a separate table in a special format, and are referred to from your own tables by an OID value.

What is OID in Postgres?

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.


2 Answers

A "relation" is a table and a "tuple" is a row.

Here's a nice shortcut for getting the name of the table from the table id (you can also query the pg_class table):

=> select 17720::regclass; ┌──────────┐ │ regclass │ ├──────────┤ │ my_table │ └──────────┘ (1 row) 

Now how about the row? The "tuple bit" is a tuple identifier, and every table in your database has a special system column called ctid where those identifiers are stored. Now that we know the table in question, we can do:

=> select * from my_table where ctid='(889,66)'; 

However! From the system column docs (emphasis added): "[A]lthough the ctid can be used to locate the row version very quickly, a row's ctid will change if it is updated or moved by VACUUM FULL. Therefore ctid is useless as a long-term row identifier." In other words, if you're quick enough you can probably trust that the row returned is the one involved in the deadlock, but that info won't be available forever.

like image 144
whit537 Avatar answered Sep 17 '22 15:09

whit537


You can look this up the system tables : the one of interest here is pg_class.

Doing a query like

SELECT OID, relname FROM pg_class  oid  |              relname                -------+------------------------------------   1247 | pg_type  11550 | user_mapping_options  11554 | user_mappings  11494 | triggered_update_columns  11497 | triggers 

or rather

SELECT relname FROM pg_class WHERE OID=17720 

might shed light on the locks.

like image 44
Peter Tillemans Avatar answered Sep 21 '22 15:09

Peter Tillemans