楼主: ZALBB

[精华] 我对ORACLE数据锁的一点体会

[复制链接]
论坛徽章:
314
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
11#
 楼主| 发表于 2004-9-28 11:09 | 只看该作者
对你这句话:以后不管是其它DML操作或是DDL操作,在检查是否有锁冲突时,
就不需要逐行检查各记录的加锁情况了,而只需要检查表一级的加锁情况。

我看不明白:

1、你这段话中的:是否有锁冲突,是指行级锁,还是表级锁?
2、SESSION1对表A执行DML操作后,SESSION2也对A执行DML操作,
   那ORACLE要不要检查行的加锁情况?若要,是不是只检查到表一级的加锁
   情况?若是,那它如何得知那些记录被加X锁的情况?哪些记录可操作,
   哪些不可?

我是这样理解的,解决记录(数据冲突)的,是靠TX锁上记录的事务信息,
而非意向锁。

你可以测试:当你对记录做了UPDATE操作后,通过DUMP保存此记录的BLOCK块,
可立即看到该块已经记录了被修改记录的事务信息-ITL(这里不考虑日志延时),
此信息指明了事务及回滚段的信息,与TX锁上的ID1,ID2表示的信息是一致的。
这样,当再有第二个事务来修此记录时,可能就在此被卡住了。

事实上,单纯地使用此语句LOCK TABLE table_name IN ROW EXCLUSIVE MODE,
并不体现对哪些数据加了X锁。

因此,我理解这个时候对表加的意向锁为S锁,是为了避免ALTER ,DROP TABLE在
其上面的操作。

请继续指教。

使用道具 举报

回复
论坛徽章:
314
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
12#
 楼主| 发表于 2004-9-28 11:23 | 只看该作者

我的体会,请拍砖

ORACLE 锁级别的理解

   为了确保并发用户在存取同一数据库对象时的正确性(即无丢失修改、可重复读、不读"脏"数据),
数据库中引入了锁机制。基本的锁类型有两种:排它锁(Exclusive locks记为X锁)和 共享锁
(Share locks记为S锁)。(表注1)

   共享锁:若事务T对数据D加S锁,则其它事务只能对D加S锁,而不能加X锁,直至T释放D上的S锁;
一般要求在读取数据前要向该数据加共享锁,所以共享锁又称为读锁。(表注1)


   排它锁:若事务T对数据D加X锁,则其它任何事务都不能再对D加任何类型的锁,直至T释放D上的X锁;
一般要求在修改数据前要向该数据加排它锁,所以排它锁又称为写锁。(表注1)

   
   由于数据是存储在表里,所以,在对数据进行DML操作时,除了对被操作的数据加X锁外,对表结构
也需要加S锁,以防止别的SESSION对此表结构的更改或删除。ORACLE的原文是这样解释的:

   If a transaction obtains a row lock for a row, the transaction also acquires a table lock
for the corresponding table. The table lock prevents conflicting DDL operations that would
override data changes in a current transaction.

   又如,其对Table Locks -- (TM) 的解释:
      
   A transaction acquires a table lock when a table is modified in the following DML
statements: INSERT, UPDATE, DELETE, SELECT with the FOR UPDATE clause, and LOCK TABLE. These
DML operations require table locks for two purposes: to reserve DML access to the table on
behalf of a transaction and to prevent DDL operations that would conflict with the
transaction. Any table lock prevents the acquisition of an exclusive DDL lock on the same
table and thereby prevents DDL operations that require such locks. For example, a table
cannot be altered or dropped if an uncommitted transaction holds a table lock for it.

对ORACLE定义的这7个级别的锁,我是这样理解的

LMODE -- Lock mode in which the session holds the lock:

0 - none                ---- 无
1 - null (NULL)         ---- 可能某些情况下,如分布式数据库的查询会产生此锁。
2 - row-S (SS)          ---- 表结构共享锁
3 - row-X (SX)          ---- 表结构共享锁+被操作的记录的排它锁(若有DML操作)
4 - share (S)           ---- 表结构共享锁+所有记录共享锁(隐含)
5 - S/Row-X (SSX)       ---- 表结构共享锁+所有记录排它锁(隐含)
6 - exclusive (X)       ---- 表结构排它锁
   
