1. 程式人生 > >Mongodb 資料檔案結構

Mongodb 資料檔案結構

MongoDB目前支援的儲存引擎為記憶體對映引擎

在MongoDB內部,每個資料庫都包含一個.ns 檔案和一些資料檔案,而且這些資料檔案會隨著資料量的增加而變得越來越多。nssize選項可以設定dbname.ns檔案的大小。

MongoDB 內部有預分配空間的機制,每個預分配的檔案都用0 進行填充,由於有了這個機制, MongoDB 始終保持額外的空間和空餘的資料檔案,從而有效避免了由於資料暴增而帶來
的磁碟壓力過大的問題。由於表中資料量的增加,資料檔案每新分配一次,它的大小都會是上一個資料檔案大小的2倍,每個資料檔案最大2G。這樣的機制有利於防止較小的資料庫浪費過多的磁碟空間,同
時又能保證較大的資料庫有相應的預留空間使用。即檔案集序號依次為0,1,2....n大小依次為64M,128M,256M..一直到2G,以後就一直為2G大小的建立下去。
檔案集在內部被切分成多個數據域,資料域之間使用雙向連結串列連線。不同資料域的儲存類別用名稱空間區別,每個集合都會有自己獨立的名稱空間,每個索引也有自己獨立的名稱空間。
在mongodb裡,每個collection都具有一個名稱空間,名字為dbname.collection_name。


名字空間和盤區
每一個數據庫都由多個名字空間組成,每一個名字空間儲存了相應型別的資料。資料庫中的每一個Collection都有各自對應的名字空間,索引檔案同樣也有名字空間。所有名字空間的元資料都儲存在.ns檔案中。
每個名稱空間可以包含多個不同的盤區,這些盤區並不是連續的。與資料檔案的增長相同,每一個名稱空間對應的盤區大小的也是隨著分配的次數不斷增長的。這樣做的目的是為了平衡名稱空間浪費的空間與保持某一個名稱空間中資料的
連續性.$freelist,這個名稱空間用於記錄不再使用的盤區(被刪除的Collection或索引)。每當名稱空間需要分配新的盤區的時候,都會先檢視$freelist 是否有大小合適的盤區可以使用,這樣就回收空閒的磁碟空間。

每個資料庫都有一個以 dbname.ns命名的名稱空間檔案,該檔案中儲存的是一個 雜湊表節點陣列,儲存的是每個名稱空間的元資料,包括其大小,域的個數,第一個域的位置,最後一個域的位置,被刪除的域的連結串列、索引資訊等。

dbname.<#>系列檔案儲存了每個庫的所有資料,其檔案格式為
--------------------------------------------
DataFileHeader
--------------------------------------------
Extent (for a particular namespace)
Record
...
Record (some chained for unused space)
--------------------------------------------
more Extents...
--------------------------------------------
DataFileHeader是資料檔案的頭部,後面的部分為Extent。檔案空間的分配以Extent為單位。每個名稱空間的所申請的Extent形成一個雙向連結串列,
表頭和表尾存在名稱空間資訊裡。Record即記錄,在Extent裡分配,每個Extent裡的所有Record形成一個雙向連結串列,表頭和表尾存在Extent頭部。
可以想到,對名稱空間的所有Record的遍歷方法為:遍歷Extent連結串列,對每個Extent,遍歷其Record連結串列。空閒的Record(Extent裡剩餘的空間、或者Record被刪除),
稱作DeleteRecord,根據其大小,形成19個單向連結串列(表頭也存在名稱空間裡)。可以想到,申請一個Record的方法:先從空閒的Record裡面找;如果找不到,則分配新的Extent。
當一個名稱空間被刪除的時候,它的所有的Extent都會掛到名為$freelist的collection的Extent連結串列中。那麼,分配Extent的時候,會先從$freelist的Extent連結串列中尋找。如果找不到,就申請新的Extent。


MongoDB 的資料分塊稱為 chunk。每個 chunk 都是 Collection 中一段連續的資料記錄,通常最大尺寸是 200MB,超出則生成新的資料塊。
為了將一個特定的collection 儲存在多個shard 中,需要為該collection 指定一個shard key,例如{age: 1} ,shard key 可以決定該條記錄屬於哪個chunk。Config Servers 就是用來儲存:
所有shard 節點的配置資訊、每個chunk 的shard key 範圍、chunk 在各shard 的分佈情況、該叢集中所有DB 和collection 的sharding 配置資訊。

////////////////////////////////////// 每一個數據庫都有自己獨立的檔案。如果開啟了directoryperdb選項,那你每個庫的檔案會單獨放在一個資料夾裡。 資料庫檔案在內部會被切分成單個的塊,每個塊只儲存一個名字空間的資料。在MongoDB中,名字空間用於區分不同的儲存類別。比如每個collection有一個獨立的名字空間,每個索引也有自己的名字空間。
在一個塊中,會儲存多條記錄,每條記錄是BSON格式的,記錄與記錄之間通過雙向連結串列進行連線。(因為是MMAP,所以檔案是記憶體的對映).
索引資料也存在資料檔案中,不過索引是被組織成B Tree結構,而不是雙向連結串列。
對每個資料庫,有一個名稱空間檔案,用於儲存每個名字空間對應的元資料。我們通過查詢這些元資料來找到對應的名字空間的儲存塊位置。如果你開啟了jorunaling日誌,那麼還會有一些檔案儲存著你所有的操作記錄。
總結如下:
1、每個資料庫都有響應的資料檔案和名稱空間檔案。
2、資料檔案從64M開始,新的資料檔案比上一個檔案大一倍,最大資料檔案為2G
3、檔案使用MMAP進行記憶體對映,會將所有資料檔案對映到記憶體中,這裡的記憶體指虛擬記憶體,只有訪問到這塊資料才會交換到實體記憶體。
4、64位機器上最多可以表示128TB的空間
5、每個資料檔案被分成一個一個的資料塊用來儲存資料,塊與塊之間是用雙向連結串列連線
6、在名字空間檔案中(資料庫名.ns),儲存的是一個 hash table,儲存了每個名字空間的儲存元資料資訊,包括其大小,塊數,第一塊和最後一塊的位置,被刪除的塊的連結串列及其索引資訊
7、.ns中記錄的資料資訊的位置通過DiskLoc資料結構進行儲存,儲存了資料檔案編號和塊在檔案中的位置
8、對每一個塊(Extent)來說,其頭部包含以下元資料:
     塊的位置、上一個和下一個塊的位置、塊中第一條和最後一條記錄的位置指標。其他部分用於儲存資料,資料之間通過雙向鏈來進行連線。
9、索引是BTree的儲存結構。葉子節點存的是_id的值和地址。