国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

buffer cache深度分析:概念以及內存結構

2024-07-21 02:32:46
字體:
來源:轉載
供稿:網友
    本文首先具體介紹了Oracle中buffer cache的概念以及所包含的內存結構。然后結合各個后臺進程(包括DBWRn、CKPT、LGWR等)深入介紹了oracle對于buffer cache的治理機制,并具體解釋了oracle為什么會采用現在的治理機制,是為了解決什么問題。 比如為何會引入toUCh次數、為何會引入增量檢查點等等。最后全面介紹了有關buffer cache監控以及調優的實用方法。

1. buffer cache的概念
  用最簡單的語言來描述oracle數據庫的本質,其實就是能夠用磁盤上的一堆文件來存儲數據,并提供了各種各樣的手段對這些數據進行治理。作為治理數據的最基本要求就是能夠保存和讀取磁盤上的文件中的數據。眾所周知,讀取磁盤的速度相對來說是非常慢的,而內存相對速度則要快的多。因此為了能夠加快處理數據的速度,oracle必須將讀取過的數據緩存在內存里。而oracle對這些緩存在內存里的數據起了個名字:數據高速緩存區(db buffer cache),通常就叫做buffer cache。按照oracle官方的說法,buffer cache就是一塊含有許多數據塊的內存區域,而這些數據塊主要都是數據文件里的數據塊內容的拷貝。通過初始化參數:buffer_cache_size來指定buffer cache的大小。oracle實例一旦啟動,該區域大小就被分配好了。

buffer cache所能提供的功能主要包括:
1) 通過緩存數據塊,從而減少I/O。
2) 通過構造CR塊,從而提供讀一致性功能。
3) 通過提供各種lock、latch機制,從而提供多個進程并發訪問同一個數據塊的功能。
2.buffer cache的內存結構

2.1 buffer cache概述
oracle內部在實現其治理的過程中,有兩個非常有名的名詞:鏈表和hash算法。
鏈表是一種數據結構,通過將對象串連在一起,從而構成鏈表結構。這樣,假如要修改、刪除、查找某個對象的話,都可以先到鏈表中去查找,而不必實際的訪問物理介質。oracle中最有名的鏈表大概就是LRU鏈表了,我們后面會介紹它。

  而hash算法則是為了能夠進行快速查找定位所使用一種技術。所謂hash算法,就是根據要查找的值,對該值進行一定的hash算法后得出該值所在的索引號,然后進入到該值應該存在的一列數值列表(可以理解為一個二維數組)里,通過該索引號去找它應該屬于哪一個列表。然后再進入所確定的列表里,對其中所含有的值,進行一個一個的比較,從而找到該值。這樣就避免了對整個數值列表進行掃描才能找到該值,這種全掃描的方式顯然要比hash查找方式低效很多。其中,每個索引號對應的數值列在oracle里都叫做一個hash bucket。

  我們來列舉一個最簡單的hash算法。假設我們的數值列表最多可以有10個元素,也就是有10個hash buckets,每個元素最多可以包含20個數值。則對應的二維數組就是t[10][20]。我們可以定義hash算法為n MOD 10。通過這種算法,可以將所有進入的數據均勻放在10個hash bucket里面,hash bucket編號從0到9。比如,我們把1到100都通過這個hash函數均勻放到這10個hash bucket里,當查找32在哪里時,只要將32 MOD 10等于2,這樣就知道可以到2號hash bucket里去找,也就是到t[2][20]里去找,2號hash bucket里有10個數值,逐個比較2號hash bucket里是否存在32就可以了。

  buffer cache就是使用多個hash bucket來治理的,其hash算法當然比我們前面列舉的要復雜多了。
我們先來看下面這個圖一。這副圖從邏輯上說明了整個buffer cache的結構是怎么樣的。這副圖的右
上角列出了三個名詞:hash bucket、buffer header和hash chain。
buffer cache深度分析:概念以及內存結構(圖一)
  這里的hash bucket就是我們前面說明hash算法中提到的二維數組的第一維。它是通過對buffer header
 里記錄的數據塊地址和數據塊類型運用hash算法以后,得到的組號。
