ORA-00600[kkqjpdpvpd No join pred found.]错误
Mar202019
今天,用友NC的一个数据库突然触发了ORA-00600错误,数据库版本11.2.0.4.0,具体告警信息如下:
Wed Mar 20 10:12:46 2019 Errors in file /u01/app/oracle/diag/rdbms/ncdb3/ncdb3/trace/ncdb3_ora_433459.trc (incident=84497): ORA-00600: internal error code, arguments: [kkqjpdpvpd: No join pred found.], [], [], [], [], [], [], [], [], [], [], [] Incident details in: /u01/app/oracle/diag/rdbms/ncdb3/ncdb3/incident/incdir_84497/ncdb3_ora_433459_i84497.trc Wed Mar 20 10:12:48 2019 Dumping diagnostic data in directory=[cdmp_20190320101248], requested by (instance=1, osid=433459), summary=[incident=84497]. Use ADRCI or Support Workbench to package the incident. See Note 411.1 at My Oracle Support for error and packaging details. Wed Mar 20 10:12:48 2019 Sweep [inc][84497]: completed Sweep [inc2][84497]: completed Errors in file /u01/app/oracle/diag/rdbms/ncdb3/ncdb3/trace/ncdb3_ora_433459.trc (incident=84498): ORA-00600: internal error code, arguments: [kkqjpdpvpd: No join pred found.], [], [], [], [], [], [], [], [], [], [], [] Incident details in: /u01/app/oracle/diag/rdbms/ncdb3/ncdb3/incident/incdir_84498/ncdb3_ora_433459_i84498.trc Use ADRCI or Support Workbench to package the incident. See Note 411.1 at My Oracle Support for error and packaging details. Wed Mar 20 10:12:54 2019 Sweep [inc][84498]: completed Sweep [inc2][84498]: completed Dumping diagnostic data in directory=[cdmp_20190320101254], requested by (instance=1, osid=433459), summary=[incident=84498].
通过600错误的参数,猜测可能和表连接有关,通过查看trace文件,发现是下面的SQL触发的。
*** 2019-03-20 10:12:46.437 dbkedDefDump(): Starting incident default dumps (flags=0x2, level=3, mask=0x0) ----- Current SQL Statement for this session (sql_id=gv7tagc3q502n) ----- SELECT o.orderno, o.orderseq, op.ordertype, o.saleorg, o.cooorg, o.ivtype, o.isroll, o.isreturn, o.num, o.invoiceamount, op.payment, op.amount FROM busi_order_2019_03 o join busi_orderpay op on o.orderno = op.orderid and o.dr = 0 and op.dr = 0 and o.orderno in (SELECT a.orderno FROM (SELECT o.orderno, sum(o.invoiceamount) amount FROM busi_order_2019_03 o WHERE o.dr = 0 and o.ivtype in ('9ef4832bfa7c42fdb709af44f53e8df0', 'e41166ae18dd46cbb1f4a7236c28a497') and substr(o.saledate, 0, 10) >= '2019-03-01' and substr(o.saledate, 0, 10) <= '2019-03-01' group by o.orderno) a join (SELECT op.orderid orderno, sum(op.amount) amount FROM busi_orderpay op WHERE op.dr = 0 group by op.orderid) b on a.orderno = b.orderno WHERE a.amount - b.amount <> 0 union all SELECT a.orderno FROM (SELECT o.orderno, o.orderseq, sum(o.invoiceamount) amount FROM busi_order_2019_03 o WHERE o.dr = 0 and o.ivtype = '301f75fe314d403393ffa49deebb6d8d' and substr(o.saledate, 0, 10) >= '2019-03-01' and substr(o.saledate, 0, 10) <= '2019-03-01' group by o.orderno, o.orderseq) a join (SELECT op.orderid orderno, op.orderseq, sum(op.amount) amount FROM busi_orderpay op WHERE op.dr = 0 group by op.orderid, op.orderseq) b on a.orderno = b.orderno and a.orderseq = b.orderseq WHERE a.amount - b.amount <> 0)
网上资料说这是个BUG,需要打补丁或者通过在执行SQL之前设置数据库的隐含参数解决。
alter session set "_optimizer_push_pred_cost_based" = FALSE;
也就是在程序里,这个SQL的前面加上上面的SQL即可解决。
alter session set "_optimizer_push_pred_cost_based" = FALSE; SELECT o.orderno, o.orderseq, op.ordertype, o.saleorg, o.cooorg, o.ivtype, o.isroll, o.isreturn, o.num, o.invoiceamount, op.payment, op.amount FROM busi_order_2019_03 o join busi_orderpay op on o.orderno = op.orderid and o.dr = 0 and op.dr = 0 and o.orderno in (SELECT a.orderno FROM (SELECT o.orderno, sum(o.invoiceamount) amount FROM busi_order_2019_03 o WHERE o.dr = 0 and o.ivtype in ('9ef4832bfa7c42fdb709af44f53e8df0', 'e41166ae18dd46cbb1f4a7236c28a497') and substr(o.saledate, 0, 10) >= '2019-03-01' and substr(o.saledate, 0, 10) <= '2019-03-01' group by o.orderno) a join (SELECT op.orderid orderno, sum(op.amount) amount FROM busi_orderpay op WHERE op.dr = 0 group by op.orderid) b on a.orderno = b.orderno WHERE a.amount - b.amount <> 0 union all SELECT a.orderno FROM (SELECT o.orderno, o.orderseq, sum(o.invoiceamount) amount FROM busi_order_2019_03 o WHERE o.dr = 0 and o.ivtype = '301f75fe314d403393ffa49deebb6d8d' and substr(o.saledate, 0, 10) >= '2019-03-01' and substr(o.saledate, 0, 10) <= '2019-03-01' group by o.orderno, o.orderseq) a join (SELECT op.orderid orderno, op.orderseq, sum(op.amount) amount FROM busi_orderpay op WHERE op.dr = 0 group by op.orderid, op.orderseq) b on a.orderno = b.orderno and a.orderseq = b.orderseq WHERE a.amount - b.amount <> 0)
将方法告诉开发人员后,通过修改程序代码,这个错误已经解决,但是下午又发现另一条SQL也触发了这个BUG。
select count(1) from (SELECT o.ivtype, o.saleorg, o.deliveryorg, op.payment, CASE o.isreturn WHEN 0 THEN op.amount ELSE op.amount * -1 END amount FROM busi_order_2019_03 o, busi_orderpay op WHERE o.orderno = op.orderid AND o.orderno IN (SELECT a.orderno FROM (SELECT o.orderno, sum(o.invoiceamount) amount FROM busi_order_2019_03 o WHERE o.ivtype IN ('9ef4832bfa7c42fdb709af44f53e8df0', 'e41166ae18dd46cbb1f4a7236c28a497') AND o.dr = 0 AND substr(o.saledate, 0, 10) >= :1 GROUP BY o.orderno) a JOIN (SELECT op.orderid orderno, sum(op.amount) amount FROM busi_orderpay op WHERE op.dr = 0 GROUP BY op.orderid) b ON a.orderno = b.orderno UNION ALL SELECT a.orderno FROM (SELECT o.orderno, o.orderseq, sum(o.invoiceamount) amount FROM busi_order_2019_03 o WHERE o.dr = 0 AND o.ivtype = '301f75fe314d403393ffa49deebb6d8d' AND substr(o.saledate, 0, 10) >= :2 GROUP BY o.orderno, o.orderseq) a JOIN (SELECT op.orderid orderno, op.orderseq, sum(op.amount) amount FROM busi_orderpay op WHERE op.dr = 0 GROUP BY op.orderid, op.orderseq) b ON a.orderno = b.orderno AND a.orderseq = b.orderseq)) JOIN bd_dict dict ON dict.code = deliveryorg AND dict.fk_dicttype = 'f39d55e9401246bba26d5f452afe53d8'
补丁目前打不了,只能通过上面的方式去解决了。很纳闷,用友这么大公司开发的产品,怎么这么容易触发600错误呢,前几天的600错误,数据库都干挂了。而且这个项目马上就要验收交接啦,真为交接的开发同事担忧啊。