上周上线碰见的ORA-00054错误回放

简介: 上周应用上线,有一个数据库脚本,包含改字段长度等操作,执行过程中,现象就是有些改字段成功了,有些执行出错,报了ORA-00054的错误。了解一下原理,就能对这个错误,有比较深入的理解了。

上周应用上线,有一个数据库脚本,包含改字段长度等操作,执行过程中,现象就是有些改字段成功了,有些执行出错,报了ORA-00054的错误。了解一下原理,就能对这个错误,有比较深入的理解了。


首先,我们模拟下报错过程,创建测试表,session 1执行update语句,但不提交,session 2执行alter table变更name字段长度,此时立即报错ORA-00054,

SQL> create table tbl_lock(id number, name varchar2(10));
Table created.

SQL> select * from tbl_lock;
    ID NAME
---------- ----------
     1 a
     2 b


session 1:

SQL> update tbl_lock set name='c' where id=1;
1 rows updated.


session 2:

SQL> alter table tbl_lock modify name varchar2(5);
alter table tbl_lock modify name varchar2(5)
            *
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired


我们看下报错,ORA-00054,提示的就是资源繁忙,因为设置了NOWAIT参数,或者超时,才返回这个错误,


看下此时的锁信息,其中14309是从dba_objects中根据object_name='TBL_LOCK'检索得出的,如下显示,TBL_LOCK表上有一个TM表锁,


表锁,又叫TM锁,当交易执行DML语句的时候,会拥有此锁。目的就是为了阻止此时有其他的进程正在执行DDL,修改表结构,

A table lock, also called a TM lock, is acquired by a transaction when a table is modified by an INSERT, UPDATE, DELETE, MERGE, SELECT with the FORUPDATE clause, or LOCK TABLE statement. DML operations require table locks to reserve DML access to the table on behalf of a transaction and to prevent DDL operations that would conflict with the transaction.


结论

至此,开始的问题,就可以解释清楚了,上线过程中,执行alter table改表的字段长度,但由于有些表,此时碰巧有业务操作,对数据做了DML,交易尚未提交,因此由于TM锁未释放,导致alter table这条DDL语句执行报错,对于alter table执行时尚未有DML未commit操作的表,自然就可以执行成功了。


解决方法

就是等一会再执行,只要出现真空期,没有业务操作,就可以执行成功了,毕竟alter table改字段长度,需要改数据字典信息,对于表结构的变更,何时执行时间,会和表数据量有关,何时则无关,以前写了几篇小文章,不同的场景,有一些不同的结论,可以参考,

一张几亿的分区表,能改名么?

alter table新增字段操作究竟有何影响?(上篇)

alter table新增字段操作究竟有何影响?(下篇)




针对ORA-00054这问题,可以再了解一些。


从11g开始,出现了一个新的参数,


这个参数可以session级别设置,作用就是可以控制一条DDL语句等待一个DML锁释放的时间,默认值是0,表示NOWAIT,最大值是1000000秒,大约11.5天,如果在设置的时间之内,仍未获取DDL锁,则抛出异常错误,错误号就是ORA-00054,

DDL_LOCK_TIMEOUT specifies a time limit for how long DDL statements will wait in a DML lock queue. The default value of zero indicates a status of NOWAIT. The maximum value of 1,000,000 seconds will result in the DDL statement waiting forever to acquire a DML lock.

If a lock is not acquired before the timeout period expires, then an error is returned.


上面的实验中,DDL_LOCK_TIMEOUT默认值是0,因此执行alter table会立即报错,


设置参数值,改为10妙,执行alter table,确实SQL等待了10秒,才返回了ORA-00054错误,

SQL> alter session set ddl_lock_timeout=10;
Session altered.
Elapsed: 00:00:00.00


SQL> alter table tbl_lock modify name varchar2(5);
alter table tbl_lock modify name varchar2(5)
            *
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
Elapsed: 00:00:10.00


