关于Oracle Advisor的一个Bug

对于Oracle不少特性,我们通常为了避免Bug,而是直接选择将一些功能屏蔽掉;虽然这样做不一定非常对,但是确实可以避免很多问题。这不一个网友咨询一个Ora-00600错误,从报错来看第一感觉可能是Bug,其中报错如下:

Exception [type: SIGSEGV, Address not mapped to object] [ADDR:0xFAC8] [PC:0x7B383AE, qksanEndSession()+30] [flags: 0x0, count: 1]
Errors in file /u01/app/oracle/diag/rdbms/xxxxx/xxxxx2/trace/xxxxx2_j002_27957.trc  (incident=554676):
ORA-07445: exception encountered: core dump [qksanEndSession()+30] [SIGSEGV] [ADDR:0xFAC8] [PC:0x7B383AE] [Address not mapped to object] []
ORA-00603: ORACLE server session terminated by fatal error
ORA-00600: internal error code, arguments: [k2gteget: pdbid], [3], [1], [], [], [], [], [], [], [], [], []
ORA-00600: internal error code, arguments: [k2gteget: pdbid], [3], [1], [], [], [], [], [], [], [], [], []
ORA-00600: internal error code, arguments: [kpdbSwitchPreRestore: txn], [0x141C1FE4F0], [0], [2685403136], [], [], [], [], [], [], [], []

这里是一套Oracle 12.1版本的多租户环境。实际上我们知道,在Oracle 12.1版本中,多租户功能还不是足够的稳定,因此近些年不少客户已经选择将12.1 升级到12.2或者19c。单纯看上述报错是无法定位问题的,需要进一步分析trace的call stack信息:

