一个很小的系统为什么负载那么高?

开发 前端
整体看还好(多核CPU可能会出现db time >100%),但是top1的等待是SQL*Net break/reset to client ,通常出现在数据库与客户端之间的通信过程中。当客户端请求中断当前操作("break")或重置它们之间的连接状态("reset")时,就会触发此等待事件,而这个等待事件和前面的logons过多相契合。

最近帮朋友优化一个系统,基本的情况如下:虚拟机,centos7.9,oracle 11.2.0.4,MES系统,数据量<50GB,日常session数不足100;按说这应该是一个负载很低的系统,但是用户却反映系统CPU经常使用率超过60%,偶尔还会有cpu满载的情况,导致系统卡顿,下面我们来根据一个AWR来看看是怎么回事?

1.首先是load profile

可以看到每秒钟logon达到280个,这个不正常,一般的系统来说这个值应该不超过50;另外每秒执行的sql数达到8200多次,这对于一个session数不足100的系统来说也是不正常的

图片图片

2.系统的平均CPU使用率和系统负载不匹配

图片图片

3.看系统的foregroud wait event

整体看还好(多核CPU可能会出现db time >100%),但是top1的等待是SQL*Net break/reset to client  ,通常出现在数据库与客户端之间的通信过程中。当客户端请求中断当前操作("break")或重置它们之间的连接状态("reset")时,就会触发此等待事件,而这个等待事件和前面的logons过多相契合。

图片图片

4.看sql的执行次数

这些sql都和用户的logon有关,有系统后台的,也有前台的应用的。1小时100万次,平均下来每秒278次和前面load profile的logons 282次契合,也就是说该系统1小时内执行了100万次登录操作,total的执行次数约为2500万次,平均每秒约6945,而整个数据库每秒的执行sql数为8254,6945/8254=84%,也就是差不多系统85%的资源都是在处理登陆操作,怪不得一个看似很小的系统有这么大的负载。

图片图片

5.数据库登陆会执行哪些后台sql

从AWR中可以看出每次登陆会执行五次

sql_id:cm5vu20fhtnq1
select /*+ connect_by_filtering */ privilege#, level from sysauth$ connect by grantee#=prior privilege# and privilege#>0 start with grantee#=:1 and privilege#>0

前台应用sql每次登陆执行2次,why?就为了取个0?

SELECT '0' FROM DUAL

其他的均是每次登陆执行一次;

根据官方文档(Doc ID 730066.1)记录,每次用户登陆数据库需要执行如下认证sqlAuthentication SQL

When a database session is in the authentication phase, it will issue a sequence of SQL statements. The authentication is not complete until all these are parsed, executed, fetched completely. Some of the SQL statements in this list e.g. on 10.2 are:

10G是如下:

1.select value$ from props$ where name = 'GLOBAL_DB_NAME';


2.select privilege#,level from sysauth$ connect by grantee#=prior privilege# ;
and privilege#>0 start with grantee#=:1 and privilege#>0


3.select SYS_CONTEXT('USERENV', 'SERVER_HOST'), SYS_CONTEXT('USERENV', 'DB_UNIQUE_NAME'),
SYS_CONTEXT('USERENV', 'INSTANCE_NAME'), SYS_CONTEXT('USERENV', 'SERVICE_NAME'), 
INSTANCE_NUMBER, STARTUP_TIME, SYS_CONTEXT('USERENV', 'DB_DOMAIN') 
from v$instance where INSTANCE_NAME=SYS_CONTEXT('USERENV', 'INSTANCE_NAME')


4.select privilege# from sysauth$ where (grantee#=:1 or grantee#=1) and privilege#>0


