redis筆記 1. Redis是什麼? Redis( Remote Dictionary Server )是一個使用 C 語言編寫的,高性能非關係型的鍵值對資料庫。 與傳統資料庫不同的是,Redis 的數據是存在記憶體中的,所以讀寫速度非常快,被廣泛應用於緩存方 向。Redis可以將數據寫入磁碟中, ...
1 redo
1.1 redo是什麼
oracle資料庫幾乎所有的操作都會產生redo日誌。redo日誌可以分為線上redo日誌和歸檔redo日誌。當資料庫實例失敗時,資料庫會使用redo日誌恢複數據。
1.2 線上重做日誌和歸檔重做日誌
1.2.1 線上重做日誌
資料庫的操作產生的redo日誌會先存放在線上重做日誌中。線上重做日誌在oracle中至少有兩組重做日誌,每組重做日誌包含一個或者多個線上重做日誌文件,同一組內的線上重做日誌內容完全一樣。日誌切換是指當一組線上重做日誌寫滿時,oracle清空下一組線上重做日誌併在下一組寫入重做日誌。所以,線上重做日誌是迴圈使用的。
1.2.2 歸檔重做日誌
如果資料庫開啟了日誌歸檔,當一組線上重做日誌填滿時,就會將這組線上重做日誌進行歸檔,這些歸檔的日誌就是歸檔重做日誌。
1.3 實例恢復和介質恢復
實例恢復一般是指資料庫實例發生故障,例如系統突然崩潰,使用shutdown abort關閉數據資料庫。資料庫重啟時就會自動進行實例恢復。實例恢復主要使用線上重做日誌進行恢復。
介質恢復是指運行資料庫的磁碟發生損壞,需要使用物理備份進行恢復。物理備份包括資料庫某個時間的快照以及歸檔重做日誌,線上重做日誌。
2 undo
2.1 undo是什麼
當我們對數據進行修改時,就會產生undo,undo存儲在undo段中。我們就是使用undo對修改但未提交的數據進行恢復的。
2.2 undo的作用
- 使用rollback時,利用undo將數據恢復到事務之前的樣子
- 為oracle的讀一致性提供數據保障
- flashback table使用undo將表數據恢復到之前某個時間點
3 提交(commit)和回滾(rollback)處理
3.1 提交(commit)
3.1.1 提交前的工作
通常commit是一個快速的操作,其處理時間和事務大小無關。因此,我們應該儘量避免將一個事務拆分進行多次提交。commit是一個快速的操作,這是因為大部分事務的工作在commit之前已經完成
- 在SGA中生成已修改的數據塊
- 在SGA中生成undo塊
- 在SGA中生成前兩項的redo緩存
- 如果前面執行的比較久,可能SGA中一些緩存數據已經寫入磁碟
- 獲取所需要的鎖
3.1.2 當進行commit時,只需要完成剩下的工作
- 為事務生成一個SCN。SCN是oracle的一個序列機制,用來保證事務的順序,並用來支持實例恢復。此外,它還用於oracle的讀一致性和檢查點。每commit一次,SCN就會增加
- LWGR將還在redo緩存中的redo寫入線上重做日誌。並將SCN記錄在線上重做日誌中。這一步才是資料庫真正的commit。此時事務條目會從V$TRANSACTION中被“刪除”
- 釋放V$lock中記錄該事務的會話中的鎖,從而讓等待鎖的其他事務繼續進行。
- 如果被修改的塊還在資料庫高速緩存中,oracle會進行塊清除。塊清除是指清除資料庫塊首部的一些鎖信息。
從以上可以看出,commit需要做的工作中,耗時最長的是將redo緩存中的redo寫入線上重做日誌。如果,commit進行多次,則需要進行多次等待。需要註意的是,PL/SQL對commit是特殊處理的。如果一個PL/SQL中有多個commit,資料庫不會在PL/SQL進行commit時等待redo緩存中的redo寫入線上重做日誌,而是立刻返回。但是,當PL/SQL執行完,將控制權返回客戶端前,會等待LGWR將對應的所有redo緩存寫入磁碟。雖然如此,也不建議在PL/SQL中使用多次commit。
3.2 回滾(rollback)
當我們進行rollback操作時,會做如下工作
-
撤銷所有修改。oracle使用undo數據撤銷所做的修改。並將對應undo數據標記為已應用。例如之前插入了一條數據,ROLLBACK會將其刪除。
-
釋放V$lock中記錄該事務的會話中的鎖,從而讓等待鎖的其他事務繼續進行。
從以上工作可以看出,rollback的操作的工作量會比commit大很多。commit最大的工作量僅僅是將redo緩存寫入磁碟。
4 臨時表的redo和undo
臨時表(GLOBAL TEMPORARY TABLE)中的事務操作不會產生事務本身的redo,但是會產生undo。undo也會有對應redo,因此臨時表也會redo。但是可以通過設置參數TEMP_UNDO_ENABLED來將臨時表的undo放在臨時表空間中,由於臨時表空間的任何數據變更都不會產生redo,所以當這個參數設置為TRUE時,任何臨時表上的DML都會產生很少甚至不產生redo。
我們可以在會話和系統級別設置參數TEMP_UNDO_ENABLED,下麵我們將這個參數在會話級別設置為 TRUE。
alter session set temp_undo_enabled=true;
5 資料庫如何利用redo進行實例恢復
一個事務commit成功是指該事務對應的redo日誌已經從redo緩存中寫入線上重做日誌。資料庫進行實例恢復時,會讀取線上重做日誌的數據。
第一步是cache recovery,SMON根據最後一次檢查點後的線上重做日誌執行日誌內容,往前滾。這一步完成後,恢復所有commit的數據。線上重做日誌中可能有一些沒有commit的redo日誌,因此這一步完成後,資料庫高速緩存中也會有一些未提交的資料庫。
第二步是Transaction Recovery,根據線上重做日誌的undo回滾未提交的數據。