dbkedDefDump(): Starting incident default dumps (flags=0x2, level=3, mask=0x0)
[TOC00003]
----- Current SQL Statement for this session (sql_id=cnphq355f5rah) -----
DECLARE job BINARY_INTEGER := :job;  next_date TIMESTAMP WITH TIME ZONE := :mydate;  broken BOOLEAN := FALSE;  job_name VARCHAR2(30) := :job_name;  job_subname VARCHAR2(30) := :job_subname;  job_owner VARCHAR2(30) := :job_owner;  job_start TIMESTAMP WITH TIME ZONE := :job_start;  job_scheduled_start TIMESTAMP WITH TIME ZONE := :job_scheduled_start;  window_start TIMESTAMP WITH TIME ZONE := :window_start;  window_end TIMESTAMP WITH TIME ZONE := :window_end;  chain_id VARCHAR2(14) :=  :chainid;  credential_owner varchar2(30) := :credown;  credential_name  varchar2(30) := :crednam;  destination_owner varchar2(30) := :destown;  destination_name varchar2(30) := :destnam;  job_dest_id varchar2(14) := :jdestid;  log_id number := :log_id;  BEGIN  DECLARE
ename             VARCHAR2(30);
exec_task         BOOLEAN;
BEGIN
-- check if tuning pack is enabled
exec_task := prvt_advisor.is_pack_enabled(
dbms_management_packs.TUNING_PACK);
-- check if we are in a pdb,
-- since auto sqltune is not run in a pdb
IF (exec_task AND -- tuning pack enabled
sys_context('userenv', 'con_id') <> 0 AND -- not in non-cdb
sys_context('userenv', 'con_id') <> 1  ) THEN -- not in root
exec_task := FALSE;
END IF;
-- execute auto sql tuning task
IF (exec_task) THEN
ename := dbms_sqltune.execute_tuning_task(
'SYS_AUTO_SQL_TUNING_TASK');
END IF;
-- check whether we are in non-CDB or a PDB
-- auto SPM evolve only runs in a non-CDB or a PDB, not the root.
IF (sys_context('userenv', 'con_id') = 0 OR
sys_context('userenv', 'con_id') > 2) THEN
exec_task := TRUE;
ELSE
exec_task := FALSE;
END IF;
-- execute auto SPM evolve task
IF (exec_task) THEN
ename := dbms_spm.execute_evolve_task('SYS_AUTO_SPM_EVOLVE_TASK');
END IF;
END;  :mydate := next_date; IF broken THEN :b := 1; ELSE :b := 0; END IF; END;
[TOC00004]
----- PL/SQL Stack -----
----- PL/SQL Call Stack -----
object      line  object
handle    number  name
0xdf06f478     12825  package body SYS.DBMS_SQLTUNE_INTERNAL
0x12fd4933e0         7  SYS.WRI$_ADV_SQLTUNE
0x137f33b9c0       602  package body SYS.PRVT_ADVISOR
0x137f33b9c0      2678  package body SYS.PRVT_ADVISOR
0x12dd557a00       241  package body SYS.DBMS_ADVISOR
0x12dd554020       937  package body SYS.DBMS_SQLTUNE
0x12caaf8568        19  anonymous block
[TOC00004-END]
[TOC00003-END]
[TOC00005]
----- Call Stack Trace -----
calling              call     entry                argument values in hex
location             type     point                (? means dubious value)
-------------------- -------- -------------------- ----------------------------
skdstdst()+45        call     kgdsdst()            7FFD64A0AE48 000000002
7FFD649EC880 ? 7FFD649EC998 ?
7FFD64A0A678 ? 000000082 ?
ksedst()+119         call     skdstdst()           7FFD64A0AE48 000000000
000000001 7FFD649EC998 ?
7FFD64A0A678 ? 000000082 ?
dbkedDefDump()+1119  call     ksedst()             000000000 000000000 ?
000000001 ? 7FFD649EC998 ?
7FFD64A0A678 ? 000000082 ?
ksedmp()+261         call     dbkedDefDump()       000000003 000000002
000000001 ? 7FFD649EC998 ?
7FFD64A0A678 ? 000000082 ?
ksfdmp()+89          call     ksedmp()             0000003EB 000000002 ?
000000001 ? 000000002
7FFD64A0A678 ? 000000082 ?
dbgexPhaseII()+1845  call     ksfdmp()             7EFFCC9C0C80 0000003EB
000000001 ? 000000002 ?
7FFD64A0A678 ? 000000082 ?
dbgexProcessError()  call     dbgexPhaseII()       7EFFCC980648 7EFFCC968840
+2539                                              7FFD64A0F850 000000002 ?
7FFD64A0A678 ? 000000082 ?
dbgeExecuteForError  call     dbgexProcessError()  7EFFCC980648 7EFFCC968840
()+110                                             000000001 000000000
7FFD64A0A678 ? 000000082 ?
dbgePostErrorKGE()+  call     dbgeExecuteForError  7EFFCC980648 7EFFCC968840
1870                          ()                   000000000 000000001 000000000
000000082 ?
dbkePostKGE_kgsf()+  call     dbgePostErrorKGE()   7EFFCC9C0C80 7EFFCC860048
90                                                 000000258 000000001 ?
000000000 ? 000000082 ?
kgeadse()+429        call     dbkePostKGE_kgsf()   7EFFCC9C0C80 7EFFCC860048
000000258 000000001 ?
000000000 ? 000000082 ?
kgerinv_internal()+  call     kgeadse()            7EFFCC9C0C80 ? 7EFFCC860048 ?
49                                                 000000258 ? 00DE7E950
000000000 ? 000000002
kgerinv()+40         call     kgerinv_internal()   7EFFCC9C0C80 ? 7EFFCC860048 ?
000000258 ? 00DE7E950 ?
000000000 ? 000000002 ?
kgeasnmierr()+150    call     kgerinv()            7EFFCC9C0C80 ? 7EFFCC860048 ?
000000258 ? 00DE7E950 ?
000000000 ? 000000002 ?
k2gteget()+375       call     kgeasnmierr()        7EFFCC9C0C80 ? 7EFFCC860048 ?
000000258 ? 00DE7E950 ?
000000000 000000003
k2gget()+331         call     k2gteget()           7EFFCC860048 ? 7EFFCC860048 ?
000000000 ? 00DE7E950 ?
000000000 ? 000000003 ?
k2glock1()+696       call     k2gget()             000000000 ? 7EFFCC860048 ?
000000006 141C1FE4F0 ?
000000000 ? 000000000
ktcrsp1()+5832       call     k2glock1()           000000000 ? 7EFFCC860048 ?
000000006 ? 141C1FE4F0 ?
000000000 ? 000000000 ?
ksudlc()+1577        call     ktcrsp1()            12F7F17008 000000000
000000000 141C1FE4F0 ?
000000000 ? 000000000 ?
kss_del_cb()+257     call     ksudlc()             12F7F16F70 ? 000000002 ?
141C1FE4F0 ? 141C1FE4F0 ?
000000000 ? 000000000 ?
kssdel()+239         call     kss_del_cb()         12F7F16F70 ? 00D39FA90
141C1FE4F0 ? 141C1FE4F0 ?
000000000 12F7F16F70
ksupop()+550         call     kssdel()             12F7F16F70 ? 000000002 ?
141C1FE4F0 ? 141C1FE4F0 ?
000000000 ? 12F7F16F70 ?
k2send()+7214        call     ksupop()             000000002 000000002 ?
141C1FE4F0 ? 141C1FE4F0 ?
000000000 ? 12F7F16F70 ?
xctRollbackTxn()+50  call     k2send()             000000003 000000000 000000000
8                                                  000000000 7FFD64A12EE8
7FFD64A12F3C
ktcPopAutonomousFra  call     xctRollbackTxn()     000000000 00D5538D0 ?
me()+1665                                          7EFFCC9C0C80 ? 000000000 ?
7FFD64A12EE8 ? 7FFD64A12F3C ?
kpdbSwitchPostResto  call     ktcPopAutonomousFra  000000001 00DC12F54 000003ED0
re()+69                       me()                 000000000 ? 7FFD64A12EE8 ?
7FFD64A12F3C ?
kpdbSwitch()+4125    call     kpdbSwitchPostResto  000000001 ? 7FFD64A13660 ?
re()                 0A0100000 ? 000000000 ?
7FFD64A12EE8 ? 7FFD64A12F3C ?
qksanAnalyzeSql()+9  call     kpdbSwitch()         000000001 ? 7FFD64A13660 ?
22                                                 0A0100000 ? 001C27460
7FFD64A13AC0 7FFD64A12F3C ?
qksanAnalyzeSegSql(  call     qksanAnalyzeSql()    7FFD64A13BF0 7EFFC7074ED0
)+132                                              00000036C 7FFD64A13BF0
7EFFC7074ED0 00000036C
kestsaInitialRound(  call     qksanAnalyzeSegSql(  7FFD64A13BF0 7EFFC7148EC8
)+659                         )                    000000000 0000000B8
7FFD64A140A0 000000003
kestsaAutoTuneSql()  call     kestsaInitialRound(  CBEDA7664 7EFFC7148EC8 ?
+1123                         )                    000000000 ? 0000000B8 ?
7FFD64A140A0 ? 000000003 ?
kestsaAutoTuneDrv()  call     kestsaAutoTuneSql()  7FFD64A147F8 7FFD64A17998
+1018                                              7FFD64A15C08 0000000B8 ?
7FFD64A140A0 ? 000000003 ?
kestsTuneSqlDrv()+1  call     kestsaAutoTuneDrv()  7EFFCC8503C8 7FFD64A186C0
89                                                 7FFD64A17998 7FFD64A187E0
7FFD64A15BD8 7FFD64A15BE0
kesaiExecAction()+1  call     kestsTuneSqlDrv()    7FFD64A18350 7FFD64A186C0
034                                                7FFD64A17998 7FFD64A187E0
7FFD64A15BD8 7FFD64A15BE0
kesaiTuneSqlDrv()+6  call     kesaiExecAction()    7FFD64A162C0 ? 7FFD64A186C0 ?
784                                                7FFD64A187E0 7FFD64A183F0
7FFD64A188A0 7FFD64A188A8
spefcifa()+403       call     kesaiTuneSqlDrv()    7FFD64A1A358 7EFFC71172A0
000000000 000000000
7FFD64A188A0 ? 7FFD64A188A8 ?
spefmccallstd()+418  call     spefcifa()           7FFD64A19F10 000000004
7EFFC7117228 7FFD64A18D60
7FFD64A18D80 000000000
pextproc()+90        call     spefmccallstd()      7FFD64A1A280 ? 7FFD0000000C
7FFD64A19CD0 7FFD0000000D
000000000 000000000 ?
peftrusted()+151     call     pextproc()           7FFD64A1A280 7FFD64A19E40
7FFD64A19CD0 7FFD64A19F10
000000000 ? 000000000 ?
psdexsp()+296        call     peftrusted()         7FFD64A1A280 7FFD64A19E40 ?
7FFD64A19CD0 ? 7FFD64A19F10 ?
000000000 ? 000000000 ?
rpiswu2()+1780       call     psdexsp()            7FFD64A19A80 7FFD64A19E40 ?
7FFD64A19CD0 000020003
000000000 ? 7FFD64A1B2D8
kxe_push_env_intern  call     rpiswu2()            7FFD64A19A80 ? 7EFFCC9C0C80 ?
al_pp_()+395                                       7FFD64A19CD0 ? 000020003 ?
7FFD64A19390 ? 7FFD64A1B2D8 ?
kkx_push_env_for_IC  call     kxe_push_env_intern  000000000 ? 003385C40 ?
D_for_new_session()           al_pp_()             7FFD64A19CD0 ? 000020003 ?
+160                                               000000000 ? 7FFD64A1B2D8 ?
psdextp()+398        call     kkx_push_env_for_IC  200000000 000000001
D_for_new_session()  7FFD64A19A80 000000000
14424CFBA8 7EFFCC8B1970
pefccal()+879        call     psdextp()            7FFD64A1B2D8 7FFD64A19E40
7FFD64A19CD0 000000000
000020003 7FFD64A1A280
pefcal()+335         call     pefccal()            7FFD64A1A280 7FFD64A19E40 ?
7FFD64A19CD0 ? 000BF9430
7EFFCC8B1970 7FFD64A1A280 ?
pevm_FCAL()+181      call     pefcal()             7FFD64A1A280 7EFFCC9C0E78
7EFFCC8B1970 000BF9430 ?
7EFFCC8B1970 ? 7FFD64A1A280 ?
pfrinstr_FCAL()+72   call     pevm_FCAL()          12BED0B6B0 12BED0B758
7EFFCC8B1970 ? 000BF9430 ?
7EFFCC8B1970 ? 7FFD64A1A280 ?
pfrrun_no_tool()+60  call     pfrinstr_FCAL()      7EFFCC8B1970 ? 12BED456A0 ?
7EFFCC8B19E0 ? 000BF9430 ?
7EFFCC8B1970 ? 7FFD64A1A280 ?
pfrrun()+1155        call     pfrrun_no_tool()     7EFFCC8B1970 ? 12BED456A0 ?
7EFFCC8B19E0 ? 000BF9430 ?
7EFFCC8B1970 ? 7FFD64A1A280 ?
plsql_run()+708      call     pfrrun()             7EFFCC8B1970 000000000
7EFFCC8B19E0 ? 7FFD64A1B2D8
7EFFCC8B1970 ? 12A4445800
peicnt()+285         call     plsql_run()          7EFFCC8B1970 000000001
000000000 7FFD64A1B2D8 ?
000000000 12A4445800 ?
kkxexe()+726         call     peicnt()             7FFD64A1B2D8 7EFFCC8B1970
000000000 ? 7EFFCC877B18
000000000 ? 12A4445800 ?
opiexe()+19651       call     kkxexe()             7EFFCC8B0610 7EFFCC8B1970 ?
000000000 ? 7EFFCC877B18 ?
000000000 ? 12A4445800 ?
kpoal8()+2848        call     opiexe()             7EFFCC8B0610 ? 7EFFCC8B1970 ?
7FFD64A1CBB0 7EFFCC877B18 ?
000000000 ? 12A4445800 ?
opiodr()+1165        call     kpoal8()             00000005E 000000000
7FFD64A209C0 7EFFCC877B18 ?
000000000 ? 12A4445800 ?
kpoodr()+1230        call     opiodr()             00000005E 000000000
7FFD64A209C0 ? 7EFFCC877B18 ?
000000000 ? 100000001
upirtrc()+2410       call     kpoodr()             7EFF00000000 00000005E
7FFD64A209C0 000000000
700000000 100000001 ?
kpurcsc()+102        call     upirtrc()            7EFFCC8A8558 ? 00000005E ?
7FFD64A209C0 ? 000000000 ?
700000000 ? 100000001 ?
kpuexec()+11806      call     kpurcsc()            7EFFCC8A8558 ? 00000005E ?
7FFD64A209C0 ? 000000000 ?
700000000 ? 100000001 ?
OCIStmtExecute()+41  call     kpuexec()            000000000 ? 7EFFCC8BD898 ?
7FFD64A209B8 ? 000000001
7FFD00000000 000000000
jslvec_execcb()+228  call     OCIStmtExecute()     000000000 ? 7EFFCC8BD898 ?
5                                                  7FFD64A209B8 ? 000000001 ?
7FFD00000000 ? 000000000 ?
jslvswu()+111        call     jslvec_execcb()      7EFFCC8BD648 7EFFCC8BD898 ?
7EFFCC8AAF40 000000001 ?
7FFD00000000 ? 000000000 ?
jslvCDBSwitchUsr()+  call     jslvswu()            000000000 0029D5510
64                                                 7FFD64A25760 000000000
7FFD00000000 ? 000000000 ?
kpdbSwitch()+2524    call     jslvCDBSwitchUsr()   7FFD64A25E78 0029D5510 ?
7FFD64A25760 ? 000000000 ?
7FFD00000000 ? 000000000 ?
jslve_execute0()+42  call     kpdbSwitch()         7FFD64A25E78 ? 0029D5510 ?
58                                                 7FFD64A25760 ? 0029C72F0
7FFD64A25E78 000000000 ?
jslve_execute()+573  call     jslve_execute0()     7FFD64A268D4 0000594F0
000000002 7FFD64A268C0
000000000 0FFFFFFFF
jslve_cdb_execute()  call     jslve_execute()      7FFD64A26850 000000000
+94                                                0000594F0 000000002
7FFD64A268C0 0FFFFFFFF ?
rpiswu2()+1780       call     jslve_cdb_execute()  7FFD64A26850 000000000 ?
0000594F0 ? 000000002 ?
7FFD64A268C0 ? 0FFFFFFFF ?
kkjex1e_cdb()+213    call     rpiswu2()            7FFD64A26850 ? 7EFFCC9C0C80 ?
0000594F0 ? 000000002 ?
7FFD64A26620 ? 0FFFFFFFF ?
kkjsexe()+1007       call     kkjex1e_cdb()        000000001 0000594F0 000535953
7FFD64A268C0 000000001
0FFFFFFFF ?
kkjrdp()+651         call     kkjsexe()            000000001 ? 0000594F0 ?
000000000 7FFD64A268C0 ?
000000001 ? 0FFFFFFFF ?
opirip()+960         call     kkjrdp()             000000001 ? 0000594F0 ?
000000000 ? 7FFD64A268C0 ?
000000001 ? 0FFFFFFFF ?
opidrv()+616         call     opirip()             000000032 000000004
7FFD64A28098 7FFD64A268C0 ?
000000001 ? 0FFFFFFFF ?
sou2o()+145          call     opidrv()             000000032 000000004
7FFD64A28098 7FFD64A268C0 ?
000000001 ? 0FFFFFFFF ?
opimai_real()+270    call     sou2o()              7FFD64A28070 000000032
000000004 7FFD64A28098
000000001 ? 0FFFFFFFF ?
ssthrdmain()+412     call     opimai_real()        000000000 7FFD64A28380
000000004 ? 7FFD64A28098 ?
000000001 ? 0FFFFFFFF ?
main()+236           call     ssthrdmain()         000000000 000000003
7FFD64A28380 000000001
000000000 0FFFFFFFF ?
__libc_start_main()  call     main()               7FFD64A29792 7FFD64A29EED
+253                                               7FFD64A28380 ? 000000001 ?
000000000 ? 0FFFFFFFF ?
_start()+41          call     __libc_start_main()  000BBDFE0 000000001
7FFD64A28598 000000000 ?
000000000 ? 0FFFFFFFF ?
[TOC00005-END]