5.ALTER SESSION SET NLS_LANGUAGE= 'AMERICAN' NLS_TERRITORY= 'AMERICA' NLS_CURRENCY= '$'
NLS_ISO_CURRENCY= 'AMERICA' NLS_NUMERIC_CHARACTERS= '.,' NLS_CALENDAR= 'GREGORIAN'
NLS_DATE_FORMAT= 'DD-MON-RR' NLS_DATE_LANGUAGE= 'AMERICAN' NLS_SORT= 'BINARY' TIME_ZONE= '+02:00'
NLS_COMP= 'BINARY' NLS_DUAL_CURRENCY= '$' NLS_TIME_FORMAT= 'HH.MI.SSXFF AM' NLS_TIMESTAMP_FORMAT=
'DD-MON-RR HH.MI.SSXFF AM' NLS_TIME_TZ_FORMAT= 'HH.MI.SSXFF AM TZR' NLS_TIMESTAMP_TZ_FORMAT=
'DD-MON-RR HH.MI.SSXFF AM TZR'

11g 部分没有找到官方文档记录,但是从AWR上可以看出是如下变化

去掉了alter session 部分,一个查询加了hint,其他并无太大变化,19c部分没有验证,应该变化不大。

1.select value$ from props$ where name = 'GLOBAL_DB_NAME';


2.select /*+ connect_by_filtering */ privilege#, level from sysauth$ connect by grantee#=prior privilege# and privilege#>0 start with grantee#=:1 and privilege#>0


3.select SYS_CONTEXT('USERENV', 'SERVER_HOST'), SYS_CONTEXT('USERENV', 'DB_UNIQUE_NAME'),
SYS_CONTEXT('USERENV', 'INSTANCE_NAME'), SYS_CONTEXT('USERENV', 'SERVICE_NAME'), 
INSTANCE_NUMBER, STARTUP_TIME, SYS_CONTEXT('USERENV', 'DB_DOMAIN') 
from v$instance where INSTANCE_NAME=SYS_CONTEXT('USERENV', 'INSTANCE_NAME')


4.select privilege# from sysauth$ where (grantee#=:1 or grantee#=1) and privilege#>0

6.前台用户登陆操作有查询  NLS_SESSION_PARAMETERS 动作,是否可以一次查询,而不用十几个查询分别来做。

c1nhutgsysm77  SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER='NLS_DATE_FORMAT'
c8mv956mdm6vg  SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER='NLS_NUMERIC_CHARACTERS'
c9u3k174kj69m  SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER='NLS_ISO_CURRENCY'
9d0cthfsv43bt  SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER='NLS_TIMESTAMP_TZ_FORMAT'
9zhaas4q6s24t  SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER='NLS_COMP'
a0db07j0jdcrw  SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER='NLS_LENGTH_SEMANTICS'


综上,根据awr分析提出三点优化建议

  1. 修改应用登陆模式,没有必要执行一次操作就断开一次连接,然后再重新登陆,这样消耗了大量的系统资源,建议修改应用端登陆模式,一次登陆一直使用,直到连接失败再重新连接;

2. 修改系统profile IDLE_TIME 为unlimited;

alter profile default limit idle_time unlimited;

3. 重新审视检查NLS_SESSION_PARAMETERS 参数机制是否合理,是否可以一次查询解决

参考文档:Troubleshooting ORA-3136 Connection Timeouts Errors - Database Diagnostics (Doc ID 730066.1)

责任编辑:武晓燕 来源: 潇湘秦
相关推荐

2023-11-07 15:11:46

Kafka技巧

2023-11-20 17:38:07

Djangoagtailadmin

2020-07-29 08:06:30

Kafka MQ消息

2023-06-08 18:25:40

Doris场景查询

2014-12-30 10:05:42

操作系统

2014-02-11 10:09:37

中小企业UC

2023-09-08 08:10:48

2023-09-08 08:22:30

2022-04-29 08:00:06

Linux目录网络

2021-06-09 09:32:58

Esbuild 工具前端

2020-08-03 07:50:56

存储对象存储

2016-01-28 10:04:09

Jenkins运维持续交付

2012-09-03 09:52:39

虚拟化

2013-09-05 09:15:29

云安全

2021-04-28 08:52:22

高并发架构设高并发系统

2022-03-03 08:02:55

数据集成平台

2013-09-04 16:27:23

云计算安全云安全

2017-03-25 21:32:40

Python编码

2009-06-16 14:43:23

大型网站系统架构

2011-08-30 09:45:27

程序员
点赞
收藏

51CTO技术栈公众号