《Oracle数据库性能优化方法论和最佳实践》——3.2 数据库登录流程的相关指标与优化-阿里云开发者社区

开发者社区> 华章出版社> 正文
登录阅读全文

《Oracle数据库性能优化方法论和最佳实践》——3.2 数据库登录流程的相关指标与优化

简介:

本节书摘来自华章计算机《Oracle数据库性能优化方法论和最佳实践》一书中的第3章,第3.2节,作者:柳遵梁 潘敏君 应以峰著,更多章节内容可以访问云栖社区“华章计算机”公众号查看

3.2 数据库登录流程的相关指标与优化

2.6节已经介绍过数据库登录流程的分解如下:
Step 1:客户端登录请求。
Step 2:listener处理和响应。
Step 3:服务进程派生。
Step 4:进程初始化和session初始化。
Step 5:用户验证和权限判断。
Step 6:session审计。
Step 7:登录触发器。
Step 8:响应客户端。
对于数据库登录流程来说,业务需求表述的输入请求和技术层面的输入请求完全一致。每次数据库登录都对应着一次客户端登录请求,输出响应时间自然就是数据库登录流程的响应时间了。
3.2.1 数据库登录流程的输入吞吐量和输出响应指标
1.?输入/输出指标
在实际可测量指标计算中,本书均以某个特定时间段作为测量的时间范畴。
测量范围基准。
begin time:开始时间。
end time:结束时间。
timeinterval:时间范围,单位为秒。
输入吞吐量指标。
logons:数据库登录次数。
logons per second:每秒数据库登录次数。
logons per second = logons / timeinterval。
输出响应指标。
logon response time:数据库登录响应时间。
logon response time per logon:每次数据库登录的平均响应时间。
logon response time per logon = logon response time / logons
从数据库登录流程的输入请求来看,数据库登录次数是一个比较合适的输入吞吐量压力指标,不管数据库登录是来自于客户端、database link、j2ee中间件还是其他中间件,不管是来自于odbc、jdbc还是oci的连接,其处理过程都没有本质的差异。
2.?logons输入吞吐量指标的测量
以下主要考虑如何获得logons和logons per second统计指标。
(1)系统启动以来的Logons输入指标
Oracle数据库的性能指标测量体系已经比较完备,对于logons,已经分别在15s、60s及基于AWR自定义快照和启动以来的总计等不同角度进行统计。
系统性能视图v$sysstat包含以下两个统计指标。
1)logons cumulative:自实例启动后的总登录次数,该统计包含成功验证登录和失败验证登录。
2)logons current:当前连接到实例的sessions。
我们可以用以下公式来计算logons输入指标。
logons = EndSnap. logons cumulative – StartSnap. logons cumulative
logons cumulative计算logons增量的代码如图3-1所示。

screenshot

(2)v$sysstat在AWR中的体现
Oracle AWR计算了v$sysstat,存储在wrh$_sysstat表格中。AWR依据快照时间间隔定义可以得到任意的时间范围数据,考虑到AWR的成本和准确性,AWR一般会把时间间隔设置在10min以上,图3-2即为从AWR表格中计算logons cumulative增量的代码。
(3)最近60s和最近15s的近实时的统计指标
Oracle在系统性能视图中提供了接近实时的指标统计。
v$metric:最近15s和60s的指标统计信息。
v$metric_history:最近1h的60s统计和最近3min的15s统计。
v$sysmetric:v$metric的子集合,仅统计15s和60s系统级别的信息。
v$sysmetric_history:v$metric_history的子集合,仅统计15s和60s系统级别的信息。
v$metric视图的信息如图3-3所示。
v$metric _history视图的信息如图3-4所示。
screenshot

screenshot

screenshot

(4)最近1小时的指标统计
v$sysmetric_summary在最近1小时范围内对v$sysmetric进行了归类操作,计算最大值、最小值和平均值等信息,如图3-5所示。
AWR也对v$sysmetric和v$sysmetric_summary进行了处理,包括wrh$_sysmetric和wrh$_sysmetric_summary表格,如图3-6所示。
screenshot
screenshot
screenshot