通过上述堆栈信息,很容易就定位到具体的Bug。

Defect 21283337 – QKSAN.C TXN MSABESAN_DTXN ISSUE: CANNOT ROLLBACK WHILE WITHIN TRIGGER CONTEXT

针对该环境要么安装该one off Patch,或者将数据库升级到12.2的19年+版本。

实际上对于该问题,我们不难看出,是sql auto tunning任务导致。我们往常的做法通常是直接关闭该任务的。

至少从目前来看,我认为在11.2,以及12.1、12.2 甚至19c版本中,默认开启该任务没有太大的用处和价值。

BEGIN
DBMS_AUTO_TASK_ADMIN.DISABLE(
client_name => 'sql tuning advisor',
operation => NULL,
window_name => NULL);
END;
/

这个case本身是非常简单的,主要目的不是记录bug流水账;而是想和大家来一起探讨一个问题:

对于数据库中的一些特性,我们的选择是什么样的?

我们都知道数据库在不断演进和发展,功能也越来越强大和丰富;同时数据库未来一定是向着自动化的方式演进。

因此我们知道,实际上Oracle从9i版本(至今近20年历史)开始就推出了SGA内存自动管理(在9i之前的版本中,设置Oracle内存参数是非常考验DBA技能的),以及后面的PGA自动管理,到后面甚至将SGA和PGA合二为一,彻底解放DBA,无需再进行繁琐的设置;设置统一的memory_target等参数即可。

