0

通过v$bh测试数据块状态

刘娣 2019-03-22
59
摘要:数据块在物理磁盘上叫做block,读取到内存以后叫做buffer数据库中有个X$BH表,bufferheader表,这个表中的每一行数据都...

问题描述

数据块在物理磁盘上叫做block,读取到内存以后叫做buffer

数据库中有个X$BH表,buffer header表,这个表中的每一行数据都对应着buffer cache中的一个buffer

c##ucr_ld@TEST> create table test as select object_id,object_name from dba_objects where rownum<2;
Table created.
c##ucr_ld@TEST>select * from test;
 OBJECT_ID OBJECT_NAM
---------- ----------
        30 I_COBJ#

查看该表占用了8个数据块

c##ucr_ld@TEST>exec show_space('TEST');
Total Blocks............................8
Total Bytes.............................65536
Unused Blocks...........................4
Unused Bytes............................32768
Last Used Ext FileId....................11
Last Used Ext BlockId...................128
Last Used Block.........................4

TEST表占用了11号文件的第131号数据块

c##ucr_ld@TEST>select dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block# from test;
     FILE#     BLOCK#
---------- ----------
        11        131

其中11号文件的第130号数据块存放的是数据块的段头信息

c##ucr_ld@TEST>select header_file,header_block from dba_segments where owner='C##UCR_LD' and segment_name='TEST';
HEADER_FILE HEADER_BLOCK
----------- ------------
         11          130

TEST表的131号数据块正在被以排它模式占有

c##ucr_ld@TEST>select file#,block#,status from v$bh where file#=11 and block#=131;

     FILE#     BLOCK# STATUS
---------- ---------- ------------------------------
        11        131 xcur

请问块有哪些状态,以及各种状态直接的变化是怎么样的

专家解答

v$bh的status状态的含义:

Oracle使用v$bh视图记录与data buffer相关的信息,该视图详细记录了数据缓冲中每一个数据块的状态信息,数据块的状态有以下几种:

sys@TEST>select distinct status from v$bh;

STATUS

------

xcur     表示该数据块处于排它模式。假设我们要读取一个数据块到buffer cache,这个被读入的数据块就叫做current块

free     表示该数据块目前没有被使用

cr       表示该数据块是一个clone的数据块,可以执行共享的只读操作。

         假设会话A修改了某个数据块没有提交;会话B也需要修改这个数据块,但是由于A还没有提交,所以B不能读取到A还没提交的内容。

         B只能从磁盘重新读取未修改之前的数据块到内存(如果已经被修改了,需要到undo里面去根据前印象构造一个cr块,B读取的就是这个cr块)

         也就是说:会话A操作的是current块,是和原始的block对应的;会话B操作的是cr块,是临时的块。如果要修改一个数据块,只能读取current块


此时清空buffer cache,可以看到TEST表对应的数据块的状态是free

sys@TEST>alter system flush buffer_cache;
System altered.

c##ucr_ld@TEST>select file#,block#,status from v$bh where file#=11 and block#=131;
     FILE#     BLOCK# STATUS
---------- ---------- ------------------------------
        11        131 free
        11        131 free

对该表执行select操作,此时读取的是current数据块,状态是xcur

c##ucr_ld@TEST>select * from test;
 OBJECT_ID OBJECT_NAM
---------- ----------
        30 I_COBJ#
        
c##ucr_ld@TEST>select file#,block#,status from v$bh where file#=11 and block#=131;
     FILE#     BLOCK# STATUS
---------- ---------- ------------------------------
        11        131 free
        11        131 free
        11        131 xcur

对该表执行DML操作,这里有疑问的是:此时该数据块同时会有current块、cr块的状态?是否表明该数据块目前以排它模式被持有,但是其他人可以以只读模式构造cr块

c##ucr_ld@TEST>update test set object_id=1;
1 row updated.

c##ucr_ld@TEST>select file#,block#,status from v$bh where file#=11 and block#=131;
     FILE#     BLOCK# STATUS
---------- ---------- ------------------------------
       11        131 free
       11        131 free
       11       131 cr
       11       131 xcur


总结:

对一个数据块进行DML操作,只能读取current数据块并做修改

对一个数据块进行DQL操作,如果current数据块没有未提交的操作直接读取current数据块;如果current数据块有未提交的操作,需要构造一个原始block的cr块。

「喜欢文章,快来给作者赞赏墨值吧」

评论

0
0
最新发布
暂无内容,敬请期待...
数据库资讯
最新 热门 更多
本月热门
近期活动
全部
暂无活动,敬请期待...
相关课程
全部
暂无课程,敬请期待...