這里的hash chain就是屬于同一個hash bucket的所有buffer header所串起來的鏈表。實際上,hash
bucket只是一個邏輯上的概念。每個hash bucket都是通過不同的hash chain而體現出來的。每個hash chain都會由一個cache buffers chains latch來治理其并發操作。

  而對于buffer header來說,每一個數據塊在被讀入buffer cache時,都會先在buffer cache中構造一個buffer header,buffer header與數據塊一一對應。buffer header包含的主要信息有:
1) 該數據塊在buffer cache中實際的內存地址。就是上圖中的虛線箭頭所表示的意思。
2) 該數據塊的類型,包括data、segment header、undo header、undo block等等。
3) 該buffer header所在的hash chain,是通過在buffer header里保存指向前一個buffer header的指針和指向后一個buffer header的指針的方式實現的。
4) 該buffer header所在的LRU、LRUW、CKPTQ等鏈表(這些鏈表我們后面都會具體說明)。也是通過記錄前后buffer header指針的方式實現。
5) 當前該buffer header所對應的數據塊的狀態以及標記。
6) 該buffer header被訪問(touch)的次數。
7) 正在等待該buffer header的進程列表(waiter list)和正在使用該buffer header的進程列表(user list)。
   
   buffer cache中,缺省的hash bucket的數量或者說缺省有多少條hash chain鏈表,是由一個隱藏參數:
_db_block_hash_buckets決定的。置于該參數的取值,在我的測試中,8i下,該參數缺省為db_block_buffers×2;但是到了9i以后,該參數似乎取的是小于且最接近于db_block_buffers×2的素數。
2.2 轉儲buffer cache
就象實例中的其他內存結構一樣,oracle提供了可以將buffer cache轉儲到跟蹤文件的方法。方法如下:buffer cache深度分析:概念以及內存結構(圖二)ALTER session SET EVENTS 'immediate trace name buffers level level';  這里的level有很多值,分別可以轉儲buffer cache中的不同的內容。level的可選值包括:
1 只轉儲buffer header
2 在level 1的基礎上再轉儲數據塊頭
3 在level 2的基礎上再轉儲數據塊內容
4 轉儲buffer header和hash chain
5 在level 1的基礎上再轉儲數據塊頭和hash chain
6 在level 2的基礎上再轉儲數據塊內容和hash chain
8 轉儲buffer header和hash chain以及users/waiters鏈表
9 在level 1的基礎上再轉儲數據塊頭、hash chain以及users/waiters鏈表
10 在level 2的基礎上再轉儲數據塊內容、hash chain以及users/waiters鏈表我們創建一個簡單的測試表,然后看看轉儲出來的buffer header是什么樣子的。buffer cache深度分析:概念以及內存結構(圖二)SQL> create table buffer_test(id number);buffer cache深度分析:概念以及內存結構(圖二)SQL> select object_id from dba_objects where object_name='BUFFER_TEST';buffer cache深度分析:概念以及內存結構(圖二) OBJECT_IDbuffer cache深度分析:概念以及內存結構(圖二)----------buffer cache深度分析:概念以及內存結構(圖二) 7087buffer cache深度分析:概念以及內存結構(圖二)SQL> insert into buffer_test values(1);buffer cache深度分析:概念以及內存結構(圖二)SQL> commit;buffer cache深度分析:概念以及內存結構(圖二)這時我們知道buffer_test表的object_id是7987,同時,該表中只有2個block具有數據。1個是segment header,另一個就是實際存放了1這個值的數據塊。接著我們把buffer header轉儲出來:

buffer cache深度分析:概念以及內存結構(圖二)SQL> ALTER SESSION SET EVENTS 'immediate trace name buffers level 1';

     到user_dump_dest所定義的目錄下,找到跟蹤文件并打開,可以看到類似下面的信息,這里我們列出前兩個buffer header以及我們建立的object_id為7087的buffer_test表所對應的buffer header的內容:
buffer cache深度分析:概念以及內存結構(圖二)BH (0x637F0720) file#: 1 rdba: 0x004011ed (1/4589) class 1 ba: 0x63570000buffer cache深度分析:概念以及內存結構(圖二)…………………………………buffer cache深度分析:概念以及內存結構(圖二) hash: [64be8000,65a5eab4] lru: [637f06ac,637f0824]buffer cache深度分析:概念以及內存結構(圖二) LRU flags: moved_to_tailbuffer cache深度分析:概念以及內存結構(圖二) ckptq: [NULL] fileq: [NULL]buffer cache深度分析:概念以及內存結構(圖二)…………………………………buffer cache深度分析:概念以及內存結構(圖二)BH (0x64BE8000) file#: 0 rdba: 0x00000000 (0/0) class 0 ba: 0x64800000buffer cache深度分析:概念以及內存結構(圖二)…………………………………buffer cache深度分析:概念以及內存結構(圖二) hash: [65a5eab4,637f0720] lru: [64be8104,65aa3f0c]buffer cache深度分析:概念以及內存結構(圖二)…………………………………buffer cache深度分析:概念以及內存結構(圖二)BH (0x63BEC0A0) file#: 6 rdba: 0x0180b00a (6/45066) class 1 ba: 0x638B0000buffer cache深度分析:概念以及內存結構(圖二) set: 3 dbwrid: 0 obj: 7087 objn: 7087buffer cache深度分析:概念以及內存結構(圖二) hash: [65a9ccd4,65a9ccd4] lru: [63bec1a4,63bec02c]buffer cache深度分析:概念以及內存結構(圖二) ckptq: [65abceb4,63bec66c] fileq: [65abcfbc,63becd10]buffer cache深度分析:概念以及內存結構(圖二) st: XCURRENT md: NULL rsop: 0x00000000 tch: 1buffer cache深度分析:概念以及內存結構(圖二) flags: buffer_dirty gotten_in_current_mode redo_since_readbuffer cache深度分析:概念以及內存結構(圖二) LRBA: [0xe9.229.0] HSCN: [0x0000.00122967] HSUB: [1] RRBA: [0x0.0.0]buffer cache深度分析:概念以及內存結構(圖二)BH (0x63BECAE8) file#: 6 rdba: 0x0180b009 (6/45065) class 4 ba: 0x638CC000buffer cache深度分析:概念以及內存結構(圖二) set: 3 dbwrid: 0 obj: 7087 objn: 7087buffer cache深度分析:概念以及內存結構(圖二) hash: [65a9cbcc,65a9cbcc] lru: [63becbec,63beca74]buffer cache深度分析:概念以及內存結構(圖二) ckptq: [637fc250,63becdc4] fileq: [65ab8ad0,63becdcc]buffer cache深度分析:概念以及內存結構(圖二) st: XCURRENT md: NULL rsop: 0x00000000 tch: 2buffer cache深度分析:概念以及內存結構(圖二) flags: buffer_dirty gotten_in_current_mode redo_since_readbuffer cache深度分析:概念以及內存結構(圖二) LRBA: [0xe9.21b.0] HSCN: [0x0000.00122965] HSUB: [1] RRBA: [0x0.0.0]buffer cache深度分析:概念以及內存結構(圖二)…………………………………buffer cache深度分析:概念以及內存結構(圖二)

    我們可以看到第一個BH (0x637F0720)的hash: [64be8000,65a5eab4]和第二個BH (0x64BE8000)的hash:[65a5eab4,637f0720]。這里記錄的就是指向前一個buffer header和后一個buffer header的指針。這里,我們看到第一個BH所指向的后一個buffer header的指針是65a5eab4,而第二個BH所指向的前一個buffer header的指針也是65a5eab4,說明這兩個buffer header是在同一個hash chain上。同樣的,我們還可以看到類似結構的lru、ckptq、fileq,這些都是治理buffer header的一些鏈表結構。

  然后,我們來看我們創建的buffer_test表所對應的buffer header。  首先,我們看到class,表示該buffer header所對應的數據塊的類型,具體的值與含義的對應為:1=data block;2=sort block;3=save undo block;4=segment header;5=save undo header;6=free list;7=extent map;8=1st level bmb;9=2nd level bmb;10=3rd level bmb;11=bitmap block;12=bitmap index block;13=unused;14=undo header;15=undo block。我們可以看到與buffer_test表相關buffer header有兩個:一個是4(segment header),另一個是1(data block)。
 
  然后,我們看到rdba,這表示buffer header所對應的數據塊的地址。我們可以看到class為1的buffer header的rdba為0x0180b00a (6/45066)。說明該數據塊的位置是6號文件的45066號block里。018表示數據文件號乘以4,而b00a表示數據塊的號。