然而理想很丰满,显示却很骨感;至少在目前我们的很多大型客户中,尤其是一些高并发环境下;仍然选择使用了内存手工调解;

对于很多小型系统来讲,比如医疗、高校、政府等数据库环境,你使用内存全自动管理,似乎问题也不大。

除了内存管理之外,对于应用SQL优化来讲,也是一件非常头疼的事情;因此Oracle推出了sql auto tunning的功能;在一些场景下,该定时任务确实能解决一些问题;然而并非没有坏处,比如本文中出现的Bug,可能导致数据库实例崩溃。

实际上对于SQL优化的工作,Oracle一直在不断迭代和演进,所以大家在Oracle 19c版本中看到了auto index 类似的功能;这是像AI4DB 方向的一个重大演进;从这一点来看,Oracle无疑是走在数据库世界前沿的。

所以我认为,本质上这是技术的演进迭代;从数据库厂商的角度来讲,我们是希望用户都能够使用最新的功能,去加快功能迭代;但是从最终用户来讲,往往更需要的是系统稳定性,因此从这一点出发,我认为关闭一些锦上添花的特性是无伤大雅的。

最后打个广告:云和恩墨 MogDB 关系型数据库2.1版本已发布,推出了多项实用功能,同时性能方面也有极大提升,欢迎使用!我们希望能为国产数据库尽一份绵薄之力!


评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注