Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgres client locking up when creating new table

Tags:

postgresql

I'm trying to create a new table in postgres but when I do it just hangs after the CREATE TABLE call.

$ sudo usermod -s /bin/bash postgres
$ sudo su - postgres
postgres@host:~$ psql ranking_analytics
psql (8.4.8)
Type "help" for help.

ranking_analytics=# BEGIN;
BEGIN
ranking_analytics=# CREATE TABLE "about_contactmessage" (
ranking_analytics(#     "id" serial NOT NULL PRIMARY KEY,
ranking_analytics(#     "user_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED,
ranking_analytics(#     "subject" text NOT NULL,
ranking_analytics(#     "message" text NOT NULL,
ranking_analytics(#     "recorded_time" timestamp with time zone NOT NULL
ranking_analytics(# )
ranking_analytics-# ;
NOTICE:  CREATE TABLE will create implicit sequence "about_contactmessage_id_seq" for serial column "about_contactmessage.id"

It will then just sit here indefinately until I CTRL-C it.

There are other tables in the database and this one doesn't already exist:

ranking_analytics=# \d about_contactmessage
Did not find any relation named "about_contactmessage".

I'm able to do insert and delete queries on other tables in the database without a problem:

ranking_analytics=# insert into locations_continent (continent_name) VALUES ('testing');
INSERT 0 1
ranking_analytics=# delete from locations_continent where continent_name = 'testing';
DELETE 1

There is plenty of drive space on the machine:

$ df -H
Filesystem             Size   Used  Avail Use% Mounted on
/dev/xvda               21G   2.3G    18G  12% /
devtmpfs               255M   132k   255M   1% /dev
none                   257M   476k   256M   1% /dev/shm
none                   257M    54k   257M   1% /var/run
none                   257M      0   257M   0% /var/lock

Any ideas what could be wrong?

like image 322
Mark L Avatar asked Jul 03 '12 07:07

Mark L


People also ask

How do I stop table locking in Postgres?

Do this instead: -- select, update, insert, and delete block until the catalog is update (milliseconds) ALTER TABLE items ADD COLUMN last_update timestamptz; -- select and insert go through, some updates and deletes block while the table is rewritten UPDATE items SET last_update = now();

Why table is lock in PostgreSQL?

PostgreSQL locks, also known as “write locks” or “exclusive locks”, work by preventing users from changing either a row or an entire PostgreSQL table. When rows have been changed by the DELETE or UPDATE operations, they will be exclusively locked until the transaction is complete.

What is PostgreSQL locking?

Locks or Exclusive Locks or Write Locks prevent users from modifying a row or an entire table. Rows modified by UPDATE and DELETE are then exclusively locked automatically for the duration of the transaction. This prevents other users from changing the row until the transaction is either committed or rolled back.

What causes Postgres deadlock?

In PostgreSQL, when a transaction cannot acquire the requested lock within a certain amount of time (configured by `deadlock_timeout`, with default value of 1 second), it begins deadlock detection.


1 Answers

If restarting postgres is an option, then that will most likely solve the issue and will save you from spending time reading the rest of this answer :-)

Check the pg_stat_activity view, there is probably some other transaction blocking the schema change.

select * from pg_stat_activity 
where 
wait_event_type is NULL and xact_start is not NULL order by xact_start;

(the pg_stat_activity is changed a bit in every major pg release, try this for elder versions):

select * from pg_stat_activity 
where 
not waiting and xact_start is not NULL order by xact_start;

The first row to show up is probably the one causing problems. It is often an "idle in transaction" - this may very well hold locks, and if it's an old transaction it may as well kill performance. Probably the programmer forgot to ensure ending the transaction with "commit" or "rollback", or maybe some db session got stuck due to network problems.

To terminate transaction with pid 1234, use select pg_cancel_backend(1234);, if that fails, select pg_terminate_backend(1234). With shell access, the equivalent commands are kill -INT 1234 and kill 1234. (keep in mind, kill -9 1234 is a really bad idea).

There is also a view pg_locks which may give some insight, though it may probably not be that easy to get any useful info out from it. If granted is true, the lock is held, when granted is false it means the query is waiting for the lock. Here are some more hints here on how to extract useful info from pg_locks: http://wiki.postgresql.org/wiki/Lock_Monitoring

If everything else fails, then it's probably time to go for the simple solution, restart that database server.

like image 145
tobixen Avatar answered Oct 31 '22 00:10

tobixen