3.?输出响应指标的测量
以下主要讨论如何建立测量指标logon response time和logon response time per logon。通过实际的client、listener和server系统跟踪,可以大致明确数据库登录在各个阶段的输出时间响应指标的比例关系。
下面来看一个具体的数据库登录跟踪状况。
user进程开始工作的时间为:07:15:16:901。
user进程结束工作的时间为:07:15:17:234。
listener进程开始工作的时间为:07:15:16:923。
listener进程结束工作的时间为:07:15:17:072。
server进程开始工作的时间为:07:15:17:038。
server进程结束工作的时间为:07:15:17:232。
user进程的持续时间为:333ms,也是整个数据库登录流程的持续时间。
listener进程的持续时间为:149ms。
server进程的持续时间为:194ms。
从user进程或者用户的角度而言,大致工作流程的时间分布如下。
Step 1:读取配置文件,为发起listener连接申请做好预处理。
开始时间:07:15:16:901;
结束时间:07:15:16:923;
持续时间:22ms。
Step 2:ping listener。
开始时间:07:15:16:923;
结束时间:07:15:16:946;
持续时间:23ms。
Step 3:服务进程派生。
开始时间:07:15:16:949;
结束时间:07:15:17:066;
持续时间:117ms(注意在服务进程派生期间,用户进程处于等待状态)。
Step 4:完成client和server的握手。
开始时间:07:15:17:068;
结束时间:07:15:17:079;
持续时间:11ms。
Step 5:完成链路通信准备和相互注册。
开始时间:07:15:17:080;
结束时间:07:15:17:120;
持续时间:40ms。
Step 6:完成用户名发送和检验。
开始时间:07:15:17:123;
结束时间:07:15:17:136;
持续时间:13ms。
Step 7:完成密码传递、验证和session信息发送。
开始时间:07:15:17:136;
结束时间:07:15:17:160;
持续时间:24ms。
Step 8:完成权限判断和session初始化工作。
开始时间:07:15:17:164;
结束时间:07:15:17:234;
持续时间:70ms。
从上述描述可以看出,影响数据库登录流程效率主要来自以下几个方面。
网络来回开销,在client和server之间需要极为频繁的网络沟通。至少18个数据通信来回和2个握手来回。
服务进程派生和重新握手达到130ms,占整个时间的40%左右,有绝对的影响。
用户权限判断和session初始化也达到70ms,达到20%左右。
用户进程预处理在本地配置文件庞大的时候可能会遇到障碍。
(1)v$sys_time_model、v$sess_time_model视图和响应时间统计
v$sys_time_model作为Oracle响应时间分析最为核心的视图,提供了目前可以提供的各种时间响应和时间分解的统计值。从v$sys_time_model视图中显然无法区分出消耗的时间是消耗于数据库登录还是数据库访问,也就是说,无法从v$sys_time_model视图中获取logon response time,如图3-7所示。
v$sess_time_model视图记录了每个session的服务时间响应,虽然与v$sys_time_model一样,随着时间的推移,其服务时间响应将与数据库访问处理合并而无法区分,但可以通过logon trigger等手段来获取其中属于数据库登录处理的服务时间响应,如图3-8所示。
(2)session时间响应统计指标:connection management call elapsed time
connection management call elapsed time的时间响应的官方解释为:花费在执行会话连接和会话断开调用所消耗的时间,单位为微秒。在这个模糊的解释中,需要界定connection management call elapsed time具体计算的是哪些部分。
从众多的测试来看,不管连接来自于何方,包括TCP远程连接、TCP本地连接和本地IPC连接,connection management call elapsed time大致保持稳定。可以认为connection management call elapsed time不包含客户端处理、Listener处理和服务进程的派生时间。从后续的权限集合、Session Aduit以及Logon Trigger测试来看,connection management call elapsed time至少包含了session建立之后的所有非空闲时间。从audses$的测试可以看出,connection management call elapsed time应该包含数据库session初始化过程;从DB time和connection management call elapsed time的差异来比较,可以认为connection management call elapsed time不包含进程信息初始化的过程和用户密码最后验证的过程。
screenshot
screenshot

