高水位线

高水位线


高水位线 (HWM)是什么呢?从很多书上得到的解释是这样的,它是oracle一个表的segment中已经使用的空间和从来没使用过的空间(unformatted)的一个分界线。 但实际上这种说法不准确。要考虑两个方面两种情况,一种是ASSM,一种是MSSM。

一个segment中HWM之下的空闲空间分配干净了,这时HWM会上移,这样HWM之下就会又分配了一些用于写的数据块。MSSM(手动段空间管理)的做法是在这些块分配完后立即格式化他们,而ASSM(自动段空间管理)的做法则不是。ASSM的做法是先不format这些数据块,只有当一条请求来了,需要写入某一个数据块时,才会格式化这个数据块。所以我们可以知道:

1.在 MSSM中, HWM以下的块都是被格式化过的(不一定存数据,但一定被格式化过)

2.在 ASSM中,  HWM以下的块有些被格式化过,有些没有被格式化过。

所以我们看到前面对HWM的定义不准确,只有在MSSM中我们可以这样理解,但是ASSM中不可以这么理解,因为ASSM中HWM以下有些块是还未被format过的。其实在MSSM中这样理解也不准确,因为在MSSM中,我们可以说HWM之下的块都是被format过的,但不可以说他们是已使用的,因为MSSM的做法是HWM只要上移,就把新分配过来的数据块format掉,这并不代表这些块已经被写入数据了。


low HWM 低高水位线


low HWM只存在与ASSM环境中。在ASSM环境中HWM之下的块被写满后HWM会上移,上移之后原来HWM的位置就会多了一个标记,这个标记就是low HWM。

这个low HWM有什么意义呢? 我们知道在ASSM中 HWM上移后多出来的这部分空间不会立即格式化。这部分空间中的data block只有在被用到的时候才会第一次格式化。那么也就是说在HWM之下有的块是没有format过的,读起来是不安全的。

在全表扫描的时候,oracle会扫描HWM之前的每一个数据块,对于ASSM,因为存在读起来不安全的数据块,所以oracle在读之前就要check这些数据块。可以想象如果每一个数据块都要去check的话无疑是一笔非常大的开销,因此oracle引入了low HWM的概念。

这样在全表扫描的时候,oracle会读取low HWM之前的所有块,对于low HWM和HWM之间的块,oracle会一个一个的check。low HWM之前的块是上一次HWM被写满时的那些块,所以毫无疑问他们是format过的,这样就大大减少了需要check的数据块。


如何查看HWM和low HWM

做如下测试

1.创建一个表 t1 并插入数据

SQL> create table scott.t1 (id number , val char(800));
 
Table created
 
SQL> 
SQL> BEGIN
  2    FOR X IN 1 .. 1000 LOOP
  3      INSERT INTO SCOTT.t1 VALUES(1,'A');
  4    END LOOP;
  5  END;
  6  /
2. 分析表。 要特别注意使用analyze命令而不是dbms_stats包。因为dbms_stats包只分析对CBO有帮助的统计信息,对于space usage information这些信息对CBO没有帮助,是不会统计的,所以要用analyze。

SQL> analyze table scott.t1 compute statistics;
 
Table analyzed
 
SQL> select blocks , empty_blocks from dba_tables where table_name='T1' and owner='SCOTT';
 
    BLOCKS EMPTY_BLOCKS
---------- ------------
       244           12

这里我们可以认为 HWM 和low HWM都是在244 这个数据块处,因为我们这个表只插入了一次数据。


但其实真正的查看方式应该是通过dump来查看。具体做法如下:

1. 查找到该表segment的第一个数据块

SQL> select header_file , header_block from dba_segments where owner='SCOTT' and segment_name='T1';
 
HEADER_FILE HEADER_BLOCK
----------- ------------
          4        55898
 
SQL> 

2. dump该数据块 找到trace文件

SQL> alter system dump datafile 4 block 55898;
 
System altered
 
SQL> select p.tracefile from v$process p , v$session s , v$mystat m
  2  where m.STATISTIC#=0 
  3  and   m.SID=s.SID
  4  and   s.PADDR=p.ADDR;
 
TRACEFILE
--------------------------------------------------------------------------------
/u01/app/oracle/diag/rdbms/sales/sales/trace/sales_ora_2995.trc
 
SQL> 

查看该文件的内容

  Low HighWater Mark :
      Highwater::  0x0100dbd8  ext#: 15     blk#: 8      ext size: 8
  #blocks in seg. hdr's freelists: 0
  #blocks below: 118
  mapblk  0x00000000  offset: 15
  Level 1 BMB for High HWM block: 0x0100dc01
  Level 1 BMB for Low HWM block: 0x0100dbc8

这样,我们就可以看到high water mark 和low high water mark的内容了。但是对于dump文件还要仔细研究。






写这篇文章的初衷是为了回答几个问题:

1. 怎么查看一个表中数据的大小(要注意,是纯数据的大小,不包括曾经有数据但是现在清空的数据块)

2. dba_blocks的值是什么


回答。

1. 表中数据的大小可以通过numrows 乘以 每行的平均长度得到。

2. dba_blocks是一个表中low HWM以下的块和 low HWM 与 HWM中间已经format过的块之和。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值