本文通过对Oracle数据库锁机制的研究,首先介绍了Oracle数据库锁的种类,并描述了实际应用中遇到的与锁相关的异常情况,特别对经常遇到的由于等待锁而使事务被挂起的问题进行了定位及解决,并对死锁这一比较严重的现象,提出了相应的解决方法和具体的分析过程。
数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。
加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。
在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。
在实际应用中经常会遇到的与锁相关的异常情况,如由于等待锁事务被挂起、死锁等现象,如果不能及时地解决,将严重影响应用的正常执行,而目前对于该类问题的解决缺乏系统化研究和指导,本文在总结实际经验的基础上,提出了相应的解决方法和具体的分析过程。
Oracle数据库的锁类型
根据保护的对象不同,Oracle数据库锁可以分为以下几大类:DML锁(data locks,数据锁),用于保护数据的完整性;DDL锁(dictionary locks,字典锁),用于保护数据库对象的结构,如表、索引等的结构定义;内部锁和闩(internal locks and latches),保护数据库的内部结构。
DML锁的目的在于保证并发情况下的数据完整性,本文主要讨论DML锁。在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。
当Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统再自动申请TX类型的锁,并将实际锁定的数据行的锁标志位进行置位。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可,大大提高了系统的效率。TM锁包括了SS、SX、S、X等多种模式,在数据库中用0-6来表示。不同的SQL操作产生不同类型的TM锁。如表1所示。
在数据行上只有X锁(排他锁)。在 Oracle数据库中,当一个事务首次发起一个DML语句时就获得一个TX锁,该锁保持到事务被提交或回滚。当两个或多个会话在表的同一条记录上执行DML语句时,第一个会话在该条记录上加锁,其他的会话处于等待状态。当第一个会话提交后,TX锁被释放,其他会话才可以加锁。
当Oracle数据库发生TX锁等待时,如果不及时处理常常会引起Oracle数据库挂起,或导致死锁的发生,产生ORA-60的错误。这些现象都会对实际应用产生极大的危害,如长时间未响应,大量事务失败等。
现在概括总结一下:
Oracle通过具有意向锁的多粒度封锁机制进行并发控制,保证数据的一致性。其DML锁(数据锁)分为两个层次(粒度):即表级和行级。通常的DML操作在表级获得的只是意向锁(RS或RX),其真正的封锁粒度还是在行级;另外,在Oracle数据库中,单纯地读数据(SELECT)并不加锁,这些都极大地提高了系统的并发程度。
在支持高并发度的同时,Oracle利用意向锁及数据行上加锁标志位等设计技巧,减小了Oracle维护行级锁的开销,使其在数据库并发控制方面有着明显的优势。
在Oracle数据库并发环境下,对于表,既要保护其数据,又要保护其结构(结构信息存储在数据字典中),很自然,针对这两种保护要求,就有了两种类型(Type)的锁:保护数据的锁我们叫数据锁(DML locks或data locks),保护结构的我们叫字典锁(DDL locks或dictionary locks)。
对于数据锁,为了适应不同事务的不同要求,提供两个层次(粒度)的锁,即表级锁(Table Locks ,TM)与行级锁(Row Locks ,TX)。
在这两个层次上,经典的上锁的方式(Mode)有两种,即共享锁(S锁)与排它锁(X锁)。
为了方便地进行锁冲突的检测,希望在表(上)级能够标识行(下)级加锁的情况,这就引入了“意向锁”(intention lock mode)的概念。根据在行级要加S锁或X锁的不同,在表级相应的就有两种意向锁,即:如果事务要在行级获得S锁,它需要首先在表级获得意向共享锁(Intent Share Lock,IS锁);如果事务要在行级获得X锁,它需要首先在表级获得意向排它锁(Intent Exclusive Lock,IX锁)。这两种意向锁与经典的S锁、X锁组合,还会产生一种新的锁:共享意向排它锁(Share Intent Exclusive Lock,SIX锁),它表示持有该锁的事务在表级加了传统的共享锁(S锁),同时该事务还将对表中的某些行加排它锁(X锁)。
这样,在表级数据锁的加锁方式就有了5种:即S、X、IS、IX、SIX。
在Oracle中,与IS对应的锁叫做Row Share Table Locks (RS)或subshare table lock, SS,它可以通过SELECT ... FOR UPDATE语句获得,但需要注意的是,这个语句在行级获得的也是排它锁,即如果两个SELECT ... FOR UPDATE语句要选定同一行,则后面的事务将被阻塞,这是与上面一般意义的定义有所不同,这时RS锁可以理解为持有该锁的事务将要修改选定的某些行。
在Oracle中,与IX对应的锁叫做Row Exclusive Table Locks (RX)或subexclusive table lock, SX,它可以通过INSERT/UPDATE/DELETE语句获得,它表征持有该锁的事务已经修改了表中的某些行。
在Oracle中,与SIX对应的锁叫做Share Row Exclusive Table Locks (SRX)或sshare-subexclusive table lock, SSX。
这样,Oracle对表级数据锁的加锁方式就有:即S、X、RS、RX、SRX等5种;而在行级只有X锁。
在Oracle中,对于字典锁,也有共享与排它之分:Share DDL Locks与Exclusive DDL Locks。对于要获得Exclusive DDL Locks的DDL操作(如ALTER、DROP等),它还必须要获得该表排它的数据锁,这样如果在某个表上有未提交的事务(即该表有某种类型的表级锁),其它SESSION提出的DROP表的操作就不会成功,因为它要向表施加X锁,与表上已有的锁不相容。
所以说,表级的数据锁既能防止与之冲突的DML操作,也能防止与之冲突的DDL操作,但不能因此就把表级的数据锁与字典锁混为一谈。
表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
|
表2 数据字典视图说明 |
视图名 |
描述 |
主要字段说明 |
v$session |
查询会话的信息和锁的信息。 |
sid,serial#:表示会话信息。
program:表示会话的应用程序信息。
row_wait_obj#:表示等待的对象。
和dba_objects中的object_id相对应。
|
v$session_wait |
查询等待的会话信息。 |
sid:表示持有锁的会话信息。
Seconds_in_wait:表示等待持续的时间信息
Event:表示会话等待的事件。
|
v$lock |
列出系统中的所有的锁。 |
Sid:表示持有锁的会话信息。
Type:表示锁的类型。值包括TM和TX等。
ID1:表示锁的对象标识。
lmode,request:表示会话等待的锁模式的信
息。用数字0-6表示,和表1相对应。
|
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一致。
|
posted on 2009-09-24 16:33
月光记忆 阅读(453)
评论(0) 编辑 收藏 所属分类:
ORCLE