connection management call elapsed time的时间响应计算方式是:从数据库session建立到登录验证结束阶段的流程响应时间(非空闲时间),注意其中不包含返回客户端的响应时间。该指标可以很好地描述在数据库登录过程中,数据库内部发生的流程和执行的操作。从测试来看,connection management call elapsed time的时间响应变化基本在5~10ms之间(不包含session audit和logon trigger)。connection manaement call elapsed time的统计值如图3-9所示。
screenshot

(3)session时间响应指标:DB time
DB time的计算显然不可能包含客户端响应和listener处理时间,关键需要确认是否包含服务进程派生过程。可以通过简单比较本地TCP连接和本地IPC连接来确定DB time的组成,本地IPC连接不包含进程派生时间,仅包含进程初始化过程。本地IPC连接的DB time和DB CPU统计如图3-10所示。

screenshot

本地TCP连接的DB time和DB CPU统计如图3-11所示。
screenshot

我们无法判断这两者之间的区别,并且可以看到DB CPU在本地IPC连接中DB CPU很有可能会大于DB time。在本书中,我们采用以下时间响应描述。
DB time:从进程初始化开始的数据库登录流程。
DB CPU:DB CPU的计算包含了进程派生过程。
DB time的本地TCP连接和IPC连接的时间响应范围多数在10~30ms之间(不包含Session Audit和Logon Trigger)。
(4)数据库登录流程实际响应时间
无论是DB time、DB CPU还是connection management call elapsed time,都不包含空闲等待事件,从本质上来看,DB time的计算还是从CPU的观点来看待问题,而不是从流程的观点来看待问题的。正是因为看待问题的角度不同,产生了数据库登录流程的实际响应时间与DB time产生了比较大的差异。从多次的测试来看,本地连接的时间响应基本在110ms以上,很少会超过150ms,远程连接基本在150ms以上,很少会超过220ms。
实际响应时间和DB time的比较(sesstime1.sql)描述如下。
远程TCP连接。

         DB time = 43.014ms
         Idle time = 51.952ms

Real elapsed time = 170ms
本地TCP连接。

         DB time = 26.442ms
         Idle time = 30.073ms

Real elapsed time = 130ms
本地IPC连接。

         DB time = 24.496ms
         Idle time = 32.363ms

Real elapsed time = 130ms
sesstime1.sql脚本代码如下:

set serverout on
var v1 number;
var v2 number;
var v3 number;
var v4 number;
connect system/oracle@172.16.8.3:1521/jason
begin
  :v1:=dbms_utility.get_time;
end;
/
connect system/oracle@172.16.8.3:1521/jason
set serverout on
begin
  :v2:=dbms_utility.get_time;
  select value into :v3 from v$sess_time_model where sid=sys_context('userenv','sid') and stat_name='DB time';
  select sum(time_waited_micro) into :v4 from v$session_event where sid=sys_context
('userenv','sid') and wait_class='Idle';
  dbms_output.put_line('DB time:='||:v3/1000||' ms'); 
  dbms_output.put_line('Idle time:='||:v4/1000||' ms'); 
  dbms_output.put_line('Real elapsed time:='||(:v2-:v1)*10||' ms');
end;
/

(5)session时间响应指标:DB time、session audit和logon trigger
可以通过session audit的触发器来衡量session audit的时间响应与DB time之间的关系。以下代码可以建立数据库登录审计,并且在aud$表格中建立触发器来衡量DB time和session audit的反应。

connect sys/oracle as sysdba
noaudit all;
truncate table sys.aud$;
create table system.aud$ as select * from sys.aud$;
drop table sys.aud$;
create synonym sys.aud$ for system.aud$;
create table locka(id number);
insert into locka values(100);
commit;
create or replace trigger iaudtrig before insert on system.aud$
declare
begin
update locka set id=300;
end;
/
Alter system set audit_trail=DB scope=spfile;
Startup force
Audit Session;
Delete from locka;
Declare
L_n number;
begin
l_n:=dbms_pipe.receive_message('p0',30);  --延迟30s
end;
/
Rollback;

