程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> 你是否了解Oracle空閒數據塊

你是否了解Oracle空閒數據塊

編輯:Oracle數據庫基礎

在向大家詳細介紹Oracle空閒數據塊之前,首先讓大家了解下回滾段存儲的數據,然後全面介紹Oracle空閒數據塊,希望對大家有用。在這裡我們要說一下回滾段存儲的數據,假如是delete操作,則回滾段將會記錄整個行的數據,假如是update,則回滾段只記錄行被修改了的字段的變化前的數據(前映像),也就是沒有被修改的字段是不會被記錄的,假如是insert,則回滾段只記錄插入記錄的rowid。

這樣假如事務提交,那回滾段中簡單標記該事務已經提交;假如是回退,則如果操作是delete,回退的時候把回滾段中數據重新寫回數據塊,操作如果是update,則把變化前數據修改回去,操作如果是insert,則根據記錄的rowid把該記錄刪除。注意,檢查點除了觸發LGWR和DBWN向數據塊頭部寫SCN和COMMIT SCN,檢查點還向控制文件和數據文件頭部寫SCN,而用戶的DML和COMMIT僅是向數據塊頭部寫SCN和COMMIT SCN而不更新控制文件和數據文件的SCN,SMON的前滾是以文件頭部的SCN為起始點的也就是從前一個檢查點開始,SMON的回滾是回滾所有回滾段中未標識為已提交的數據塊,用戶的回滾是回滾與此事務有關的回滾段中未標識為已提交的數據塊。

下面我們要講DBWN如何來寫數據文件,在寫數據文件前首先要找到可寫的Oracle空閒數據塊,Oracle空閒數據塊可以通過Freelist或BITMAP來維護,它們位於一個段的頭部用來標識當前段中哪些數據塊可以進行INSERT。在本地管理表空間中Oracle自動管理分配給段的區的大小,只在本地管理的表空間中才能選用段自動管理,采用自動段空間管理的本地管理表空間中的段中的Oracle空閒數據塊的信息就存放在段中某些區的頭部,使用位圖來管理(最普通的情況是一個段的第一個區的第一個塊為FIRST LEVEL BITMAP BLOCK,第二個塊為SECOND LEVEL BITMAP BLOCK,第三個塊為PAGETABLE SEGMENT HEADER,再下面的塊為記錄數據的數據塊,FIRST LEVEL BITMAP BLOCK的父數據塊地址指向SECOND LEVEL BITMAP BLOCK,SECOND LEVEL BITMAP BLOCK的父數據塊地址指向PAGETABLE SEGMENT HEADER,FIRST LEVEL BITMAP BLOCK記錄了它所管理的所有塊(包括頭部三個塊,不僅僅指數據塊)的狀態,標識的狀態有Metadata、75-100% free、50-75% free、25-50% free、0-25% free、full、unformatted,在SECOND LEVEL BITMAP BLOCK中有一個列表,記錄了它管理的FIRST LEVEL BITMAP BLOCK,PAGETABLE SEGMENT HEADER中記錄的內容比較多,除了記錄了它管理的SECOND LEVEL BITMAP BLOCK,還記錄了各個區的首塊地址以及各個區的DB BLOCK的個數,段的各個區所對應的FIRST LEVEL BITMAP BLOCK的塊地址以及區裡面記錄數據的數據塊的起始地址。

如果一個區擁有很多塊,這時會在一個區裡出現兩個或多個FIRST LEVEL BITMAP BLOCK,這些FIRST LEVEL BITMAP BLOCK分別管理一個區中的一些塊,當區的數據塊比較少時,一個區的FIRST LEVEL BITMAP BLOCK可以跨區管理多個區的數據塊,BITMAP BOLCK最多為三級)。采用手動管理的本地管理表空間中的段和數據字典管理的表空間中的段中的Oracle空閒數據塊的管理都使用位於段頭部的空閒列表來管理,例如SYSTEM表空間是本地管理表空間,但是它是采用了手動段空間管理,所以也是用Freelist來管理段中的Oracle空閒數據塊的。空閒列表是一個邏輯上的鏈表,在段的HEADER BLOCK中記錄了一個指向第一個空閒塊的BLOCK ADDRESS,第一個DB BLOCK中同時也記錄了指向下一個空閒塊的BLOCK ADDRESS。

