Published on Sat, Nov 19, 2011
Before discussing on deadlocks, lets see type of locks and their
acquiring methodolgy in PostgreSQL.
Types of Locks:
Table-Level Locks:
Row-Level Locks:
Two types of row-level locking share and exclusive locks. Don’t fall into confusion of LOCK naming, you can differentiate row-lock and table-lock by the column ‘lock_type’ in pg_locks.
Note: In either cases of row-level locks, data retreival is not at all effectied. Row-level lock block Writers (ie., Writer will block the Writer)
DeadLocks:
Now Deadlocks, you have seen the lock modes and their lock aquiring methodology, there are situations some of the transactions fall under deadlock. I believe application designing is the culprit forcing transactions to deadlocks. Deadlock mostly caused by ExclusiveLock’s i.e., UPDATE or DELETE.
What is deadlock ?
Process A holding lock on object X and waiting for lock on Object Y. Process B holding lock on Object Y and waiting for lock on Object X. At this point the two processes are now in what’s called ‘deadlock’ each is trying to obtain a lock on something owned by the other. They both will wait on each other forever if left in this state. One of them has to give up and release the locks they already have. Now, deadlock detector comes into picture and allow one process to success and another to rollback.
To over come deadlock, design application in such a way that any transaction UPDATE or DELETE should succeed with complete ownership on the table. Lock the table with *‘SHARE UPDATE EXCLUSIVE MODE’ *or ‘SELECT…FOR UPDATE’ or ‘ACCESS EXCLUSIVE MODE’ and complete the transaction. In this model, deadlock detector never throw that it has hit by a EXCLUSIVE LOCK’s.
You can test the scenario given in the pic above with the resolution, you see that deadlock detector never throws error.
Locking Query:
\set locks 'SELECT w.locktype AS waiting_locktype,w.relation::regclass AS waiting_table,w.transactionid, substr(w_stm.current_query,1,20) AS waiting_query,w.mode AS waiting_mode,w.pid AS waiting_pid,other.locktype AS other_locktype,other.relation::regclass AS other_table,other_stm.current_query AS other_query,other.mode AS other_mode,other.pid AS other_pid,other.granted AS other_granted FROM pg_catalog.pg_locks AS w JOIN pg_catalog.pg_stat_activity AS w_stm ON (w_stm.procpid = w.pid) JOIN pg_catalog.pg_locks AS other ON ((w.\"database\" = other.\"database\" AND w.relation = other.relation) OR w.transactionid = other.transactionid) JOIN pg_catalog.pg_stat_activity AS other_stm ON (other_stm.procpid = other.pid) WHERE NOT w.granted AND w.pid <> other.pid;;'
Locking information Links
http://www.postgresql.org/docs/9.0/static/sql-lock.html
http://developer.postgresql.org/pgdocs/postgres/explicit-locking.html
Hope you got some idea on PostgreSQL Locks. See you all soon with another good blog…. :)
–Raghav