表空间和缓冲池
?
表空間是數據庫系統中數據庫邏輯結構與操作系統物理結構之間建立映射的重要存儲結構,它作為數據庫與實際存放數據的容器之間的中間層,用于指明數據庫中數據的物理位置。任何數據庫的創建都必須顯式或隱式的為其指定表空間,且數據庫中的所有數據都位于表空間中。
用戶可以根據硬件環境以及成本等需求,通過指定建立在不同容器上的表空間來自由選擇數據的物理存儲位置。同時由于備份和恢復可以在表空間級別執行,用戶能夠進行更多粒度的備份恢復控制。
理解表空間前先理解容器。
容器(Container)
容器是物理存儲設備,可以通過目錄名,設備名或文件名進行標識。事實上,這也正是三種容器類型。設備容器(如磁帶等)和文件容器被同等看待,通常直接將其理解為數據文件(磁盤存儲內部結構中有介紹,數據文件中包含若干Extent。)。系統管理表空間只能使用目錄容器,數據庫管理表空間只能使用設備容器和文件容器。
容器被分配給某個表空間,單個表空間可以使用多個容器,但容器只能屬于一個表空間。容器通常位于本地磁盤上,某些遠程網絡設備或文件也能作為表空間的容器,但由于網絡延遲與可靠性方面的原因,遠程容器對數據庫安全與性能會造成影響,因此不建議使用遠程容器。
DB2數據庫系統的表空間有三種管理類型:
系統管理表空間(SMS,System-Managed Space)
SMS表空間由操作系統的文件系統管理器分配并管理。在這種表空間中,數據存儲空間完全由操作系統管理,SMS表空間能夠使用的唯一容器是目錄容器,SMS表空間可以定義多個容器,目錄容器可以根據需要增加大小,因此SMS表空間的大小是可以動態增加的。但是一旦SMS表空間創建,就不能再為表空間增加或刪除容器了。SMS表空間中通常包含多個文件,這些文件代表了存儲在文件系統空間中的表對象,比如表數據,表索引,表大對象都是單獨占用一個或若干個文件的。一旦為表指定了SMS表空間,那么表中的數據就不允許分開存儲,即表的常規數據,索引,大對象數據不能位于不同的表空間中。在DB2 V9之前的數據庫版本中,創建數據庫(創建數據庫時如果不指定表空間則會默認創建3個表空間)或表空間的默認類型就是SMS表空間。另外,只有DB2數據庫允許有系統管理表空間,Oracle數據庫的表空間都是數據庫管理的,不存在系統管理表空間。
舉個SMS表空間的簡單例子:創建一個以containers1目錄為容器的SMS表空間MYSPACE。再創建一張表TEST,其常規數據,索引,大對象均位于MYSPACE表空間中(如果三者指定不同的表空間則表創建會失敗,事實上,指定了常規數據的表空間為SMS表空間后,索引和大對象的表空間也就默認了)。表創建完成后,物理磁盤上的數據是這樣的:
其中SQL00002.DAT數據文件存放表中的常規數據;SQL00002.DTR數據文件存放由于重組,表連接等產生的臨時數據。SQL00002.INX數據文件存放表中的索引。還有LF后綴的存放LONG VARCHAR或LONG VARGRAPHIC數據,LB后綴的存放BLOB,CLOB和DBLOB數據,LBA后綴的存放LB后綴文件的分配和可用空間信息等。另外順便說下圖中的SQLTAG.NAM文件。事實上每一個容器都有一個TAG數據結構用于標識容器屬于哪一個實例的哪一個數據庫的哪一個表空間。對于DMS表空間的容器,TAG位于第一個Extent內,對于SMS表空間的容器,則是以SQLTAG.NAM文件的形式存在。
使用SMS表空間的每一個表都會在表空間的容器(也就是目錄)下對應產生一系列的SQL*.DAT ,SQL*.INX等文件。表和其對應的文件的信息存放在SYSIBM.SYSTABLES這個系統編目表中,每個表對應一個FID(表所在的文件組編號)和TID(表所在的表空間編號),可以使用查詢語句進行查詢:
Select fid,tid, name from sysibm.systables where name='TEST';
?
數據庫管理表空間(DMS,Database-Managed Space)
DMS表空間由數據庫管理系統(DBMS)自己管理控制,本質上講,這種類型的表空間是為了最大程度滿足數據庫管理器的需要而設計并實現的一種特定目的的文件系統。DMS表空間是由有限數量的容器所組成的,DMS表空間可以使用的容器有設備容器和文件容器,這些容器的空間都是預先分配的且不允許修改大小的,但是與SMS表空間不同的是,DMS表空間允許添加容器。也就是說,SMS表空間和DMS表空間分別通過擴大容器大小和增加容器數量的方式實現表空間大小的增加。DMS表空間創建時需要手動指定一個或多個容器。以文件為容器的表空間創建完以后就是一個單獨的文件。使用DMS表空間的表的數據可以分開存儲,即為常規數據,索引和大對象數據指定不同的DMS表空間。
DMS自動存儲表空間(Automatic Storage DMS)
自動存儲表空間不是真正意義上的獨立類型的表空間。它是DMS存儲的另外一種處理方法。DMS需要很多的維護操作,而自動存儲器則是作為一種簡化的空間管理手段,能夠自動進行表空間的管理維護,它是DB2 V8.8.2中引入的概念,目前取代SMS成為默認的表空間類型。
三種表空間的對比
三種表空間在各方面的區別是非常多的,下表顯示了一些主要的區別:
除了使用 SMS 表空間可以簡化管理之外,SMS和DMS存儲模型之間最顯著的差異是表空間的最大大小。在使用 SMS 時,DBA 最多只能在表空間中放 64GB 的數據。將頁面大小改為 32K,可以將這個限制擴大到 512GB,但代價是每個頁面上的可用空間可能會更少。改為 DMS 模型會將表空間限制擴大到 2TB(4K 頁面大小的情況下)。如果將頁面大小改為 32K,可用空間可以增長到 16TB。盡管還有讓表大小突破 64GB 限制的其他方法,但是最簡單的方法可能是一開始就使用 DMS 表空間。(為什么會有這些限制后面介紹)
DMS與自動存儲DMS
那么DMS和自動存儲哪種方式更佳呢?自動存儲允許 DBA 為數據庫設置在創建所有表空間容器時可以使用的存儲路徑。DBA 不必顯式地定義表空間的位置和大小,系統將自動地分配表空間。在 DB2 9 中,數據庫在創建時將啟用自動存儲,除非 DBA 顯式地覆蓋這個設置。?
啟用自動存儲的數據庫有一個或多個相關聯的存儲路徑。表空間可以定義為 “由自動存儲進行管理”,它的容器由 DB2 根據這些存儲路徑進行分配。數據庫只能在創建時啟用自動存儲。對于在最初沒有啟用自動存儲的數據庫,不能在以后啟用這個特性。同樣,對于在最初啟用了自動存儲的數據庫,也不能在以后禁用這個特性。?
下面的表總結了管理非自動存儲和自動存儲之間的一些差異。
引入自動存儲模型的主要目的是簡化 DMS 表空間的管理,同時保持其性能特征。有的時候 DBA 必須定義使用的表空間的所有特征,但是許多應用程序都會從自動存儲提供的簡化管理獲益。
上述是按照管理方式的不同對數據庫表空間類型進行了劃分,事實上,根據用途的不同,表空間也可以劃分為五種類型:
系統表空間(SYSCATSPACE)
系統表空間又稱為系統編目表空間,DB2系統編目表是DB2數據庫保存所有DB2對象元數據的地方,在Oracle數據庫中,被稱為數據字典。而系統編目表就存放在系統表空間中。系統表空間是數據庫創建時自動創建的,且每個數據庫必須有且僅有一個系統表空間,系統表空間被強制命名為SYSCATSPACE。系統表空間默認是SMS表空間,也可以顯式指定為DMS表空間。
系統工具表空間(SYSTOOLSPACE)
系統工具表空間是供DB2管理工具和SQL管理例程使用的特定表空間,系統工具表空間不能被顯式創建,只有第一次使用下面任一工具或過程時才會自動創建:ADMIN_COPY_SCHEMA 過程 ,ADMIN_DROP_SCHEMA 過程, 管理任務調度程序, 改變表筆記本, ALTOBJ 過程, 自動重組(包括 db.tb_reorg_req 運行狀況指示器), 自動收集統計信息(包括 db.tb_runstats_req 運行狀況指示器), 配置自動維護向導, db2look 命令, 設計顧問程序, GET_DBSIZE_INFO 過程, 存儲管理工具,SYSINSTALLOBJECTS 過程。其中管理任務調度程序、ADMIN_COPY_SCHEMA 和 ADMIN_DROP_SCHEMA 過程的首次使用不會創建系統工具表空間,但是他們使用的是系統工具表空間。
用戶表空間(USERSPACE)
用戶表空間也是數據庫創建時自動創建的,表空間名稱為USERSPACE1,數據庫中的用戶表默認存放于這個表空間中,用戶表空間是可選的,一個數據庫可以有多個用戶表空間。必須至少有一個用戶表空間(沒有用戶表空間的話數據庫無法存放用戶數據)。用戶表空間也可以是SMS表空間或DMS表空間,通常使用DMS表空間。
臨時表空間(TEMPSPACE)
臨時表空間也是數據庫創建時自動創建的,數據庫管理器使用臨時表空間在執行SQL操作時存儲臨時數據,例如排序,表重組,索引創建以及表鏈接等操作所產生的中間表都由臨時表空間存儲,數據庫必須至少有一個臨時表空間,也可以有多個。創建數據庫時默認創建的臨時表空間名稱為TEMPSPACE1,且為SMS表空間。但是這個表空間的名稱可以是任意的,當另外的臨時表空間被創建后,該默認臨時表空間也可以被刪除。(但必須保證數據庫有一個臨時表空間)。臨時表空間也可以是DMS表空間。另外,DB2支持系統臨時表空間和用戶臨時表空間兩種類型,系統臨時表空間必須存在,用戶臨時表空間可以有0個或多個,用來聲明臨時表。
除了根據管理和用途劃分表空間類型,還可以根據容量將表空間劃分為常規表空間和大型表空間。但是這里的常規表空間和大型表空間都是針對DMS表空間而言,SMS表空間大小上限還不及常規表空間。
行指針
首先考慮一個問題:邏輯上,數據以數據行(元組)的形式保存在數據庫的表中,但物理上,根據數據庫磁盤存儲的知識(數據庫深入學習筆記----磁盤存儲內部結構),數據肯定是存儲在數據文件上的,確切的說是存儲在數據塊(頁)上。那么,數據庫是如何根據表中的行尋址到物理磁盤上數據頁中的數據呢?
Oracle和DB2的解決方案是使用一種新的數據結構:行指針(或行指示器),Oracle數據庫中稱為ROWID,DB2中稱為RID。在實際的數據庫表中,每張表都會附加一個特定的隱藏列,即行指針列,也就是說,每一行數據都有一個行指針屬性,它指向該行數據在物理磁盤中的具體位置。實際上不管是Oracle還是DB2,行指針都是可以參與SQL查詢的(畢竟是有效的行屬性。Oracle中的ROWID可以直接當作屬性進行查詢,DB2中則需要使用rid函數查詢RID)如下圖是DB2數據庫的RID格式:
常規表空間
在DB2 V9之前,RID具有4個字節(32位)長度,其中3個字節用于數據頁尋址,最后1個字節用于數據頁內槽號尋址(《數據庫深入學習筆記----磁盤存儲內部結構》介紹過,每一行數據都是一條記錄,存儲在數據頁的數據存儲空間里,每一條記錄都對應槽目錄中的一個槽號)。
由RID的結構我們就可以計算出數據頁能夠容納的記錄數(行數)和表空間的容量了:
因為一個RID只有1個字節(8位)槽號,所以,一個數據頁存儲的記錄數的最大值為255條(2的8次方-1,為什么要減1?這是因為磁盤存儲那篇文章已經講過,有的數據頁是會有一個可用空間控制記錄(FSCR)的,所以需要預留)。(說明:8位能尋址的范圍就是0-255,槽號編號就只能是0-255,如果記錄再多,就無法被槽目錄編號了,無法被尋址,數據存了也是白存。)
同理,可以根據3個字節的頁號,得出一個表空間最多能容納16777216(16M,2的24次)個數據頁。那么,如果是一個數據頁4KB的話,表空間大小就是16M*4KB=64GB了。如果一個數據頁32KB的話,就是16M*32KB=512GB。(DB2表空間支持的頁面大小有4KB,8KB,16KB和32KB四種,一個表空間只能使用一種大小的數據頁)
可以想象,如果數據庫表中的行長度(一行所占用的存儲空間)太小,由于一個數據頁理論上最多只能存儲255行(實際上,每一頁允許存儲的記錄數通常少于255條),那必然造成數據頁空間的浪費,比如4KB頁,長度為12B的行存滿頁面也只占用12B*255=3060B的空間,剩下的1036KB多的空間只能浪費。下表顯示了頁面空間被浪費前的最小行長度:
一旦表空間中滿足了最大頁限制,有以下三種方案可供選擇:
1.在視圖中把這些表連接起來(多個表空間中的表在視圖中合在一起);
2.使用DB2的數據庫分區功能(DPF,Database Partitioning Feature),橫跨多個分區將數據進行組合;
3.使用范圍分區表。
無論哪種方案都需要將一些數據進行遷移并可能對應用程序進行修改,這無疑是很繁瑣的。
大型表空間
為了能夠讓數據頁中容納更多的行(記錄)以及表空間中容納更多的數據頁,DB2 V9引入了一種新的行指針(RID,行指示器)格式。數據頁標記由3個字節增加到4個字節,槽位由1個字節增加到2個字節,這種6字節的RID格式最終將表空間大小上限擴充到原來的32倍。即4KB頁的表空間最大容量為2TB,32KB頁的表空間最大容量為16TB。同時,每個數據頁所能容納的行數理論上也擴大為65000多行,但由于規定每一行的最小長度為12B左右,所以,實際上4KB頁能容納的最大行數為4KB/12KB=341行左右,32KB頁則是2300行左右。
下表是4種頁實際用于存儲數據的空間大小和實際允許存放的行數:
這種RID格式很好的解決了表空間大小受限以及數據頁空間浪費(不再受制于槽號,而是行長度)的問題。但同時也帶來了管理上的挑戰,比如備份和恢復。事實上,當表開始增長到TB級的時候,就應該考慮使用一些諸如表分區,數據庫分區等技術來進行大型數據量的管理了。
使用舊的4字節RID格式的表空間就是常規表空間,使用新的6字節RID格式的表空間就是大型表空間了。DB2 V9中大型表空間是DMS表空間的默認類型,當然也可以顯式的創建常規表空間(指明表空間為REGULAR)。很顯然,SMS表空間是不可能支持大型表空間的。
支持6字節RID格式的表空間包括:系統臨時表空間,用戶臨時表空間,用戶常規表空間。也就是說,只有系統表空間是不能創建為大型表空間的。因為目前的編目表不足以達到能夠及時保證較大的表空間大小的狀態。
大型表空間在DB2 V9之前叫長型表空間,用于存儲長型或 LOB 表列,以彌補常規表空間在處理長型或LOB數據上的不足。
常規表空間向大型表空間的遷移
DB2 V9不會自動將常規表空間升級為大型表空間,但是可以手動升級:ALTER TABLESPACE tablespacename CONVERT TO LARGE。
ALTER命令不會物理地改變表空間的結構,只是改變了編目方式以指示表空間可以支持6字節的RID格式。要注意的是:
1.執行LARGE升級后需要立即COMMIT WORK,進行事務提交,否則表空間上會持有排它鎖,同時在該表空間中對表所做的其他工作不會繼續執行,直到該鎖解除為止。
2.一旦表空間被修改為LARGE,為了更好的利用6字節RID的優勢,還需要繼續數據重組和索引重組。如果不進行索引重組,那么先前存在的表將延續每頁255行以及3字節數量的限制,因為索引使用的仍是舊的RID,無法索引到超出原范圍的頁。而數據重組(表重組)與索引重組的影響不同,索引重組影響表空間中頁的數量,表重組影響的是頁中存放的行數。
?
臨時表空間分為系統臨時表空間和用戶臨時表空間
系統臨時表空間用來存儲各種數據操作(排序、重組表、創建索引、連接表)中所需的內部臨時數據,雖然可以創建任意多個系統臨時表空間,但建議用戶只使用大多數表所使用的頁大小創建一個,默認系統臨時表空間名為TEMPSPACE1。
用戶臨時表空間用來存儲已說明全局臨時表(已說明全局臨時表存儲的是應用程序臨時數據)。用戶臨時表空間不是在數據庫創建時默認創建的。
緩沖池(BufferPool)
對于數據庫管這種對性能要求極高的系統而言,緩存自然也是不可少的。數據庫中的緩存稱為緩沖池,緩沖池存在的唯一目的就是提高數據庫系統性能。
緩沖池本質上是分配給數據庫管理器管理的一塊內存空間,用于讀寫數據頁。(包括表行和索引數據頁。內存中表行數據頁稱為緩存表)由于從內存訪問數據比從磁盤訪問數據快得多(訪問磁盤是典型的I/O操作,一次I/O大概耗時0.0125S),通過將部分常用或者需要預取的數據存放在緩沖池以便系統直接訪問和操作可以減少磁盤I/O,合理的緩沖池空間和好的緩沖池頁面替換算法(提高命中率)可以大大提高數據庫系統的性能。
注意分配給DB2的內存空間不僅僅是緩沖池,還包括包緩存空間,日志緩存空間等等一些其他的內存空間,其中緩沖池占了DB2內存的大部分。
?
緩沖池大概實現
DB2緩沖池的結構和具體實現是非常復雜的,只知道一個大概的實現過程,其實也跟操作系統緩存差不多。
首次訪問數據庫表中的數據行時,由于緩沖池內沒有數據頁,數據庫管理器會將磁盤上相應的數據頁讀入緩沖池中,每當向緩沖池添加新頁時,都會為該頁生成一個頁面描述符(BPD)以標識該頁并指明該頁狀態,描述符被存放在Database Heap中,刪除頁時會將其描述符一并刪除,頁面狀態發生變化后會更新該頁描述符。
對緩沖池中數據頁進行操作時會根據操作類型為數據添加一個共享鎖或排它鎖以保證數據的同步,添加的鎖被存放在Locklist中統一管理。同時將操作的SQL語句存儲到包緩存(package Cache)中,根據包緩存的數據在日志緩沖區(Log Cache)中生成日志文件。當操作提交時,如果數據頁沒有被修改(干凈頁),則無需向磁盤回寫數據頁,如果數據頁被修改(臟頁),則需要將修改后的數據頁回寫到磁盤,替換原有頁,,該臟頁變成干凈頁。同時立即將相應的日志文件寫入磁盤,以保證發生斷電等突發事故時保證能夠利用磁盤上的日志文件進行回滾(Undo)或重做(Redo)?!疚刺峤淮_認的修改會回滾,已提交確認的修改會重做】
操作提交后,數據頁所持有的共享鎖或排它鎖也相應解除。所有這些數據頁在操作提交后都會繼續保留在緩沖池中。當下次進行訪問時,如果緩沖池中存在需要訪問的數據頁(命中),則直接對該頁進行操作,并同樣進行日志記錄和數據頁回寫等操作。如果緩沖池中不存在需要訪問的數據頁(未命中),則需要先從磁盤將數據頁讀入緩沖池,重復以上過程。
如果需要將新的數據頁從磁盤讀入緩沖池,而緩沖池正好已經滿了該怎么辦呢?這個時候就要根據頁面替換算法,選擇將某些頁從緩沖池刪除以容納新頁。頁面替換算法有很多種,DB2使用的是一種類似于最近最少使用(LRU)算法的時鐘算法。
緩沖池和表空間的關系
一個緩沖池是與單個數據庫相關聯的,可以被多個表空間使用。一個數據庫可以有多個緩沖池。數據庫創建時會生成一個名為IBMDEFAULTBP的默認緩沖池。當考慮將緩沖池用于一個或多個表空間時,必須保證表空間頁大小和緩沖池頁大小對于緩沖池所“服務”的所有表空間而言都是一樣的(和表空間一樣,緩沖池中的頁大小也分為4KB,8KB,16KB和32KB四種)。一個表空間只能使用一個緩沖池。
總結
- 上一篇: 本博客Matlab、FPGA代码获取方法
- 下一篇: jsp 特殊字符转义