ORACLE的文档中,对SS锁是这样解释的:

Row Share Table Locks (RS)
A row share table lock (also sometimes called a subshare table lock, SS) indicates that the
transaction holding the lock on the table has locked rows in the table and intends to update
them. A row share table lock is automatically acquired for a table when one of the following
SQL statements is executed:

SELECT ... FROM table ... FOR UPDATE OF ... ;  

LOCK TABLE table IN ROW SHARE MODE;

按照上面的解释:是ORACLE锁住某表及该表的某些记录,准备(倾向)修改这些记录。


但尝试以 LOCK TABLE table IN ROW SHARE MODE 来锁住某表后,查看V$LOCK视图,发现只有TM=2的锁,
而并未对哪些记录加了S锁;比较SELECT FOR UPDATE,发现除了TM=2的锁外,还存在TX=6的锁,
并且通过TX=6中的ID1,ID2,可在回滚段中查看到被加了X锁的记录。此外,ORACLE文档中也
说明,被SS的表(TM=2的锁),其中的记录可以被DML,但不允许对该表加X锁;这说明,该表的
记录并未被加S锁(因为可以修改记录),而只是表结构加了S锁(因为不可以对表加X锁),故此,认定,
SS锁实际就是对表加S锁。


对于RX锁,通过DML操作后得知:DML操作会产生TX=6 和 TM=3的锁,从TX=6中的ID1,ID2,可在回滚段中
查看到被加了X锁的记录,而这些记录在未提交/回滚之前,是不可以再被修改的。通过对该表,
除了这些记录被加X锁外,别的记录仍可以被DML,这说明,表被加了S锁,被操作的记录被加了X锁。
因此认定,RS实际就是:表结构共享锁+被操作的记录的排它锁。当只是对表加RX锁时候。

S锁:由于加了S锁的表,无法对其数据进行DML操作,故猜测,S锁实际是对表结构和表记录加了
共享锁。对于加了S锁后,仍可以对表执行SELECT FOR UPDATE,我是这样理解的:SELECT FOR UPDATE
是比较特殊的一种情况:由于其不修改记录,所以对这些记录而言,并未产生真正的排它锁,这与DML操作
产生的排它锁相比,是有差别的;但由于不允许在这些记录“再”加SELECT FOR UPDATE,所以,也不是纯粹
的共享锁,我认为其是介于共享锁和排它锁之间的一种特殊的情况,因此,ORACLE在对表加了S锁后,还
允许对该表执行SELCT FOR UPDATE,但实际上,此时此语句已经无意义了,因为加了S锁的表不允许DML
操作,故,此语句于普通的SELECT 语句无差别。

SRX锁,第4级别是S锁(表结构共享锁+所有记录共享锁),第6级别是X锁(表结构排它锁+所有记录排它锁),
而根据锁级别不断升高,锁的限制不断加强的规律判断,SRX--第5层锁,只能是:表结构共享锁+所有记录
排它锁 这种情况。但目前,还想不出在什么情况下会使用这样的锁?

X锁:表结构排它锁。其实,表结构加排它锁后,表记录自然也算是加了排它锁,因为此时,表记录无法加
共享锁,只能只读。故,此锁级别最高,通常使用在修改表结构或删除表时使用。

(表注1)
:引用 itpub.net 上的 jeffli73 写的:oracle多粒度封锁机制研究(论坛).doc

使用道具 举报

回复
论坛徽章:
3
授权会员
日期:2005-10-30 17:05:33ITPUB技术丛书作者
日期:2010-09-26 15:24:56优秀写手
日期:2014-02-13 06:00:15
13#
发表于 2004-9-29 00:08 | 只看该作者

需要澄清两个概念

表级锁(TABLE LOCK)与数据字典锁(data dictionary lock,DDL)在ORACLE中是两个不同的概念,ZALBB朋友谈到的所谓“表结构共享锁”、“表结构排它锁”,从汉语字面理解应该属于数据字典锁(data dictionary lock,DDL),但ZALBB朋友又将其与表级锁混在一起谈,我想是不妥的。

