ORACLE数据库SQL中使用大量绑定变量导致数据库关闭(ORA-07445)

数据库在晚上九点多挂掉了,查看报错日志,如下

Tue Jul 14 21:57:28 2020
Exception [type: SIGSEGV, Address not mapped to object] [ADDR:0x1F72E] [PC:0x184FE23, opiaba()+583] [flags: 0x0, count: 1]
Errors in file /oracle/diag/rdbms/xxxxx/xxxxx/trace/xxxxx_ora_61686.trc  (incident=622249):
ORA-07445: exception encountered: core dump [opiaba()+583] [SIGSEGV] [ADDR:0x1F72E] [PC:0x184FE23] [Address not mapped to object] []
Incident details in: /oracle/diag/rdbms/xxxxx/xxxxx/incident/incdir_622249/xxxxxx_ora_61686_i622249.trc
Use ADRCI or Support Workbench to package the incident.
See Note 411.1 at My Oracle Support for error and packaging details.
Tue Jul 14 21:57:38 2020
Dumping diagnostic data in directory=[cdmp_20200714215738], requested by (instance=1, osid=61686), summary=[incident=622249].
Tue Jul 14 21:57:42 2020
Sweep [inc][622249]: completed
Sweep [inc2][622249]: completed
Tue Jul 14 21:58:38 2020
Errors in file /oracle/diag/rdbms/xxxx/xxxx/trace/xxxxxx_pmon_28148.trc  (incident=600017):
ORA-00600: internal error code, arguments: [17147], [0x1209F04AC8], [], [], [], [], [], [], [], [], [], []
Incident details in: /oracle/diag/rdbms/xxxxxxx/xxxxxx/incident/incdir_600017/xxxxxx_pmon_28148_i600017.trc
Use ADRCI or Support Workbench to package the incident.
See Note 411.1 at My Oracle Support for error and packaging details.
Errors in file /oracle/diag/rdbms/xxxxxx/xxxxxx/trace/xxxxxx_pmon_28148.trc:
ORA-00600: internal error code, arguments: [17147], [0x1209F04AC8], [], [], [], [], [], [], [], [], [], []
PMON (ospid: 28148): terminating the instance due to error 472

Tue Jul 14 21:58:40 2020
opiodr aborting process unknown ospid (16323) as a result of ORA-1092
Tue Jul 14 21:58:40 2020
opiodr aborting process unknown ospid (11039) as a result of ORA-1092
Tue Jul 14 21:58:40 2020
opiodr aborting process unknown ospid (11037) as a result of ORA-1092
Tue Jul 14 21:58:40 2020
ORA-1092 : opitsk aborting process
Tue Jul 14 21:58:40 2020
opiodr aborting process unknown ospid (11035) as a result of ORA-1092
Instance terminated by PMON, pid = 28148

可以看到实例是被PMON杀死的,查看报错中的trc文件

Dump continued from file: /oracle/diag/rdbms/xxxxxx/xxxxx/trace/xxxxx_ora_61686.trc
ORA-07445: exception encountered: core dump [opiaba()+583] [SIGSEGV] [ADDR:0x1F72E] [PC:0x184FE23] [Address not mapped to object] []

========= Dump for incident 622249 (ORA 7445 [opiaba()+583]) ========
----- Beginning of Customized Incident Dump(s) -----
Exception [type: SIGSEGV, Address not mapped to object] [ADDR:0x1F72E] [PC:0x184FE23, opiaba()+583] [flags: 0x0, count: 1]
Registers:
%rax: 0x0000000000000000 %rbx: 0x0000001209f09db0 %rcx: 0x0000000000000000
%rdx: 0x0000000000000000 %rdi: 0x000000000000fb97 %rsi: 0x000000000000ffee
%rsp: 0x00007fff561f1820 %rbp: 0x00007fff561f1890  %r8: 0x0000001209e89e48
 %r9: 0x00000000000000ff %r10: 0x0000000000003739 %r11: 0x00000012ace37508
%r12: 0x00000012ac06adf0 %r13: 0x0000000000000000 %r14: 0x000000129607cdb0
%r15: 0x0000000000000168 %rip: 0x000000000184fe23 %efl: 0x0000000000010213
  opiaba()+571 (0x184fe17) je 0x184fe3b
  opiaba()+573 (0x184fe19) add $-1,%ecx
  opiaba()+576 (0x184fe1c) movsxdq %ecx,%rdi
  opiaba()+579 (0x184fe1f) mov -0x58(%rbp),%rcx
> opiaba()+583 (0x184fe23) movzwl (%rcx,%rdi,2),%esi
  opiaba()+587 (0x184fe27) test %esi,%esi
  opiaba()+589 (0x184fe29) jnz 0x184ff0c
  opiaba()+595 (0x184fe2f) mov -0x58(%rbp),%rsi
  opiaba()+599 (0x184fe33) movzwl 0x2a(%rbx),%ecx

*** 2020-07-14 21:57:28.804
dbkedDefDump(): Starting a non-incident diagnostic dump (flags=0x3, level=3, mask=0x0)
----- Current SQL Statement for this session (sql_id=9tt4rdcg36vp3) -----
begin  
                        insert into xxxx.xxxxx
                        (id,sorting_id,model_code,stage_code,
                        part_name,part_sn,del_flag,add_by,add_date,sorting_sn,sorting_config)
                        VALUES
                        (xxxx.xxxxx.NEXTVAL,:1,:2,
                        :3,:4, :5,0,:6,sysdate,:7,:8)
                 ; 
                        insert into xxxx.xxxxx
                        (id,sorting_id,model_code,stage_code,
                        part_name,part_sn,del_flag,add_by,add_date,sorting_sn,sorting_config)
                        VALUES
                        (xxxx.xxxxx.NEXTVAL,:9,:10,
                        :11,:12, :13,0,:14,sysdate,:15,:16)
                 ; 
                        insert into xxxx.xxxxx
                        (id,sorting_id,model_code,stage_code,
                        part_name,part_sn,del_flag,add_by,add_date,sorting_sn,sorting_config)
                        VALUES
                        (xxxx.xxxxx.NEXTVAL,:17,:18,
                        :19,:20, :21,0,:22,sysdate,:23,:24)
                 ; 
...................
                        insert into xxxx.xxxxx
                        (id,sorting_id,model_code,stage_code,
                        part_name,part_sn,del_flag,add_by,add_date,sorting_sn,sorting_config)
                        VALUES
                        (xxx.xxxxx.NEXTVAL,:587137,:587138,
                        :587139,:587140, :587141,0,:587142,sysdate,:587143,:587144)
                 ; 
                        insert into xxxx.xxxxx
                        (id,sorting_id,model_code,stage_code,
                        part_name,part_sn,del_flag,add_by,add_date,sorting_sn,sorting_config)
                        VALUES
                        (xxxx.xxxxx.NEXTVAL,:587145,:587146,
                        :587147,:587148, :587149,0,:587150,sysdate,:587151,:587152)
                 ;end;

可以看到大量的insert语句,并且这个语句块(begin--》end)用了587152个绑定变量。

开发的程式,用的应该是java,mybatis。

 

 经过分析,发现上述代码在执行时,MyBatis会将循环的SQL当成一个匿名块发给oracle,oracle会一次性对这个块中的所有SQL进行绑定变量并执行,而不是一条一条的执行,当变量超过65535时,就会触发oracle的bug 12578873,导致实例崩溃

参考:https://www.jianshu.com/p/f70d8bbee075

我们知道上面是一个简单的批量执行语句,但是通过分析可知,MyBatis将循环拼接成一个类似下面的匿名SQL块送给数据库做预分析。MyBatis底层机制是将mapper xml 转换成JDBC中 PreparedStatement预处理,整块代码送给Oracle数据库一次性做变量绑定。Oracle会一次性的对这些SQL顺序绑定变量(尽管block里面是很多单单条SQL组成),这样随着循环体内元素数量变大,需要的变量也会顺序增长,而Oracle只预设了一次性分配65535个变量的阈值,当需要绑定的变量个数超过这个阈值时,就报错了,甚至触发Bug,导致数据库实例Down掉。
posted @ 2020-07-15 14:52  monkey6  阅读(22)  评论(0编辑  收藏  举报