锁--DDL锁和闩

DDL

1> 作用:在DDL操作中会自动为对象加DDL锁,从而保护这些对象不会被其他会话所修改。

2> DDL语句执行期间会一直持有DDL锁,一旦操作执行就立即释放DDL锁。实际上,通常会把DDL语句包装在隐式提交(或提交/回滚对)中来执行这些工作。在Oracle中,DDL一定会提交,每条CREATE ALTER等语句实际上都如下执行(伪代码):

Begin

Commit;

DDL-STATEMENT

Commit;

       Exception

               When others then roolback;

End;

3> 三种DDL

1)排他DDL锁(Exclusive DDL lock):防止其他会话得到它们自己的DDL锁或TMDML)锁。这说明,在DDL操作期间,你可以查询一个表,但是无法以任何方式修改这个表。

2)共享DDL锁(Shared DDL lock):这些锁会保护所引用对象的结构,使之不会被其他会话修改,但是允许修改数据。

3)可中断解析锁(Breakable parse locks):这些锁允许一个对象(如共享池中缓存的一个查询计划)向另外某个对象注册其依赖性。如果在被依赖的对象上执行DDLOracle会查看已经对该对象注册了依赖性的对象列表,并使这些对象无效。因此,这些锁是“可中断的”,它们不能防止DDL出现。

4> 例:

1)大多数DDL都带有一个排他DDL锁,如:

alter table t add new_colunm date;

2)有些DDL操作没有DDL锁也可以发生,如:

create index t_idx on t(x) ONLINE;

说明:Oracle并不是加一个排他DDL锁来防止数据修改,而只会试图得到表上的一个低级(mode 2TM锁。这会有效防止其他DDL发生,同时还允许DML正常进行。

3)在创建存储的编译对象(如过程和视图)时,会对依赖的对象加这种共享DDL锁。如:

create view MyView

as

select *

from emp,dept

where emp.deptno = dept.deptno;

说明:表EMPDEPT都会加共享DDL锁,而CREATE VIEW命令仍在处理。可以修改这些表的内容,但是不能修改它们的结构。

4)会话解析一条语句时,对于该语句引用的每一个对象都会加一个解析锁。目的是:如果以某种方式删除或修改了一个被引用的对象,可以将共享池中已解析的缓存语句置为无效(刷新输出)。可通过DBA_DDL_ LOCKS查看共享池中锁定的对象。如:

create or replace procedure p as begin null; end;
Procedure created.

exec p;
PL/SQL procedure successfully completed.

select session_id sid,owner,name,type,mode_held held,mode_requested request from dba_ddl_locks;

此时过程P在过程中出现。

alter procedure p compile;
Procedure altered.

select session_id sid,owner,name,type,mode_held held,mode_requested request from dba_ddl_locks;

重新编译过程P后,它从DBA_DDL_LOCKS视图中消失,说明解析锁被中断了。

闩(latch

1> 闩是轻量级的串行化设备,用于协调对共享数据结构、对象和文件的多用户访问。闩是一种锁,设计为只保持极短的一段时间(例如,修改一个内存中数据结构所需的时间)。闩用于保护某些内存结构,如数据库块缓冲区或共享池中的库缓存。

2> 一般会在内部以一种“愿意等待”模式请求闩。这说明,如果闩不可用,请求会话会睡眠很短的一段时间,并在以后再次尝试这个操作。还可以采用一种“立即”模式请求其他闩。闩释放后,紧接着不论哪个会话请求闩都会得到它。等待闩的会话不会排队,只是一大堆会话在不断的重试。

3> 由于设置和释放闩的指令是原子性的,尽管可能有多个进程在同时请求它,但操作系统本身可以保证只有一个进程能测试和设置闩。闩只保持很短的时间,而且提供了一种清理机制,万一某个闩持有者在持有闩时异常地“死掉了”,就由PMON执行清理。

4> 与队列锁的区别:队列锁是一种更复杂的串行化设备,它允许请求者“排队”等待资源。对于闩请求,请求者会话会立即得到通知是否得到了闩。而对于队列锁,请求者会话会阻塞,直至真正得到锁。队列锁没有闩快,但能提供闩所没有的一些功能(如共享锁)。

5> 闩“自旋”(spin

1)如果闩不是立即可用的,我们就得等待,在一台多CPU机器上,我们的会话就会自旋,即:在循环中反复尝试来得到闩。出现自旋的原因是:上下文切换(即进程被“踢出”CPU,然后又必须调度回CPU)的开销很大,所以如果进程不能立即得到闩,我们就会一直呆在CPU上,并立即再次尝试,而不是先睡眠,放弃CPU,等到必须调度回CPU时才再次尝试。之所以呆在CPU上,是因为我们指望闩的持有值正在另一个CPU上忙于处理(由于闩设计为只保持很短的时间),而且会很快放弃闩。如果出现自旋并不断地尝试想得到闩,但是之后还是得不到闩,此时我们的进程才会睡眠,或者让开CPU,而让其他工作进行。

2> 得到一个闩的开销不只是“测试和设置”操作这么简单,我们尝试得到闩时,可能会耗费大量的CPU时间。系统看上去很忙(因为消耗了很多CPU时间),但是并没有作多少实际的工作。例如我们通过比较两个程序来研究闩定共享池的开销,其中好的程序使用了绑定变量,而不好的程序中每条语句使用了SQL直接量或各不相同的SQL。对于未使用绑定变量的程序:同时运行这样的两个程序耗费的CPU时间是只运行一个这样的程序耗费的CPU时间的3倍而不是2倍;对于使用绑定变量的程序:同时运行这样的两个程序耗费的CPU时间是只运行一个这样的程序耗费的CPU时间的22.5倍。这是因为不使用绑定变量则增加了硬解析SQL的次数,而我们需要闩定共享池来解析SQL语句,所以就增加了等待闩的时间,把一部分CPU时间浪费在闩的自旋上。

手动锁定和用户定义锁

1> 更新一个表时,Oracle 会为它加一个 TM ,以防止其他会话删除这个表(实际上,也会防止其他会话对这个表执行大多数 DDL) 。在我们修改的各个块上会加上 TX ,这样就能告诉别人哪些数据是“我们的”。数据库采用 DDL 锁来保护对象,这样当我们正在修改这些对象时,别人不会同时对它们进行修改。数据库在内部使用了闩和锁(lock)来保护自己的结构。

2> 通过一条SQL语句手动地锁定数据:如select for update或使用LOCK TABLE语句。

3> 通过DBMS_LOCK包创建我们自己的锁。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17014649/viewspace-609871/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/17014649/viewspace-609871/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值