Db file scattered read
这个等待事件在实际生产库中经常可以看到,这是一个用户操作引起的等待事件,当用户发出每次I/O需要读取多个数据块这样的SQL 操作时,会产生这个等待事件,最常见的两种情况是全表扫描(FTS: Full Table Scan)和索引快速扫描(IFFS: index fast full scan)。
这个名称中的scattered( 分散),可能会导致很多人认为它是以scattered 的方式来读取数据块的,其实恰恰相反,当发生这种等待事件时,SQL的操作都是顺序地读取数据块的,比如FTS或者IFFS方式(如果忽略需要读取的数据块已经存在内存中的情况)。
这里的scattered指的是读取的数据块在内存中的存放方式,他们被读取到内存中后,是以分散的方式存在在内存中,而不是连续的。
这个等待事件有三个参数:
File#: 要读取的数据块所在数据文件的文件号。
Block#: 要读取的起始数据块号。
Blocks: 需要读取的数据块数目。
案例分析:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
12
:
04
:
54
SYS@ prod>select event,TOTAL_WAITS,AVERAGE_WAIT
from
v$system_event
12
:
04
:
59
2
where
upper(event) like
'DB FILE%'
;
EVENT TOTAL_WAITS AVERAGE_WAIT
---------------------------------------------------------------- ----------- ------------
db file sequential read
5069
.02
db file scattered read
930
.03
db file single write
27
.36
db file parallel write
15
14.24
db file parallel read
34
.64
Elapsed:
00
:
00
:
00.12
12
:
06
:
53
SCOTT@ prod>select *
from
t1;
12
:
05
:
04
SYS@ prod>select event,TOTAL_WAITS,AVERAGE_WAIT
from
v$system_event
2
*
where
upper(event) like
'DB FILE%'
EVENT TOTAL_WAITS AVERAGE_WAIT
---------------------------------------------------------------- ----------- ------------
db file sequential read
5166
.02
db file scattered read
966
.03
db file single write
27
.36
db file parallel write
16
13.69
db file parallel read
34
.64
Elapsed:
00
:
00
:
00.02
|
oracle在执行FTS时也进行Single Block I/O。这时即便是FTS也会发生db file sequential read等待。FTS上使用Single Block I/O或读取比MBRC值小的块数的情况如下:
(1)达到区的界线时:如一个区有9个块,一次Multi Block I/O读取8个块,则一次以Multi Block I/O读取之后的剩余一个块通过Single Block I/O读取,如果剩下的块有两个,就会执行Multi Block I/O,而且只读取两个块。
(2)扫描过程中读取被缓存的块时:如读取8个块时,其中第三个块被缓存,oracle将前两个块通过Multi Block I/O读取,对于第三个块执行一次Logical I/O,剩下的5个块通过Multi Block I/O读取。这种情况经常发生时,因引发多次的I/O,可能成为FTS速度下降的原因。
(3)存在行链接时:在执行FTS的过程中,如果发现了行链接,oracle为了读取剩下的行引起的附加I/O,此时执行Single Block I/O。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
14
:
16
:
34
SYS@ prod>show parameter mult
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_file_multiblock_read_count integer
19
parallel_adaptive_multi_user boolean TRUE
14
:
17
:
28
SYS@ prod>col segment_name
for
a20
14
:
18
:
08
SYS@ prod>select OWNER,SEGMENT_NAME ,SEGMENT_TYPE,EXTENT_ID,BLOCK_ID,BLOCKS
from
dba_extents
14
:
18
:
47
2
where
segment_name=
'T1'
AND owner=
'SCOTT'
;
OWNER SEGMENT_NAME SEGMENT_TYPE EXTENT_ID BLOCK_ID BLOCKS
------------------------------ -------------------- ------------------ ---------- ---------- ----------
SCOTT T1 TABLE
0
168
8
SCOTT T1 TABLE
1
184
8
SCOTT T1 TABLE
2
192
8
SCOTT T1 TABLE
3
200
8
SCOTT T1 TABLE
4
208
8
SCOTT T1 TABLE
5
216
8
SCOTT T1 TABLE
6
224
8
SCOTT T1 TABLE
7
232
8
SCOTT T1 TABLE
8
240
8
SCOTT T1 TABLE
9
248
8
SCOTT T1 TABLE
10
256
8
SCOTT T1 TABLE
11
264
8
SCOTT T1 TABLE
12
272
8
SCOTT T1 TABLE
13
280
8
SCOTT T1 TABLE
14
288
8
SCOTT T1 TABLE
15
296
8
SCOTT T1 TABLE
16
384
128
OWNER SEGMENT_NAME SEGMENT_TYPE EXTENT_ID BLOCK_ID BLOCKS
------------------------------ -------------------- ------------------ ---------- ---------- ----------
SCOTT T1 TABLE
17
512
128
SCOTT T1 TABLE
18
640
128
SCOTT T1 TABLE
19
768
128
SCOTT T1 TABLE
20
896
128
SCOTT T1 TABLE
21
1024
128
22
rows selected.
Elapsed:
00
:
00
:
00.78
|
Db file sequential read
这个等待事件在实际生产库也很常见,当Oracle 需要每次I/O只读取单个数据块这样的操作时,会产生这个等待事件。最常见的情况有索引的访问(除IFFS外的方式),回滚操作,以ROWID的方式访问表中的数据,重建控制文件,对文件头做DUMP等。
这里的sequential也并非指的是Oracle 按顺序的方式来访问数据,和db file scattered read一样,它指的是读取的数据块在内存中是以连续的方式存放的。
这个等待事件有三个参数:
File#: 要读取的数据块锁在数据文件的文件号。
Block#: 要读取的起始数据块号。
Blocks: 要读取的数据块数目(这里应该等于1)。
案例分析:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
14
:
28
:
55
SYS@ prod>alter system flush buffer_cache;
System altered.
Elapsed:
00
:
00
:
00.28
14
:
29
:
08
SYS@ prod>select event,TOTAL_WAITS,AVERAGE_WAIT
from
v$system_event
14
:
29
:
41
2
where
upper(event) like
'DB FILE%'
;
EVENT TOTAL_WAITS AVERAGE_WAIT
---------------------------------------------------------------- ----------- ------------
db file sequential read
13991
.04
db file scattered read
1637
.03
db file single write
36
.35
db file parallel write
946
2.98
db file parallel read
46
.48
Elapsed:
00
:
00
:
00.03
14
:
26
:
46
SCOTT@ prod>create index t1_ind
on
t1(id);
Index created.
14
:
28
:
30
SCOTT@ prod>select *
from
t1
where
id=
1000
14
:
28
:
48
2
;
ID
----------
1000
1000
1000
Elapsed:
00
:
00
:
00.05
14
:
29
:
46
SYS@ prod>select event,TOTAL_WAITS,AVERAGE_WAIT
from
v$system_event
2
*
where
upper(event) like
'DB FILE%'
EVENT TOTAL_WAITS AVERAGE_WAIT
---------------------------------------------------------------- ----------- ------------
db file sequential read
13994
.04
db file scattered read
1637
.03
db file single write
36
.35
db file parallel write
946
2.98
db file parallel read
46
.48
Elapsed:
00
:
00
:
00.03
|
14:29:58 SYS@ prod>
数据文件关于Multi Block I/O和Single Block I/O的活动信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
14
:
38
:
22
SYS@ prod>select f.file#,
2
f.name,
3
s.phyrds,
4
s.phyblkrd,
5
s.readtim,
6
s.singleblkrds,
7
s.singleblkrdtim,
8
(s.phyblkrd - s.singleblkrds)
as
multiblkrd,
9
(s.readtim - s.singleblkrdtim)
as
multiblkrdtim,
10
round(s.singleblkrdtim /
11
decode(s.singleblkrds,
0
,
1
, s.singleblkrds),
12
3
)
as
singleblk_avgtim,
13
round((s.readtim - s.singleblkrdtim) /
14
nullif((s.phyblkrd - s.singleblkrds),
0
),
15
3
)
as
multiblk_avgtim
16
from
v$filestat s, v$datafile f
17
*
where
s.file# = f.file#
FILE# NAME PHYRDS PHYBLKRD READTIM SINGLEBLKRDS SINGLEBLKRDTIM MULTIBLKRD MULTIBLKRDTIM SINGLEBLK_AVGTIM MULTIBLK_AVGTIM
---------- -------------------------------------------------- ---------- ---------- ---------- ------------ -------------- ---------- ------------- ---------------- ---------------
1
/u01/app/oracle/oradata/prod/system01.dbf
16977
68027
419
12896
373
55131
46
.029
.001
2
/u01/app/oracle/oradata/prod/sysaux01.dbf
2041
3089
142
1894
134
1195
8
.071
.007
3
/u01/app/oracle/oradata/prod/undotbs1.dbf
11
11
4
11
4
0
0
.364
4
/u01/app/oracle/oradata/prod/users01.dbf
591
3355
8
359
7
2996
1
.019
0
5
/u01/app/oracle/oradata/prod/example01.dbf
10
14
0
9
0
5
0
0
0
6
/u01/app/oracle/oradata/prod/tbs1.dbf
4
4
0
4
0
0
0
0
7
/u01/app/oracle/oradata/prod/undotbs2.dbf
1815
1818
50
1812
48
6
2
.026
.333
8
/u01/app/oracle/oradata/prod/perftbs01.dbf
4
4
0
4
0
0
0
0
9
/u01/app/oracle/oradata/prod/tbs2.dbf
4
4
0
4
0
0
0
0
9
rows selected.
select f.file#,
f.name,
s.phyrds,
s.phyblkrd,
s.readtim, --所有的读取工作信息
s.singleblkrds,
s.singleblkrdtim, --Single Block I/O
(s.phyblkrd - s.singleblkrds)
as
multiblkrd, --Multi Block I/O次数
(s.readtim - s.singleblkrdtim)
as
multiblkrdtim, --Multi Block I/O时间
round(s.singleblkrdtim /
decode(s.singleblkrds,
0
,
1
, s.singleblkrds),
3
)
as
singleblk_avgtim, --Single Block I/O 平均等待时间(cs)
round((s.readtim - s.singleblkrdtim) /
nullif((s.phyblkrd - s.singleblkrds),
0
),
3
)
as
multiblk_avgtim --Multi Block I/O 平均等待时间(cs)
from
v$filestat s, v$datafile f
where
s.file# = f.file#;
|