0%

Oracle解锁用户和表

查看用户是否被锁

1
2
select username,account_status,lock_date from dba_users;
select username,account_status,lock_date from dba_users where username='SCOTT';

解锁用户

1
alter user arlo account unlock;

数据级别解锁表

锁表查询的代码有以下的形式

1
2
select count(*) from v$locked_object;
select * from v$locked_object;

查看哪个表被锁

1
2
3
select b.owner,b.object_name,a.session_id,a.locked_mode from v$locked_object a,dba_objects b where b.object_id = a.object_id;
--
select b.owner TABLEOWNER, b.object_name TABLENAME, c.OSUSER LOCKBY,c.USERNAME LOGINID, c.sid SID, c.SERIAL# SERIAL from v$locked_object a,dba_objects b, v$session c where b.object_id = a.object_id AND a.SESSION_ID =c.sid;

查看是哪个session引起的

1
select b.username,b.sid,b.serial#,logon_time from v$locked_object a,v$session b where a.session_id = b.sid order by b.logon_time;

查看是哪个sql引起的

1
select b.username,b.sid,b.serial#,c.* from v$locked_object a,v$session b,v$sql c where a.session_id = b.sid and b.SQL_ID = c.sql_id and c.sql_id = '' order by b.logon_time;

查看审计信息(包含登录用户,客户端等)

1
select sessionid,userid,userhost,comment$text,spare1,to_char(ntimestamp#+1/3,'yyyy-mm-dd hh24:mi:ss') from aud$ where returncode=1017 and userid='USERNAME' order by ntimestamp#;

杀掉对应进程

1
alter system kill session'1025,41';		 --其中1025为sid,41为serial#

系统界别解锁表

今天在使用上述方法解锁用户的时候报错

1
2
3
4
alter system kill session '2293,85'
*
ERROR at line 1:
ORA-00031: session marked for kill

查找进程id

如果利用上面的命令杀死一个进程后,进程状态被置为”killed”,但是锁定的资源很长时间没有被释放,那么可以在os一级再杀死相应的进程(线程),首先执行下面的语句获得进程(线程)号:2293

1
2
3
4
5
SYS@orcl> select spid, osuser, s.program from v$session s,v$process p where s.paddr=p.addr and s.sid=2293;
SPID OSUSER PROGRAM
-------- ----------------------- ---------------------------------------------
384159 Administrator SQL Developer

在Linux中结束进程

在Linux操作系统中执行命令杀掉进程

1
kill -9 384159

在Windows中结束进程

在windows(unix也适用)用orakill杀死线程,orakill是oracle提供的一个可执行命令,语法为:
orakill sid thread – sid:表示要杀死的进程属于的实例名 thread:是要杀掉的线程号

1
C:> orakill orcl 384159  

查看Oracle链接客户端的IP等信息

查看每个oracle帐户的连接总数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
--查看当前连接数
select count(*) from v$process;

--查看会话session:
select * from v$session where username is not null;
select username,count(username) from v$session where username is not null group by username;

--查看最大连接数
select value from v$parameter where name ='processes';

--查看并发连接数
Select count(*) from v$session where status='ACTIVE';

--查询:客户端设备标识、客户端程序、oracle用户名、消耗的连接数量
SELECT B.MACHINE 机器名,
B.PROGRAM 程序名,
B.USERNAME 用户名,
COUNT(*) 连接数
FROM V$PROCESS A, V$SESSION B
WHERE A.ADDR = B.PADDR
AND B.USERNAME IS NOT NULL
GROUP BY B.MACHINE, B.PROGRAM, B.USERNAME
ORDER BY COUNT(*) DESC;

--杀死指定的进程
alter system kill session 'sid,serial#' immediate;

缺省从 v$session 中不能直接获得客户端 IP,可以在数据库中创建一个追踪客户端IP地址的触发器

1
2
3
4
create or replace trigger on_logon_trigger after logon on database  
begin  
    dbms_application_info.set_client_info(sys_context('userenv', 'ip_address'));  
end; 

比较常用的显示客户端信息的sql

1
2
3
4
select sid,serial#,username,program,machine,client_info  
from v$session  
where username is not null  
order by username,program,machine;   

connection、process和session的基本知识

每个sql login称为一个连接(connection),而每个连接,可以产生一个或多个会话,如果数据库运行在专用服务器方式,一个会话对应一个服务器进程(process),如果数据库运行在共享服务器方式,一个服务器进程可以为多个会话服务。

Connection并不是直接建立在用户进程和数据库实例之间的。而是在用户进程和Server Process(服务器进程)之间的,因此有一个Connection就一定会有一个用户进程和一个服务器进程,但不一定会存在Session。比如,如果需要将东西从A运到B,Connection可以看成是一座“桥”,而卡车把东西从A运到B后并返回A,这就是Session。所以,只要不断开连接,随时都可以在这个连接上创建出会话。