首页 > 解决方案 > 在 Oracle 中为 ALTER TABLE ADD COLUMN 设置超时值(DDL_LOCK_TIMEOUT 不起作用)

问题描述

问题

如何在 oracle 中为非阻塞 DDL(ALTER TABLE 添加列)设置超时值,以便如果任何 DML 长时间(几个小时)锁定表,我的 DDL 可以快速失败而不是等待几个小时。(我们预计 oracle 会引发类似 ORA-00054 的错误:资源繁忙并使用指定的 NOWAIT 获取或超时过期以中断我们的 DDL)

PS:DDL_LOCK_TIMEOUT 不起作用(请参阅下面的“我尝试过的”)

背景

我正在开发一个大型 oracle 数据库(Oracle Database 19c)。每小时都有旧版应用程序会进行聚合工作以计算过去一小时的数据,例如计数器的 AVG、SUM。生产有 40 个 CPU 和 200GB+ 内存,通常聚合作业会运行大约 30 分钟,但在某些情况下,例如由于维护中断,聚合作业会延迟,下一个聚合作业需要处理更多数据,导致作业运行几个小时。

那些遗留应用程序是我无法控制的。无法更改聚合作业。

不使用基于版本的重新定义。

我的工作是更新数据库表(由于添加了新计数器)。我们使用 ALTER TABLE 将新列添加到现有表中。但在某些情况下,聚合作业将表锁定几个小时使我的脚本挂在那里几个小时。它让客户不高兴。所以我想让我的脚本快速失败。

我试过的

google了半天,似乎DDL_LOCK_TIMEOUT是最简单的解决方案。

但是,根据测试,我们注意到 DDL_LOCK_TIMEOUT 在我们的案例中不起作用。又google了半天,发现Oracle文档这里明确提到:

DDL_LOCK_TIMEOUT 参数影响阻塞 DDL 语句(但不影响非阻塞 DDL 语句)

ALTER TABLE 添加列完全是“非阻塞 DDL”列表中列出的“非阻塞 DDL”

期待

当一个 DML 锁定表 1 小时时,喜欢SELECT * FROM MY_TABLE FOR UPDATE并在 1 小时后提交。我希望我的 DDLALTER TABLE MY_TABLE ADD (COL_A number)可以在 10 分钟后超时,而不是等待 1 小时。

其他解决方案

1

在我的脑海里有一个解决方案,我们可以先发出 alock table MY_TABLE IN EXCLUSIVE MODE wait 600来获得锁拳。但是在我们使用这个解决方案之前,我想寻求是否有任何简单的解决方案,就像DDL_LOCK_TIMEOUT只设置一个参数一样。

2

基于 oracle doc,启用Supplemental Logging能够将非阻塞 DDL 降级为阻塞方式。但是补充日志是数据库级别的配置。我无权进行此类更改。

标签: oracletimeoutlockingddlfreeze

解决方案


推荐阅读