设为首页 收藏本站
查看: 833|回复: 0

[经验分享] oracle数据块状态视图v$bh的用法

[复制链接]
YunVN网友  发表于 2016-8-15 06:22:17 |阅读模式
1.创建一个测试表,test,并且插入10000行数据;

begin
for i in 1 .. 10000 loop
execute immediate 'insert into test values(:x)'
using i;
end loop;
end;

2.创建一个存储过程SHOW_SPACE:

create or replace procedure show_space(p_segname   in varchar2,
p_owner     in varchar2 default user,
p_type      in varchar2 default 'TABLE',
p_partition in varchar2 default NULL) as
l_total_blocks       number;
l_total_bytes        number;
l_unused_blocks      number;
l_unused_bytes       number;
l_LastUsedExtFileId  number;
l_LastUsedExtBlockId number;
l_last_used_block    number;
procedure p(p_label in varchar2, p_num in number) is
begin
dbms_output.put_line(rpad(p_label, 40, '.') || p_num);
end;
begin
dbms_space.unused_space(segment_owner             => p_owner,
segment_name              => p_segname,
segment_type              => p_type,
partition_name            => p_partition,
total_blocks              => l_total_blocks,
total_bytes               => l_total_bytes,
unused_blocks             => l_unused_blocks,
unused_bytes              => l_unused_bytes,
last_used_extent_file_id  => l_LastUsedExtFileId,
last_used_extent_block_id => l_LastUsedExtBlockId,
last_used_block           => l_last_used_block);
p('Total Blocks', l_total_blocks);
p('Total Bytes', l_total_bytes);
p('Unused Blocks', l_unused_blocks);
p('Unused Bytes', l_unused_bytes);
p('Last Used Ext FileId', l_LastUsedExtFileId);
p('Last Used Ext BlockId', l_LastUsedExtBlockId);
p('Last Used Block', l_last_used_block);
end;

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...................58745
Last Used Block.........................5


由上可知,该表test共占用了24个数据块,196608字节,文件ID为1
4.获得表test在数据块中的分布情况:

select f, b
from (select dbms_rowid.rowid_relative_fno(rowid) f,
dbms_rowid.rowid_block_number(rowid) b
from test)
group by f, b
order by b;


DSC0000.png
由此可见,表test中的数据共占用了16个数据块,但是前面第三步中,发现该表占用了24个数据块。这是正常的,因为oracle本身会使用8个数据库来记录段头、位图块等额外的信息。我们现在只需要了解到,表test共占用了24个数据块,其中16个是数据,8个是表信息。
5.检查x$bh和v$bh的更新:

select file#, dbablk, tch
from x$bh
where obj = (select data_object_id
from dba_objects
where owner = 'SYS'
and object_name = 'TEST')
order by dbablk;


DSC0001.png

select file#, block#, status
from v$bh
where objd = (select data_object_id
from dba_objects
where owner = 'SYS'
and object_name = 'TEST')
order by block#;


DSC0002.png
这里可以看到,在v$bh和x$bh中得到的数据块,是从58729~58749的21条记录,但是在第四步中,我们知道数据是占用了58730~58745的16个数据库,这里,58729数据块里面存放的是段头信息,可以通过如下命令进行验证:

select header_file, header_block
from dba_segments
where owner = 'SYS'
and segment_name = 'TEST';


DSC0003.png
在v$bh视图中,我们可以看到这21个数据块都是xcur状态,表示这些数据块都是排斥状态,正在被使用,该字段还有其他的类型,
引用

oracle的缓冲块的管理机制一直没有正式的发布过,因此许多有经验的oracle工程师都是通过经验或者一下oracle文档中的注释来推断oracle的缓冲块的管理机制的。
    事实上,oralce使用v$bh视图来记录与数据缓冲(data buffer)相关的信息,它详细记录了数据缓冲中每一个数据块(data block)的状态信息。
    在v$bh视图中的status字段,记录了数据块的状态,在非OPS、非RAC这样的集群环境中,数据块的状态会是下列几种之一:xcur,cr,read,free,用户可以通过如下命令得到数据库的状态信息:
    SQL> select unique status from v$bh;
    其状态的意义分别是:
    xcur:(exclusive current)的意思,表示该数据块处于排外模式;
    cr:表示该数据块是一个克隆(clone)的数据库,可以执行共享的只读操作;
    free:表示这是一个限制的数据块,oracle现在没有使用它;
    read:表示该数据块正在从磁盘读取数据;
    write:表示数据库正在往磁盘写入数据;
    在数据库恢复过程中,该字段还有另外两个描述:mrec和irec:
    mrec:(media recovery)表示数据块处于介质恢复模式;
    irec:(instance recovery)表示数据块处于实例恢复模式;
    在RAC环境中,数据块还有另外一种模式:
    scur (shared current),表示该数据库正在和其他实例共享数据。


6.清空数据缓存:

alter system flush buffer_cache;

7.重新检查v$bh和x$bh的内容:

select file#, dbablk, tch
from x$bh
where obj = (select data_object_id
from dba_objects
where owner = 'SYS'
and object_name = 'TEST')
order by dbablk;


DSC0004.png

select file#, block#, status
from v$bh
where objd = (select data_object_id
from dba_objects
where owner = 'SYS'
and object_name = 'TEST')
order by block#;


DSC0005.png
这时候我们可以看到,x$bh中的tch字段,已经由原来的3变成了0,同时v$bh视图的数据块状态也变成了free,但是记录的数据块并没有发生变化,还是在58729~58749这些数据块中,这就是说,虽然数据已经被写到了磁盘中,但是数据库记录的指针并没有清空,仅仅是其状态发生了改变。
8.进阶
明白是oracle数据库管理数据块的部分工作模式后,我们可以利用v$bh文件统计对象在数据缓冲中被cache的块数了,如:

select count(*)
from v$bh
where objd = (select data_object_id
from dba_objects
where owner = 'SYS'
and object_name = 'TEST')
and status != 'free';

引用
COUNT(*)
----------
        17
   
表示表test中有17个数据块还存在于缓存当中。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-257702-1-1.html 上篇帖子: 【转】oracle-PL/SQL中用游标查询多条记录 下篇帖子: Oracle 10g中对Merge语句的增强
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表