1,创建一个测试表,test,并且插入10000行数据; SQL> create table test (id int);
SQL> begin
2 for i in 1..10000 loop
3 insert into test values(i)
4 end loop;
5 end;
6 /
SQL> commit;
2,创建一个存储过程SHOW_SPACE:
|
文件: |
show_spaceprocedure.rar |
大小: |
0KB |
下载: |
下载 | |
3,检查表test的空间使用情况: SQL> exec show_space('TEST');
Total Blocks............................24
Total Bytes.............................196608
Unused Blocks...........................3
Unused Bytes............................24576
Last Used Ext FileId....................1
Last Used Ext BlockId...................62177
Last Used Block.........................5
由上可知,该表test共占用了24个数据块,196608字节,文件ID为1
4, 获得表test在数据块中的分布情况: SQL> select f,b from (
2 select dbms_rowid.rowid_relative_fno(rowid) f,
3 dbms_rowid.rowid_block_number(rowid) b
4 from test) group by f,b order by b;
F B
---------- ----------
1 62162
1 62163
1 62164
1 62165
1 62166
1 62167
1 62168
1 62169
1 62170
1 62171
1 62172
1 62173
1 62174
1 62175
1 62176
1 62177
16 rows selected.
由此可见,表test中的数据共占用了16个数据块,但是前面第三步中,发现该表占用了24个数据块。这是正常的,因为oracle本身会使用8个数据库来记录段头、位图块等额外的信息。我们现在只需要了解到,表test共占用了24个数据块,其中16个是数据,8个是表信息。
5,检查x$bh和v$bh的更新: SQL> select file#,dbablk,tch from x$bh where obj=
2 (select data_object_id from dba_objects
3 where owner='SYS' and object_name='TEST')
4 order by dbablk;
FILE# DBABLK TCH
---------- ---------- ----------
1 62161 6
1 62162 3
1 62163 3
1 62164 3
1 62165 3
1 62166 3
1 62167 3
1 62168 3
1 62169 3
1 62170 3
1 62171 3
1 62172 3
1 62173 3
1 62174 3
1 62175 3
1 62176 3
1 62177 3
1 62178 3
1 62179 3
1 62180 3
1 62181 3
21 rows selected.
SQL> select file#,block#,status from v$bh where objd=
2 (select data_object_id from dba_objects
3 where owner='SYS' and object_name='TEST')
4 order by block#;
FILE# BLOCK# STATUS
---------- ---------- -------
1 62161 xcur
1 62162 xcur
1 62163 xcur
1 62164 xcur
1 62165 xcur
1 62166 xcur
1 62167 xcur
1 62168 xcur
1 62169 xcur
1 62170 xcur
1 62171 xcur
1 62172 xcur
1 62173 xcur
1 62174 xcur
1 62175 xcur
1 62176 xcur
1 62177 xcur
1 62178 xcur
1 62179 xcur
1 62180 xcur
1 62181 xcur
21 rows selected.
这里可以看到,在v$bh和x$bh中得到的数据块,是从62161~62181的21条记录,但是在第四步中,我们知道数据是占用了62162~62177的16个数据库,这里,62161数据块里面存放的是段头信息,可以通过如下命令进行验证:
SQL> select header_file,header_block from dba_segments
2 where owner='SYS' and segment_name='TEST';
HEADER_FILE HEADER_BLOCK
----------- ------------
1 62161
在v$bh视图中,我们可以看到这21个数据块都是xcur状态,表示这些数据块都是排斥状态,正在被使用,该字段还有其他的类型,请参见
数据块的状态类型。
6,清空数据缓存: SQL> alter system flush buffer_cache;
7,重新检查v$bh和x$bh的内容: SQL> select file#,dbablk,tch from x$bh where obj=
2 (select data_object_id from dba_objects
3 where owner='SYS' and object_name='TEST')
4 order by dbablk;
FILE# DBABLK TCH
---------- ---------- ----------
1 62161 0
1 62162 0
1 62163 0
1 62164 0
1 62165 0
1 62166 0
1 62167 0
1 62168 0
1 62169 0
1 62170 0
1 62171 0
1 62172 0
1 62173 0
1 62174 0
1 62175 0
1 62176 0
1 62177 0
1 62178 0
1 62179 0
1 62180 0
1 62181 0
21 rows selected.
SQL> select file#,block#,status from v$bh where objd=
2 (select data_object_id from dba_objects
3 where owner='SYS' and object_name='TEST')
4 order by block#;
FILE# BLOCK# STATUS
---------- ---------- -------
1 62161 free
1 62162 free
1 62163 free
1 62164 free
1 62165 free
1 62166 free
1 62167 free
1 62168 free
1 62169 free
1 62170 free
1 62171 free
1 62172 free
1 62173 free
1 62174 free
1 62175 free
1 62176 free
1 62177 free
1 62178 free
1 62179 free
1 62180 free
1 62181 free
21 rows selected.
这时候我们可以看到,x$bh中的tch字段,已经由原来的3变成了0,同时v$bh视图的数据块状态也变成了free,但是记录的数据块并没有发生变化,还是在62161~62181这些数据块中,这就是说,虽然数据已经被写到了磁盘中,但是数据库记录的指针并没有清空,仅仅是其状态发生了改变。
8,进阶 明白是oracle数据库管理数据块的部分工作模式后,我们可以利用v$bh文件统计对象在数据缓冲中被cache的块数了,如:
SQL> select count(*) from v$bh where objd=
2 (select data_object_id from dba_objects
3 where owner='SYS' and object_name='TEST')
4 and status != 'free';
COUNT(*)
----------
17
表示表test中有17个数据块还存在于缓存当中。