惜分飞文章(http://www.xifenfei.com/2012/07/oracle-11g%E7%9A%84ddl_lock_timeout%E5%8F%82%E6%95%B0.html)介绍了这个参数的作用,

ddl_lock_timeout可以在一定程度上解决因为我们不清楚这个表是否有dml操作而导致ddl操作不能进行的情况,从一定程度上减少了自己去尝试ddl操作,或者查询相关视图然后找出相关会话,然后kill掉对应数据的情况,可以说是在修改表结构的时候一个很不错的新特性。


11g之前,DDL操作,碰见TM锁,是直接报错,11g则用这参数,通过设置等待时间,可以避免一些DDL语句重复执行,例如开始碰见的问题,如果设置了DDL_LOCK_TIMEOUT,可能等待一会就会执行成功,而不需要我们手工再执行。


但这参数有一个问题,就是对于alter table加字段操作,是不起作用,无论ddl_lock_timeout设置为0还是非0,

SQL> alter table tbl_lock add sex varchar2(1);

会一直处于hang


直到人为中止

c^Calter table tbl_lock add sex varchar2(1)
*
ERROR at line 1:
ORA-01013: user requested cancel of current operation


但是alter table删除字段、drop table删除表操作,可以生效,

SQL> alter table tbl_lock drop column name;
alter table tbl_lock drop column name
            *
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired


SQL> drop table tbl_lock;
drop table tbl_lock
           *
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired


MOS(Alter Table Add Column Command Hangs With Wait Event 'blocking txn id for DDL' (文档 ID 1553725.1))这篇文章,同样说明了这一个问题,由于11g中,alter table add column操作,没有被DDL排他锁覆盖,因此不受DDL_LOCK_TIMEOUT参数的控制,更不会抛出ORA-00054错误,而是出于hang,

In 11g,  ALTER TABLE ADD COLUMN is not covered by an exclusive ddl lock; therefore, it will not wait for the specified time in DDL_LOCK_TIMEOUT parameter and it will not raise the ORA-00054 error.


《DDL_LOCK_TIMEOUT Behavior in 11G (文档 ID 779569.1)》介绍了这个参数。


11.1.0.6版本,有人开了《Bug 7707888 : DDL_LOCK_TIMEOUT IS NOT WORKING AS EXPECTED》这个bug,此版本中,若有seesion执行DML未提交,此时alter table add column可以执行,但是drop table可以执行。



总结:

1. DDL_LOCK_TIMEOUT是11g新参数,对于一些频繁DML的表,若需要结构变更,可以设置非0,一定程度上,可以避免人为重新执行,自动找出真空期,执行完成DDL语句。

2. alter table加字段操作,不受DDL_LOCK_TIMEOUT控制,需要人为控制。



如果您觉得此篇文章对您有帮助,欢迎关注微信公众号:bisal的个人杂货铺,您的支持是对我最大的鼓励!共同学习,共同进步:)

目录
相关文章
|
8月前
|
Java 程序员 开发者
太卷了!这份Java性能调优手册仅上线1小时,竟被恶意封杀下架
在各大厂的面试中,性能优化的问题肯定不会缺席,这足以说明其重要性。今天给大家带来的便是由资深程序员葛一鸣老师写的《Java程序性能优化实战》,同样是没有开源版本,我会将领取方式放在文末 Java程序性能优化实战 我看过几篇讲解Java程序性能优化的图书,要么是内容不够深入,要么是过于晦涩难懂,不够浅显,而这本书却让我眼前一亮,很多困扰我的问题都能在书中找到答案。它涵盖了各种程序员所需的性能优化知识点,是Java开发者提升水平的必读佳作 来看看目录内容,里面一定有你想看的 亮个相吧(狗头.jpg) 想要更进一步的Java开发者一定不能
49 0
|
12月前
|
运维 测试技术
【超干货】近期收到的测试面试题分析
【超干货】近期收到的测试面试题分析
|
安全 Java 测试技术
全面复盘Android开发者容易忽视的Backup功能(1)
全面复盘Android开发者容易忽视的Backup功能(1)
全面复盘Android开发者容易忽视的Backup功能(1)
|
XML 安全 API
全面复盘Android开发者容易忽视的Backup功能(2)
全面复盘Android开发者容易忽视的Backup功能(2)
全面复盘Android开发者容易忽视的Backup功能(2)
|
机器学习/深度学习 算法 数据安全/隐私保护
算法日志——第二天
算法日志——第二天
85 0
算法日志——第二天
|
移动开发 应用服务中间件 nginx
没想到,日志还能这么分析!
这次,将用一个大概几万条记录的 nginx 日志文件作为案例,一起来看看如何分析出「用户信息」。
没想到,日志还能这么分析!
|
数据可视化 前端开发 NoSQL
BUG记录 | 【内附前端福利】
今天在安装VMWare软件的时候,突然报了这个错误
116 0
BUG记录 | 【内附前端福利】
|
安全 Java Apache
1214 最新:Log4j 再发版,彻底斩断核弹级漏洞,又要熬夜了。。。
这几天为了应对《突发!Apache Log4j2 报核弹级漏洞。。赶紧修复!!》,Log4j2 连续发布了两个 RC(Release Candidate)候选版本,1 个正式版本。
1214 最新:Log4j 再发版,彻底斩断核弹级漏洞,又要熬夜了。。。
|
测试技术 程序员 网络虚拟化
小猿日记(15) - 脚本订正注意事项
小猿日记(15) - 脚本订正注意事项
303 0