oracle - 插入操作可以让另一个 DDL 操作等待吗?
问题描述
我试图了解我收到以下错误的原因。
`ORA-04021: timeout occurred while waiting to lock object`
运行命令时从过程中抛出此错误alter table <<T_NAME>> truncate subpartition <<SUBPARTITION_NAME>>.
v_dyncursor_stmt := 'with obj as (select /*+ materialize */ data_object_id, subobject_name from user_objects where object_name = UPPER(''' ||
p_table_name ||
''') and object_type = ''TABLE SUBPARTITION'') select '||p_hint||' distinct subobject_name from ' ||
p_table_name || ' t, obj where data_object_id = DBMS_MView.PMarker(t.rowid) and ' || p_where;
/* log */
log_text(v_unit_name, 'INFO', 'Open cursor', v_dyncursor_stmt);
/* loop over partitions which needs to be truncated */
v_counter := 0;
open c_subpartitions for v_dyncursor_stmt;
loop
FETCH c_subpartitions
INTO v_subpartition_name;
EXIT WHEN c_subpartitions%NOTFOUND;
v_statement := 'alter table ' || p_table_name || ' truncate subpartition "' || v_subpartition_name || '"';
execStmt(v_statement);
代码两次调用上述过程,第一次尝试成功。它可以很好地截断子分区。在第二次尝试中它失败了......下面给出了 execStmt 函数,错误是从EXCEUTE IMMEDITE
行中抛出的......
procedure execStmt(p_statement IN VARCHAR2) IS
v_unit_name varchar2(1024) := 'execStmt';
v_simulate varchar2(256);
begin
v_simulate := utilities.get_parameter('PART_PURGE_SIMULATE', '0');
if (v_simulate = '1') then
log_text(v_unit_name, 'INFO', 'Statement skipped. (PART_PURGE_SIMULATE=1)',
p_statement);
else
/* log */
log_text(v_unit_name, 'INFO', 'Executing statement', p_statement);
EXECUTE IMMEDIATE p_statement;
end if;
end;
由于这主要发生在周末,我没有机会检查锁定表以查看锁定对象的原因。但我确定这是一张有很多插入发生的表。所以我的问题是表上的插入操作可以防止上述 DDL 吗?
从 oracle 文档中,我看到一个插入获取了一个 SX 锁,解释如下,
A row exclusive lock (RX), also called a subexclusive table lock (SX), indicates that the transaction holding the lock has updated table rows or issued SELECT ... FOR UPDATE. An SX lock allows other transactions to query, insert, update, delete, or lock rows concurrently in the same table. Therefore, SX locks allow multiple transactions to obtain simultaneous SX and SS locks for the same table.
解决方案
发生此错误是因为您尝试截断的分区当时正在使用中。正如您所提到的,这些插入语句当时正在运行,它会影响 DDL 操作。
推荐阅读
- python - 运行相同 docker 命令的两台主机之间的差异
- typescript - 如何在 RxJS 6 管道运算符中保留一个值?
- swift - 通过 UIButton 使用自定义 TableViewCell 添加到收藏夹并保存到 UserDefaults
- window-functions - 如何为 Presto 编写自定义窗口函数?
- python-3.x - 在 tensorflow 2.4 中使用 sampled_softmax 时,无法将符号 Keras 输入/输出转换为 numpy 数组 TypeError
- sql - 使用连接或任何其他方法连接两个查询?
- bash - 如何使用 Iperf3 仅输出 5 个并行连接的平均带宽?
- c# - IIS。是否可以将网站配置为限制连接数 = 1,但是所有新连接都将放在队列中?
- java - 从 Spring Boot 程序调用的 Oracle 存储过程不在数据库中进行任何更改
- javascript - 使用正则表达式验证字符串