很多時候我們總會看到CR,但是CR具體是什麼?又有什麼作用呢?當ORACLE 發生一緻性讀得時候,會利用UNDO塊和當前數據塊構造CR塊來獲得一緻性讀。但是既然UNDO已經記錄了前鏡像,為什麼還要辛苦的構造CR塊呢?直接讀取UNDO不就好了嗎?下面一起來探讨下CR。
Cr塊(consistent read塊)也就是用來維護oracle的讀一緻性的數據塊。當查詢某些數據的時候,發現數據塊的版本比我們要查詢的新,例如session1執行了dml操作并沒有提交,session2此時查找跟session1相關的dml操作的數據信息,此時查詢的數據卻是原來的數據信息。
查詢的過程會在undo段中查找該數據塊的前映像後,然後把前映像和current塊合并形成了一個CR block,通過查詢cr block就可以滿足數據的一緻性了。
CR block存在與sga的buffer cache中,在db cache裡申請一個數據塊,然後對應的回滾段的前映像生成cr block。
cr塊的數量是由隐含參數_db_block_max_cr_dba控制的,默認是最高同時存在5個cr塊,構造cr塊時cr block created計數器都會增加1.
由于cr block和current block的數據塊的rdba都是相同的,會放在相同的hash鍊上,當然某些block的cr block的版本過多,自然會引起hash鍊上的競争,導緻latch buffer cache chain闩競争。
當然在利用回滾段的前映像和current block構造cr塊時,很有可能回滾段的已經被覆蓋,也就會出現常見的ora-01555快照過舊。
一個sql語句如何去查詢數據信息了,根據以前的latch基本記載知道獲取該數據塊的latch然後才能對該數據塊進行讀取,其實一個sql訪問數據信息的數據塊,需要像鍊接一樣的結構中去收索這個數據塊是否在内存中,此時訪問鍊表也需要一個latch,如果獲取失敗也就是會産生latch buffer cache chain等待了。
1)克隆這個塊到另一個buffer,克隆的塊跟之前的current塊在一個HASH CHAIN上。我們後面的四個步驟,就是發生在新克隆的塊上的。
2)如果這個塊上存在 延遲塊清除或者快速塊清除,那麼對它進行塊清除的動作。
3)對于塊上所有未提交的事務進行塊級别的回滾,注意這裡并不是回滾整個事務,而是隻針對事務裡修改了這個塊的操作進行回滾。
4)檢查ITL槽位裡,COMMIT SCN有沒有大于查詢時刻SCN(snapshot SCN)的條目,如果有的話,對這個條目涉及到的事務進行塊級别的回滾(類似步驟3)。
5)如果回滾後,ITL槽位裡依然有大于查詢時刻SCN的條目,重複步驟四。
有幾點需要說明:
1)構造一緻性讀發生在克隆塊上,不産生日志。但是在步驟2上,雖然科隆塊不産生日志,但是current block由于也需要做塊清除,所以會産生日志。
2)步驟四可能會發生多次。如果查詢耗時較長,在讀取到某個塊前,N個事務已經對它做了修改提交,那麼這個塊就要發生N次步驟4的操作。
3)構造出來的一緻性讀的塊一般由于TCH數很小很容易被LUR算法抛棄重用。
4)一緻性讀取回滾的隻是這個塊,假如一個事務修改了1000個塊,産生了1000個undo record,但是隻有1個undo recored是這個塊産生的,那麼oracle能夠根據ITL槽位裡記錄的UBA快速的識别到這個undo record,而其他的999條,不會讀取。
後面會分享更多devops和DBA方面的内容,感興趣的朋友可以關注一下~
,
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!