Sau*_*hin 8 oracle deadlock oracle-11g
我的订购应用程序使用 Oracle 11g 数据库。这个数据库有一个主表 ORDERS 和多个子表,如 ORDER_DETAILS、PLAN 等。
ORDERS 表在 STATUS 列上进行 LIST 分区,所有其他表都使用 ORDERID 作为外键进行引用分区。
在负载高峰时,当订单状态发生变化并且 ORDERS 表行从一个分区移动到另一个分区时,Oracle 将对 ORDERS 表分区引用的所有子表执行行迁移。由于许多表依赖于 ORDERS 表,大量行移动发生导致子表之一出现死锁。
我的问题是,如何解决在ORACLE 的内部行迁移步骤中造成的死锁?
这是一个示例设置:
订单表:
CREATE TABLE ORDERS (
orderID NUMBER PRIMARY KEY,
description VARCHAR2(30),
status VARCHAR2(30))
PARTITION BY LIST (status) (
PARTITION A VALUES ('COMPLETED'),
PARTITION B VALUES ('ACTIVE'),
PARTITION C VALUES ('SUBMITTED'))
Run Code Online (Sandbox Code Playgroud)
子表:PLAN
CREATE TABLE PLAN (
planID NUMBER PRIMARY KEY,
orderID NUMBER,
description VARCHAR2(30),
CONSTRAINT FKC64393AD1EC7235 FOREIGN KEY (orderID)
REFERENCES ORDERS (orderID) ON DELETE CASCADE
)
PARTITION BY REFERENCE (FKC64393AD1EC7235);
Run Code Online (Sandbox Code Playgroud)
还有更多子表,其中 ORDERS 是父表。
在重负载下,当 ORDER 状态改变导致行在分区之间移动时,日志中会打印以下死锁错误 ORA-00060: deadlock detected while waiting for resource
在 Oracle 跟踪日志中,我看到以下 SQL 导致死锁
update /*+ opt_param('_and_pruning_enabled', 'false') */ "TEST"."PLAN" partition (dataobj_to_partition( "TEST"."ORDERS" , :1)) move to partition (dataobj_to_partition( "TEST"."ORDERS" , :1)) set "ORDERID" = "ORDERID" where "ORDERID" = :1
Run Code Online (Sandbox Code Playgroud)
现在这个 SQL 是由 Oracle 内部生成的,用于执行子 PLAN 表的行迁移。
为了解决这个问题,我尝试了以下更改:
但是还没有成功。我如何处理这种情况下的死锁?
- - - - - - - - - - - - - 更新 - - - - - - - - - - - - ——
根据 Wernfried 和 Gandolf989 的建议,我通过运行 Gandolf989 答案中给出的查询来验证我的所有外键是否都有索引。
结果是“未找到行”。所以这意味着,所有的索引似乎都到位了。但是在分析时我意识到,如果我检查如下简单查询的解释计划,即使在 ORDERID 列上有索引后,我也会在 PLAN 表上看到完整的表扫描。
UPDATE PLAN SET DESCRIPTION = 'ABC' WHERE orderid= '234';
Run Code Online (Sandbox Code Playgroud)
以下是最初在该表上运行的索引语句。
CREATE INDEX IDX_PLAN_ORDERID ON PLAN(ORDERID);
Run Code Online (Sandbox Code Playgroud)
所以出于某种原因,ORACLE 在对 PLAN 表运行更新查询时没有考虑索引。我错过了什么吗?
| 归档时间: |
|
| 查看次数: |
952 次 |
| 最近记录: |