Hard Parse Failure 引发DB较为严重的性能问题
1.1问题现象
一个朋友再次遇到SQL解析失败的问题,导致数据库负载很高,让整个数据库无法正常运行业务SQL。
本篇文档对解析失败,从而引发的数据库性能问题,进行分析说明。
现象:数据库负载很高,业务反映数据库慢 or 部分业务无法正常处理;
1.2 AWR观察
快速创建一个awr报告观察里面的指标内容。
可以参考MOS文档
从AWR观察到failed parse elapsed time 比较高时,就可以判断是这个问题。
Time Model Statistics
- Total time in database user-calls (DB Time): 300306.2s
- Statistics including the word "background" measure background process time, and so do not contribute to the DB time statistic
- Ordered by % or DB time desc, Statistic name
Statistic Name | Time (s) | % of DB Time |
---|---|---|
failed parse elapsed time | 299,058.23 | 99.58 |
parse time elapsed | 298,685.36 | 99.46 |
DB CPU | 2,082.85 | 0.69 |
MOS
Oracle Database - Enterprise Edition - Version 10.2.0.2 and later
In the AWR report Parse Failures are recorded in two places:
1. Time Model Statistics failed parse elapsed time
2. XXX Instance Activity Stats 中的parse count (failures) 正常情况失败的SQL解析很少,只有某些应用程序出现问题,才会出现较多的失败的解析SQL。
1.3 定位异常的程序
1)定位执行解析失败SQL的文本
开启event 10035,每个实例都需要执行,开启后,DB ALERT会输出SQL文本
正常情况下11g版本无法查询失败的SQL文本,SQL_ID 可以通过session event library cache lock等可能查询到,解析都失败了,因此文本并不会被记录。
ALTER SYSTEM SET EVENTS '10035 trace name context forever, level 1'; ALTER SESSION SET EVENTS '10035 trace name context forever, level 1'; EVENT="10035 trace name context forever, level 1" Levels: level 1+ Print out failed parses of SQL statements to Note: The event can be turned off as follows: ALTER SYSTEM SET EVENTS '10035 trace name context off'; ALTER SESSION SET EVENTS '10035 trace name context off';
2)根据OSPID定位数据库执行错误SQL的机器、程序、用户【如果能从v$session层面快速定位可以跳过这个步骤】
When the event is set,any statement that fails to parse as a result of an error, will be documented in the alert.log, together with the error number and the process OSPID as displayed below
Mon Aug 29 09:48:24 2011
select empid from emp
1.4 问题处理
1) 以前遇到的问题再次进行记录:
Oracle数据库中实际的用户名,由于PB初次连接到数据库时要自动建立五个系统表(PowerBuilder Catalog Table:PBCATTBL,PBCATCOL,PBCATEDT,PBCATFMT,PBCATVLD,
存储表的扩展属性),因此第一个连接到Oracle的用户必须具有建表、给PUBLIC角色授权等权限。例如可用SYSTEM用户进行第一次连接,此后的连接对用户则无特殊要求;
对于如下的错误SQL,开发人员最初也是不承认自己的代码有的,后续发现是PowerBuilder工具连接Oracle第一次连接时后台自动创建这些对象,
如果第一次连接没有创建system用户下表的权限,后续通过SQL调用执行查询后台会一直查询system.某个表,最终导致报错SQL累计异常。
2)权限问题,开发测试环境无异常;
生产环境权限有要求,开发用户无访问某些对象的权限,因此后台其实一直解析失败,确认后重新授权即可。
1.5 一般这种情况数据库会出现什么样的等待事件呢?
可能性1) 数据库出现大量library cache lock 以及少量的cursor : pin S wait on X
可能性2)数据库出现大量library cache lock 被library cache: mutex X 阻塞
通过V$SQL 无法查询 sql_id对应的文本时! SQL执行太快,或者SQL根本没有执行成功。可以使用oradebug 获取current sql_text.
SQL> oradebug setmypid
SQL> oradebug unlimit
SQL> oradebug setinst all
SQL> oradebug -g def hanganalyze 3;
SQL>oradebug tracefile_name
1.6 Oracle的改进
1)无法立即定位问题,并且修改应用程序,可以考虑设置参数,重启库,目的是减少解析错误消耗的资源
Parse errors are syntax error and needs to be verified from application team. High CPU and Library Cache Contention A high number of invalid (syntactically incorrect) SQL can result in high CPU and library cache contention. Ideally, the solution is to
fix the application to issue valid SQL. However, as a temporary workaround, it is possible to set _cursor_features_enabled in order to ease the effect of the incorrect parsing. When set the parse error is recorded in a table SQLERROR$ which is checked so that repeated attempts to parse syntactically or semantically
invalid statements will not continually incur the full costs associated with hard parsing. In order to enable this workaround,add 32 to the current value of _cursor_features_enabled. For Example: The default value of _cursor_features_enabled = 2. In order to enable the fix set _cursor_features_enabled to 2 + 32. _cursor_features_enabled is not dynamic and requires a restart: SQL> show parameter _cursor_features_enabled NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ _cursor_features_enabled integer 32 SQL> alter system set "_cursor_features_enabled" = 34 scope=spfile; System altered. After restarting the database certain (not all) parse errors for non-SYS users will be recorded in sqlerror$. The following notes include information on the necessary fixes to enable this feature. These fixes are included in 112.0.4
and 12.1.0.1
大量无效(在语法上不正确)的SQL可能导致较高的CPU和库高速缓存争用。理想情况下,解决方案是修复应用程序以发出有效的SQL。
但是,作为临时的解决方法,可以设置_cursor_features_enabled,以减轻错误分析的影响。
设置分析错误后,将在表SQLERROR $中记录该错误,将对其进行检查,以便反复尝试分析语法或语义上无效的语句将不会持续产生与硬分析相关的全部费用。
重新启动数据库后,非SYS用户的某些(不是全部)解析错误将记录在sqlerror $中。【谷歌翻译】
2)新版本12.2 无需设置参数,Alert会打印解析错误的信息。