oracle的DDL锁定简介

当我们发出DDL命令时,会自动在被处理的对象上添加DDL锁定,从而防止对象被其他用户所修改。当DDL命令结束以后,则释放DDL锁定。我们不能显式地请 求一个DDL锁定,只有当对象结构被修改或者被引用时,才会在对象上添加DDL锁定。比如创建或者编译存储过程时会对引用的对象添加DDL锁定。在创建视图 时,也会对引用的表添加DDL锁定等。

在执行DDL命令之前,Oracle会自动添加一个隐式提交命令,然后执行具体的DDL命令,在DDL命令执行结束之后,还会自动添加一个隐式提交命令。实际上, Oracle在执行DDL命令时,都会将其转换为对数据字典表的DML操作。比如我们发出创建表的DDL命令时,Oracle会将表的名称插入数据字典表tab$里,同时将 表里的列名以及列的类型插入col$表里等。因此,在DDL命令中需要添加隐式的提交命令,从而提交那些对数据字典表的DML操作。即使DDL命令失败,它也会 发出提交命令。

我们来看下面的例子,启动两个session,其中一个叫做sess #1,另一个叫做sess #2。在sess #1里发出如下的SQL语句:

SQL> insert into t values(1);

1 row created.

然后在sess #2里查询表T里的数据:

SQL> select * from t;

no rows selected

显然,由于sess #1还没有提交,因此sess #2里不能检索出sess #1所插入的记录。接下来,我们在sess #1里执行下面的语句:

SQL> create table t(c1 number);

create table t(c1 number)

*

ERROR at line 1:

ORA-00955: name is already used by an existing object

由于表T已经存在,因此创建表T的命令失败。这时我们再回到sess #2里查询表T:

SQL> select * from t;

ID

----------

1

很明显,我们并没有在sess #1里发出commit命令,但这时sess #1里所作的插入操作已经被提交了。这个commit就是通过create table这个DDL命令隐式发出 的,尽管create table命令已经失败了。

DDL锁定具有以下三种类型。

(1)排他的DDL锁定(Exclusive DDL Lock)

大部分的DDL操作都会在被操作的对象上添加排他的DDL锁定,从而防止在DDL命令执行期间,对象被其他用户所修改。当对象上添加了排他的DDL锁定以后, 该对象上不能再添加任何其他的DDL锁定。如果是对表进行DDL命令,则其他进程也不能修改表里的数据。

(2)共享的DDL锁定(Shared DDL Lock)

用来保护被DDL的对象不被其他用户进程所更新,但是允许其他进程在对象上添加共享的DDL锁定。如果是对表进行DDL命令,则其他进程可以同时修改表里的 数据。比如我们发出create view命令创建视图时,在视图的所引用的表(这种表也叫基表)上添加的就是共享的DDL命令。也就是说,在创建视图时,其他 用户不能修改基表的结构,但是可以更新基表里的数据。

(3)可打破的解析锁定(Breakable Parsed Lock)

在shared pool里缓存的SQL游标或者PL/SQL程序代码都会获得引用对象上的解析锁定。如果我们发出DDL命令修改了某个对象的结构时,该对象相关的、位于 shared pool里的解析锁定就被打破,从而导致引用了该对象的SQL游标或者PL/SQL程序代码全都失效。下次再次执行相同的SQL语句时,需要重新解析,这也 就是所谓的SQL语句的reload了。可打破的解析锁定不会阻止其他的DDL锁定,如果发生与解析锁定相冲突的DDL锁定,则解析锁定也会被打破。

我们主要通过dba_ddl_locks视图来监控DDL锁定,没有与DDL锁定相关的V$视图。如果没有发现dba_ddl_locks视图,则执行脚本 $ORACLE_HOME/rdbms/admin/catblock.sql来创建该视图,执行脚本时应该以用户sys的身份登录数据库。

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/database/Oracle/

我们来做个试验,并从dba_ddl_locks视图里查看有关DDL锁定的情况。在该试验中,我们创建一个存储过程,如下所示:

SQL> create or replace procedure p_test is

2  ln_id number;

3  begin

4     dbms_lock.sleep(600);

5  end;

6  /

在该存储过程中,我们调用dbms_lock.sleep,dbms_lock.sleep能够让系统挂起,挂起的时间长度由传入参数决定,传入参数的单位是秒。在本例中,也就 是让系统挂起600秒。

然后,我们启动三个session,并检索每个session的SID号,如下所示:

SQL> select sid from v$mystat where rownum=1;

SID

----------

149

SQL> select sid from v$mystat where rownum=1;

SID

----------

151

SQL> select sid from v$mystat where rownum=1;

SID

----------

159

在149号session里我们执行存储过程p_test:

SQL> exec p_test;

这时149号session被挂起,挂起持续的时间为600秒。然后我们到151号session里执行下面的SQL语句,对p_test进行编译:

SQL> alter procedure p_test compile;

我们会发现151号session也被挂起了,因为这时149号session正在执行p_test,因此151号的编译p_test命令必须等待。

接下来,我们到159号session里执行下面的语句,删除p_test:

SQL> drop procedure p_test;

显然,由于151号session正在编译p_test,我们也无法删除p_test,因此159号session也被挂起了。

我们查询dba_ddl_locks视图,来了解这时DDL锁定的情况:

SQL> select session_id,type,mode_held,mode_requested from dba_ddl_locks

2  where session_id in(149,151,159) and owner='HR' and name='P_TEST';

SESSION_ID TYPE                       MODE_HELD     MODE_REQUESTED

---------- ---------------------  ---------      --------------

159  Table/Procedure/Type     Null            None

