千家信息网

使用python进行Oracle数据库性能趋势分析

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,一、 概述随着信息系统业务需求快速增长,业务系统关联日益复杂,信息系统性能问题逐渐突显,一旦出现信息系统性能问题及不可用问题,将严重影响信息系统的稳定运行及用户体验。结合运维实践,数据库性能问题是造成
千家信息网最后更新 2025年02月01日使用python进行Oracle数据库性能趋势分析

一、 概述



随着信息系统业务需求快速增长,业务系统关联日益复杂,信息系统性能问题逐渐突显,一旦出现信息系统性能问题及不可用问题,将严重影响信息系统的稳定运行及用户体验。

结合运维实践,数据库性能问题是造成信息系统性能下降和非停的重要原因之一,如何进行常态化的数据库性能趋势分析,及时发现数据库性能衰减"病灶",常态化提升信息系统性能,避免救火式性能优化,成为衡量信息系统管理部门运营能力的重要指标之一。

二、研究目标



使用python语言进行Oracle数据库性能趋势分析。

三、工具介绍



开发语言:python 2.7

数据库:Oracle 11.2.0.4

Web框架:Django

图形展示工具:echart

四、算法介绍



核心算法由运行可靠率、资源竞争率、进程等待率和SQL稳定率四部分组成,如下图所示,本文主要以SQL稳定率为例:

Trend =100-100*sum(( c_time-h_time) /h_time)

说明:

Trend: 表示信息系统性能趋势(%)

c_time: 前一小时SQL平均执行时间()

h_time: 3个月内SQL平均执行时间()

五、效果展示



(1)、系统性能趋势:


(2)TOPSQL性能趋势分析


(3)TOPSQL日性能趋势分析


(4)TOPSQL月性能趋势分析


六、核心代码



核心代码分为数据采集层、数据转换层、web展示层。

(1)、数据采集层:


点击(此处)折叠或打开

  1. def get_topsql_info(username,password,ip,port,dbname,c_type,param=0,b_param=0):

  2. s_top10 = ''

  3. #s_snap_id = 0

  4. print oracle_link_target



  5. if c_type == 'sql_topsql':

  6. sql_topsql="

  7. select round(Elapsed_Time, 2) Elapsed_Time,

  8. round(cpu_time, 2) cpu_time,

  9. Executions,

  10. round(elap_per_exec, 2) elap_per_exec,

  11. round(total_db_time, 2) total_db_time,

  12. sql_id,

  13. substr(nvl(sql_module, ' ** SQL module Not Available ** '), 1, 30) sql_module,

  14. sql_text

  15. from (select nvl((sqt.elap / 1000000), to_number(null)) Elapsed_Time,

  16. nvl((sqt.cput / 1000000), to_number(null)) CPU_Time,

  17. sqt.exec Executions,

  18. decode(sqt.exec,

  19. 0,

  20. to_number(null),

  21. (sqt.elap / sqt.exec / 1000000)) Elap_per_Exec,

  22. (100 *

  23. (sqt.elap /

  24. (SELECT sum(e.VALUE) - sum(b.value)

  25. FROM DBA_HIST_SYS_TIME_MODEL e, DBA_HIST_SYS_TIME_MODEL b

  26. WHERE B.SNAP_ID = "+str(b_param)+"

  27. AND E.SNAP_ID = "+str(param)+"

  28. AND B.DBID = (select dbid from v$database)

  29. AND E.DBID = (select dbid from v$database)

  30. AND B.INSTANCE_NUMBER =

  31. (select instance_number from v$instance)

  32. AND E.INSTANCE_NUMBER =

  33. (select instance_number from v$instance)

  34. and e.STAT_NAME = 'DB time'

  35. and b.stat_name = 'DB time'))) Total_DB_Time,

  36. sqt.sql_id,

  37. to_char(decode(sqt.module,

  38. null,

  39. null,

  40. 'Module: ' || sqt.module)) SQL_Module,

  41. nvl(to_char(substr(st.sql_text, 1, 30)),

  42. ' ** SQL Text Not Available ** ') SQL_Text

  43. from (select sql_id,

  44. max(module) module,

  45. sum(elapsed_time_delta) elap,

  46. sum(cpu_time_delta) cput,

  47. sum(executions_delta) exec

  48. from dba_hist_sqlstat

  49. dba_hist_sqltext st

  50. where st.sql_id(+) = sqt.sql_id

  51. order by nvl(sqt.elap, -1) desc, sqt.sql_id)

  52. where rownum < 100

  53. "

  54. elif c_type == 'top10':

  55. #a list of top10: m_top10

  56. m_top10=get_hsql_info(t,'top10')



  57. #after get top10



  58. #end get top10

  59. for h_sql_id in m_top10:

  60. l_sql_id = h_sql_id[0]

  61. s_top10 = s_top10+",'"+l_sql_id+"'"

  62. s_top10 = s_top10.strip(',')

  63. sql_hsql_top10="select sql_id,to_char(substr(sql_text,1,2000)) sql_text,length(sql_text) sql_length,command_type from dba_hist_sqltext t where t.sql_id in ("+s_top10+')'

  64. else:

  65. cmd=sql_tablespace



  66. #print s_top10

  67. #print log_cmd_i



  68. cmd =""

  69. if c_type == 'sql_topsql':

  70. cmd=sql_topsql

  71. elif c_type == 'top10':

  72. cmd=sql_hsql_top10

  73. else:

  74. cmd=sql_tablespace

  75. #print len(m_top10)



  76. print 'before get topsql exe sql: '

  77. print cmd

  78. print 'get db shell: '

  79. conn = cx_Oracle.connect(oracle_link_target)

  80. cursor = conn.cursor()

  81. cur = cursor.execute(cmd)

  82. db_list = cur.fetchall()

  83. #print 'before return db_list'

  84. #print db_list

  85. return db_list



  86. cursor.close()

  87. conn.close()


(2)、数据转换层


点击(此处)折叠或打开

  1. select row_number() over(partition by ip order by to_number(total_db_time) desc) rn,

  2. ip,

  3. db_name,

  4. sql_id,

  5. decode(elap_per_exec, '0', 0.01, elap_per_exec) elap_per_exec,

  6. decode(elap_avg_exec, '0', 0.01, elap_avg_exec) elap_avg_exec,

  7. decode(sign(decode(elap_avg_exec, '0', 0.01, elap_avg_exec) - decode(elap_per_exec, '0', 0.01, elap_per_exec)),

  8. 1,

  9. 'up',

  10. -1,

  11. 'down',

  12. 'equ') sql_status,

  13. round((decode(elap_avg_exec, '0', 0.01, elap_avg_exec) -

  14. decode(elap_per_exec, '0', 0.01, elap_per_exec)) /

  15. decode(elap_avg_exec, '0', 0.01, elap_avg_exec),

  16. 2) sql_cont,

  17. executions,

  18. total_db_time,

  19. substr(sql_module, 1, 12) sql_module,

  20. substr(sql_text, 1, 12) sql_text,

  21. ch_date

  22. from (select rownum rn,

  23. d.ip,

  24. d.db_name,

  25. d.sql_id,

  26. replace(d.elap_per_exec, 'None', 0) elap_per_exec,

  27. e.elap_avg_exec,

  28. d.executions,

  29. d.sql_module,

  30. d.sql_text,

  31. d.ch_date,

  32. d.total_db_time

  33. from hsql.h_topsql d,

  34. (select b.ip,

  35. b.sql_id,

  36. round(avg(replace(b.elap_per_exec, 'None', 0)),

  37. 2) elap_avg_exec

  38. from hsql.h_topsql_bak b

  39. group by b.ip, b.sql_id) e

  40. where d.sql_id = e.sql_id

  41. and d.ip = e.ip)));


(3)web展示层


点击(此处)折叠或打开

  1. def topsql_line_servlet(request):

  2. cursor = conn.cursor()

  3. query = "select ip,

  4. (select service_name

  5. from hsql.h_instance h

  6. where h.ip = b.ip

  7. and rownum = 1) service_name,

  8. sql_id,

  9. executions,

  10. elap_per_exec,

  11. to_char(ch_date, 'hh34:mi') sj,

  12. to_char(ch_date, 'yyyy-mm-dd') rq

  13. from hsql.h_topsql b

  14. where ch_date > trunc(sysdate)

  15. order by sj"



  16. print query

  17. cursor.execute(query)

  18. resultset = cursor.fetchall()

  19. cursor.close()

  20. conn.close()


七、总结



通过Oracle性能趋势分析工具的应用可以进行细粒度的数据库性能管理,及时发现潜在的信息系统性能衰减隐患,通过持续性、常态化的信息系统性能优化,优化信息系统提升,提升用户体验。
0