作为 ETL 过程的一部分,我有这个交换子分区声明:
ALTER TABLE DWH.QV_FACT_AMS EXCHANGE SUBPARTITION P08_2018_300_SALES WITH TABLE DWH.STG_QV_FACT_AMS;
(每个运行不同的子分区但相同的 2 个表)。
我们开始得到一个异常:
ORA-00054: 资源繁忙并使用指定的 NOWAIT 获取或超时已过期。
这意味着某些进程会更新表,我们无法更改。
由于最终表 - QV_FACT_AMS 仅用于报告,而 STG_QV_FACT_AMS 是在 ETL 本身中创建的内部动态表,我不知道谁可以更新这些表。
ETL 不能与 ETL 本身的另一次运行发生冲突,因此不能尝试从这两个进程修改同一个表。
交换语句每天运行很多次并正常完成,异常仅在晚上 9 点左右引发。
所以我在这两张表上应用了 AUDIT ALL:
AUDIT ALL on dwh.qv_Fact_ams;
AUDIT ALL on dwh.stg_qv_Fact_ams;
但是对表格的所有访问都不是在那个时间段内,只有 select 不应该锁定表格。
失败日志示例:
LOG_ID: 5879089
START_TIME: 18-07-2019 21:29:01
END_TIME: 18-07-2019 21:29:28
STATUS: FAILED
ORA_EXCEPTION: ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
我们可以看到异常发生在 18-07-2019 21:29:28。
这是审计:
SELECT *
FROM DBA_MAINT.AUD$
WHERE OBJ$NAME IN ('QV_FACT_AMS','STG_QV_FACT_AMS')
ORDER BY TIMESTAMP# DESC;
除了 etl 本身,唯一的访问是只有 action# = 3(选择),3 小时后......