關于Freelists和Freelist Groups的研究(修訂版)- freelists存儲在
2024-07-21 02:05:33
供稿:網友
三. freelists存儲在哪兒freelists存儲在每個segment的header block中,我們可以通過dump來得到更清楚的認識。dump在研究oracle的內部機制時通常都扮演著很重要的角色。假設我們創建一個表空間ts_test,此表空間是非自動段空間管理的,然后在該表空間中創建t_manual,t_manual_free2,t_manual_freegroup2三張表。這三張表的freelists和freelist groups設置如下。 sql> select segment_name,segment_type,freelists,freelist_groups from user_segments where tablespace_name='ts_test'; segment_name segment_type freelists freelist_groups-------------------- ------------------ ---------- ---------------t_manual table 1 1t_manual_free2 table 2 1t_manual_freegroup2 table 4 2 則可以參照下面的方法對segment header block進行dump操作。首先先從數據字典中得到存儲這個segment的文件號和此segment的第一個block號(也就是segment header block) sql> select file_id,block_id from dba_extents where segment_name='t_manual'; file_id block_id---------- ---------- 7 9 使用dump命令轉儲這個block的內容,轉儲的結果將保存在初始化參數user_dump_dest指定的目錄中。 sql> alter system dump datafile 7 block 9; system altered 查看user_dump_dest目錄中的相應trace文件,我們可以看到包含如下幾行:frmt: 0x02 chkval: 0x0000 type: 0x10=data segment header – unlimited表示這個block正是segment header block。#blocks in seg. hdr's freelists: 2 #blocks below: 2表示位于freelist中的數據塊有2個,在高水位標志(hwm)下的數據塊也有2個。seg lst:: flg: used lhd: 0x01c0000a ltl: 0x01c0000b由于我們dump的是ts_manual表的header block,而這張表的freelists=1,所以在dump文件中看到只有一個seg lst,這個freelist被稱為segment free list或者master free list,每個segment都至少有一個而且只有一個master free list(當然是在非自動段空間管理類型下)。flg(flag)表示該freelist是否被使用lhd(list header)表示位于該list中的第一個可用block的dba(data block address)ltl(list tail)表示位于該list中的最后一個可用block的dba,這個block必定位于hwm之下。此時我們可以發現freelists只是記錄了這個segment中空閑塊的第一個塊地址和最后一個塊地址,在第一個空閑塊的塊頭處(block header)記錄了它之后的下一個空閑塊的地址,而下一個空閑塊又記錄了再下一個空閑塊的地址,由此依次記錄,一直到最后一個空閑塊。oracle通過這種鏈表的方式實現了freelists對于空閑塊的管理。 注意:每次當一個block被加入到free list中時,該block會被放置在free list的鏈表頭部。 同樣我們可以dump第一個空閑塊來驗證上面的鏈表說法。比如在lhd部分記錄的dba是0x01c0000a,這是一個16進制的數,首先轉化為10進制,于是得到29360138。然后通過oracle提供的兩個函數將塊地址轉化為可以供我們使用的文件號和塊號,以便于我們進行dump操作。 sql> select dbms_utility.data_block_address_file(29360138) from dual; dbms_utility.data_block_addres------------------------------ 7 sql> select dbms_utility.data_block_address_block(29360138) from dual; dbms_utility.data_block_addres------------------------------ 10 現在我們已經得到第一個空閑塊是7號文件的10號塊。用前面提到的轉儲命令dump這個塊的內容,我們可以找到下面的內容:fnx: 0x1c0000b表示下一個可用的塊地址是0x1c0000b,在我們的例子這個塊正好是可用的最后一個塊(segment header block中的lhd部分),我們可以再次dump這個0x1c0000b塊,同樣查看轉儲的結果,找到下面的內容:fnx: 0x00x0表示下面沒有可用的空閑塊了,也就是表明這是freelists中的最后一個空閑塊。 注意:你們的測試可能得到跟我不一樣的轉儲內容,這是正常的。