以此形成一個單向鏈表。如果段上有兩個FREE LIST則會在段頭部的HEADER BLOCK存有兩個指針分別指向兩個空閒塊並建立獨立的兩個單向鏈表。空閒列表的工作方式:首先當建立一個段時,初始分配的第一個區的第一個塊會成為段的頭塊,初始分配的第一個區的其它塊將全部加入空閒列表,再次擴展一個區時,這個區中的塊立即全部加入空閒列表,擴展一次加入一次。與位圖管理不同的是用空閒列表時區的頭部將不記錄區裡面空閒塊的信息。當其中空閒空間小於PCTFREE設置的值之後,這個塊從空閒列表刪除,即上一個指向它的塊中記錄的下一個空閒塊地址更改為其它空閒塊的地址,使得這個塊類似於被短路,當這個塊中的內容降至PCTUSED設置的值之下後,這個數據塊被再次加入空閒列表,而且是加入到空閒列表前端,即頭塊直接指向它,它再指向原頭塊指向的空閒塊,位於空閒列表中的數據塊都是可以向其中INSERT的塊,但是INSERT都是從空閒列表指向的第一個塊開始插入,當一個塊移出了空閒列表,但只要其中還有保留空間就可以進行UPDATE,當對其中一行UPDATE一個大數據時,如果當前塊不能完全放下整個行,只會把整個行遷移到一個新的數據塊,並在原塊位置留下一個指向新塊的指針,這叫行遷移。如果一個數據塊可以INSERT,當插入一個當前塊裝不下的行時,這個行會溢出到兩個或兩個幾上的塊中,這叫行鏈接。

如果用戶的動作是INSERT則服務器進程會先鎖定Freelist,然後找到第一個空閒塊的地址,再釋放Freelist,當多個服務器進程同時想要鎖定Freelist時即發生Freelist的爭用,也就是說多個進程只在同時INSERT時才會發生Freelist爭用,可以在非采用自動段空間管理的表空間中創建表時指定Freelist的個數,默認為1,如果是在采用自動段空間管理的表空間中創建表,即使指定了Freelist也會被忽略,因為此時將使用BITMAP而不是Freelist來管理段中的空閒空間。采用自動段空間管理還會忽略的參數有PCTUSED和Freelist GROUPS。如果用戶動作是UPDATE或DELETE等其它操作,服務器進程將不會使用到Freelist和BITMAP,因為不要去尋找一個空閒塊,而使用鎖的隊列。對數據塊中數據操作必須使用transaction entrIEs,即事務入口。

在建立段時我們可以通過MINTRANS和MAXTRANS參數指定它的最大值和最小值,MAXTRANS規定了在段中每一個塊上最大並發事務數量,可以輸入1到255之間的值。我們可以把它比喻為是一些長在塊頭部的事務插座,每個插座後面是一個可以伸縮的操作手,當事務進程插到一個插座上時相當於找到一個可以操作數據塊中數據行的操作手,通過這個操作手,事務進程可以對塊中數據進行INSERT、UPDATE、DELETE等操作。在沒有超過MAXTRANS設定的最大值時,如果transaction entries不夠用,則會在塊上自動分配一個,但不會影響其它塊中的transaction entrIEs數量。只不過INSERT操作必須要先找到空閒塊然後才能INSERT。

那麼DBWN是根據什麼順序來寫DB BUFFER中的髒數據的呢?Oracle從8I開始加入新的數據結構--檢查點隊列(Buffer Checkpoint Queue)。檢查點隊列是一個鏈接隊列。這個隊列的按照Buffer塊第一次被修改的順序排列,分別指向被修改的Buffer塊。在DB_Buffer中的數據被第一次被修改時,會記錄所生成的REDO LOG條目的位置RBA作為該Buffer的Low RBA,記錄在該Buffer的頭部(Buffer Header),如果該數據繼續被修改,則把該塊修改的最新的REDO LOG的RBA作為High RBA記錄在該Buffer的頭部。如果DB_Buffer中的塊沒有被修改的數據,則該塊的頭部不會有Low RBA和High RBA的信息。檢查點隊列按照被修改塊的Low RBA的遞增值鏈接修改塊,沒有被修改的塊因為沒有Low RBA,而不會加入到檢查點隊列中。

在沒有檢查點發生時DBWR就按照檢查點隊列的Low RBA的升序,將被修改的塊寫入到數據文件中。當塊被寫入到數據文件後,該塊會從檢查點隊列中斷開。DBWR繼續寫下一個塊。CKPT進程每三秒記錄檢查點隊列中對應的最小Low RBA到控制文件中,也就是更新控制文件中的CheckPointRBA,當實例崩潰時,恢復將從CheckPointRBA所指向的日志位置開始。這就是"增量檢查點"的行為和定義。CKPT進程也會記錄檢查點位置到數據文件的頭部,但是只是日志切換時才寫。而不是每三秒。當檢查點發生時,DBWN不會一直不停的寫DB BUFFER中髒數據,它將寫到檢查點隊列的開始塊的Low RBA的值大於該檢查點的Checkpoint RBA的值時停止寫入,然後完成這次檢查點,CKPT進程將記錄該檢查點的有關信息到控制文件中去。以上介紹Oracle空閒數據塊。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved