Oracle AWR裸数据提取-Tablespace io指标发现的Bug

近日,梳理并确认Oracle数据库历史数据收集SQL有效性与正确性是发现了一个异常的现象,利用如下SQL采集数据库tablespace io相关统计信息时发现,AWR中1-bk Rds/s指标数据却与SQL裸数据提取的Writes数据完全一致。

AWR报告结果

20200105-1

SQL裸数据提取结果:

20200105-2

可以看到,AWR数据中的1-bk Rds/s与Writes数据完全一致,但是1-bk Rds/s的含义应该是每秒发生的读取单个block的次数,然而Writes是通过dba_hist_filestatxs视图中提取PHYWRTS数据指标来实现的,这两个指标含义完全不一致,不可能这么产生如此的巧合。到底是哪里出的问题?并且1-bk Rds/s居然比Av Rds/s(RPS)还要大,这明显是不正常的现象。

AWR Tablespace IO Stats裸数据提取SQL:

with a as
 (select E.SNAP_ID,
         e.tsname tsname,
         sum(e.phyrds – nvl(b.phyrds, 0)) reads,
         round(sum(e.phyrds – nvl(b.phyrds, 0)) /
               (SELECT EXTRACT(DAY FROM
                               E.END_INTERVAL_TIME – B.END_INTERVAL_TIME) *
                       86400 + EXTRACT(HOUR FROM E.END_INTERVAL_TIME –
                                       B.END_INTERVAL_TIME) * 3600 +
                       EXTRACT(MINUTE FROM
                               E.END_INTERVAL_TIME – B.END_INTERVAL_TIME) * 60 +
                       EXTRACT(SECOND FROM
                               E.END_INTERVAL_TIME – B.END_INTERVAL_TIME)
                  FROM DBA_HIST_SNAPSHOT B, DBA_HIST_SNAPSHOT E
                 WHERE B.SNAP_ID =
                       (select max(snap_id) – 1 from dba_hist_sqlstat)
                   AND E.SNAP_ID =
                       (select max(snap_id) from dba_hist_sqlstat)
                   AND B.INSTANCE_NUMBER =
                       (select instance_number from v$instance)
                   AND E.INSTANCE_NUMBER =
                       (select instance_number from v$instance)
                   AND B.STARTUP_TIME = E.STARTUP_TIME
                   AND B.END_INTERVAL_TIME < E.END_INTERVAL_TIME),
               2) rps,
         round(decode(sum(e.phyrds – nvl(b.phyrds, 0)),
                      0,
                      0,
                      10 * (sum(e.readtim – nvl(b.readtim, 0)) /
                      sum(e.phyrds – nvl(b.phyrds, 0)))),
               2) atpr,
         round(decode(sum(e.phyrds – nvl(b.phyrds, 0)),
                      0,
                      0,
                      sum(e.phyblkrd – nvl(b.phyblkrd, 0)) /
                      sum(e.phyrds – nvl(b.phyrds, 0))),
               2) bpr,
         sum(e.phywrts – nvl(b.phywrts, 0)) writes,
         round(sum(e.phywrts – nvl(b.phywrts, 0)) /
               (SELECT EXTRACT(DAY FROM
                               E.END_INTERVAL_TIME – B.END_INTERVAL_TIME) *
                       86400 + EXTRACT(HOUR FROM E.END_INTERVAL_TIME –
                                       B.END_INTERVAL_TIME) * 3600 +
                       EXTRACT(MINUTE FROM
                               E.END_INTERVAL_TIME – B.END_INTERVAL_TIME) * 60 +
                       EXTRACT(SECOND FROM
                               E.END_INTERVAL_TIME – B.END_INTERVAL_TIME)
                  FROM DBA_HIST_SNAPSHOT B, DBA_HIST_SNAPSHOT E
                 WHERE B.SNAP_ID =
                       (select max(snap_id) – 1 from dba_hist_sqlstat)
                   AND E.SNAP_ID =
                       (select max(snap_id) from dba_hist_sqlstat)
                   AND B.INSTANCE_NUMBER =
                       (select instance_number from v$instance)
                   AND E.INSTANCE_NUMBER =
                       (select instance_number from v$instance)
                   AND B.STARTUP_TIME = E.STARTUP_TIME
                   AND B.END_INTERVAL_TIME < E.END_INTERVAL_TIME),
               2) wps,
         sum(e.wait_count – nvl(b.wait_count, 0)) waits,
         round(decode(sum(e.wait_count – nvl(b.wait_count, 0)),
                      0,
                      0,
                      10 * (sum(e.time – nvl(b.time, 0)) /
                      sum(e.wait_count – nvl(b.wait_count, 0)))),
               2) atpwt,
         sum(e.phyrds – nvl(b.phyrds, 0)) +
         sum(e.phywrts – nvl(b.phywrts, 0)) ios
    from dba_hist_filestatxs e, dba_hist_filestatxs b
   where b.snap_id = (select max(snap_id) – 1 from dba_hist_sqlstat)
     and e.snap_id = (select max(snap_id) from dba_hist_sqlstat)
     and b.dbid = e.dbid
     and b.instance_number = e.instance_number
     and e.instance_number = (select instance_number from v$instance)
     and b.instance_number(+) = e.instance_number
     and b.tsname(+) = e.tsname
     and b.file#(+) = e.file#
     and b.creation_change#(+) = e.creation_change#
     and ((e.phyrds – nvl(b.phyrds, 0)) + (e.phywrts – nvl(b.phywrts, 0))) > 0
   group by E.SNAP_ID, e.tsname
  union all
  select E.SNAP_ID,
         e.tsname tsname,
         sum(e.phyrds – nvl(b.phyrds, 0)) reads,
         round(sum(e.phyrds – nvl(b.phyrds, 0)) /
               (SELECT EXTRACT(DAY FROM
                               E.END_INTERVAL_TIME – B.END_INTERVAL_TIME) *
                       86400 + EXTRACT(HOUR FROM E.END_INTERVAL_TIME –
                                       B.END_INTERVAL_TIME) * 3600 +
                       EXTRACT(MINUTE FROM
                               E.END_INTERVAL_TIME – B.END_INTERVAL_TIME) * 60 +
                       EXTRACT(SECOND FROM
                               E.END_INTERVAL_TIME – B.END_INTERVAL_TIME)
                  FROM DBA_HIST_SNAPSHOT B, DBA_HIST_SNAPSHOT E
                 WHERE B.SNAP_ID =
                       (select max(snap_id) – 1 from dba_hist_sqlstat)
                   AND E.SNAP_ID =
                       (select max(snap_id) from dba_hist_sqlstat)
                   AND B.INSTANCE_NUMBER = E.INSTANCE_NUMBER
                   AND E.INSTANCE_NUMBER =
                       (select instance_number from v$instance)
                   AND B.STARTUP_TIME = E.STARTUP_TIME
                   AND B.END_INTERVAL_TIME < E.END_INTERVAL_TIME),
               2) rps,
         round(decode(sum(e.phyrds – nvl(b.phyrds, 0)),
                      0,
                      0,
                      (sum(e.readtim – nvl(b.readtim, 0)) /
                      sum(e.phyrds – nvl(b.phyrds, 0))) * 10),
               2) atpr,
         round(decode(sum(e.phyrds – nvl(b.phyrds, 0)),
                      0,
                      to_number(NULL),
                      sum(e.phyblkrd – nvl(b.phyblkrd, 0)) /
                      sum(e.phyrds – nvl(b.phyrds, 0))),
               2) bpr,
         sum(e.phywrts – nvl(b.phywrts, 0)) writes,
         round(sum(e.phywrts – nvl(b.phywrts, 0)) /
               (SELECT EXTRACT(DAY FROM
                               E.END_INTERVAL_TIME – B.END_INTERVAL_TIME) *
                       86400 + EXTRACT(HOUR FROM E.END_INTERVAL_TIME –
                                       B.END_INTERVAL_TIME) * 3600 +
                       EXTRACT(MINUTE FROM
                               E.END_INTERVAL_TIME – B.END_INTERVAL_TIME) * 60 +
                       EXTRACT(SECOND FROM
                               E.END_INTERVAL_TIME – B.END_INTERVAL_TIME)
                  FROM DBA_HIST_SNAPSHOT B, DBA_HIST_SNAPSHOT E
                 WHERE B.SNAP_ID =
                       (select max(snap_id) – 1 from dba_hist_sqlstat)
                   AND E.SNAP_ID =
                       (select max(snap_id) from dba_hist_sqlstat)
                   AND B.INSTANCE_NUMBER = E.INSTANCE_NUMBER
                   AND E.INSTANCE_NUMBER =
                       (select instance_number from v$instance)
                   AND B.STARTUP_TIME = E.STARTUP_TIME
                   AND B.END_INTERVAL_TIME < E.END_INTERVAL_TIME),
               2) wps,
         sum(e.wait_count – nvl(b.wait_count, 0)) waits,
         round(decode(sum(e.wait_count – nvl(b.wait_count, 0)),
                      0,
                      0,
                      (sum(e.time – nvl(b.time, 0)) /
                      sum(e.wait_count – nvl(b.wait_count, 0))) * 10),
               2) atpwt,
         sum(e.phyrds – nvl(b.phyrds, 0)) +
         sum(e.phywrts – nvl(b.phywrts, 0)) ios
    from dba_hist_tempstatxs e, dba_hist_tempstatxs b
   where b.snap_id = e.snap_id
     and e.snap_id = (select max(snap_id) from dba_hist_sqlstat)
     and b.dbid(+) = e.dbid
     and b.instance_number = e.instance_number
     and e.instance_number = (select instance_number from v$instance)
     and b.instance_number(+) = e.instance_number
     and b.tsname(+) = e.tsname
     and b.file#(+) = e.file#
     and b.creation_change#(+) = e.creation_change#
     and ((e.phyrds – nvl(b.phyrds, 0)) + (e.phywrts – nvl(b.phywrts, 0))) > 0
   group by E.SNAP_ID, e.tsname
   order by ios desc, tsname)
select snap_id,tsname,reads,rps,atpr,bpr,writes,wps,waits,atpwt,ios from a
    从裸数据SQL提取中看到,writes指标是通过sum(e.phywrts – nvl(b.phywrts, 0))来实现,难道是Oracle 的Bug?以上结果是在Oracle 11.2.0.4中的结果,12.1.0.2版本的AWR中的截图,12c中并不存在此现象的发生,1-bk Rds/s与Av Rds/s(RPS)数值关系显示正常。由此推断,在11.2.0.4版本中AWR 信息1-bk Rds/s显示存在Bug,是不准确的

20200105-3