對Oracle高水位線的研究實踐
高水位線是Oracle段物件的一個重要引數。對Oracle Segment物件而言,HWM(High Water Mark)標記著資料使用過的最高位置,有時也稱為格式化過的資料位置。
當Oracle資料表進行FTS(全表掃描)操作的時候,會從段頭一直檢索到HWM位置。本篇中,我們一起從邏輯結構分析的角度,來研究一下HWM的確切位置。
1、環境準備
我們選擇在Oracle 10g下進行試驗,準備資料表T。
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
SQL> show user
User is "SYS"
SQL> create table t as select * from dba_objects;
Table created
SQL> exec dbms_stats.gather_table_stats(user,'T',cascade => true);
PL/SQL procedure successfully completed
2、原始HWM位置分析
根據Oracle“表-段-區-塊”的層次順序,分析一下對應資料表的情況。
SQL> select HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS, EXTENTS from dba_segments where wner='SYS' and segment_name='T';
HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS
----------- ------------ ---------- ---------- ----------
1 63057 6291456 768 21
對應768個資料塊,包括21個分割槽中。
SQL> select EXTENT_ID, FILE_ID, BLOCK_ID, BYTES, BLOCKS from dba_extents where wner='SYS' and segment_name='T';
EXTENT_ID FILE_ID BLOCK_ID BYTES BLOCKS
---------- ---------- ---------- ---------- ----------
0 1 63057 65536 8
(篇幅原因,有省略……)
19 1 63881 1048576 128
20 1 64009 1048576 128
21 rows selected
Oracle對segment的空間分配,是按照一個extent一個extent進行的。噹噹前的extent使用完,並且沒有可以使用的空間時,Oracle會給segment一個新的extent使用,分配新的extent_id編號。
HWM記錄的位置是在資料段segment的段頭塊中。我們透過dba_segments檢視,可以知道對應的段頭塊為fno=1,blockno=63057。我們使用dump命令,可以將其邏輯結構展現出來。
SQL> select f_get_trace_name from dual;
F_GET_TRACE_NAME
--------------------------------------------------------------------------------
D:\ADMIN\ORCL\UDUMP\orcl_ora_1984.trc
SQL> alter system dump datafile 1 block 63057;
System altered
在trace檔案中,我們找到HWM位置記錄和對應的Extent分配map。
Extent Header:: spare1: 0 spare2: 0 #extents: 21 #blocks: 767
last map 0x00000000 #maps: 0 offset: 4128
Highwater:: 0x0040fa42 ext#: 20 blk#: 57 ext size: 128
#blocks in seg. hdr's freelists: 0
#blocks below: 696
mapblk 0x00000000 offset: 20
Unlocked
Map Header:: next 0x00000000 #extents: 21 obj#: 56436 flag: 0x40000000
Extent Map
-----------------------------------------------------------------
0x0040f652 length: 7
0x0040f659 length: 8
(篇幅原因,省略…..)
0x0040f909 length: 128
0x0040f989 length: 128
0x0040fa09 length: 128
從extent allocation map中,我們可以看到對應的21個extents使用分配情況。段頭塊中記錄著HWM的位置地址,其中的(Highwater:: 0x0040fa42)就表示這個具體位置。
注意:當Oracle要進行FTS的時候,首先訪問的就是段頭segment header塊。從其中,可以獲得分配的分割槽資訊(Map Header)和Scan截止位置HWM。
下面考慮解析HWM地址。在Oracle 10g中,我們可以使用dbms_utility包方法進行解析。
SQL> select to_number('40fa42','xxxxxx') from dual;
TO_NUMBER('40FA42','XXXXXX')
----------------------------
4258370
SQL> select dbms_utility.data_block_address_file(4258370) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRES
------------------------------
1
SQL> select dbms_utility.data_block_address_block(4258370) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRES
------------------------------
64066
可以知道,對應HWM指向的位置是在檔案編號為1的檔案中,對應塊號為64066。
那麼,我們檢查一下這個位置在哪裡。
SQL> select EXTENT_ID, FILE_ID, BLOCK_ID, BYTES, BLOCKS from dba_extents where wner='SYS' and segment_name='T' and (block_id<=64066 and block_id+blocks-1>=64066) and file_id=1;
EXTENT_ID FILE_ID BLOCK_ID BYTES BLOCKS
---------- ---------- ---------- ---------- ----------
20 1 64009 1048576 128
對應的blockno=64066為最大extent編號下的一個資料塊。我們可以看一下對應的相鄰資料塊中內容。
--高水位線對應資料塊
SQL> select count(*) from t where dbms_rowid.rowid_relative_fno(t.rowid)=1 and dbms_rowid.rowid_block_number(t.rowid)=64066;
COUNT(*)
----------
0
-高水位線對應上一個資料塊
SQL> select count(*) from t where dbms_rowid.rowid_relative_fno(t.rowid)=1 and dbms_rowid.rowid_block_number(t.rowid)=64065;
COUNT(*)
----------
1
---高水位線對應上上個資料塊
SQL> select count(*) from t where dbms_rowid.rowid_relative_fno(t.rowid)=1 and dbms_rowid.rowid_block_number(t.rowid)=64064;
COUNT(*)
----------
65
---高水位線對應下一個資料塊
SQL> select count(*) from t where dbms_rowid.rowid_relative_fno(t.rowid)=1 and dbms_rowid.rowid_block_number(t.rowid)=64067;
COUNT(*)
----------
0
從上面的資料,我們可以清晰的看到HWM的對應。HWM位於segment編號最大的extent中的一個資料塊。在Oracle中,HWM對應的資料塊是那個沒有使用過的資料塊。HWM上面的就是正在使用的最大資料塊。
那麼,我們觀察一下,在新增和刪除過程中,HWM的變化情況。
3、HWM變化
下面我們觀察一下HWM在insert,delete和move操作時候的變化。
當進行insert操作時,如果是一個heap表的話,首先會在堆中尋找空位插入。如果沒有找到,就推高HWM到一個新的塊位置。
我們繼續在上面實驗的基礎上,進行試驗。
SQL> insert into t select * from dba_objects where wner='SCOTT';
25 rows inserted
SQL> commit;
Commit complete
此時,我們dump出資料塊檢視HWM情況。
Extent Header:: spare1: 0 spare2: 0 #extents: 21 #blocks: 767
last map 0x00000000 #maps: 0 offset: 4128
Highwater:: 0x0040fa47 ext#: 20 blk#: 62 ext size: 128
#blocks in seg. hdr's freelists: 5
#blocks below: 701
水位線位置從原來的0x0040fa42變化到0x0040fa47。真實對應的位置如下:
SQL> select to_number('40fa47','xxxxxx') from dual;
TO_NUMBER('40FA47','XXXXXX')
----------------------------
4258375
SQL> select dbms_utility.data_block_address_file(4258375) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRES
------------------------------
1
SQL> select dbms_utility.data_block_address_block(4258375) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRES
------------------------------
64071
對應從原來的64066塊偏移到了64071塊,移動了5個資料塊。結論:確實insert操作可能會推高水位線位置。
那麼,一般的delete操作呢?
SQL> delete t where wner='SCOTT';
50 rows deleted
SQL> commit;
Commit complete
SQL> alter system dump datafile 1 block 63057;
System altered
此時,HWM位置為:
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 21 #blocks: 767
last map 0x00000000 #maps: 0 offset: 4128
Highwater:: 0x0040fa47 ext#: 20 blk#: 62 ext size: 128
#blocks in seg. hdr's freelists: 6
#blocks below: 701
mapblk 0x00000000 offset: 20
Unlocked
Map Header:: next 0x00000000 #extents: 21 obj#: 56436 flag: 0x40000000
資料HWM位置沒有發生變化,說明HWM確實不會在delete的時候下降。
影響HWM下降的兩個常見命令,Move和Truncate效果如何呢?
SQL> alter table t move;
Table altered
SQL> select HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS, EXTENTS from dba_segments where wner='SYS' and segment_name='T';
HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS
----------- ------------ ---------- ---------- ----------
1 63441 6291456 768 21
此時,頭塊位置已經發生改變!!
SQL> alter system dump datafile 1 block 63441;
System altered
Move操作影響到了頭塊位置,HWM位置必然發生變化。
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 21 #blocks: 767
last map 0x00000000 #maps: 0 offset: 4128
Highwater:: 0x0040fd41 ext#: 20 blk#: 56 ext size: 128
#blocks in seg. hdr's freelists: 0
#blocks below: 695
mapblk 0x00000000 offset: 20
Disk Lock:: Locked by xid: 0x0006.007.000005a6
Map Header:: next 0x00000000 #extents: 21 obj#: 56512 flag: 0x40000000
最後,我們一起看一下truncate table命令。
SQL> truncate table t;
Table truncated
SQL> select HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS, EXTENTS from dba_segments where wner='SYS' and segment_name='T';
HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS
----------- ------------ ---------- ---------- ----------
1 63441 65536 8 1
注意:truncated table命令是不會影響到段頭塊的。
我們dump出頭塊情況。
SQL> alter system dump datafile 1 block 63441;
System altered
Dump出的資料塊結構如下:
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 7
last map 0x00000000 #maps: 0 offset: 4128
Highwater:: 0x0040f7d2 ext#: 0 blk#: 0 ext size: 7
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
Disk Lock:: Locked by xid: 0x0008.001.0000058b
Map Header:: next 0x00000000 #extents: 1 obj#: 56513 flag: 0x40000000
Extent Map
-----------------------------------------------------------------
0x0040f7d2 length: 7
nfl = 1, nfb = 1 typ = 1 nxf = 0 ccnt = 0
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
水位線下降到什麼位置呢?我們計算一下這個:0x0040f7d2。
SQL> select to_number('40f7d2','xxxxxx') from dual;
TO_NUMBER('40F7D2','XXXXXX')
----------------------------
4257746
SQL> select dbms_utility.data_block_address_block(4257746) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRES
------------------------------
63442
SQL> select dbms_utility.data_block_address_file(4257746) from dual;
DBMS_UTILITY.DATA_BLOCK_ADDRES
------------------------------
1
注意:這裡的HWM指向塊號為63442。我們的資料段頭塊為63441。說明:在truncate table的時候,HWM要重置到頭塊後面的第一個資料塊上。
4、結論
經過上面的討論,我們已經可以清晰的看到Oracle HWM的位置和工作原則。對segment物件而言,HWM的作用十分重要,需要我們深刻理解。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28389881/viewspace-1255924/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle 高水位線的一點研究Oracle
- oracle 高水位線及如何有效的降低高水位線Oracle
- oracle的高水位線HWMOracle
- oracle的高水位線(HWM)Oracle
- ORACLE 高水位線(HWM)Oracle
- oracle 回收高水位線Oracle
- Oracle 降低高水位線Oracle
- oracle回收高水位線Oracle
- 降低Oracle高水位線的方法Oracle
- Oracle的高水位線介紹Oracle
- oracle高水位線處理Oracle
- Oracle之降低高水位線Oracle
- oracle 高水位線詳解Oracle
- 一、oracle 高水位線詳解Oracle
- Oracle表段中的高水位線HWMOracle
- oracle表碎片以及整理(高水位線)Oracle
- Oracle高水位Oracle
- ORACLE資料庫降低高水位線方法Oracle資料庫
- Oracle delete 高水位線處理問題Oracledelete
- Oracle高水位線(HWM)及效能優化Oracle優化
- oracle回收高水位Oracle
- Oracle 高水位(HWM)Oracle
- Oracle案例10——HWM(高水位線)效能優化Oracle優化
- oracle高水位問題Oracle
- oracle 高水位分析處理Oracle
- Oracle 高水位(HWM)標記Oracle
- delete與高水位線HWM回收delete
- 關於高水位線和deletedelete
- ORACLE的簡單處理高水位Oracle
- ORACLE高水位表的查詢方法Oracle
- 深入瞭解oracle的高水位(HWM)Oracle
- 高水位線、行遷移行連結
- Oracle 找出需要回收高水位的表Oracle
- oracle11g表的高水位線hwm與dbms_space系列一Oracle
- Rollback&Truncate操作對高水位線影響之效能優化篇優化
- Oracle表段中高水位線HWMOracle
- Enq : HW-contention高水位線的擴充套件競爭ENQ套件
- 關於高水位的知識