`

Oracle数据库的锁(ora-00054错误参考资料)

 
阅读更多

 Oracle数据库的锁        

 

数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。

在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。


 

Oracle数据库的锁类型

根据保护的对象不同,Oracle数据库锁可以分为以下几大类:DML锁(data locks,数据锁),用于保护数据的完整性;DDL锁(dictionary locks,字典锁),用于保护数据库对象的结构,如表、索引等的结构定义;内部锁和闩(internal locks and latches),保护数据库的内部结构。

DML锁的目的在于保证并发情况下的数据完整性,。在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。

当Oracle 执行DML语句时,系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统再自动申请TX类型的锁,并将实际锁定的数据行的锁标志位进行置位。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可,大大提高了系统的效率。TM锁包括了SS、SX、S、X 等多种模式,在数据库中用0-6来表示。不同的SQL操作产生不同类型的TM锁。

在数据行上只有X锁(排他锁)。在 Oracle数据库中,当一个事务首次发起一个DML语句时就获得一个TX锁,该锁保持到事务被提交或回滚。当两个或多个会话在表的同一条记录上执行 DML语句时,第一个会话在该条记录上加锁,其他的会话处于等待状态。当第一个会话提交后,TX锁被释放,其他会话才可以加锁。

当Oracle数据库发生TX锁等待时,如果不及时处理常常会引起Oracle数据库挂起,或导致死锁的发生,产生ORA-60的错误。这些现象都会对实际应用产生极大的危害,如长时间未响应,大量事务失败等。

悲观封锁和乐观封锁

一、悲观封锁
锁在用户修改之前就发挥作用:
Select ..for update(nowait)
Select * from tab1 for update
用户发出这条命令之后,oracle将会对返回集中的数据建立行级封锁,以防止其他用户的修改。
如果此时其他用户对上面返回结果集的数据进行dml或ddl操作都会返回一个错误信息或发生阻塞。
1:对返回结果集进行update或delete操作会发生阻塞。
2:对该表进行ddl操作将会报:Ora-00054:resource busy and acquire with nowait specified.

原因分析
此时Oracle已经对返回的结果集上加了排它的行级锁,所有其他对这些数据进行的修改或删除操作都必须等待这个锁的释放,产生的外在现象就是其他的操作将发生阻塞,这个这个操作commit或rollback.
同样这个查询的事务将会对该表加表级锁,不允许对该表的任何ddl操作,否则将会报出ora-00054错误::resource busy and acquire with nowait specified.

二、乐观封锁
乐观的认为数据在select出来到update进取并提交的这段时间数据不会被更改。这里面有一种潜在的危险就是由于被选出的结果集并没有被锁定,是存在一种可能被其他用户更改的可能。因此Oracle仍然建议是用悲观封锁,因为这样会更安全。

阻塞

定义:
当一个会话保持另一个会话正在请求的资源上的锁定时,就会发生阻塞。被阻塞的会话将一直挂起,直到持有锁的会话放弃锁定的资源为止。4个常见的dml语句会产生阻塞
INSERT
UPDATE
DELETE
SELECT…FOR UPDATE


INSERT

Insert发生阻塞的唯一情况就是用户拥有一个建有主键约束的表。当2个的会话同时试图向表中插入相同的数据时,其中的一个会话将被阻塞,直到另外一个会话提交或会滚。一个会话提交时,另一个会话将收到主键重复的错误。回滚时,被阻塞的会话将继续执行。

UPDATE 和DELETE当执行Update和delete操作的数据行已经被另外的会话锁定时,将会发生阻塞,直到另一个会话提交或会滚。

Select …for update

当一个用户发出select..for update的错作准备对返回的结果集进行修改时,如果结果集已经被另一个会话锁定,就是发生阻塞。需要等另一个会话结束之后才可继续执行。可以通过发出 select… for update nowait的语句来避免发生阻塞,如果资源已经被另一个会话锁定,则会返回以下错误:Ora-00054:resource busy and acquire with nowait specified.


 

死锁-deadlock

定义:当两个用户希望持有对方的资源时就会发生死锁.
即两个用户互相等待对方释放资源时,oracle认定为产生了死锁,在这种情况下,将以牺牲一个用户作为代价,另一个用户继续执行,牺牲的用户的事务将回滚.
例子:
1:用户1对A表进行Update,没有提交。
2:用户2对B表进行Update,没有提交。
此时双反不存在资源共享的问题。
3:如果用户2此时对A表作update,则会发生阻塞,需要等到用户一的事物结束。
4:如果此时用户1又对B表作update,则产生死锁。此时Oracle会选择其中一个用户进行会滚,使另一个用户继续执行操作。
起因:
Oracle的死锁问题实际上很少见,如果发生,基本上都是不正确的程序设计造成的,经过调整后,基本上都会避免死锁的发生。

DML锁分类表


 

表1 Oracle的TM锁类型
锁模式 锁描述 解释 SQL操作
0 none    
1 NULL Select
2 SS(Row-S) 行级共享锁,其他对象只能查询这些数据行

Select for update、Lock for update、Lock row share

3 SX(Row-X) 行级排它锁,在提交前不允许做DML操作

Insert、Update、Delete、Lock row share

4 S(Share) 共享锁 Create index、Lock share
5 SSX(S/Row-X) 共享行级排它锁 Lock share row exclusive
6 X(Exclusive) 排它锁

Alter table、Drop able、Drop index、Truncate table 、Lock exclusive

 

 

1.关于V$lock表和相关视图的说明
 

 

 

Column
Datatype
Description
ADDR
RAW(4 | 8)
Address of lock state object
KADDR
RAW(4 | 8)
Address of lock
SID
NUMBER
Identifier for session holding or acquiring the lock
TYPE
VARCHAR2(2)
Type of user or system lock
The locks on the user types are obtained by user applications. Any process that is blocking others is likely to be holding one of these locks. The user type locks are:
TM - DML enqueue   
TX - Transaction enqueue
UL - User supplied
--我们主要关注TX和TM两种类型的锁
--UL锁用户自己定义的,一般很少会定义,基本不用关注
--其它均为系统锁,会很快自动释放,不用关注
ID1
NUMBER
Lock identifier #1 (depends on type)
ID2
NUMBER
Lock identifier #2 (depends on type)
---当lock type 为TM时,id1为DML-locked object的object_id
---当lock type 为TX时,id1为usn+slot,而id2为seq。
--当lock type为其它时,不用关注
LMODE
NUMBER
Lock mode in which the session holds the lock:
  • 0 - none
  • 1 - null (NULL)
  • 2 - row-S (SS)
  • 3 - row-X (SX)
  • 4 - share (S)
  • 5 - S/Row-X (SSX)
  • 6 - exclusive (X)
--大于0时表示当前会话以某种模式占有该锁,等于0时表示当前会话正在等待该锁资源,即表示该会话被阻塞。
--往往在发生TX锁时,伴随着TM锁,比如一个sid=9会话拥有一个TM锁,一般会拥有一个或几个TX锁,但他们的id1和id2是不同的,请注意
REQUEST
NUMBER
Lock mode in which the process requests the lock:
  • 0 - none
  • 1 - null (NULL)
  • 2 - row-S (SS)
  • 3 - row-X (SX)
  • 4 - share (S)
  • 5 - S/Row-X (SSX)
  • 6 - exclusive (X)
--大于0时,表示当前会话被阻塞,其它会话占有改锁的模式
CTIME
NUMBER
Time since current mode was granted
BLOCK
NUMBER
The lock is blocking another lock
0, 'Not Blocking', /* Not blocking any other processes */
1, 'Blocking', /* This lock blocks other processes */
2, 'Global', /* This lock is global, so we can't tell */

--该锁是否阻塞了另外一个锁
 

 

2.其它相关视图说明

 

 

视图名 描述 主要字段说明
v$session 查询会话的信息和锁的信息。
sid,serial#:表示会话信息。
program:表示会话的应用程序信息。
row_wait_obj#:表示等待的对象,和dba_objects中的object_id相对应。
lockwait :该会话等待的锁的地址,与v$lock的kaddr对应.
v$session_wait 查询等待的会话信息。
sid:表示持有锁的会话信息。
Seconds_in_wait:表示等待持续的时间信息
Event:表示会话等待的事件,锁等于enqueue
     
dba_locks 对v$lock的格式化视图。
Session_id:和v$lock中的Sid对应。
Lock_type:和v$lock中的type对应。
Lock_ID1: 和v$lock中的ID1对应。
Mode_held,mode_requested:和v$lock中
的lmode,request相对应。
v$locked_object 只包含DML的锁信息,包括回滚段和会话信息。
Xidusn,xidslot,xidsqn:表示回滚段信息。和
v$transaction相关联。
Object_id:表示被锁对象标识。
Session_id:表示持有锁的会话信息。
Locked_mode:表示会话等待的锁模式的信
息,和v$lock中的lmode一致。

 

 

1.查询数据库中的锁

select * from v$lock;
select * from v$lock where block=1;

2.查询被锁的对象

select * from v$locked_object;

3.查询阻塞

查被阻塞的会话
select * from v$lock where lmode=0 and  type in ('TM','TX');

查阻塞别的会话锁
select * from v$lock where lmode>0 and  type in ('TM','TX');

4.查询数据库正在等待锁的进程

select * from v$session where lockwait is not null;

5.查询会话之间锁等待的关系

 

select a.sid holdsid,b.sid waitsid,a.type,a.id1,a.id2,a.ctime from v$lock a,v$lock b
where a.id1=b.id1 and a.id2=b.id2 and a.block=
1 and b.block=0;

6.查询锁等待事件
select * from v$session_wait where event='enqueue';
 
解决方案:
    select session_id from v$locked_object;  --首先得到被锁对象的session_id
    SELECT sid, serial#, username, osuser FROM v$session where sid = session_id;   --通过上面得到的session_id去取得v$session的sid和serial#,然后对该进程进行终止。
   ALTER SYSTEM KILL SESSION 'sid,serial';
   example:
   ALTER SYSTEM KILL SESSION '13, 8';
分享到:
评论

相关推荐

    Oracle数据库发生ORA-04031错误原因浅析及处理.pdf

    Oracle数据库发生ORA-04031错误原因浅析及处理 Oracle数据库是甲骨文公司提供的一种分布式数据库管理系统,以分布式数据库为核心的软件产品。它具有完整的数据管理功能,作为一个关系数据库,它是一个非常实用的...

    Oracle_ORA-12518故障_处理

    在Oracle数据库管理过程中,遇到ORA-12518错误是较为常见的问题之一。此错误通常发生在客户端试图连接到数据库服务器的过程中,当监听器无法将客户端连接顺利地移交给服务器进程或调度进程时触发。本文旨在详细介绍...

    使用工具IMPDP导入数据时ORA-39002、ORA-39070错误排查

    在使用Oracle Data Pump工具IMPDP(Import Data Pump)进行数据导入的过程中,可能会遇到ORA-39002和ORA-39070等错误。本文将针对这些错误的排查方法进行详细介绍,帮助用户理解问题的原因及解决策略。 ### 错误...

    Oracle SQL Developer连接报错(ORA-12505)的解决方案(两种)

    用oracle数据库新建连接时遇到ora-12505,此问题解决后又出现ora-12519错误,郁闷的半天,经过一番折腾问题解决,下面小编把我的两种解决方案分享给大家,仅供参考。  解决方案一: 今天工作时在新建连接的时候遇到...

    连接Oracle数据库时报ORA-12541:TNS:无监听程序的图文解决教程

    主要介绍了连接Oracle数据库时报ORA-12541:TNS:无监听程序的图文解决教程,非常不错,具有参考借鉴价值,需要的朋友可以参考下

    ORACLE8I数据库应用EXP工具时ORA-06553报错的解决方法.pdf

    ORA-06553报错的解决方法是通过正确地配置EXP工具的参数、定义同义词和安装Oracle数据库的JAVA工具来解决。 知识点9:ORACLE 8I数据库的应用 ORACLE 8I数据库是关系型数据库管理系统,广泛应用于医疗信息系统、...

    oracle 12 c ORA-01017: 用户名/口令无效; 登录被拒绝

    - **格式要求**:在Java应用程序中使用JDBC连接Oracle数据库时,正确的URL格式对于避免ORA-01017等错误至关重要。 - 正确的URL格式: ```plaintext jdbc:oracle:thin:@localhost:1521/YXSYSPDB ``` - 注意事项...

    Oracle 授权 ORA-00990: 权限缺失或无效

    在Oracle数据库管理中,"ORA-00990: 权限缺失或无效"是一个常见的错误代码,它表示用户尝试执行的操作没有足够的权限。这个错误通常发生在试图访问、修改或者管理数据库对象(如表、视图、索引等)时。在本篇文章中...

    Oracle 报错ORA-00845 MEMORY_TARGET not supported on this system

    Oracle数据库在运行过程中,经常会遇到各种错误代码,错误代码ORA-00845是其中的一个,它是指“MEMORY_TARGET not supported on this system”。这个错误一般发生在尝试在不支持MEMORY_TARGET参数的系统上设置该参数...

    oracle错误ora-00257解决办法

    本文将详细讲解如何理解和解决“ORA-00257”错误,以及相关的Oracle数据库管理知识。 “ORA-00257”错误通常表示在尝试执行数据库的日志切换或归档操作时遇到了问题,这可能是由于以下原因导致的: 1. **归档日志...

    ora-00845 ora-00845

    ORA-00845 错误是指 Oracle 数据库中的一个错误代码,该错误通常表示“MEMORY_TARGET not supported on this system”,即系统不支持 MEMORY_TARGET 参数。这通常发生在尝试在不支持该特性的旧版本操作系统或某些...

    Oracle Database on Linux Fails to Start - ORA-27154 ORA-27300 OR

    在本文中,我们将深入探讨一个特定的Oracle数据库在Linux环境下启动失败的问题,涉及错误代码ORA-27154、ORA-27300、ORA-27301和ORA-27302,这些错误通常与系统信号量相关。此问题可能发生在尝试启动一个新的数据库...

    BLOG_【故障处理】Oracle_lhr_ORA-01565 告警日志报“ORA-01565 Unable To open Spfile”.pdf

    在Oracle数据库管理过程中,遇到ORA-01565错误提示是一个较为常见的问题,特别是对于采用RAC(Real Application Clusters)架构的数据库来说。该错误通常意味着系统无法打开指定的服务器参数文件(Server Parameter ...

    如何解决ORACLE系统Ora-00600错误故障.pdf

    标题和描述中提到的是关于如何解决Oracle数据库系统中出现的Ora-00600错误的故障处理方法。Ora-00600错误是Oracle数据库内部错误,通常表明系统遇到了无法处理的异常情况。这篇文档可能提供了解决这个问题的步骤和...

    Oracle错误码大全 oracle数据库

    "Oracle错误码大全"是一份非常实用的参考资料,它包含了Oracle数据库可能出现的所有错误码及其对应的解释,对于DBA(数据库管理员)和开发人员来说,是解决问题的重要工具。 Oracle错误码通常由三位数字组成,例如...

    ORA-12560解決方法

    ORA-12560 是一个常见的 Oracle 数据库错误代码,通常在尝试连接到 Oracle 实例时出现。该错误提示可能出现在使用 Oracle 的不同版本(如 Oracle Enterprise Edition 8.1.7)以及不同的操作系统环境(如 Windows ...

    Oracle RAC环境修改字符集遇到ORA-00205解决方法.rar

    然而,在修改Oracle RAC环境的字符集时,可能会遇到各种问题,其中最常见的错误之一是ORA-00205。这个错误通常表示启动参数文件(SPFILE)中的系统ID(SID)与实例ID不匹配,或者SPFILE本身存在问题。下面我们将详细...

    断电与ORA-600问题集

    由于ORA-600错误通常涉及Oracle数据库内部组件的问题,因此可以通过Oracle官方支持网站METELINK(现称为My Oracle Support)来查找相关文档和技术建议。如果遇到ORA-600错误,首先应当在METELINK上搜索该错误代码...

    Oracle错误码大全

    "Oracle错误码大全"是一份非常重要的参考资料,它包含了Oracle数据库系统中可能出现的所有错误码及其详细解释,对于DBA(数据库管理员)或开发人员来说,是解决问题的得力助手。 Oracle错误码通常由三部分组成:...

Global site tag (gtag.js) - Google Analytics