Oracle讀取和修改資料區塊的過程
Oracle資料庫處理SQL都會經過三個過程:解析(parse)、執行(exec)、返回結果(fetch)。為了便於理解,我們首先省略的SQL的處理過程,而直接介紹資料區塊的讀取或修改過程。
物理讀和邏輯讀概念
1.對要訪問的塊地址做HASH
HASH(FILE#,BLOCK#) = hash_value(HV)
2.根據HV找到對應的HASH bucket
3.搜尋bucket中的HASH chain鏈表,比對chain上的buffer_header(BH).
邏輯讀
1.找到BH後,讀取BH中的(buffer_address)BA
2.根據BA訪問buffer_cache中的目標buffer.
物理讀
1.搜遍hash_chain上的BH都沒有找到目標BH
2.從DBF中載入block到buffer中.
3.並將buffer頭鏈入對應的BUCKET中的hash chain上.
4.訪問buffer.
latch和pin
buffer_cache中的buffer對每個server_process而已都是公有資源誰都可以讀,誰都可以改,為保證這些鏈不被並發修改導致破壞。oracle採用latch和buffer_pin鎖來控制對記憶體結構體使用時的並發。
CBC latch
某個伺服器處理序在chain上搜尋BH時,另一個進程要做入鏈出鏈的操作,對於一個buffer,兩個進程同時都要去做出入鏈,記憶體則沒有安全保證。為保證這些鏈不被並發修改導致破壞
例如:我在搜尋鏈表上的buffer_header時,你不能更改鏈表,我在更改鏈表時,你不能遍曆鏈表
oracle對hash_chain必須加以保護。 oracle採取的保護方式就是latch(閂鎖),確切的說是:cache buffer chain latch,簡稱為: CBC latch。
buffer pin
當在hash_chain上找到目標BH時,根據訪問方式要對BH加鎖.才能根據(buffer_address)BA訪問buffer。這把上在buffer_header上的鎖稱之為buffer pin
共用與獨佔
無論是CBC latch還是buffer pin都有鎖的保持模式。他們都有共用和獨佔模式,對公有資源而言,有獨佔就有爭用。
CBC latch何時共用持有:
1.讀非唯一索引的根塊+分支塊
注意:讀非唯一索引的葉子塊是排他.
2.通過唯一索引訪問時,索引的根塊+分支塊+葉子塊+表塊
原因:因為根塊和分支塊的訪問頻度高,而且很少改動。
CBC latch何時獨佔持有:
1.所有涉及改的操作。
2.以及上面列出的共用持有以外的所有讀操作.
通過上面的比較是否更深入的理解 INDEX UNIQUE SCAN 和 INDEX RANGE SCAN建索引能唯一就唯一,絕對不會錯。
擷取CBC latch的目的是什麼?
1.在hash chain上的雙向鏈表搜尋BH
2.在BH中修改buffer pin鎖的狀態
buffer pin何時共用持有:通過BH中的BA讀buffer
buffer pin何時獨佔持有:通過BH中的BA寫buffer
buffer pin何時無需持有:
1.所有不涉及索引的根塊+分支塊改動的讀(分裂)
2.唯一索引葉子塊+表塊
BH上的隊列:
users list對buffer操作的進程列表,相容模式操作
waiter list因訪問模式不相容,等待隊列中的使用者
再給大家進一步介紹Hash Latches、HashBucket 、buffer Header及Buffer cache之間的關係圖。
Oracle讀取或修改資料區塊的流程:
一.(讀操作)非唯一索引方式,非索引根塊和分支塊
1. 對要訪問的塊地址做HASH
HASH(FILE#,BLOCK#) = hash_value(HV)
2. 根據HV找到對應的HASH bucket
3. 以獨佔方式申請管轄此bucket的CBC latch
4. 搜尋bucket中的HASH chain鏈表,比對chain上的buffer_header(BH),找到目標BH
5. 修改BH中的buffer pin鎖為S(share)模式(之前為0,無鎖)
6. 釋放CBC latch.
7. 根據BH中的BA指標找到buffer
8. 讀取buffer中的資料到PGA中.
9. 以獨佔方式申請管轄此bucket的CBC latch
10.修改BH中的buffer pin鎖為0(無鎖)模式
11.釋放CBC latch
二.(讀操作)唯一索引方式所有塊,非唯一索引根塊和分支塊
1. 對要訪問的塊地址做HASH
HASH(FILE#,BLOCK#) = hash_value(HV)
2. 根據HV找到對應的HASH bucket
3. 以共用方式申請管轄此bucket的CBC latch
4. 搜尋bucket中的HASH chain鏈表,比對chain上的buffer_header(BH),找到目標BH
5. 根據BH中的BA指標找到buffer
6. 讀取buffer中的資料到PGA中
7. 釋放CBC latch
三.(寫操作)
1. 對要訪問的塊地址做HASH
HASH(FILE#,BLOCK#) = hash_value(HV)
2. 根據HV找到對應的HASH bucket
3. 以獨佔方式申請管轄此bucket的CBC latch
4. 搜尋bucket中的HASH chain鏈表,比對chain上的buffer_header(BH),找到目標BH
5. 修改BH中的buffer pin鎖為X(exclusive)模式(之前為0,無鎖)
6. 釋放CBC latch
7. 根據BH中的BA指標找到buffer
8. 產生redo資料
8. 修改buffer中的資料.
9. 以獨佔方式申請管轄此bucket的CBC latch.
10.修改BH中的buffer pin鎖為0模式
11.釋放CBC latch.