HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlMinor

Alter table statement waiting (for hours, on dev machine), but no locks shown

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
statementwaitinghoursbutshowndevformachinealterlocks

Problem

I have been trying to issue a simple:

ALTER TABLE tablename ADD COLUMN id_col character varying (30)

type statement on a Postgres 9.1.13 build on Debian. The application is still in private beta, so the volume is low, and yet something is blocking this statement. Following this Postgres lock monitoring post, and running the query,

SELECT bl.pid        AS blocked_pid,
     a.usename       AS blocked_user,
     kl.pid          AS blocking_pid,
     ka.usename      AS blocking_user,
     a.current_query AS blocked_statement
 FROM  pg_catalog.pg_locks  bl
 JOIN pg_catalog.pg_stat_activity a  ON a.procpid = 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.procpid = kl.pid
 WHERE NOT bl.granted;


returns no results.

If I run,

SELECT * FROM pg_stat_activity


all I see is the ALTER TABLE statement with waiting = t, and a couple of other queries in an IDLE state.

I am not a DBA, more of a database developer, and so apologies if I am missing something really obvious, but I have never seen a situation like this on a low volume dev box, so am at a loss as to how to proceed.

Solution

Per the notes given on the wiki for that query, it only shows row level locks.

ALTER TABLE takes a table level ACCESS EXCLUSIVE lock. One or more transactions will be holding weaker locks on the table that prevent ALTER TABLE from acquiring its lock.

You can identify the lock being waited on with something like:

select * 
from pg_stat_activity sa 
inner join pg_locks lwait on (sa.pid = lwait.pid) 
where sa.waiting = 't' 
  and sa.query like '%ALTER%' 
  and not lwait.granted;


(change "sa.pid" to "sa.procpid" on 9.1 and older).

Code Snippets

select * 
from pg_stat_activity sa 
inner join pg_locks lwait on (sa.pid = lwait.pid) 
where sa.waiting = 't' 
  and sa.query like '%ALTER%' 
  and not lwait.granted;

Context

StackExchange Database Administrators Q#84739, answer score: 4

Revisions (0)

No revisions yet.