`

Oracle 数据块(data block)的结构和解析

 
阅读更多

 First of all let’s create a new tablespace and a table:

SQL> create tablespace my_tbs datafile '/u01/oradata/chenlin/my_tbs.dbf' size 200m ;

 Tablespace created.

 then:

SQL> create table my_tab tablespace my_tbs as select * from dba_objects  ;

 Table created.

 Now let’s get more information about this table from DBA_SEGMENTS view:

SQL> select header_file, header_block, bytes, blocks, extents from dba_segments where segment_name='MY_TAB';


 HEADER_FILE   HEADER_BLOCK       BYTES        BLOCKS       EXTENTS
-----------    ------------           --------      ----------      ----------
  12                         17               4194304           1024        19

 

From the output we can say that the header block of the table is stored in the datafile 12, block 17. 

The size of the table 4194304 bytes (4.2 Mb) and it contains 1024 blocks and 19 extents.

After getting block size of the database, let’s do some math:


SQL> show parameter db_block_size


 NAME                                 TYPE        VALUE
--------------                  ----------- --------------------------
db_block_size                     integer     4096

 

BLOCKS (dba_segments) * DB_BLOCK_SIZE (parameter file) = BYTES (dba_segments)

so : 1024 * 4096 =  4194304 


Now let’s query DBA_EXTENTS view to get some information on extents and data blocks of this table: 

SQL> col segment_name format a20

SQL> select segment_name, extent_id, block_id,  blocks, bytes from dba_extents where segment_name='MY_TAB';

 SEGMENT_NAME EXTENT_ID BLOCK_ID BLOCKS BYTES

 --------------------  ----------   ----------    ----------   -------
MY_TAB                              0         17         16        65536
MY_TAB                              1         33         16        65536
MY_TAB                              2         49         16        65536
MY_TAB                              3         65         16        65536
MY_TAB                              4         81         16        65536
MY_TAB                              5         97         16        65536
MY_TAB                              6        113        16        65536
MY_TAB                              7        129        16        65536
MY_TAB                              8        145        16        65536
MY_TAB                              9        161        16        65536
MY_TAB                             10       177        16        65536
MY_TAB                             11       193        16        65536
    
.............................

 

19 rows selected.

 we do this test by follow  info :


SEGMENT_NAME          EXTENT_ID   BLOCK_ID     BLOCKS      BYTES
--------------------    ---------         ---------    ----------      ----------
MY_TAB                             0                    17              16         65536
MY_TAB                             1                    33              16         65536

 

Here we see that the first extent (0) contains 16 blocks which id range between 17 and 33 ,

so: 17 (block_id) + 16 (number of blocks) = 33 (block_id of the next extent)

And now let’s start dumping the header block of the table. For this we need data file and header block number.

It can be taken from the DBA_SEGMENTS


SQL> select header_file, header_block from dba_segments where segment_name='MY_TAB';


HEADER_FILE     HEADER_BLOCK
-----------           ------------
    12                            17

 

See more about dba_segments:

http://docs.oracle.com/cd/B19306_01/server.102/b14237/statviews_4097.htm#i1626854


Now, dump the data block 12 of the datafile 17:

notice :you should rm  your udump file   by force  first  , and  relogin  again 


 SQL> alter system dump datafile 12 block 17;    


 System altered.


If you use  SecureCRT  , you can use the command  : rz  or sz to download or upload files 


Clone a new session and change to oracle user  by using : su - oracle 


[oracle@chance udump]$ ll

total 4

-rw-r-----  1 oracle oinstall 2106 May  6 22:15 chenlin_ora_7831.trc


[oracle@chance udump]$sz chenlin_ora_7831.trc 

rz

Starting zmodem transfer.  Press Ctrl+C to cancel.

Transferring chenlin_ora_7831.trc...

 100%       2 KB    2 KB/s 00:00:01       0 Errors


Let's find  the file chenlin_ora_7831.trc  at  C:\Users\Administrator\Downloads  and see the infomation  in it :

 #---------------------------------begin--------------------------

/u01/admin/chenlin/udump/chenlin_ora_7831.trc

Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production

With the Partitioning, OLAP and Oracle Data Mining options

JServer Release 9.2.0.4.0 - Production

ORACLE_HOME = /u01/oracle

System name:Linux

Node name:chance

Release:2.6.9-89.EL

Version:#1 Mon Jun 22 12:19:40 EDT 2009

Machine:i686

Instance name: chenlin

Redo thread mounted by this instance: 1

Oracle process number: 14

Unix process pid: 7831, image: oracle@chance (TNS V1-V3)

*** SESSION ID:(11.17) 2012-05-06 22:15:42.270

Start dump data blocks tsn: 14 file#: 12 minblk 17 maxblk 17

buffer tsn: 14 rdba: 0x03000011 (12/17)

scn: 0x0000.000a40da seq: 0x01 flg: 0x04 tail: 0x40da1001

frmt: 0x02 chkval: 0x28a8 type: 0x10=DATA SEGMENT HEADER - UNLIMITED


 Extent Control Header

  -----------------------------------------------------------------

  Extent Header:: spare1: 0      spare2: 0      #extents: 19     #blocks: 1023  

  last map  0x00000000  #maps: 0      offset: 2080  

  Highwater::  0x03000351  ext#: 18     blk#: 64     ext size: 256   


  #blocks in seg. hdr's freelists: 0     

  #blocks below: 831   

  mapblk  0x00000000  offset: 18    

  Unlocked

  Map Header:: next  0x00000000  #extents: 19   obj#: 30558  flag: 0x40000000


  Extent Map

  -----------------------------------------------------------------

   0x03000012  length: 15    

   0x03000021  length: 16    

   0x03000031  length: 16    

   0x03000041  length: 16    

   0x03000051  length: 16    

   0x03000061  length: 16    

   0x030000c1  length: 16    

   0x030000d1  length: 16    

   0x030000e1  length: 16    

   0x030000f1  length: 16    

   0x03000101  length: 16    

   0x03000111  length: 256   

   0x03000211  length: 256   

   0x03000311  length: 256   

   nfl = 1, nfb = 1 typ = 1 nxf = 0 ccnt = 0

  SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000 

 End dump data blocks tsn: 14 file#: 12 minblk 17 maxblk 17


#---------------------------------------end------------------------------------------


* Start dump data blocks tsn: 14 file#: 12 minblk 17 maxblk 17  

This means that the following lines is the output of datafile 17, block 17. Range of blocks can be given to dump:


 SQL> alter system dump datafile 1 block min 1 block max 17 

* rdba: 0x03000011


rdba is the Data Block Address which is internal representation of the block address.The first 10 bits contains file number, and the rest 22 bits contains block id.


if we want to convert 0x03000011 to decimal, we would get 12/17 which is shown between brackets.


Moreover, DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE and DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK can be used to get the file and block number based on RDA value. But before using these functions, rda should be converted to the decimal value.


So here, we convert the rda value (0x03000011) to decimal and got  50331665.


In order to convert hexadecimal value to the decimal online, you can use the following link:http://www.statman.info/conversions/hexadecimal.html


 SQL>  select DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(50331665) as fileNo , DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(50331665) as blockNo from dual;


FILENO                      BLOCKNO
----------                  ----------
         12                            17

 

 By using DBMS_UTILITY.MAKE_DATA_BLOCK_ADDRESS function and passing file and block value, we can get RDA value:

SQL> select DBMS_UTILITY.MAKE_DATA_BLOCK_ADDRESS(12,17) from dual;



 DBMS_UTILITY.MAKE_DATA_BLOCK_ADDRESS(12,17)
          -------------------------------------------
                                                          50331665

 



* scn: 0x0000.000a40dais the SCN value of the block which defines when it was last modified. We can compare it with each transaction SCN value inside the dump file. The SCN value of the data block is 0×0000.02eeaf02. If second part of this value (02eeaf02) is converted to the decimal, then we got – 49196802. If we query the current_scn value we got:


The SCN value of the data block is 0×0000.02eeaf02.


If second part of this value (000a40da) is converted to the decimal, then we got – 671962. If we query the current_scn value we got:


SQL> select dbms_flashback.get_system_change_number from dual;



 GET_SYSTEM_CHANGE_NUMBER
          ------------------------
                                  683658

 

* tail is used to keep track of consistency information between the beginning and end of the block against the possibility of distribution of oracle blocks over multiple OS blocks

* frmt – is the block format which tells whether it’s Oracle 9 or Oracle 10 and higher block. 0×02 represents that it’s Oracle 8 and higher block. (0×01 represents that it’s Oracle 7 block)

* chkval – which is checksum written to the blocks when it is set and used by Oracle in part to check the consistency and validity of the block, and  you show set  the parameter db_block_checksum  to true in init.ora file

* type : Type defines which type of block it is. In this example it is “Data Segment Header”

* Extent Header: spare1: 0    spare2: 0      #extents: 19     #blocks: 1023  

Then in the Extent Control Header part we can get information about extents. So it has 19 extents and 1023 blocks.

* Highwater:  0x03000351  ext#: 18     blk#: 64     ext size: 256   

#blocks in seg. hdr's freelists: 0     

#blocks below: 831 


Highwater mark  ( 50332497 ) is at extent 18, block 64. This extent has 256 blocks. And there’re 831 data block below it. Let’s do some math:


As it has 831 blocks below and the number of block is 1023 (dump file didn’t count the header block), then there’re 1023-831=192 data blocks free (and above the hightwater mark).


Moreover, as the highwater mark is at block 64  and the extent has  256  data blocks, then 256-64 = 192 data blocks are free,


So this means that there’s 192*4096 = 786432 bytes (768Kb) free space left

* Map Header: next  0x00000000  #extents: 19   obj#: 30558  flag: 0x40000000

Next, we got object id. To find more details on that object, query sys.obj# view:


SQL>  set lines 180

SQL> select obj#, owner#, name, status, ctime, type# from sys.obj$ where obj#=30558;


OBJ#   OWNER#   NAME       STATUS      CTIME          TYPE#
------- -------    -------     ----------   ---------          ----
30558      0       MY_TAB               1   06-MAY-12          2

 



 SQL> select username from dba_users where user_id=0;


                           USERNAME
------------------------------
                                   SYS

 


So we can see the owner id is 0 (SYS user) and type is 2 (it means table)


In order to show the free space, we can use DBMS_SPACE.UNUSED_SPACE procedure. Let’s create  procedure : 

 

SQL> 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 )
       authid current_user
       as 
          l_free_blks                 number;
          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( 'Total MBytes', trunc(l_total_bytes/1024/1024) );
            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  show_space;
   /

 

 


SQL> set serveroutput on 

SQL> exec show_space('MY_TAB','SYS');

 

      Total Blocks............................1024
      Total Bytes.............................4194304
      Total MBytes............................4
      Unused Blocks...........................192
      Unused Bytes............................786432
      Last Used Ext FileId....................12
      Last Used Ext BlockId...................785
      Last Used Block.........................64

 


PL/SQL procedure successfully completed.


As it has 831 blocks below and the number of block is 1023 (dump file didn’t count the header block), then there’re 1023-831=192 data blocks free (and above the hightwater mark)


Moreover, as the highwater mark is at block 64  and the extent has  256  data blocks, then 256-64 = 192 data blocks are free,


So this means that there’s 192*4096 = 786432 bytes (768Kb) free space left .


As you see comparison of both values led us to the same results .


So in this post you’ve learned how to dump a header block of the segment and how to read it. 


ps: 如果你想真正知道oracle的block块里面真正有些什么,请耐心读完这篇文章~

 

分享到:
评论

相关推荐

    oracle数据块(block)结构详解

    本文将深入解析Oracle数据块的结构及其相关知识点。 首先,Oracle数据块由多个部分组成,主要包括: 1. 头部(Header):数据块头部包含了关于数据块本身的信息,如数据块号、块状态、块的所有者、以及用于锁定和...

    oracle数据块解析

    通过查询 `DBMS_ROWID` 包含的函数,可以获取该行数据所在的文件号(`file#`)和块号(`block#`)。在这个例子中,数据位于文件号 6 的第 135 块。 接下来,使用 `ALTER SYSTEM DUMP DATAFILE` 语句转储特定文件号...

    【转】Oracle数据块深入分析总结

    在本文中,我们将对 Oracle 数据块的内部结构进行深入分析,并且使用 dump 和 BBED 工具对数据库内部结构进行分析。 一、数据块结构 Oracle 数据块由多个部分组成,每个部分都有其特定的功能。基本结构包括: 1. ...

    oracle 11g 数据文件头block 1解析

    oracle 11g 数据文件头block 1解析 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ##powered by :黄林杰_Huanglinjie ##version : 2023-v11 ##联系方式:17767151782 ##blog: https://blog.csdn.net/lixora/ ##info: ...

    Oracle 坏块修复

    Oracle 坏块修复是指在 Oracle 数据库中出现的数据块混乱现象,导致数据库进程无法正常解析数据块的内容,进而使数据库进程报错乃至挂起,并级联导致整个数据库实例出现异常。 一、坏块的产生原因 坏块的产生原因...

    oracle数据管理指南

    逻辑结构包括表空间、段、区和块。物理结构涉及数据文件、控制文件、重做日志文件等。管理员需要监控空间使用情况,合理分配表空间,调整数据文件大小,以及进行表空间扩展或收缩。 3. **管理对象和容量**:对象...

    oracle dul source code

    1. **Oracle数据格式**:理解Oracle数据库的数据存储结构,包括数据块、行链接、块内数据组织等。这涉及到Oracle的物理存储机制,如ROWIDs(行标识符)和块头信息。 2. **数据读取**:源代码可能包含使用Oracle的低...

    oracle数据库性能优化与内部原理解析

    Oracle数据库是关系型数据库管理系统(RDBMS),其内部由多个层次构成,包括实例(Instance)、数据库(Database)、表空间(Tablespace)、数据文件(Datafile)、段(Segment)、区(Extent)以及数据块(Data ...

    oracle核心技术路易斯

    #### 二、Oracle数据块结构与管理 在Oracle数据库中,数据是以块的形式存储的,每个块包含了一定数量的数据记录。数据块的管理和维护对于保证数据的一致性和完整性至关重要。 - **数据块的基本组成**:一个典型的...

    dissassembling_the_data_block-converted(1).docx

    Oracle数据块是数据库存储的基本单位,包含了表空间、段、区和块等层次的结构。在Oracle bbed中,你可以拆解这些数据块,理解其内部结构,包括行目录、数据、索引信息等。数据块的拆解过程涉及解析块头信息、行指针...

    oracle数据库体系结构之一【内存结构】.docx

    在Oracle 9i之前,数据缓冲区大小由DB_BLOCK_BUFFERS参数控制,而在后续版本中,使用DB_CACHE_SIZE和DB_nK_CACHE_SIZE参数来设定不同大小的数据块缓存。通过计算数据缓冲区的命中率(BUFFER HIT RATIO),可以评估其...

    Oracle数据库结构 - ch4.pptx

    逻辑数据库空间按照由小到大的顺序分别为数据块(Data Block)、区(Extent)、段(Segment)和表空间(Tablespace)。逻辑数据库是由若干表空间组成,每个表空间由若干个段组成,每个段由若干区组成,每个区是由若干个连续...

    Oracle 12c硬核知识点逻辑存储结构深入浅出

    逻辑存储结构主要包括数据块(Data Block)、扩展区(Extent)、段(Segment)以及表空间(Tablespace)。 - **数据块**:这是Oracle数据库中最小的数据存储单位,也是I/O操作的基本单位。 - **扩展区**:一组连续...

    ORACLE BBED一些案例

    **BBED**(Block Browser and Editor)是Oracle提供的一款用于查看和编辑数据库块内部结构的强大工具。它允许用户直接访问Oracle数据库文件系统中的数据块,并对其进行修改。尽管BBED在现代Oracle版本中已较少被直接...

    Oracle数据库的体系结构和操作及网络配置.pptx

    DB_BLOCK_SIZE参数决定了数据块的大小,而DB_BLOCK_BUFFERS参数则定义了数据块的数量,两者相乘即为数据缓冲区的总大小。 当用户通过应用程序连接到Oracle服务器时,会涉及用户进程和服务器进程。用户进程发起SQL...

    oracle逻辑结构详解

    本文将从数据库、表空间、数据段、区(Extent)、块(Block)等多个层面深入解析Oracle数据库的逻辑结构。 #### 一、表空间(Tablespace) **1. 表空间概述** - **功能和作用:** - 组织数据段空间,通过这种方式...

    oracle 11g architecture diagram

    1. **逻辑存储结构**:Oracle 11g的逻辑存储结构主要包括表空间(Tablespace)、段(Segment)、区(Extent)和块(Block)。其中,表空间是最顶层的概念,可以看作是物理磁盘上的一个或多个文件,用于存储数据库的...

    oracle9I的坏块错误。

    例如,我们可能会看到类似于“ORA-01578: ORACLE data block corrupted”的错误消息,这表明存在物理损坏的数据块。 坏块错误的影响广泛,可能会影响数据的完整性和一致性,导致查询失败、应用崩溃或者性能下降。...

    Oracle bbed工具

    - **数据块(Data Blocks)**:Oracle数据库的基本存储单元,包含行、索引和其他数据库对象的数据。 - **块地址(Block Address)**:每个数据块都有一个唯一的地址,用于定位它在磁盘上的位置。 - **头信息(Header...

Global site tag (gtag.js) - Google Analytics