lvm分析之命令

一個設備可以被 LVM 使用之前必須先被初始化爲一個 PV 。這會在設備的起始位置放置一個標籤,俗稱“8e”。默認情況下,LVM 標籤被放在第2個 512 字節的扇區,第一個扇區可能是啓動扇區。 LVM 標籤在重啓後也會存在,同時在一個集羣中都可知。

LVM 標籤用於把一個設備識別爲一個 PV ,標籤包含以下部分:

Ø  對該設備的隨機的唯一的標識符(UUID)

Ø  指出塊設備的大小(字節)

Ø  記錄 LVM 元數據的存儲位置

Ø  設備順序方面的信息

標籤後面是 pv 所在卷組的元數據,元數據的存儲位置大概是從4k開始到後面1M爲止的空間,然後就是可用空間。其在磁盤上面的排列圖如圖2-1所示。


圖2-1 lvm關鍵數據分佈

 

pvcreate主要乾的事情是:

1.       根據傳入的設備,如果沒有uuid則爲其生成一個uuid

2.       讀取該設備的大小等信息,同時構建用戶態pv的內存數據,因爲此時設備還沒有加入vg,因此將其放入一個臨時的orphans_lvm2的卷組中

3.       構建pv的label並寫入分區頭部的4k空間內,同時預留4k-1M的區間爲元數據保存區域,數據存儲的區域從1M位置處開始

通過

> dd if=/dev/sdc2 of=/home/fangying/test1bs=4k count=1

> cat test1

可以看到如下信息:

