延遲塊清理介紹(select也會產生redo的原因)

a960549548發表於2024-02-29

Oracle 中資料鎖(這裡主要指 TX 型別行鎖)實際上是資料的屬性,儲存在塊首部,稱之為事務槽 (ITL)

COMMIT 操作的職責包括釋放塊上的鎖,實際的釋放方式即清除塊上相應的事務槽,但這裡存在一個效能的考量:

 

       設想一個 UPDATE 大量資料的操作,因為執行時間較長, 一部分已修改的塊已被緩衝池 flush out 寫至磁碟 ,當 UPDATE 操作完成執行 COMMIT 操作時,則需要將那些已寫至磁碟的資料塊重新讀入,這將消耗大量 I/O ,並使 COMMIT 操作十分緩慢。

 

下面說說關於上面那句話的理解:

假設有 100 個塊在進行 update ,但是還沒有進行 commit 操作,由於 buffer cache 快被佔滿了,就先將前 20 個塊從緩衝池寫到了磁碟 ( 對應一 部分已修改的塊已被緩衝池 flush out 寫至磁碟 ) ,此時這 20 個塊的記錄的狀態資訊是不對的還是未 commit ,因此在真正 commit 期間,還需要將這些狀態資訊不對的塊重新讀入到 buffer cache 裡進行狀態資訊的修改 ( 對應 需要將那些已寫至磁碟的資料塊重新讀入 ) ,因此會造成許多無用的 I/O ,而且使得 commit 緩慢。

 

因此偉大的 Or acle 在這裡引入了延遲段清理的概念 ( 40689.1)

它留給訪問受更新影響的任何塊的下一個事務 (select update delete insert 都可以 ) 整理 該塊,也就是修改塊的狀態資訊(因此稱為 延遲塊清理 )。

對待存在以下情況的塊 COMMIT 操作不做塊清除 ( 而是轉為延遲清除 )

1 、在更新過程中,被緩衝池 flush out 寫至磁碟的塊 若更新操作涉及的塊超過了塊緩衝區快取的 10% 時,超出的部分塊

2 、被其他事務被順帶著從 buffer 刷到了磁碟上的塊 (buffer cache 是一個整體,不會看你是哪個事務來分開來去刷到磁碟上 )

 

        雖然 COMMIT 放棄對這些塊的塊清除 (block cleanout) 操作,但 COMMIT 操作仍會修改回滾段的段頭,回滾段的段頭包括了段中的事務的字典, COMMIT 操作將本事務轉化為非 ACTIVE 狀態。當下一次操作 ( 事務 ) SELECT,UPDATE,INSERT DELETE 訪問到這些塊時可能需要在讀入後完成塊清除,這樣的操作稱之為塊延遲清除( deferred block cleanout )。

         塊延遲清除透過事務槽上的回滾段號,槽號等資訊訪問回滾段頭的事務字典,若事務不再活躍或事務過期則完成清除塊上的事務槽,事務槽清除後繼續執行相應的操作。

         總結來說塊延遲清除是 COMMIT 操作的一個延續,始終是一種十分輕微的操作,且該種操作是行級的,不會使段 (Segment) 的屬性有所改變。

        塊延遲清除的影響在 SELECT 操作過程中體現的最為明顯。在 select 時若發生了延遲塊清除,就會去修改塊的狀態資訊, 因此會產生 redo


來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70013625/viewspace-3007707/,如需轉載,請註明出處,否則將追究法律責任。

相關文章