【Oracle】“锁”一般解决步骤(故障排查操作说明)
mhr18 2024-09-29 14:18 28 浏览 0 评论
文中使用的Oracle版本为10g。
本文将介绍在Oracle中当出现“锁”现象时的排查步骤,经验证此方法能够解决80%以上的“锁”问题。
基本操作步骤
- 先查出锁定object的session信息以及被锁定的object名,执行如下语句:
SELECT l.session_id sid,
s.serial#,
l.locked_mode,
l.oracle_username,
l.os_user_name,
s.machine,
s.terminal,
o.object_name,
s.logon_time
FROM v$locked_object l, all_objects o, v$session s
WHERE l.object_id = o.object_id
AND l.session_id = s.sid
ORDER BY sid, s.serial# ;
一般来说通过查询出来的object_name和logon_time基本能够定位到要解除锁定的对象对应的记录。
- 这段语句是查出锁定脚本的session_id, sid, serial#,os_user_name, machine name, terminal相关信息的,执行如下语句:
SELECT l.session_id sid,
s.serial#,
l.locked_mode,
l.oracle_username,
s.user#,
l.os_user_name,
s.machine,
s.terminal,
a.sql_text,
a.action
FROM v$sqlarea a,v$session s, v$locked_object l
WHERE l.session_id = s.sid
AND s.prev_sql_addr = a.address
ORDER BY sid, s.serial#;
第一条语句是通过session(会话)关联all_objects(所有对象)和locked_object(锁定对象),关注点在于对象。而第二条语句则通过sqlarea(脚本位置)关联session(会话)和locked_object(锁定对象),这说明第二条语句查询的是通过SQL脚本造成的锁定信息。两者有本质上的区别。
- 这段语句是查出锁定进程的sid, serial#,os_user_name, machine_name, terminal, type相关信息的,执行如下语句:
SELECT s.sid,
s.serial#,
s.username,
s.schemaname,
s.osuser,
s.process,
s.machine,
s.terminal,
s.logon_time,
l.type
FROM v$session s, v$lock l
WHERE s.sid = l.sid
AND s.username IS NOT NULL
ORDER BY sid;
这个通过语句中关联信息就能够猜出,这里通过session(会话)找到锁定的进程。
- 使用命令直接kill掉,执行如下语句:
alter system kill session 'sid,serial#'
通过上面三种锁定的查询可以拿到sid和serial#信息,之后直接kill掉就能够解锁,但是需要注意的是Oracle的锁不是kill就立刻释放,它有自己的释放机制,这个有机会再细讲。
锁表问题排查
- 检查Oracle的job(定时器)是否存在资源没有释放的情况,执行如下语句:
Select * from dba_job;
Select * from dba_job_running;
确定没有job执行之后,将job中对应的定时计划先删除(这个用PL/SQL非常容易就不再解释)。
- 检查所有远程计算机,看看有没有客户端存在session占用的情况(这具体的做法就是访问各个远程计算机,看看有没有正在对表的数据进行操作,就算没有都要将客户端关闭)。
- 通过语句先看看有没有对象被锁的情况,执行如下语句:
select t2.username,
t2.sid,
t2.serial#,
t2.logon_time
from v$locked_object t1,v$session t2
where t1.session_id=t2.sid
order by t2.logon_time;
结果看到没有显示锁表的情况。
- 尝试对某一字段进行修改(这个比较简单直接在PL/SQL操作即可)
结果显示修改失败表被占用。
然后进行数据的插入,若可以对表中行数据进行增删查改操作的,初步断定是修改表结构时忘记提交了因此一直被锁定了(但这个只是猜测,不能真正确定问题所在)。
- 查询表的操作记录,执行如下语句:
select * from v$sqlarea a where a.sql_text like ‘%<table_name>%’;
看看这个表的历史操作,发现了lock table 表名 in exclusive mode。
这时可以确定表是因为系统DML的隐式table lock锁定了表。所以在操作记录上没有处理session。
由于第一次的exclusive mode锁定是系统隐式做的,所以是找不到sid是什么了(由于第一次锁的时候没有及时发现,所以没有找到sid,而在做完了锁定一段时间之后sid就会取消了)。
- 最后处理办法有两个
第一、重启当前数据库实例;
第二、另开一张新表(与当前被锁的表同构的)进行操作,数据操作都重新指向那个表。
后记
- 一般情况下Oracle的“锁”操作都可以通过手动解锁,就算不手动解锁过一段时间也会自动解锁的。
- Oracle“锁表”无论是什么table-lock模式,都存在时间限制。当session结束或者操作结束后(commit 或 rollback)都会重新释放。若表长期被锁住就要检查一下是不是进行了多重锁定或者session等待的情况。
附录
# table-lock模式
Oracle的锁定可以分为以下3类:
DML lock(data lock) DDL lock(dictionary lock) Internal lock/latch。
关于DDL lock和Internal lock/latch这两个如果后期还有时间的话会划分出另一篇文章来详细描述,今天只针对DML lock进行说明。
DML lock(data lock)可分为row lock和table lock两种
√row lock
select.. for update/insert/update/delete时隐式自动产生
√table lock
table lock除了隐式产生,也可以调用lock table <table_name> in </table_name> name来显示锁定。
如果不希望别的session lock/insert/update/delete表中任意一行只允许查询,可以用_lock table table_name in exclusive mode(X)_。这种锁定模式级别最高,并发度最小。
如果允许别的session查询或用select for update锁定记录,不允许_insert/update/delete,可以用lock table table_name in share row exclusive mode。(SRX)
如果允许别的session查询或select for update以及lock table table_name in share mode,只是不允许insert/update/delete,可以用lock table table_name in share mode。(share mode和share row exclusive mode的区别在于一个是非抢占式的而另一个是抢占式的。进入share row exclusive mode后其他session不能阻止你insert/update/delete,而进入share mode后其他session也同样可以进入share mode,进而阻止你对表的修改。(S)_
还有两种锁定模式row share(RS)和row exclusive(RX)。他们允许的并发操作更多,一般直接用DML语句自动获得不用lock语句。
# unlock table
- kill session
解除锁定最容易想到的就是关闭会话,除了直接关闭窗口外还可以通过命令解除,执行如下语句:
SQL> select object_id,session_id from v$locked_object; -- 注意session_id 就是上锁的 session标志
SQL> select username,sid,SERIAL# from v$session where sid='<sid>'; -- 这里的SID = session_id
SQL> alter system kill session 'id,serial#'; -- 杀死该session
- rollback/commit 终止事务处理(PL/SQL处理)
相关推荐
- 一文带您了解数据库的行列之争:行式与列式存储的异同
-
数据库存储格式是数据库管理系统中一个至关重要的方面,它直接影响到数据的组织和检索效率。在数据库中,有两种主要的存储格式,即行式存储和列式存储。这两者采用截然不同的方法来组织和存储数据,各自具有一系列优...
- NL2SQL(三)开源项目怎么选:talk is cheap, show me the code!
-
老规矩,先看效果下面的demo来自试用的SuperSonic,将会在下面详细介绍:大模型时代Text-to-SQL特点随着基于LLM技术的发展,RAG/AIAgent/Fine...
- JDK25长期支持版九月降临:18项王炸功能全解析
-
Java要放大招啦!9月份推出的JDK25长期支持版已经锁定18个超能力,从稳定值到结构化并发,还有Linux系统下的"预知未来"性能分析!下面我用打游戏的术语给你们掰扯明白:1、飞...
- OceanBase 推出单机版 高度兼容MySQL和Oracle
-
【环球网科技综合报道】3月27日,独立数据库厂商OceanBase正式发布单机版产品。据悉,这一产品基于自主研发的单机分布式一体化架构设计,具备极简数据库架构和高度兼容性,为中小规模业务提供兼具性能与...
- 黄远邦:应对7月1日闰秒对Oracle数据库影响
-
由于今年7月1日全世界会多出一秒,这可能对时间敏感的IT系统造成较大影响。中亦科技数据库团队对此问题做了深入的研究,并对用户系统提出了相应的解决方法及建议。中亦科技数据库产品总监黄远邦认为,闰秒调整会...
- MySQL数据库密码忘记了,怎么办?(mysql 数据库密码)
-
#头条创作挑战赛#MySQL数据库密码忘记了且没有其他可以修改账号密码的账户时怎么办呢?登录MySQL,密码输入错误/*密码错误,报如下错误*/[root@TESTDB~]#mysql-u...
- Chinese AI Talent in Spotlight as Nvidia and Meta Escalate Talent War
-
OntherightisBanghuaZhu,ChiefResearchScientistatNVIDIATMTPOST--SiliconValley’stoptech...
- 用Cursor开启JAVA+AI生涯(javascirpt怎么开启)
-
Cursor是基于VSCode开发的一款编辑器,支持多种语言的开发编辑。与传统的开发工具相比,它有多种优势:与AI无缝集成,响应速度快,占用内存小。但很多同学在"起步"过程中遇到了...
- 毕业十年了,自从做了开发用了很多软件,但距离写开发工具还很远
-
办公系统类:办公软件Word、Excel、PowerPoint三大必备技能+腾讯/金山在线文档解压缩操作:7-zip/winrar文件文本处理:Notepad++(文本编辑器正则表达式超级好...
- 盘点Java中最没用的知识⑤:这3个老古董你还在代码里“考古”?
-
一、Stack类:“继承Vector”的历史bug,为何成了性能拖油瓶?你是不是在学Java集合时,老师说过“栈结构用Stack类”?是不是在老代码里见过"newStack<>(...
- Gemini 2.5 Pro 0506发布,编程最强大模型, 碾压 Claude3.7 sonnent
-
一、Gemini2.5Pro(I/Oedition)发布1、为何叫I/Oedition?谷歌史上最强编程模型Gemini2.5Pro(I/Oedition)发布,具体型号是Gemin...
- 如何让无聊变得有趣(附本人大量美图)
-
文/图:金冬成在这条长300公里的公路上,我已经来回往返了无数次。3小时车程,一个人,想想都是多么无聊的一件事。其实,人生道路上,类似这种无聊的事情有很多很多。无聊的事情、枯燥的工作,往往让我们容易失...
- Oracle 推出 Java 24,增强 AI 支持和后量子加密
-
导读:Oracle宣布正式发布Java24,该语言增加了几个新功能,例如StreamGatherersAPI和Class-FileAPI的可用性,以及专门为AI推理和量子安全设计...
- 公司ERP突然变慢?“索引重建”这颗“药”可不能随便吃!
-
各位老板、IT小哥、财务小姐姐,有没有遇到过公司ERP系统突然卡顿得像“老爷车”,点个按钮半天没反应,急得直跺脚?这时候,可能有人会跳出来说:“我知道,重建一下数据库索引就好了!”听起来像个“神操作”...
- 基于Java实现,支持在线发布API接口读取数据库,有哪些工具?
-
基于java实现,不需要编辑就能发布api接口的,有哪些工具、平台?还能一键发布、快速授权和开放提供给第三方请求调用接口的解决方案。架构方案设计:以下是一些基于Java实现的无需编辑或只需少量编辑...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 一文带您了解数据库的行列之争:行式与列式存储的异同
- NL2SQL(三)开源项目怎么选:talk is cheap, show me the code!
- JDK25长期支持版九月降临:18项王炸功能全解析
- OceanBase 推出单机版 高度兼容MySQL和Oracle
- 黄远邦:应对7月1日闰秒对Oracle数据库影响
- MySQL数据库密码忘记了,怎么办?(mysql 数据库密码)
- Chinese AI Talent in Spotlight as Nvidia and Meta Escalate Talent War
- 用Cursor开启JAVA+AI生涯(javascirpt怎么开启)
- 毕业十年了,自从做了开发用了很多软件,但距离写开发工具还很远
- 盘点Java中最没用的知识⑤:这3个老古董你还在代码里“考古”?
- 标签列表
-
- oracle位图索引 (74)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (59)
- oracle 空为0 (51)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)