sesstime1.sql进行验证响应的结果如下,显然DB time中包含了session audit时间。

         DB time = 20967.444ms
         Idle time = 107.607ms

Real elapsed time = 21770ms
下面再来看logon trigger是否也是同样的情形,使用disable session audit语句创建logon trigger。

Noaudit all;
create or replace trigger logontrig 
after logon on database
declare
begin
update sys.locka set id=500;
end;
/
Declare
L_n number;
Begin
Delete from sys.locka;
L_n:=dbms_pipe.recieve_message('p0',30);
Rollback;
End;
/

再次用sesstime1.sql进行验证,很明显,DB time包含了logon trigger的运行时间。

         DB time = 21?712.469ms
         Idle time = 124.371ms

Real elapsed time = 22570ms
3.2.2 输入压力与输出响应之间的关系
1.?输入压力与输出响应之间关系的测试
回顾数据库登录流程的处理过程和输出响应指标。
这里已经明确获得了两个输出响应指标:DB time和connection management call elapsed time,分别描述了logon response time的一部分。再来看看随着输入压力的持续增大,输出响应时间会有什么样的反应:logon response time、DB time和connection management call elapsed time。
这里用sesstime2.sh来进行输入压力模拟:

echo "connect system/oracle@192.168.0.21:1521/ora10g" > dbtime.sql
echo "select stat_name,value from v\$sess_time_model where sid=sys_context('userenv','sid') and stat_name in('DB time','DB CPU','connection management call elapsed time');" >> dbtime.sql
echo "exit">> dbtime.sql
a=1
while [ $a -lt 500 ] 
do
  sqlplus -s /nolog @dbtime.sql > out$a.log &
  a='expr $a + 1'
done

下面来看上述运行的典型值:

STAT_NAME                        VALUE
---------------------------------------- ----------
DB time                         200205
DB CPU                         12556
connection management call elapsed time        198423
EVENT                   TIME_WAITED_MICRO
------------------------------ -----------------
latch: library cache                 22825
SQL*Net message from client            160129

connection management call elapsed time从常规的5~10ms增长到了198ms,DB time从常规的10ms增长到了200ms。从DB CPU和wait event可以看出,DB time和connection management call elapsed time的增长贡献与数据库操作本身没有太大关系,主要贡献来源于短时间内有大量的进程同时派生,导致CPU无法及时处理进程派生和进程初始化,尤其是进程派生过程中包含了派生进程和listener之间的握手。
下面用tnsping来测试listener的输入:

a=1
  while [ $a -lt 500 ] 
  do
tnsping 192.168.0.21:1521/ora10g > tnsping.$a &
a='expr $a + 1'
done

在大量的tnsping压力下,listener的处理能力并没有发生大的变化,主要原因在于tnsping并不需要派生服务进程,从而使tnsping命令可以被快速处理。但是当有大量服务进程派生的时候,listener进程服务需要不断与服务进程进行握手。由于服务进程响应缓慢,导致listener的服务队列很快撑满,从而使listener处理能力大幅度下降。比如,在高压力的listener运行下,tnsping的反应如下:

C:\Users\LiuZL>tnsping 192.168.0.21:1521/ora10g
TNS Ping Utility for 64-bit Windows: Version 11.2.0.1.0 - Production on 16-APR-2
014 23:38:37
Copyright (c) 1997, 2010, Oracle.  All rights reserved.
Used parameter files:
F:\Oracle\product\10.2.0\client\sqlnet.ora
Used HOSTNAME adapter to resolve the alias
Attempting to contact (DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=ora10g))(ADDRESS=
(PROTOCOL=TCP)(HOST=192.168.0.21)(PORT=1521)))
OK (2440 msec)

