IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

ORACLE 11g新特性-允许DDL锁等待DML锁

信春哥,系统稳,闭眼上线不回滚 2012-07-07 22:53:30 累计浏览 3,326 次
本机暂存

之前也写了一些关于ORACLE11g新特性的文章,现在ORACLE 11g已成为主流的ORACLE数据库版本,了解和学习ORACLE 11g的新特性至关重要,本人也是ORACLE 11g新特性的初学者,在此分享下我的学习过程和心得。
本文主要记录的是ORACLE 11g的一个新特性,允许DDL锁等待DML锁,这也是在6月30日,张乐奕(kamus)老师在ACOUG活动中分享的一个主题。
在11g之前的版本,默认情况下,DDL锁都不等待DML锁,在一个存在DML锁的表上执行DDL操作,会立即返回失败(同一SESSION除外),下面简单做下试验,在SESSION1向表STREAM中插入数据,不要提交,此时表STREAM会存在DML锁,在SESSION2执行TRUNCATE表STREAM操作,就会立即返回失败:

SESSION1 >insert into stream select * from dbdream;
10 rows created.
SESSION2 >truncate table stream;
truncate table stream
               *
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

在11g版本,ORACLE推出了DDL_LOCK_TIMEOUT参数,允许DDL锁等待DML锁,该参数控制DDL锁等待DML锁的时间,单位为秒,默认值为0,即DDL锁不等待DML锁,最大值是100万,也就是11.5天,该参数可以全局设置,也可以在SESSION级设置。

SESSION2 >show parameter ddl_lock_timeout
NAME                    TYPE        VALUE
----------------------- ----------- ------
ddl_lock_timeout        integer     0
SESSION2 >alter session set ddl_lock_timeout=2000000;
ERROR:
ORA-00068: invalid value 2000000 for parameter ddl_lock_timeout, must be
between 0 and 1000000

下面演示下DDL_LOCK_TIMEOUT参数的效果,还拿以上STREAM表为例,目前STREAM表仍然存在DML锁,在SESSION2将DDL_LOCK_TIMEOUT设置为60秒,然后再执行TRUNCATE操作,此时不会马上返回失败,而会等待60秒的时间,如果60秒内STREAM表的DL锁没有释放,才会返回失败。

SESSION2 >alter session set ddl_lock_timeout=60;
Session altered.
SESSION2 >set timing on         
SESSION2 >truncate table stream;
--此时,SESSION2挂起,在60秒的时间内等待SESSION1释放DML锁,60秒后返回失败
truncate table stream
               *
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
Elapsed: 00:01:00.01

DDL_LOCK_TIMEOUT参数的出现,极大简化了DBA的操作,比如我们要在一张表上增加个字段,可是这张表有大量的DML操作,并且我们不能使用ALTER SYSTEM KILL SESSION的方法结束这些操作,那么我们想要在这张表上增加字段就需要无数次的执行增加字段的操作,或者写脚本去干这个活,现在有了DDL_LOCK_TIMEOUT参数,我们只需要将这个参数的值设置的稍大一点,执行一下SQL就不用管啦,下面演示下这个过程。
SESSION2增加字段:

SESSION2 >alter table stream add jpg_path varchar2(255) default '/home/oracle/';

此时挂起,等待STREAM表的DML锁释放,SESSION1提交释放DML锁后,SESSION2操作便成功了。

SESSION1 >commit;
Commit complete.
SESSION2 >alter table stream add jpg_path varchar2(255) default '/home/oracle/';
Table altered.
SESSION2 >select * from stream;
        ID IDENTIFIER      PIC_NO JPG_PATH
---------- --------------- ------ ---------------
         1 18-0220-003     1      /home/oracle/
         2 18-0221-003     1      /home/oracle/
         3 18-0221-003     2      /home/oracle/
         4 18-0221-003     3      /home/oracle/
         5 18-0223-005     1      /home/oracle/
         6 18-0223-005     2      /home/oracle/
         7 18-0223-005     3      /home/oracle/
         8 18-0223-005     4      /home/oracle/
         9 18-0223-005     5      /home/oracle/
        10 18-0223-005     6      /home/oracle/
10 rows selected.

同分类推荐文章

  1. 使用deepseek进行Oracle恢复,引起重大故障 (2026-06-22 10:56:00)
  2. 接手一个只差临门一脚的数据库恢复 (2026-06-18 00:13:09)
  3. 我做了一个 AI 版的 StarRocks 升级风险扫描工具,直接帮我定位到一个风险 (2026-06-15 01:00:00)

查看更多 数据库 文章 →

建议继续学习

  1. 如何获取hive建表语句 (累计阅读 7,183)
  2. MySQL数据库之枚举数据类型ENUM的DDL变更测试 (累计阅读 4,824)
  3. Oracle11g中的result cache (累计阅读 4,274)
  4. Oracle如何监控表的DML次数 (累计阅读 4,203)
  5. MySQL数据库之数据类型集合类型和枚举类型测试环境 (累计阅读 2,980)
  6. 11G real time query,BUG不是一般的多 (累计阅读 2,790)
  7. MySQL数据库之集合类型SET的DDL变更测试总结 (累计阅读 2,504)
  8. (总结)mysql中对已存在的表做增/删/改列的相关操作 (累计阅读 2,341)