Oracle Redo&undo
Oracle中的redo和undo是關鍵技術的核心, 諸如實例恢復, 介質恢復, DataGuard, 閃回機制等都是給予redo和undo的, 所以很有必要詳細梳理這塊的知識, 總結記錄.
-
數據變化日志
當我們改變一個數據塊時, 都記錄了哪些日志, 具體是怎么樣的流程呢?
當在Oracle中改變一條數據時, 不僅僅要在數據文件里(可能在buffer里直接找到)找到並修改數據, 更重要的是需要做完善的日志記錄, 具體如下:
- 創建一個重做改變向量, 描述如何往undo塊插入一條undo記錄(即undo的redo日志)
- 創建一個重做改變向量, 描述數據塊的變化(即data的redo日志)
- 合並這兩個重做改變向量為一條日志記錄, 並寫到重做日志緩沖區
- 向undo塊插入undo記錄
- 改變數據塊中的數據
圖1: 更新操作經歷的事件時序圖
-
Redo
redo處理方式:
session -> redo日志 -> 寫入redo log buffer -> 寫到redo日志文件(循環利用) -> 歸檔到日志中
寫redo log buffer會成為系統的瓶頸
session每次數據更改都會插入一條redo記錄到buffer中, 一個session可能很短時間內做了很多更改, 同時可能有很多session並發操作, 卻只有一個redo log buffer.
-
老機制, redo allocation latch: 保護redo log buffer, 控制對共享區內存的訪問.
session -> 請求redo allocation latch -> 為寫入到buffer的信息預留一些空間
避免了多個進程同時寫入buffer相同部分的風險.
大並發系統會出現latch競爭, cpu空轉
-
新機制, private redo和IMU(In-Memory undo)
在session的整個事務期間內, 生成所有改變向量, 寫入private redo log buffer(PGA中), 當事務提交時, session會將private redo buffer中的記錄copy到公共redo log buffer中.
一個session在一次事務里只需要獲取一次公共的redo allocation latch.
e.g
腳步更新表記錄, 觀察期間latch統計信息.
-
9i的輸出:
Gets Im_Gets opy 0 llocation 53 alue ntries ize -
10g的輸出:
Gets Im_Gets opy 0 llocation 5 ory undo latch 53 alue ntries ize
10g里, redo copy latch只命中了一次; redo allocation latch也get很少; 只生成了一個redo entry;
測試中發現, 貌似競爭問題轉移了?
-
-
待跟進:
- 分析v$latch_children, 搞清楚為什么latch活動的變化不是新的威脅(瓶頸);
- 分析重做日志, 搞清楚那個大的日志條目(redo entry)都記錄了什么;
- 分析動態性能表(x$kcrfstrand和x$ktifp), 理解各種實例活動信息是如何串聯到一起的;
-
redo的2組內存結構:
- x$kcrfstrand, 私有redo區: 處理"前滾"改變向量(私有redo區里也包含傳統的"公共"redo log buffer);
- x$ktifp, IMU區: 處理undo改變向量;
IMU區中有N多IMU池, N取決於數據庫參數transactions/10, 每個池都有自己的latch.
x$ktifp中的每條記錄(即IMU)在x$kcrfstrand中都有對應的一條private redo記錄.
x$kcrfstrand中的每條private redo記錄都由其自身的redo allocation latch保護, 每條"公共"的重做記錄都由傳統的redo copy latch保護.
-
In-Memory undo latch(IMU latch):
任何一個改變都會產生一次對IMU latch的訪問, 用一個latch(IMU latch)代替兩個(redo allocation latch與redo copy latch), 至少latch競爭是減半了.
IMU latch有許多子latch, 每個子latch負責一個IMU內存區域(池).
-
新機制的redo allocation latch:
2種latch:
- 一類保護私有redo線程(private redo thread)
- 另一類保護公共redo線程(public redo thread)
每個線程都有自己的latch
-
-
undo
-
讀一致性
塊的ITL entries里必須包含一個指向undo記錄的指針(指針是有限的)
-
回滾
-