重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
一些ORACLE中的进程被杀掉后,状态被置为"killed",但是锁定的资源很长时间不释放,有时实在没办法,只好重启数据库。现在提供一种方法解决这种问题,那就是在ORACLE中杀不掉的,在OS一级再杀。\x0d\x0a1.下面的语句用来查询哪些对象被锁:\x0d\x0aselectobject_name,machine,s.sid,s.serial#\x0d\x0afromv$locked_objectl,dba_objectso,v$sessions\x0d\x0awherel.object_id=o.object_idandl.session_id=s.sid;\x0d\x0a2.下面的语句用来杀死一个进程:\x0d\x0aaltersystemkillsession'24,111';(其中24,111分别是上面查询出的sid,serial#)\x0d\x0a【注】以上两步,可以通过Oracle的管理控制台来执行。\x0d\x0a3.如果利用上面的命令杀死一个进程后,进程状态被置为"killed",但是锁定的资源很长时间没有被释放,那么可以在os一级再杀死相应的进程(线程),首先执行下面的语句获得进程(线程)号:\x0d\x0aselectspid,osuser,s.program\x0d\x0afromv$sessions,v$processp\x0d\x0awheres.paddr=p.addrands.sid=24(24是上面的sid)\x0d\x0a4.在OS上杀死这个进程(线程):\x0d\x0a1)在unix上,用root身份执行命令:\x0d\x0a#kill-912345(即第3步查询出的spid)\x0d\x0a2)在windows(unix也适用)用orakill杀死线程,orakill是oracle提供的一个可执行命令,语法为:\x0d\x0aorakillsidthread\x0d\x0a其中:\x0d\x0asid:表示要杀死的进程属于的实例名\x0d\x0athread:是要杀掉的线程号,即第3步查询出的spid。\x0d\x0a例:c:orakillorcl12345
让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:空间域名、虚拟主机、营销软件、网站建设、蔡甸网站维护、网站推广。
1、首先以DBA的身份登录Oracle10g。
2、修改SOCCT账户权限,"alteruserscottaccountunlock;"
3、修改HR账户权限,"alteruserhraccountunlock;" 在commit操作之后,继续:"alteruserhridentifiedbyhr;"
4、然后检查状态,就会发现已经解锁了。
查询锁表
SELECT object_name, machine, s.sid, s.serial#
FROM gv$locked_object l, dba_objects o, gv$session s
WHERE l.object_id = o.object_id
AND l.session_id = s.sid;
2解锁
--释放SESSION SQL:
--alter system kill session 'sid, serial#';
ALTER system kill session '23, 1647';
3锁表原因分析
1.对数据库操作update,insert,delete时候,数据库无法更新,操作等待时长,操作结果不发生改变
2.在程序中,底层(数据访问层)操作时候,不成功,数据库连接超时,无法操作,或者操作等待时长等现象
【加锁的原理】:比如一个操作在进行修改一表,它没完成,另一个操作也操作这张表时候就需要等待,前面操作结束之后才可进行操作。
4锁表分类以及如何避免锁表
Oracle锁表 行级锁 表级锁
---- 行被排他锁定
----在某行的锁被释放之前,其他用户不能修改此行 ----使用 commit 或 rollback 命令释放锁
----Oracle 通过使用 INSERT、UPDATE 和 SELECT…FOR UPDATE 语句自动获取行级锁
SELECT…FOR UPDATE 子句 ―在表的一行或多行上放置排他锁 ―用于防止其他用户更新该行
―可以执行除更新之外的其他操作
―select * from goods where gid=1001 ―for update of gname;
―只有该用户提交事务,其他用户才能够更新gname
FOR UPDATE WAIT 子句 ―Oracle9i 中的新增功能 ―防止无限期地等待锁定的行 ―等待间隔必须指定为数值文字
―等待间隔不能是表达式、赋值变量或 PL/SQL 变量
―select * from goods where gid=1001 for update of gname wait 3 ―等待用户释放更新锁的时间为3秒,否则超时。 •表级锁
―保护表的数据
―在多个用户同时访问数据时确保数据的完整性 ―可以设置为三种模式:共享、共享更新和 排他
语法:lock table table_namein mode; 共享锁 ―锁定表
―仅允许其他用户执行查询操作 ―不能插入、更新和删除
―多个用户可以同时在同一表中放置此锁 ―lock table table_name ―in share mode [nowait];
― rollback 和commit 命令释放锁 ― nowait 关键字告诉其他用户不用等待 共享更新锁
―锁定要被更新的行
―允许其他用户同时查询、插入、更新未被锁定的行
―在 SELECT 语句中使用“FOR UPDATE”子句,可以强制使用共享更新锁 ―允许多个用户同时锁定表的不同行
加锁的两种方法
lock table tab_name in share update mode; select column1,column2 from goods where goods where gid=1001
for update of column1,column2 排他锁
―与其他两种锁相比,排他锁是限制性最强的表锁 ―仅允许其他用户查询数据
―不允许执行插入、删除和更新操作
―在同一时间仅允许一位用户在表上放置排他锁 ―共享锁与此相反
lock table tab_name in exclusive mode; lock table 表名[ 表名]... in share mode [nowait]
lock table 表名[ 表名]... in exclusive mode [nowait] lock table 表名[ 表名]... in share update mode[nowait]
-----------------------------------------------------------------------------------------------
LOCK Name
LOCK — 在事务中明确地锁定一个表 LOCK [ TABLE ] name
LOCK [ TABLE ] name IN [ ROW | ACCESS ] { SHARE | EXCLUSIVE } MODE
LOCK [ TABLE ] name IN SHARE ROW EXCLUSIVE MODE 输入
name
要锁定的现存的表.
ACCESS SHARE MODE
注意: 这个锁模式对被查询的表自动生效。
这是最小限制的锁模式,只与 ACCESS EXCLUSIVE 模式冲突。 它用于保护被查询的表免于被并行的 ALTER TABLE, DROP TABLE 和 VACUUM 对同一表操作的语句修改。
ROW SHARE MODE
注意: 任何 SELECT...FOR UPDATE 语句执行时自动生效。 因为它是一个共享锁,以后可能更新为 ROW EXCLUSIVE 锁。
与 EXCLUSIVE 和 ACCESS EXCLUSIVE 锁模式冲突。
ROW EXCLUSIVE MODE
注意: 任何 UPDATE, DELETE和 INSERT 语句执行时自动生效。
与 SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE 和 ACCESS EXCLUSIVE 模式冲突。
SHARE MODE
注意: 任何 CREATE INDEX 语句执行时自动附加。 共享锁住整个表.
与 ROW EXCLUSIVE,SHARE ROW EXCLUSIVE,EXCLUSIVE 和 ACCESS EXCLUSIVE 模式冲突。这个模式防止一个表被并行更新。
SHARE ROW EXCLUSIVE MODE
注意: 这个模式类似 EXCLUSIVE MODE,但是允许其他事务的 SHARE ROW 锁.
-----------------------------------------------------------------------------------------------
与 ROW EXCLUSIVE,SHARE,SHARE ROW EXCLUSIVE,EXCLUSIVE 和 ACCESS EXCLUSIVE 模式冲突。
EXCLUSIVE MODE
注意: 这个模式同样比 SHARE ROW EXCLUSIVE 更有约束力. 它阻塞所有并行的 ROW SHARE/SELECT... FOR UPDATE 查询。
与 ROW EXCLUSIVE,SHARE,SHARE ROW EXCLUSIVE,EXCLUSIVE 和 ACCESS EXCLUSIVE 模式冲突。
ACCESS EXCLUSIVE MODE
注意: 由语句 ALTER TABLE, DROP TABLE,VACUUM 执行时自动生效。这是最严格的约束锁,它与所有其他的锁 模式冲突并且保护一个被锁定的表不被任何其他并行的操作更改。
注意: 一个不合格的 LOCK TABLE 同样要求这个锁模式 (例如,一条没有显式锁模式选项的命令)。
输出
LOCK TABLE 成功锁定后的返回.
ERROR name: Table does not exist. 如果name 不存在,返回此信息.
描述
LOCK TABLE 控制一次事务的生命期内对某表的并行访问. Postgres 在可能的情况下尽可能使用最小约束的锁模式。 LOCK TABLE 在你需要时提供更有约束力的锁。
RDBMS 锁定使用下面术语:
EXCLUSIVE
排它锁,防止其他(事务)锁的产生.
SHARE
允许其他(事务)共享锁.避免 EXCLUSIVE 锁.
ACCESS
-----------------------------------------------------------------------------------------------
锁定表结构.
ROW
锁定独立的行.
注意: 如果没有声明 EXCLUSIVE 或 SHARE,假设为 EXCLUSIVE.锁存在于事务周期内.
例如,一个应用在 READ COMMITED 隔离级别上运行事务, 并且它需要保证在表中的数据在事务的运行过程中都存在。要实现这个你 可以在查询之前对表使用 SHARE 锁模式进行锁定。这样将保护数据不被 并行修改并且为任何更进一步的对表的读操作提供实际状态的数据, 因为 SHARE 锁模式与任何写操作需要的 ROW EXCLUSIVE 模式冲突,并且你的 LOCK TABLE name IN SHARE MODE 语句将等到所有并行的写操作提交或回卷后才执行。
注意: 当在 SERIALIZABLE 隔离级别运行事务,而且你需要读取真实状态的数据时, 你必须在执行任何 DML 语句 (这时事务定义什么样的并行修改对它自己是可见的) 之前运行一个 LOCK TABLE 语句。
除了上面的要求外,如果一个事务准备修改一个表中的数据, 那么应该使用 SHARE ROW EXCLUSIVE 锁模式以避免死锁情况(当两个 并行的事务试图以 SHARE 模式锁住表然后试图更改表中的数据时, 两个事务(隐含的)都需要 ROW EXCLUSIVE 锁模式,而此模式与并行的 SHARE 锁冲突)。
继续上面的死锁(两个事务彼此等待)问题, 你应该遵循两个通用的规则以避免死锁条件:
事务应该以相同的顺序对相同的对象请求锁。
例如,如果一个应用更新行 R1 然后更新行 R2(在同一的事务里), 那么第二个应用如果稍后要更新行 R1 时不应该更新行 R2(在 同一事务里)。相反,它应该与第一个应用以相同的顺序更新行 R1 和 R2。
事务请求两个互相冲突的锁模式的前提:其中一个锁模式是自冲突的 (也就是说,一次只能被一个事务持有)。 如果涉及多种锁模式,那么事务应该总是最先请求最严格的锁模式。
这个规则的例子在前面的关于用 SHARE ROW EXCLUSIVE 模式取代 SHARE 模式的讨论中已经给出了。 -----------------------------------------------------------------------------------------------
注意: Postgres 的确检测死锁, 并将回卷至少一个等待的事务以解决死锁。
注意
LOCK 是 Postgres 语言扩展.
除了ACCESS SHARE/EXCLUSIVE 锁模式外,所有其他 Postgres 锁模式和 LOCK TABLE 语句都与那些在 Oracle 里面的兼容。
LOCK 只在事务内部使用.
用法
演示在往一个外键表上插入时在有主键的表上使用 SHARE 的锁:
BEGIN WORK;
LOCK TABLE films IN SHARE MODE; SELECT id FROM films
WHERE name = 'Star Wars: Episode I - The Phantom Menace';
-- 如果记录没有返回则回卷
INSERT INTO films_user_comments VALUES
(_id_, 'GREAT! I was waiting for it for so long!'); COMMIT WORK;
在执行删除操作时对一个有主键的表进行 SHARE ROW EXCLUSIVE 锁:
BEGIN WORK;
LOCK TABLE films IN SHARE ROW EXCLUSIVE MODE; DELETE FROM films_user_comments WHERE id IN (SELECT id FROM films WHERE rating 5); DELETE FROM films WHERE rating 5; COMMIT WORK; 兼容性 SQL92
在SQL92里面没有LOCK TABLE ,可以使用 SET TRANSACTION 来声明当前事务的级别. 我们也支持这个,参阅 SET TRANSACTION 获取详细信息。
1、在sql语句后面加上for update可以获得行锁。
2、捕捉返回的sqlcode 和 sqlerrmc 可以得到返回值和错误信息。
---
以上,希望对你有所帮助。
1. 先通过top命令查看产用资源较多的spid号
2.查询当前耗时的会话ID,用户名,sqlID等:
select sid,serial#,machine,username,program,sql_hash_value,sql_id,
to_char(logon_time,'yyyy/mm/dd hh24:mi:ss') as login_time from v$session
where paddr in (select addr from v$process where spid in ('5648612','256523'));
3. 如果上一步sql_id或者 hash_value不为空,则可用v$sqlarea查出当前正在使用的sql
select sql_text
from v$sqltext_with_newlines
where hash_value = hash_value
order by piece;
也可直接使用:
select a.*,b.SQL_TEXT from (
select sid,serial#,machine,username,program,sql_hash_value,sql_id,
to_char(logon_time,'yyyy/mm/dd hh24:mi:ss') as login_time from v$session
where paddr in (select addr from v$process where spid in ('23226'))
) a,v$sql b
where a.sql_id = b.SQL_ID(+)
4.kill占用大资源的session
Alter system kill session 'SID,SERIAL#'
解锁:
1.查询哪些对象被锁:
select object_name,machine,s.sid,s.serial#
from v$locked_object l,dba_objects o ,v$session s
where l.object_id = o.object_id and l.session_id=s.sid;
2.下面的语句用来杀死一个进程:
alter system kill session '524,1095'; (其中24,111分别是上面查询出的sid,serial#)
3.再一次查询目前锁定的对象,若发现以上方法不能解除锁定的表,则用以下方法:
3.1 执行下面的语句获得进程(线程)号:
select spid, osuser, s.program
from v$session s,v$process p
where s.paddr=p.addr and s.sid=524 (524是上面的sid)