buffer cache深度分析:概念以及內存結構(圖二)SQL> select to_number('018','xxx')/4 as file#,to_number('b00a','xxxx')
as block# from dual;buffer cache深度分析:概念以及內存結構(圖二) FILE# BLOCK#buffer cache深度分析:概念以及內存結構(圖二)---------- ----------buffer cache深度分析:概念以及內存結構(圖二) 6 45066我們看到,該buffer header指向的就是6號文件里的45066號數據塊。我們可以再來看看表buffer_test
里的rowid所告訴我們的文件號以及數據塊號,從下面可以看到,結果是一樣的。
buffer cache深度分析:概念以及內存結構(圖二)SQL> select id,dbms_rowid.rowid_relative_fno(rowid) as file#,buffer cache深度分析:概念以及內存結構(圖二) 2 dbms_rowid.rowid_block_number(rowid) as block# from cost.buffer_test;buffer cache深度分析:概念以及內存結構(圖二) ID FILE# BLOCK#buffer cache深度分析:概念以及內存結構(圖二)---------- ---------- ----------buffer cache深度分析:概念以及內存結構(圖二) 1 6 45066

  我們可以來看一下st,這表示buffer cache所指向的數據塊的狀態。一共有六種狀態:FREE(0)=可以被重用的數據塊;XCURRENT(1)=實例以排他方式獲取的當前模式數據塊;SCURRENT(2)=可以與其他實例共享的當前模式數據塊;CR(3)=作為一致性讀鏡像的數據塊,永遠不會被寫入磁盤;READING(4)=正在從磁盤讀出的數據塊;MRECOVERY(5)=正在進行介質恢復的數據塊;IRECOVERY(6)=正在進行實例恢復的數據塊。從狀態說明中我們可以看到,現在表buffer_test的數據塊都是當前模式的數據塊。我們可以來構造一個CR狀態的數據塊。
分別建立兩個session,在一個session中,執行:
buffer cache深度分析:概念以及內存結構(圖二)SQL> update buffer_test set id=2 where id=1;不要提交,然后在另外一個session中,執行:
buffer cache深度分析:概念以及內存結構(圖二)SQL> select * from buffer_test;buffer cache深度分析:概念以及內存結構(圖二) IDbuffer cache深度分析:概念以及內存結構(圖二)----------buffer cache深度分析:概念以及內存結構(圖二) 1
  然后我們轉儲buffer header后,到跟蹤文件中找到obj為7087的記錄,可以看到類似如下的內容。可以看到該buffer header的狀態就是CR。
buffer cache深度分析:概念以及內存結構(圖二)…………………………………buffer cache深度分析:概念以及內存結構(圖二)BH (0x63FFBBC8) file#: 6 rdba: 0x0180b00a (6/45066) class 1 ba: 0x63F5C000buffer cache深度分析:概念以及內存結構(圖二)…………………………………buffer cache深度分析:概念以及內存結構(圖二) ckptq: [NULL] fileq: [NULL]buffer cache深度分析:概念以及內存結構(圖二) st: CR md: NULL rsop: 0x00000000 tch: 0buffer cache深度分析:概念以及內存結構(圖二)…………………………………buffer cache深度分析:概念以及內存結構(圖二)

  另外,我們還可以看到tch,就是表示該數據塊被掃描的次數。 以上這些是轉儲出來的內容。Oracle還提供了視圖來顯示buffer header的內容,這就是X$BH。這個視圖就是把轉儲到平面文件以后所看到的諸如hash、st、tch等的值以列的方式呈現出來。這里就不做過多的介紹了,有愛好的話,可以將該視圖取出的結果與轉儲出來的文件進行比較,就可以知道每一列的含義。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 建昌县| 高青县| 闽清县| 寻乌县| 栾城县| 祁东县| 聂荣县| 宜阳县| 西吉县| 保靖县| 庆云县| 武强县| 株洲县| 会理县| 桑日县| 基隆市| 绥化市| 峡江县| 北宁市| 咸宁市| 邹平县| 志丹县| 安康市| 普宁市| 兴和县| 南乐县| 通州区| 龙泉市| 和平县| 洛南县| 白银市| 洱源县| 沙河市| 河津市| 灵石县| 墨竹工卡县| 革吉县| 济宁市| 临西县| 安溪县| 博兴县|