PG_TERMINATE_BACKEND does not end a specific session - session

I was unable to drop a redshift db because of a connection:
Couldn't drop my_db : #<ActiveRecord::StatementInvalid: PG::ObjectInUse: ERROR: database "my_db" is being accessed by other users
I connected (via psql) to another db of the same cluster, and checked to see the pid of of my pending session:
my_other_db=# select procpid from pg_stat_activity where datname='my_db';
procpid
---------
20457
(1 row)
So I attempted a call to PG_TERMINATE_BACKEND:
my_other_db=# select pg_terminate_backend(20457);
pg_terminate_backend
----------------------
1
(1 row)
But when I checked my pg_stat_activity, my blocking session was still here:
my_other_db=# select procpid from pg_stat_activity where datname='my_db';
procpid
---------
20457
(1 row)
And I was still unable to drop my db.
Any idea ? (I had to restart the cluster to get rid of it, which is not a satisfying solution)
(Of course, I tried with another session, which I managed to terminate)

When you cancel the query or terminate the session Redshift has to return the database to a safe state by reverting any changes already made. This can take a varying amount of time depending on what the session was doing and any other queries are inflight that affect the same table(s).

You can do one of the following
select pg_terminate_backend([pid])
cancel [pid]
Kill the query via the Redshift console
On rare occasions, ghost pids will continue to run. In these instances, you can reboot the cluster.

Related

Oracle how to find the blocking sql

I have got a java app which after x number of requests just hangs. Looking at the app, it hangs on the execution of a query against an oracle database. Checked the blocking session using this sql and getting this:
Clearly SID 68 is blocking the SID 10. But why isn't it showing the blocking sql? The output from v$lock shows the following locks:
How do I find the actual blocking sqls?
The reason it's not showing the blocking SQL statement is because this cannot be known.
Consider this scenario:
Session 1 - 'SELECT FOR UPDATE ... WHERE EMP_ID = '123" (thus locking that row)
SESSION 1 - .... some other SQL (still hasn't committed)
Session 1 - .... some other SQL (still hasn't committed)
Session 1 - .... some other SQL (still hasn't committed)
Session 1 - .... some other SQL (still hasn't committed)
Session 2 - 'SELECT FOR UPDATE ... WHERE EMP_ID = '123" (is blocked by session 1, which _still has not committed and so is still holding it's lock)
So, we can know that session 1 is the blocking session, but there is no view that will indicate that it was the sql 3 previous to it's current sql that actuall placed the lock.
In your case, the blocking session is inactive, you must look at PREV_SQL_ID on V$SESSION in order to identify the last sql executed by the session that remains inactive.
V$LOCK lists the locks currently held by the Oracle Database and outstanding requests for a lock or latch. There are many types of locks in Oracle that is why you have so many rows on that view.
Regards

What is the way to kill an executing procedure?

I am using Oracle sql developer. I have a procedure involving MINUS statement between two tables (table 1 and table 2). The table 1 has more than a million rows data. In this situation, when I am trying to execute it, it returns nothing but is in executing stage.
Meanwhile, I need to truncate this table data. But, when doing this, I got a resource busy error. How to terminate the executing stored procedure and how to do truncate operation meanwhile?
You do not kill a procedure, you kill a session.
Before killing the session, you might want to know that readers do not block writers and vice-versa. So, if you want to select/project the rows from the table being modified, you could always do it.
Identify the session:
SELECT s.sid,
s.serial#,
p.spid,
s.username,
s.program
FROM v$session s
JOIN v$process p ON p.addr = s.paddr
WHERE s.type != 'BACKGROUND';
Kill the session:
ALTER SYSTEM KILL SESSION 'sid,serial#';
The KILL SESSION command doesn't actually kill the session. It merely asks the session to kill itself. In some situations, like waiting for a reply from a remote database or rolling back transactions, the session will not kill itself immediately and will wait for the current operation to complete. In these cases the session will have a status of "marked for kill". It will then be killed as soon as possible.
In addition to the syntax described above, you can add the IMMEDIATE clause.
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
This does not affect the work performed by the command, but it returns control back to the current session immediately, rather than waiting for confirmation of the kill.
Read this article for more details.

SAS connection to Oracle hung up for 2 hours

In SAS we have a library which is actually ORACLE schema and today I faced with a strange event when trying to query a table in this library.
A regular SAS SQL query:
proc sql;
delete from table where id=123;
quit;
Was hung up for two hours while it usually took some seconds:
NOTE: PROCEDURE SQL used (Total process time):
real time 2:00:33.49
cpu time 0.03 seconds
While this operation was being performed I tried to delete a nearby row in ORACLE SQL DEVELOPER but it hung up processing delete request too. However deleting a row that was not nearby these rows did not cause any problems. Well how can I find out the possible reason? I guess that was a sort of deadlock.
It sounds like someone has locked a row that your session is trying to delete. You should be able to spot this by querying v$session:
select sid, schemaname, osuser, terminal, program, event
from v$session
where type != 'BACKGROUND';
and checking if your session has an event of "enq: TX - row lock contention" (or similar). If so, then you'll have to work out who has the blocking lock (if you have access to Toad's session browser, this is easy to do, but Google should throw up something that can help. Or, if your database is Oracle 11.2, there's a view: v$session_blockers that ought to pinpoint the blocking session), and then get them to either commit or rollback their transaction.

Not able to insert the same record after connection interruption

I was inserting some records in the production table ,while doing that before commit ,I lost the production connection and none of the record got inserted.
Now when I am trying to insert the same record ,the sql plus is getting hanged and data is not getting saved.
But when I tried for other record which I was not inserted ,those records are getting inserted.
I have checked the table again ,for availability of data.Those previous data has not stored anywhere.
SQL plus is not generating any error also ,so that I can check the error and try to rectify.
Can anyone please help me to analyse and troubleshoot the problem.
while inserting in oracle the connection has lost now I am not able to add the same data
If your SQL/Plus session hangs, it's probably being blocked by your previous session. To find the offending session, you can use (requires DBA privileges):
select * from v$lock where block = 1
This should give you the session ID of the blocking session. Now you can run
select * from v$session
and check whether the session ID returned by the first query indeed belongs to your previous session. To kill the session, use the command
alter system kill session '<SID>,<serial#>'

How can I get any statistics about "idle in transaction" connections to my PostgreSQL instance?

I want to get statistics about "idle in transaction" connections.
This statistics should be a part of performance tests results and it can reveal some bugs in the tested system.
What can I use to gather this statistics?
I'm not sure what you mean with "statistics" but you can see all open connections (and their transaction state) by querying the system view pg_stat_activity:
http://www.postgresql.org/docs/current/static/monitoring-stats.html#MONITORING-STATS-VIEWS
In postgresql.conf set logging to
log_statement = 'all' # none, ddl, mod, all
and check that
log_line_prefix='%t:%r:%a:%u#%d:[%p]: '
contains %p, which is the [process ID] of the SQL.
After a reload of the database settings, in the Table *pg_stat_activity* you can read the procpid column of the idle in transaction process.
Now you can grep through the logfiles to see what SQL has been executed on the connections before they became idle in transaction.

Resources