2.?数据库登录流程输入/输出响应指标的确定
从输入压力和输出响应之间关系的测试可以知道,DB time和connection management call elapsed time可以很好地反映数据库登录的输入压力,尤其是connection management call elapsed time反映数据库登录的专业描述,后续的业务访问并不会增加该指标值。connection management call elapsed time反映了登录流程的进程(session)初始化和数据库内部操作,而tnsping的响应速度慢则反映了服务进程派生缓慢导致的问题。显然,两者结合就可以判断数据库登录流程在哪个环节出现了问题。
最终,数据库登录流程可以由以下主要指标构成。
以下是输入指标:
logons:合计登录次数。
logons per second:每秒数据库登录次数。
以下是输出指标:
connection management call elapsed time:关键数据库连接管理时间的消耗。
DB time:辅助数据库连接管理时间的消耗,可以不记录。
listener response time:衡量listener的处理能力,利用tnsping获得。
network response time:衡量网络的响应能力,利用ping获得。
network wait time:衡量网络和客户端的响应能力,利用事件等待获得。
client request time:客户端预处理时间,目前不可衡量。
整体的logon response响应时间可以用公式大致描述如下:
logon response time = client request time + network response time × 6
          + listener response time + DB time(connection management call elapsed time)
          + network wait time
由于在需要优化的时候,logon response time会成为一个已知值,在只有一个未知client request time的情况下,client request time就成为一个可以推算的值,我们自然可以依据上述公式来判断数据库登录流程在哪个环节出现了问题才会导致数据库登录缓慢。
可以通过logon response time的变种来简化数据库登录流程的性能优化:
logon response time = Network Response Time × 10 + Native TCP Logon
        = Network Response Time × 10 + Listener Response Time + Native IPC Logon Time
3.?listener.log和数据库登录流程输入压力
有时候可能会缺乏对应输入压力(logons per second)的数据,Oracle listener组件的日志提供了细节性的感性认知数据。可以用cat listener.log|grep CONNECT_DATA过滤文件内容,得到listener连接数据,代码如下

12-FEB-2014 09:01:56 * (CONNECT_DATA=(SERVICE_NAME=jason)(CID=(PROGRAM=D:\Program?Files\HP\LoadRunner\bin\mmdrv.exe)(HOST=LIGUOFEN)(USER=liguofen))) * (ADDRESS=(PROTOCOL=tcp)(HOST=172.16.4.112)(PORT=4826)) * establish * jason * 0
12-FEB-2014 09:01:56 * (CONNECT_DATA=(SERVICE_NAME=jason)(CID=(PROGRAM=D:\Program?Files\HP\LoadRunner\bin\mmdrv.exe)(HOST=LIGUOFEN)(USER=liguofen))) * (ADDRESS=(PROTOCOL=tcp)(HOST=172.16.4.112)(PORT=4827)) * establish * jason * 0
12-FEB-2014 09:01:56 * (CONNECT_DATA=(SERVICE_NAME=jason)(CID=(PROGRAM=D:\Program?Files\HP\LoadRunner\bin\mmdrv.exe)(HOST=LIGUOFEN)(USER=liguofen))) * (ADDRESS=(PROTOCOL=tcp)(HOST=172.16.4.112)(PORT=4828)) * establish * jason * 0
12-FEB-2014 09:01:56 * (CONNECT_DATA=(SERVICE_NAME=jason)(CID=(PROGRAM=D:\Program?Files\HP\LoadRunner\bin\mmdrv.exe)(HOST=LIGUOFEN)(USER=liguofen))) * (ADDRESS=(PROTOCOL=tcp)(HOST=172.16.4.112)(PORT=4829)) * establish * jason * 0

显然,从文件中可以得到logons per second输入压力指标、数据库登录请求的主要源节点(IP地址和主机名),以及主要的应用程序等信息。
如果关心某个时间段的logons per second信息,也可以简单地通过listener service命令获得,通过established的值时间快照差计算获得logons per second:

[ora10205@mcdbatest log]$ lsnrctl service
LSNRCTL for Linux: Version 10.2.0.5.0 - Production on 18-APR-2014 08:25:51
Copyright (c) 1991, 2010, Oracle.  All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC0)))
Services Summary...
Service "PLSExtProc" has 1 instance(s).
  Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
    Handler(s):
      "DEDICATED" established:0 refused:0
         LOCAL SERVER
Service "jason" has 2 instance(s).
  Instance "jason", status UNKNOWN, has 1 handler(s) for this service...
    Handler(s):
      "DEDICATED" established:1 refused:0
         LOCAL SERVER
  Instance "jason", status READY, has 1 handler(s) for this service...
    Handler(s):
      "DEDICATED" established:0 refused:0 state:ready
         LOCAL SERVER
Service "jasonXDB" has 1 instance(s).
  Instance "jason", status READY, has 1 handler(s) for this service...
    Handler(s):
      "D000" established:0 refused:0 current:0 max:972 state:ready
         DISPATCHER <machine: mcdbatest, pid: 3585>
         (ADDRESS=(PROTOCOL=tcp)(HOST=mcdbatest)(PORT=2602))
Service "jason_XPT" has 1 instance(s).
  Instance "jason", status READY, has 1 handler(s) for this service...
    Handler(s):
      "DEDICATED" established:0 refused:0 state:ready
         LOCAL SERVER
Service "jyk" has 1 instance(s).
  Instance "jyk", status UNKNOWN, has 1 handler(s) for this service...
    Handler(s):
      "DEDICATED" established:0 refused:0
         LOCAL SERVER
The command completed successfully

4.?数据库登录流程输入/输出关系曲线图
下面先用以下脚本(sessiontime3.sh)收集数据:

echo "
  computetime(){
  echo "time \'date +%s\'"
  time -p echo exit|sqlplus -s system/oracle@192.168.0.21:1521/ora10g 
  }
  dispatchlogon(){
  sleepN=10
  pid=\$\$  
  while [ \$sleepN -gt 0 ] 
  do
    computetime
    sleep \$sleepN
    sleepN=\'expr \$sleepN - 1\'    
  done
}
dispatchlogon
" > dispatchlogon.sh
chmod +x dispatchlogon.sh
loop=0
while [ $loop -lt 100 ] 
do
  loop='expr $loop + 1'
  ./dispatchlogon.sh > out$loop.log 2>&1 &
Sleep 1

得到的并行logon和响应时间的关系图如图3-12所示。

screenshot

再用下面的脚本收集数据。

echo "
  computetime(){
  sqlplus -s system/oracle@192.168.0.21:1521/ora10g @tmpsql.sql 
  }
  dispatchlogon(){
  sleepN=10
  pid=\$\$  
  while [ \$sleepN -gt 0 ] 
  do
    computetime
    sleep \$sleepN
    sleepN=\'expr \$sleepN - 1\'    
  done
}
dispatchlogon
" > dispatchlogon.sh
chmod +x dispatchlogon.sh
loop=0
  echo "
        col stat_name format a40
        col op_time format a20
        set head off
        set linesize 120
        select to_char(sysdate,'yyyymmddhh24miss') optime,stat_name,value from v\$sess_
time_model where sid=sys_context('userenv','sid') and stat_name in('DB time','connection management call elapsed time');
        exit" > tmpsql.sql
while [ $loop -lt 100 ] 
do
  loop='expr $loop + 1'
  ./dispatchlogon.sh > out$loop.log 2>&1 &
  sleep 1
done

得到的并行logon输入和DB time的输出响应时间关系图如图3-13所示。

screenshot

