Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 502 Vote(s) - 3.53 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to release possible Postgres row locks?

#1
I ran an update statement on a large PostgreSQL table through the phpPgAdmin interface. This timed out as it ran for too long.

I can now update some rows from that table but not all. Trying to update some rows will hang.

Are the rows locked? How can I allow these rows to be updated?
Reply

#2
i've never worked with PostreSql but if it's similar to others i'd say you have to kill the connection/end the transaction that's holding the locks.
Reply

#3
What version of PostgreSQL are you running? The following assumes 8.1.8 or later (it may apply to earlier versions too, I don't know).

I presume that you mean that phpPgAdmin timed out -- the PostgreSQL backend will take as long as it takes to complete a query/update. In that case, it's possible that the original session is still alive and the UPDATE query is still running. I suggest running the following query (taken from [chapter 24 of the PostgreSQL docs](

[To see links please register here]

)) on the machine that hosts the PostgreSQL server process, to see whether the session is still alive:

ps auxwww|grep ^postgres

Several rows should appear: 1 for the `postmaster` master process, and 1 each for "writer", "stats buffer", and "stats collector" processes. Any remaining lines are for processes serving DB connections. These lines will contain the username and database name.

Hopefully, from that you can see whether the session you performed the original UPDATE in is still hanging around. Although in theory you could find more detailed info by `SELECT`ing from the system view `pg_stat_activity`, by default PostgreSQL is not set up to populate the most useful fields (such as `current_query` and `query_start`). See chapter 24 for how to enable this in the future.

If you see the session is still there, kill it. You will need to be logged in as the user running the process (usually `postgres`) or root to do so -- if you don't run the server yourself, get your DBA to do this for you.

One more thing: for updating rows in a table, PostgreSQL avoids using locks. Instead, it allows every writing transaction to create a new "version" of the DB, which becomes the "current version" when the transaction is committed, provided it doesn't conflict with updates made in the meantime by other transactions. So I suspect the "hanging" you're seeing is caused by something else -- though what, I'm not sure. (Have you checked the obvious things, like whether the disk partition containing the DB is full?)
Reply

#4
It's possible to see the locks.

Here is a view to make it a bit easier than using pg_locks directly:

CREATE OR REPLACE VIEW public.active_locks AS
SELECT t.schemaname,
t.relname,
l.locktype,
l.page,
l.virtualtransaction,
l.pid,
l.mode,
l.granted
FROM pg_locks l
JOIN pg_stat_all_tables t ON l.relation = t.relid
WHERE t.schemaname <> 'pg_toast'::name AND t.schemaname <> 'pg_catalog'::name
ORDER BY t.schemaname, t.relname;

Then you just select from the view:

SELECT * FROM active_locks;

And kill it with:

SELECT pg_cancel_backend('%pid%');


Other solutions:

[To see links please register here]

Reply

#5
To release possible locks from Postgres I generally follow these in sequence.

1. Find long-running queries in your DB by running the following query. This will help you fetch the PIDs of the long-running query which is blocking your update.

SELECT
pid,
now() - pg_stat_activity.query_start AS duration,
query,
state
FROM pg_stat_activity
WHERE (now() - pg_stat_activity.query_start) > interval '5 minutes';

2. or if you can find out which processes are holding a lock on a particular table by running this query


SELECT *
FROM pg_locks l
JOIN pg_class t ON l.relation = t.oid AND t.relkind = 'r'
WHERE t.relname = 'Bill';

3. Once you figure out the PID which is 'active' and blocking your update you can kill it by running this query. It takes some time to kill the process.

SELECT pg_cancel_backend(__pid__);

4. Check by running Query 2 if the process is killed. If it still is active then kill this process by running this query.

SELECT pg_terminate_backend(__pid__);

Reply

#6
This will clear all locks on all tables.

SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE pid <> pg_backend_pid();
Reply

#7
**Simple:**

<i>Get the active locks from pg_locks:</i>

```sql
SELECT t.relname, l.locktype, page, virtualtransaction, pid, mode, granted
FROM pg_locks l, pg_stat_all_tables t
WHERE l.relation = t.relid
ORDER BY relation asc;
```

<i>Copy the pid(ex: 14210) from above result and substitute in the below command.</i>

```sql
SELECT pg_terminate_backend(14210)
```
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through