ORACLE在引入意向锁后,其表级锁主要有5种,任何一个DML操作,总是先获得某种类型的表级锁,才可能去获得行级锁。
如:
SESSION1 发出SELECT * FROM DEPT WHERE DEPTNO=10 FOR UPDATE;
首先在表级获得RX锁,表示该事务要以SELECT FOR UPDATE 方式访问该表的某些记录,获得该锁后,将DEPTNO=10 的记录上的锁标志置位,可以理解为在行上加X锁;
之后,SESSION2发出UPDATE DEPT SET LOC=LOC WHERE DEPTNO=10,它首先要求在表级获得RX锁(该锁表示事务要修改某些行),与SESSION1获得的RS锁可以相容,故该表级锁可以获得,之后SESSION2试图获得DEPTNO=10的行级锁,但被SESSION1已获得的锁阻塞;

如果SESSION2发出的不是UPDATE,而是DROP TABLE DEPT,则事务既要获得排它的DDL锁(注意,不是表级锁,是数据字典锁),还要获得DEPT表级的X锁(DDL operations also acquire DML locks (data locks) on the schema object to be
modified.同样出自ORACLE CONCEPTS,另外实验也可以证明),而X锁与SESSION1获得的RS锁不相容,故DROP不成功。
而如果SESSION2发出的是lock table dept in  EXCLUSIVE MODE,也会因与RS锁不相容,被阻塞。

所以说,DML锁两个主要作用:保护数据、防止DDL操作。
应该指出的是,ORACLE多数的DML操作,其实际的封锁粒度在行级,表级只是加了起到表示下级封锁情况的意向锁(RS或RX),但因此就说表级锁就是表结构锁,我想肯定是不合适的。

关于“意向锁”,我一直在说其本质意义在于效率,是因为:
如果没有RS或RX锁,我们UPDATE一行数据只在行上加X锁,那么如果其它的DML或DDL要在表级加X锁,那么它就不仅要查看表级加锁的情况,还要查看各记录的加锁情况,对于拥有很多记录的表,其消耗恐怕是无法容忍的。所以,要引入“意向锁”来表示下面行的加锁情况。


另外,将我写的《oracle多粒度封锁机制研究》的第二个版本发给你,我想你会看到关于锁的更多的情况。

使用道具 举报

回复
论坛徽章:
3
授权会员
日期:2005-10-30 17:05:33ITPUB技术丛书作者
日期:2010-09-26 15:24:56优秀写手
日期:2014-02-13 06:00:15
14#
发表于 2004-9-29 00:20 | 只看该作者

该附件我可能在1-2天内删除

该附件我可能在1-2天内删除

使用道具 举报

回复
论坛徽章:
31
管理团队2006纪念徽章
日期:2006-04-16 22:44:452012新春纪念徽章
日期:2012-02-13 15:11:522012新春纪念徽章
日期:2012-02-13 15:11:522012新春纪念徽章
日期:2012-02-13 15:11:522012新春纪念徽章
日期:2012-02-13 15:11:52铁扇公主
日期:2012-02-21 15:02:402013年新春福章
日期:2013-02-25 14:51:242014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11马上有车
日期:2014-02-19 11:55:14
15#
发表于 2004-9-30 13:19 | 只看该作者
Very good note.

Just put in my some understanding .

the lock mode itself  has not  meaning at all,  the meaning must depend on context.  

DML row lock is implemented by row level lock and transaction lock. so in this case ,  jeffli73 said there is no share lock for  row lock , this looks good  to me. Because indeed Oracle doesn't put any  mechenism there to implement row share lock, it is either in use or not. I think this is also due to Oracle 's consistent read feature.

And I thought Steve Adams said very well in his book, lock applied to compound and simple object.
row  is a simple object, table is a compound object .

Only for  compound object , there is a need for SS, SX and SIX lock .

使用道具 举报

回复
论坛徽章:
31
管理团队2006纪念徽章
日期:2006-04-16 22:44:452012新春纪念徽章
日期:2012-02-13 15:11:522012新春纪念徽章
日期:2012-02-13 15:11:522012新春纪念徽章
日期:2012-02-13 15:11:522012新春纪念徽章
日期:2012-02-13 15:11:52铁扇公主
日期:2012-02-21 15:02:402013年新春福章
日期:2013-02-25 14:51:242014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11马上有车
日期:2014-02-19 11:55:14
16#
发表于 2004-10-1 11:40 | 只看该作者
>row is a simple object, table is a compound object .

It should read :

A cache buffer is a simple object, a table is a compound object , a row is a component part of a table.

使用道具 举报

回复
论坛徽章:
31
管理团队2006纪念徽章
日期:2006-04-16 22:44:452012新春纪念徽章
日期:2012-02-13 15:11:522012新春纪念徽章
日期:2012-02-13 15:11:522012新春纪念徽章
日期:2012-02-13 15:11:522012新春纪念徽章
日期:2012-02-13 15:11:52铁扇公主
日期:2012-02-21 15:02:402013年新春福章
日期:2013-02-25 14:51:242014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11马上有车
日期:2014-02-19 11:55:14
17#
发表于 2004-10-1 19:56 | 只看该作者
Further to this topic,

There is a text book called "Database System Implementation" , which is written by some Stanford profressors. In that book, the author describe to manage locks on a hierarchy of database elements, a "warning protocol" is needed . That is , in addition to the "ordinary" lock ( S or X) , we also need "warning" lock ( IS or IX) .

( below is in page 509 )
<quote>
The rules of warning protocol are:
1. To place an ordinary S or X lock on any element, we must begin at the root of hierarchy.
2. If we are at the element that we want to lock, we need look no further. We request an S or X lock on that element.
3. If the element we wish to lock is further down the hierarchy , then we place a warning at this node; that is, if we want to get a shared lock on a subelement we request an IS lock at this node, and if we want an exclusive lock on a subelement, we request an IX lock on this node. When the lock on the current node is granted, we proceed to the appriopriate child ( the one whose subtree contains the node we wish to lock). we then repeat step (2) or step (3) , as appropriate , until we reach the desired node.

<endquote>

Basically this looks to me also what Oracle do with the TM lock (RS and RX)  to handle the table and row hierarchy locking.

And to design the lock in such a way is basically to ensure that we have the maximum concurrency possible.

And to provide concurrency is the lock's job.

使用道具 举报

回复
论坛徽章:
3
授权会员
日期:2005-10-30 17:05:33ITPUB技术丛书作者
日期:2010-09-26 15:24:56优秀写手
日期:2014-02-13 06:00:15
18#
发表于 2004-10-2 00:58 | 只看该作者

对前面的讨论做一个小结

使用道具 举报

回复
论坛徽章:
2
参与2007年甲骨文全球大会(中国上海)纪念
日期:2007-08-06 15:19:01参与2007年甲骨文全球大会(中国上海)纪念
日期:2007-08-06 15:19:01
19#
发表于 2004-10-3 13:00 | 只看该作者
看了jeffli73和ZALBB的讨论,受益非浅。谈一下我的理解,请指正。
oracle或者说数据库管理系统采用多粒度封锁机制,是为了提高数据库系统的并发执行效率。封锁对象可以为数据库,表,记录。多粒度封锁允许各类对象独立地加锁-因此提高了事务的并发执行,不会发生象jeffli73所举的tom的例子。
但多粒度封锁也带来了加锁的复杂性-eg我对表table1加锁,不仅要检查它上一级对象的加锁情况,还要检查其下一级对象的加锁情况,看是否有冲突。因此引入了意向锁的概念。
------------
ZALLBB:但我目前所理解的SRX,就是:SRX--表结构共享锁+所有记录排它锁
还不知道是不是对的?

SRX应该是S+RX,表示事务要读整个表(s),同时对更新个别记录(rx)。而不是所以记录排他锁。
--------------
ZALBB:...所以,在对数据进行DML操作时,除了对被操作的数据加X锁外,对表结构
也需要加S锁,以防止别的SESSION对此表结构的更改或删除。

我想应该是RX或RS锁,和ddl 锁而不是S锁。在jeffli73文章中主要讨论dml锁。
对表加RS,RX锁和S锁是不同的。他们的封锁强度不同。

------
oracle对行级只有加X锁,是因为采用了rollback segment机制,允许一个事务在更新个数据项时,其它事务可以同时读这个数据项。

使用道具 举报

回复
论坛徽章:
16
咸鸭蛋
日期:2011-09-06 18:06:46三菱
日期:2013-08-19 19:29:14
20#
发表于 2004-10-3 23:34 | 只看该作者
很不错,意向锁这个概念很好

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表