LABELONEd WW  LVM2 001KOeSOU0WPs0Va8aibqokjbcjBx2UKcO0€>ðÖŽÛ LVM2 x[5A%r0N*>ð

其中紅色部分爲設備的uuid。

觀察其io數據可以看到:

[16479.271726] dev name:sdc rw:17bio-sector:524290056 size:4096

[16479.272512] dev name:sdc rw:17bio-sector:524290048 size:4096

[16479.273092] dev name:sdc rw:17bio-sector:524290056 size:4096

[16479.273437] dev name:sdc rw:17bio-sector:524290048 size:4096

       其中524290048代表的是block數目,每個block爲512字節,524290048代表的是1M+250G,在測試機上正好是sdc2分區開始的位置,也就是pvcreate修改了分區開始的8k數據。rw:17代表寫操作。

 

1.2.         vgcreate

LVM 元數據含有LVM 卷組的詳細配置信息。默認情況下,一個卷組的元數據被放置到該卷組中的每個 PV 的一個特殊區域, 元數據很小,且以 ASCII 格式存儲。當前 LVM 允許在每個 PV 上存儲0,1,2 個元數據的拷貝,默認是1個。一旦配置在每個 PV 上存儲多少個元數據的拷貝後,在後續就不能改動了。(也就是一旦 pv 加入 VG ,就不允許再修改了)。第一個拷貝被放在設備的起始位置,在 PV 標籤的後面。如果有第2份拷貝,則放在設備的結束位置。假如不小心覆蓋了開始位置的數據,可以使用結束位置的第2份來恢復。

在一個 VG 中,PE是整個LVM最小的存儲單位,VG就是一個大的PE存儲池。 LVM的重點在於可以彈性調整文件系統的容量,實現這個便是通過交換PE來進行數據轉換,將原本LV內的PE移到其他設備中以降低LV容量或將其他設備的PE加到此LV中以擴大容量。

PE與VG的相關性如圖2-3所示:

圖2-3 PE、lv和vg關係圖

VG要擴充的話,加上其他的PV即可;LV通過加入VG內沒有使用到的PE進行擴充。

vgcreate主要做的事情:

1.       創建vg用戶態的元數據結構,生成vg的uuid

2.       遍歷加入vg的pv,提取pv的信息記錄到vg中,主要是磁盤空間的起始位置等

3.       將vg元數據刷寫道pv分區的元數據區域

4.       如果有需要的話元數據會備份到/etc/lvm目錄

 

通過測試將sdc1和sdc2加入到vgtest中,看到其磁盤的io數據如下所示:

[20122.273044]dev name:sdc rw:17 bio-sector:2056 size:4096

[20122.286020]dev name:sdc rw:17 bio-sector:524290056 size:4096

[20122.286517]dev name:sdc rw:17 bio-sector:2056 size:4096

[20122.286903]dev name:sdc rw:17 bio-sector:524290056 size:4096

[20122.288834]dev name:sdc rw:17 bio-sector:2056 size:4096

[20122.289242]dev name:sdc rw:17 bio-sector:524290056 size:4096

rw:17代表寫操作。2056=2048+8,正好是第一塊分區的起始位置後的4k處,sdc1和sdc2都是250G,524290056正好是sdc2分區起始的4k位置,由此看以看到vg的元數據被保存到了pv起始的4k後的元數據區域。

查看sdc1前8k數據,執行:

dd if=/dev/sdc1of=/home/fangying/test11 bs=4k count=2

cat test11

結果如下:

LABELONE9B~LVM2 001YYL299FqlbumVS8Lkh9eqwqiA3KHfADx€>ð®ÖÕ LVM2 x[5A%r0N*>ð_ÖçXvgtest{

id ="2WITMf-U6Hu-0NOl-i0gB-fn6T-D5go-B8OWRW"

seqno = 1

format ="lvm2" # informational

status =["RESIZEABLE", "READ", "WRITE"]

flags = []

extent_size =8192

max_lv = 0

max_pv = 0

metadata_copies= 0

 

physical_volumes{

 

pv0 {

id = "YYL299-Fqlb-umVS-8Lkh-9eqw-qiA3-KHfADx"

device ="/dev/sdc1"

 

status =["ALLOCATABLE"]

flags = []

dev_size =524288000

pe_start = 2048

pe_count =63999

}

 

pv1 {

id ="aEwUYo-xsdy-AELb-lAi0-3300-yANe-UyFQrp"

device ="/dev/sdc2"

 

status =["ALLOCATABLE"]

flags = []

dev_size =524288000

pe_start = 2048

pe_count =63999

}

}

 

}

# Generated byLVM2 version 2.02.98(2) (2012-10-15): Thu Mar 21 04:24:12 2013

 

contents ="Text Format Volume Group"

version = 1

 

description =""

 

creation_host ="gulala"        # Linux gulala3.2.28 #2 SMP Wed Mar 20 22:42:34 EDT 2013 x86_64

creation_time =1363854252      # Thu Mar 21 04:24:122013

查看sdc1前4k數據:

dd if=/dev/sdc1of=/home/fangying/test12 bs=4k count=1

cat test12

結果:

LABELONE9B~LVM2 001YYL299FqlbumVS8Lkh9eqwqiA3KHfADx€>ð

查看sdc1前4k-8k之間數據:

dd if=/dev/sdc1of=/home/fangying/test13 bs=4k count=1 skip=1

cat test13

結果:

®ÖÕ LVM2x[5A%r0N*>ð_ÖçXvgtest {

id ="2WITMf-U6Hu-0NOl-i0gB-fn6T-D5go-B8OWRW"

seqno = 1

format ="lvm2" # informational

status =["RESIZEABLE", "READ", "WRITE"]

flags = []

extent_size =8192

max_lv = 0

max_pv = 0

metadata_copies= 0

 

physical_volumes{

 

pv0 {

id ="YYL299-Fqlb-umVS-8Lkh-9eqw-qiA3-KHfADx"

device ="/dev/sdc1"

 

status =["ALLOCATABLE"]

flags = []

dev_size =524288000

pe_start = 2048

pe_count = 63999

}

 

pv1 {

id ="aEwUYo-xsdy-AELb-lAi0-3300-yANe-UyFQrp"

device ="/dev/sdc2"

 

status =["ALLOCATABLE"]

flags = []

dev_size =524288000

pe_start = 2048

pe_count =63999

}

}

 

}

# Generated byLVM2 version 2.02.98(2) (2012-10-15): Thu Mar 21 04:24:12 2013

 

contents ="Text Format Volume Group"

version = 1

 

description =""

 

creation_host ="gulala"        # Linux gulala3.2.28 #2 SMP Wed Mar 20 22:42:34 EDT 2013 x86_64

creation_time =1363854252      # Thu Mar 21 04:24:122013

查看sdc2前8k數據:

dd if=/dev/sdc2of=/home/fangying/test21 bs=4k count=2

cat test21

結果:

LABELONEúÿÆLVM2 001aEwUYoxsdyAELblAi03300yANeUyFQrp€>ð®ÖÕ LVM2 x[5A%r0N*>ð_ÖçXvgtest{

id ="2WITMf-U6Hu-0NOl-i0gB-fn6T-D5go-B8OWRW"

seqno = 1

format ="lvm2" # informational

status =["RESIZEABLE", "READ", "WRITE"]

flags = []

extent_size =8192

max_lv = 0

max_pv = 0

metadata_copies= 0

 

physical_volumes{

 

pv0 {

id ="YYL299-Fqlb-umVS-8Lkh-9eqw-qiA3-KHfADx"

device ="/dev/sdc1"

 

status =["ALLOCATABLE"]

flags = []

dev_size =524288000

pe_start = 2048

pe_count =63999

}

 

pv1 {

id ="aEwUYo-xsdy-AELb-lAi0-3300-yANe-UyFQrp"

device ="/dev/sdc2"

 

status =["ALLOCATABLE"]

flags = []

dev_size =524288000

pe_start = 2048

pe_count =63999

}

}

 

}

# Generated byLVM2 version 2.02.98(2) (2012-10-15): Thu Mar 21 04:24:12 2013

 

contents ="Text Format Volume Group"

version = 1

 

description =""

 

creation_host ="gulala"        # Linux gulala3.2.28 #2 SMP Wed Mar 20 22:42:34 EDT 2013 x86_64

creation_time =1363854252      # Thu Mar 21 04:24:122013

查看sdc2前4k數據:

dd if=/dev/sdc2of=/home/fangying/test22 bs=4k count=1

cat test22

結果:

LABELONEúÿÆLVM2 001aEwUYoxsdyAELblAi03300yANeUyFQrp€>ð

查看sdc2前4k-8k數據:

dd if=/dev/sdc2of=/home/fangying/test23 bs=4k count=1 skip=1

cat test23

結果:

®ÖÕ LVM2x[5A%r0N*>ð_ÖçXvgtest {

id = "2WITMf-U6Hu-0NOl-i0gB-fn6T-D5go-B8OWRW"

seqno = 1

format ="lvm2" # informational

status =["RESIZEABLE", "READ", "WRITE"]

flags = []

extent_size =8192

max_lv = 0

max_pv = 0

metadata_copies= 0

 

physical_volumes{

 

pv0 {

id ="YYL299-Fqlb-umVS-8Lkh-9eqw-qiA3-KHfADx"

device ="/dev/sdc1"

 

status =["ALLOCATABLE"]

flags = []

dev_size =524288000

pe_start = 2048

pe_count =63999

}

 

pv1 {

id ="aEwUYo-xsdy-AELb-lAi0-3300-yANe-UyFQrp"

device ="/dev/sdc2"

 

status =["ALLOCATABLE"]

flags = []

dev_size =524288000

pe_start = 2048

pe_count =63999

}

}

 

}

# Generated byLVM2 version 2.02.98(2) (2012-10-15): Thu Mar 21 04:24:12 2013

 

contents ="Text Format Volume Group"

version = 1

 

description =""

 

creation_host ="gulala"        # Linux gulala3.2.28 #2 SMP Wed Mar 20 22:42:34 EDT 2013 x86_64

creation_time =1363854252      # Thu Mar 21 04:24:122013

 

 

 

 

1.3.         lvcreate

邏輯卷分爲4種類型 :線性邏輯卷、條帶化邏輯卷、鏡像卷和快照卷。

1.       線性邏輯卷

線性邏輯卷聚合多個 PV 成爲一個邏輯卷,顧名思義,多個物理存儲設備可以看成首位相接的。建立一個線性卷時,會按順序分配某個範圍的 PE 給 LV 用。

 

2.       條帶化邏輯卷

 條帶化邏輯卷和線性邏輯卷的區別在於,線性邏輯卷是將pv順序連接,只會按順序連接一次,條帶化邏輯卷會將各個pv上的區域劃分成更小的stripe,現將所有pv的一個stripe線性連接,然後再將所有pv的第二個stripe連接到其後,如此循環連接。對於大型的連續讀寫來說,這可以提高性能。通過條帶化,I/O 可以以並行的方式進行,在某些情況下,可以達到幾乎線性倍數的性能提高。下面是一個分佈於三個 PV 上的條帶化邏輯卷。


在一個條帶化的邏輯卷中,stripe 的大小不可以超過 PE 的大小。

要擴展一個 striped 邏輯卷不像擴展一個 linear 邏輯卷那麼簡單,需要邏輯卷所在卷組有一定的自由空間以移動數據。例如有一個跨越兩個 PV 的 striped LV ,如果想擴展它,必須“至少”增加2個 PV 才能實現條帶化邏輯卷的擴展。

3.       鏡像邏輯卷

當建立一個鏡像邏輯卷時,LVM 確保寫進一個底層 pv 的數據會被寫進另外一個 pv 。當一個鏡像 LV 的一部分失效時(例如一個 PV 失效),鏡像 LV 會變成一個普通的線性 LV ,仍然可以被訪問。可以用 LVM 建立一個帶有多個鏡像的邏輯卷。

 一個 LVM 鏡像設備把源設備分成一個個區域,大小爲 512 KB 。LVM 會維護一個日誌,它用於跟蹤那個(些)區域是同步。 這個日誌可以放在磁盤上,重啓也不會丟失,或者可以被讀入內存。


4.       快照卷

LVM 的快照功能允許你爲一個設備在某個特定的時間點建立一個“虛擬的”的鏡像,而不用中斷服務。和鏡像邏輯卷一樣,LVM 的 snapshot 功能並不被集羣所支持。在快照建立完成後,如果源設備有改變,則會把被改變的區域做一個拷貝,這樣日後可以用於重建設備。因爲 snapshot 只拷貝在快照卷建立後被改變的數據區域,所以 snapshot 功能只需要很少的存儲空間。例如在一個很少更新的 LV 中,3-5%的空間就足夠用於維護快照捲了。

snapshot只是一個虛擬的拷貝,不是實際的介質備份。snapshot 並不能取代普通的備份過程。一旦快照卷滿了,就被卸載。這是爲了確保源文件系統有足夠的空間。你應該定時觀察快照卷的使用情況。 快照卷是可以調整大小的。當建立一個快照文件系統時,源文件系統還是可以讀寫的。假如快照的一個 chunk 被改變,該 chunk 被打上標記,並不再從原來的卷中拷貝。

快照卷有如下用途 :

1、你可以在不用卸載原來的文件系統或者停止應用的情況下對一個 LV 進行備份;

2、你可以對快照捲進行 fsck 再決定原來的文件系統是否需要修復;

3、因爲快照卷是可讀寫的,你可以告訴應用程序對快照卷的數據進行測試,而不用動原來的數據。

1.3.1.       線性卷

首先說明線性卷的實現,先從用戶態層面看看其實現。創建一個線性卷,lvm用戶態主要會做如下事情(這裏不考慮lvmetad模塊,該模塊後續介紹):

1.       從磁盤元數據區域讀取卷組的元數據

2.       從vg的剩餘pe中爲線性卷分配要求的空間,分配的根據就是之前讀取的元數據,但是此時分配發生在用戶態

3.       調用ioctl接口先創建一個dm設備

4.       根據之前分配給該dm設備的情況調用ioctl接口更新dm設備的table表,此時lv纔算真正的創建起來,有了dm table才能在內核建立io和真正的存儲設備的映射關係

5.       更新vg的元數據到pv的元數據區域

6.       備份元數據到/etc/lvm下面

以上幾個步驟也是其他類型邏輯卷的主要步驟,只是細節實現上略有不同。

創建一個邏輯卷,然後用dd查看分區的元數據區域,信息如下所示:

LABELONE9B~LVM2 001YYL299FqlbumVS8Lkh9eqwqiA3KHfADx€>ðÒb«< LVM2 x[5A%r0N*>ð˜0¢

contents ="Text Format Volume Group"

version = 1

 

description =""

 

creation_host ="gulala"        # Linux gulala3.2.28 #2 SMP Wed Mar 20 22:42:34 EDT 2013 x86_64

creation_time =1363854252      # Thu Mar 21 04:24:122013

 

vgtest {

id ="2WITMf-U6Hu-0NOl-i0gB-fn6T-D5go-B8OWRW"

seqno = 2

format ="lvm2" # informational

status =["RESIZEABLE", "READ", "WRITE"]

flags = []

extent_size =8192

max_lv = 0

max_pv = 0

metadata_copies= 0

 

physical_volumes{

 

pv0 {

id ="YYL299-Fqlb-umVS-8Lkh-9eqw-qiA3-KHfADx"

device ="/dev/sdc1"

 

status =["ALLOCATABLE"]

flags = []

dev_size =524288000

pe_start = 2048

pe_count =63999

}

 

pv1 {

id ="aEwUYo-xsdy-AELb-lAi0-3300-yANe-UyFQrp"

device ="/dev/sdc2"

 

status =["ALLOCATABLE"]

flags = []

dev_size =524288000

pe_start = 2048

pe_count =63999

}

}

 

logical_volumes{

 

lv1 {

id ="0bANxh-Ht9S-3V8s-YwAN-D4Lz-O1Zq-ft62ma"

status =["READ", "WRITE", "VISIBLE"]

flags = []

creation_host ="gulala"

creation_time =1363857801

segment_count = 1

 

segment1 {

start_extent = 0

extent_count =1280

 

type ="striped"

stripe_count =1        # linear

 

stripes = [

"pv0",0

]

}

}

}

}

# Generated byLVM2 version 2.02.98(2) (2012-10-15): Thu Mar 21 05:23:21 2013

 

contents ="Text Format Volume Group"

version = 1

 

description =""

 

creation_host ="gulala"        # Linux gulala3.2.28 #2 SMP Wed Mar 20 22:42:34 EDT 2013 x86_64

creation_time =1363857801      # Thu Mar 21 05:23:212013

上面紅色部分就是lv的元數據了,從右下角的時間也可以看出來和vg的時間是不同的。

       以下說明用戶態是如何創建這個線性的邏輯卷的。

> ls -l/dev/mapper

crw------T 1root root 10, 236 Mar 20 22:49 control

lrwxrwxrwx 1root root       7 Mar 21 05:23 vgtest-lv1-> ../dm-0

該目錄下有個字符設備control。

> cat/proc/devices |grep misc

10 misc

> cat/proc/misc |grep device-mapper

236device-mapper

lvm首先會創建一個主設備號10次設備號236的虛擬設備,也就是/dev/mapper/control設備,這個設備就是內核dm設備驅動的控制接口。

字符設備的操作都通過字符設備驅動完成,內核的該control的字符設備驅動就是內核miscdevice設備,可以看到其fileoperation接口爲_ctl_fops。可以看到其實現了ioctl接口,追蹤其實現,其ioctl接口如下所示。

以上接口就是內核實際操縱dm驅動的入口,lvm通過ioctl接口進行設備的創建和管理。創建線性邏輯卷最後會依次調用dev_createtable_load接口。

dev_create會構建device設備、構建設備隊列,重要的是初始化io處理函數,io請求到達塊層後會調用此時初始化的io處理函數dm_request。table_load則根據創建的dm設備類型建立dm table以及dm目標設備(target),這裏會調用target驅動的ctr接口初始化目標設備。線性邏輯卷對應的dm目標設備爲linear target。


linear_map會將訪問線性邏輯卷的io映射到邏輯卷所在的磁盤物理設備上去,並調用該物理設備的驅動完成io操作。

1.3.2.       條帶化卷

其創建過程和線性卷類似,只是其對應的dm目標設備爲stripped,其target驅動爲


1.3.3.       鏡像卷

創建一個鏡像卷lv2,查看/dev/mapper/

> ls -l/dev/mapper/

total 0

crw------T 1root root 10, 236 Mar 20 22:49 control

lrwxrwxrwx 1root root       7 Mar 21 22:41 vgtest-lv2-> ../dm-4

lrwxrwxrwx 1root root       7 Mar 21 22:41vgtest-lv2_mimage_0 -> ../dm-2

lrwxrwxrwx 1root root       7 Mar 21 22:41vgtest-lv2_mimage_1 -> ../dm-3

lrwxrwxrwx 1root root       7 Mar 21 22:41vgtest-lv2_mlog -> ../dm-1

總共有四個和lv2相關的邏輯卷,查看分區的元數據:

lv2 {

id ="IPynpd-GHtq-MScH-eCE1-vzqi-ans6-dNdh9i"

status =["READ", "WRITE", "VISIBLE"]

flags = []

creation_host ="gulala"

creation_time =1363920086

segment_count =1

 

segment1 {

start_extent =0

extent_count =1280

 

type ="mirror"

mirror_count =2

mirror_log ="lv2_mlog"

region_size =1024

 

mirrors = [

"lv2_mimage_0",0,

"lv2_mimage_1",0

]

}

}

鏡像卷對應的是內核的mirror target,其設備的組織結構和target類型如下圖所示:


       lv2_mimage_0和mimage_1相當於兩個線性卷,mirror會將io同時映射到這兩個捲上,理論上這兩個卷位於不同的pv之上。

 

1.3.4.       快照卷

詳細闡述下快照卷的實現,其他卷都是相通的。詳細的實現方式見第4章。

創建一個lv1的快照卷,查看/dev/mapper/

> ls -l/dev/mapper/

total 0

crw------T 1root root 10, 236 Mar 20 22:49 control

lrwxrwxrwx 1root root       7 Mar 22 02:57 vgtest-lv1-> ../dm-0

lrwxrwxrwx 1root root       7 Mar 22 02:57vgtest-lv1-real -> ../dm-2

lrwxrwxrwx 1root root       7 Mar 22 02:57vgtest-snap_lv1 -> ../dm-1

lrwxrwxrwx 1root root       7 Mar 22 02:57vgtest-snap_lv1-cow -> ../dm-3

快照卷對應的是內核的snapshot target和origin target,其設備的組織結構和target類型如下圖所示:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章