以上数据是从笔者笔记本的虚拟机中获得的,由于资源有限,所以受到资源响应的冲击很大,但也基本反映了logon吞吐量和响应时间输出之间的关系。随着logon并行次数的增加,输出响应时间随之变大。
3.2.3 数据库登录流程响应问题的优化案例
1.?案例描述一:频繁短连接的业务系统
场景描述:某运营商电子运维系统(hp rx6600/Oracle 10.2.0.4)遭遇业务系统性能故障,几乎每1~2个星期就由于业务系统响应缓慢需要重新启动主机。主机可以进行远程拨号
访问。
优化过程:从描述来看,似乎这又是一个简单的HP-UX的交换空间缺省配置问题,拨号登录系统之后进行如下系统检查。
检查HP-UX交换空间配置,正常。
进入数据库检查,数据库处于轻载运行状态,唯一感觉有问题的就是logons偏高,达到每秒40多个。
回到操作系统检查,资源表现正常。
listener进程CPU占有率偏高,本地tnsping响应慢。
本地IPC连接响应很快,本地TCP连接响应缓慢。
检查netstat输出,发现较多的time_waited连接,表示存在着大量频繁退出的连接,与数据库内部logons偏高一致。
检查listener.log,每秒产生大量的连接,几乎所有的连接都来自于中间件服务器。
告知用户检查中间件连接池,估计是连接池参数配置不当或者没有使用连接池所引起的。
用户咨询开发人员之后确认,系统没有采用连接池管理。
优化结论和改善如下。
本系统显然是一个轻载型系统,偶尔的高并发性业务导致业务系统性能故障。
短连接的业务响应时间包含了数据库连接过程。
改变短连接为连接池管理。
如果在开发人员完成连接池管理之前遇到类似问题,大多数情况下(非持续性高压力访问),可以通过重新启动listener而不是重启主机解决。
2.?案例描述二:连接池参数设置不当
场景描述:某工商局业务系统间歇性表现为业务系统性能不佳,在持续的卡壳之后可以自我恢复。自我性能恢复似乎与业务系统吞吐量并没有太大的关系。
优化过程如下。
检查典型时段的AWR报告,显然数据库处于轻载运行状态。
排除数据库问题,业务性能缓慢应该是由连接池管理问题引起。
用户检查连接池,在问题出现的时候往往空闲连接池的数量很少。
考虑到用户业务系统性能与业务系统吞吐量高低并没有直接关系,似乎不是中间件的bug或者其他系统性障碍。
让用户检查中间件活动连接增长状况和min-max配置。
连接池参数配置为min = 5,max = 500,常规活动状况为30左右。
综合来看,应该是连接池配置管理不当引起的,设置min = 100。
优化结论和改善如下。
由于connection pool的最小连接池参数设置过小,所以连接池管理不断释放可用连接,导致后续业务无法从connect pool中获得连接,需要进行动态扩张。
频繁的动态扩张连接,使业务系统响应包含了数据库登录过程,导致业务系统反应
缓慢。
检查增加连接池管理,使最小连接到合适的大小即可。
建议中间件连接池的最小连接和最大连接的参数保持相同,避免动态扩展和回收。
建议以连接池管理综合硬件能力和业务需求来进行设置,而且以硬件能力为主,业务需求辅助。
3.?案例描述三:数据库登录sequence cache不足导致数据库登录缓慢
场景描述:某医院HIS业务系统的账户登录操作异常缓慢,部分情况下甚至会出现长时间的卡壳,业务影响主要发生在每天早上的上班时刻。
优化过程如下。
账户登录过程一般涉及在账户表格以及对应日志表格上的冲突,比如buffer busy waits或者TX lock,AWR未体现该特征。
AWR报告显示connection management call elapsed time时间偏长,sequence load elapsed time具有一个明显偏大的值。
即使在经常发生性能问题的上班时刻,tnsping的表现也相对比较正常,说明Listener处理正常。
检查sequence audses$的cache设置,发现该值为20,与早上上班的高峰期数据库登录有些不匹配,增加audseq$的cache值到10?000。
优化结论和改善如下。
sequence audses$的cache大小不足是导致数据库登录响应缓慢的主要原因。一般情况下,该值在20时并不会产生问题,只有在大量高并发登录的时候才会有问题。
修改sequence audses$的cache值为10?000,以支持同一时间段的大批量数据库登录。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:

华章出版社

官方博客
官网链接