159  Table/Procedure/Type     None            Exclusive

151  Table/Procedure/Type     Exclusive      None

149  Table/Procedure/Type     Null            None

从MODE_HELD列上可以看到,151号session尝试编译p_test,因此它获得了p_test上的排他的DDL锁定。而从MODE_REQUESTED列上可以看到,159号session尝 试删除p_test,因此也需要在p_test上添加排他的DDL锁定。但是这时p_test上已经存在DDL锁定了,于是159号session只好等待。

时间: 2025-01-19 14:24:24

oracle的DDL锁定简介的相关文章

oracle的DDL语句为什么不能回滚

在ITPUB上看到有人提出了这个问题.在Sqlserver或一些其他的数据库中,DDL语句也是可以回滚的,那么Oracle为什么不能回滚DDL语句呢. 要说明这个问题,首先需要说明什么是DDL语句.DDL语句是数据定义语句,包括各种数据对象的创建.修改和删除,以及授权等操作. 在Oracle中DDL语句将转化为修改数据字典表的DML语句.一个简单的修改表的DDL语句,会导致Oracle在后台通过递归SQL语句进行大量的查询和修改的操作. 如果有兴趣,可以通过SQL_TRACE根据一下DDL语句,

Oracle诊断工具SQLT简介 (文档 ID 1677588.1、1526574.1)

Oracle诊断工具SQLT简介 (文档 ID 1677588.1.1526574.1) SQLT 使用指南 (文档 ID 1677588.1)   文档详细信息   类型: 状态: 上次主更新: 上次更新: 语言: REFERENCE PUBLISHED 2016-6-16 2016-6-16 English简体中文??? 215187.1SQLTXPLAIN (SQLT) 12.1.06 2014年1月30日 帮助诊断性能较差的 SQL 语句的工具 SQLT 概览 安全模式 安装 SQLT

Oracle后台进程及其作用简介

Oracle后台进程及其作用简介 This background process is available starting with Oracle Database 11g Release 2 (11.2.0.2). describes Oracle Database background processes. In this context, a background process is defined as any process that is listed in V$PROCESS 

ORACLE获取DDL的几种常用的方法

oracle ORACLE获取DDL的几种常用的方法   作者:刘颖博 时间:2004-2-26 mail:liuyingbo@126.com,请指正   转载请注明出处及作者   大体的分为三种方法: 一:可以通过toad.plsql develop等第三方工具进行导出DLL操作,用这种办法的好处在于操作简单方便,但需要安装,下面简单介绍一下用这两个工具获得DLL语句的操作.   1.首先是toad工具,可以到www.quest.com网站上下载 操作步骤的简要介绍如下: a.    启动to

oracle中的锁定(lock)

锁定(lock)用来控制多个用户对表里相同数据的并行访问.如下表中的示例. 如果没有使用锁定来管理事务,则在9:04的时候,用户A检索id为1的c1列值时,将显示为20,用户A会发现他所做的更新丢失了,实际是被B所做的更新覆盖 掉了. 当我们引入锁定以后,则情况发生了变化,如下表所示.由于使用了锁定来管理事务的并发性,因此用户A在9:04时,检索c1列的值,将显示他所更新的10. 在锁定中,存在以下两种基本的模式. (1)排他锁(Exclusive,简称X锁):一旦用户对某个资源添加了X锁,则其

SQL Server和Oracle防止数据锁定的比较

oracle|server|比较|数据 廖铮 2002-5-30 14:23:50 -------------------------------------------------------------------------------- 数据库并行访问,也就是两个或两以上用户同时访问同一数据,这也是数据库引擎如何设计和实现适度反应所面临的最大问题.设计优良.性能卓越的数据库引擎可以轻松地同时为成千上万的用户服务.而"底气不足"的数据库系统随着更多的用户同时访问系统将大大降低其性

Oracle Stream Replication技术简介

Stream 是Oracle 的消息队列(也叫Oracle Advanced Queue)技术的一种扩展应用. Oracle 的消息队列是通过发布/订阅的方式来解决事件管理.流复制(Stream replication)只是基于它的一个数据共享技术,也可以被用作一个可灵活定制的高可用性方案. 它可以实现两个数据库之间数据库级,schema级,Table级的数据同步,并且这种同步可以是双向的. Oracle Stream也是通过数据冗余来提高可用性,这一点和Data Guard 类型. Oracl

Oracle恢复内部原理简介

Oracle 7 v7.2 恢复大纲 作者:Andrea Borr  & Bill Bridge 版本:1                May 3, 1995 本文概述了Oracle 7.2版本如何进行数据库恢复.本文读者应当熟悉Oracle 7.2的管理指南.相比于管理指南,本文目的是为了更详细描述Oracle恢复用到的算法.数据结构以及一些技术细节. 一.简介 Oracle数据库提供了下列两类失败模式下的数据库恢复: 1.  实例失败:丢失了Oracle数据缓存中的数据或者内存中的数据 2

PostgreSQL Oracle兼容性之 - 锁定执行计划(Outline system)

背景 绑定SQL执行计划,大家一定会想到SQL HINT,通过HINT告诉优化器你要用什么访问方法,用什么JOIN方法,JOIN的顺序,驱动表等等. 但是SQL HINT有一定的弊端,它需要修改应用程序中的SQL语句,把SQL加上HINT. 对pg_hint_plan感兴趣的同学,可以参考我写到文档https://yq.aliyun.com/articles/57945 但是,有什么方法可以在不修改应用程序,不修改SQL的情况下,锁定SQL的执行计划呢? 锁定执行计划 要锁定执行计划,同样要用到