Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect query which holds the lock in Postgres?

I want to track mutual locks in postgres constantly.

I came across Locks Monitoring article and tried to run the following query:

SELECT bl.pid     AS blocked_pid,      a.usename  AS blocked_user,      kl.pid     AS blocking_pid,      ka.usename AS blocking_user,      a.query    AS blocked_statement FROM  pg_catalog.pg_locks         bl  JOIN pg_catalog.pg_stat_activity a  ON a.pid = bl.pid  JOIN pg_catalog.pg_locks         kl ON kl.transactionid = bl.transactionid AND kl.pid != bl.pid  JOIN pg_catalog.pg_stat_activity ka ON ka.pid = kl.pid WHERE NOT bl.granted; 

Unfortunately, it never returns non-empty result set. If I simplify given query to the following form:

SELECT bl.pid     AS blocked_pid,      a.usename  AS blocked_user,      a.query    AS blocked_statement FROM  pg_catalog.pg_locks         bl  JOIN pg_catalog.pg_stat_activity a  ON a.pid = bl.pid WHERE NOT bl.granted; 

then it returns queries which are waiting to acquire a lock. But I cannot manage to change it so that it can return both blocked and blocker queries.

Any ideas?

like image 973
Roman Avatar asked Oct 21 '14 14:10

Roman


People also ask

How do I find Postgres blocked Sessions?

The pg_blocking_pids() function is a useful shortcut to find the database connections / sessions that are blocking another session. The pg_blocking_pids() function returns an postgreSQL array of PIDs that are blocking the specified server process PID that you provide to the query.

How do you check if there is a lock on a table?

You can use the sys. dm_tran_locks view, which returns information about the currently active lock manager resources.

How do I find a lock on my database?

To obtain information about locks in the SQL Server Database Engine, use the sys. dm_tran_locks dynamic management view.

Where is deadlock in PostgreSQL?

To detect the deadlock, we use the wait-for-graph approach. This is the simple and established way. To detect a deadlock, you can analyze which transaction is waiting for what. Figure 4 is a very simple wait-for-graph.


1 Answers

Since 9.6 this is a lot easier as it introduced the function pg_blocking_pids() to find the sessions that are blocking another session.

So you can use something like this:

select pid,         usename,         pg_blocking_pids(pid) as blocked_by,         query as blocked_query from pg_stat_activity where cardinality(pg_blocking_pids(pid)) > 0; 
like image 67
a_horse_with_no_name Avatar answered Oct 14 '22 09:10

a_horse_with_no_name