存储管理之LVM
# 为什么要用LVM
传统的磁盘管理我们将某个硬盘通过fdisk或gdisk工具进行隔断,划分出了一个个的分区,紧接着,对这些分区进行格式化,即在分区上安装文件系统,通过文件系统这个软件来对分区进行管理...
So, 分区 是站在 硬件角度 的说法,文件系统 是站在 软件角度 的说法!!!
在我们对磁盘分区的大小进行规划时, 往往不能确定每个分区使用的空间大小, 只能凭经验分配一个大小.. 每个分区的大小就固定死了.. 这样做会有点弊端:
若分区设置的过大, 就白白浪费了磁盘空间;
若分区设置的过小, 就会导致空间不够用的情况出现;
针对A磁盘空间不够用,有个解决方案是新增块硬盘(不分区,整体作为一个分区),新增的硬盘格式化后,将A磁盘中的某个目录作为其挂载点.. "具体可以参考文件系统那的实践案例" ... 很麻烦,增大了管理难度 TnT
上述的问题,可以通过LVM来解决..
# LVM原理
PV物理卷 -- 把常规的磁盘设备通过pvcreate命令对其进行初始化,形成了物理卷
磁盘空间可以是 整块硬盘(sda)也可以是某块盘的某个分区(sdb5)
PE基本单元 -- 物理卷里最小的存储单位,默认为4MB
VG卷组 -- 将多个PV整合到一起,那么卷组的大小就是多个PV大小之和..
或者说, 将这些PV里的PE放到了一个名为VG的资源池里
注意哦, 不一定要将所有的pv放到一个vg里
LV逻辑卷 -- 从卷组中划分需要的空间大小出来, 用户仅需对其格式化创建文件系统,挂载后即可使用
LV可由VG里面不同的PV里的一个个PE组成...即跨越磁盘
VG不够用可以扩容,加PV进去即可. 通常不会从卷组中移除磁盘...
LV可以动态扩容/缩容: 从VG里再拿几个PE/还几个PE给VG..
虽然LVM支持LV缩容,但LV格式化若制作成xfs文件系统,是不支持缩容的
打个比方,磁盘空间是小麦,PV将一束束小麦都磨成了面粉,PE将这些面粉整合到了一起揉成了一个面团,LV就是在将面团切成一块一块的.
# LVM优缺点
优点
1> 可以在系统运行的状态下动态的扩展文件系统(LV格式化并挂载后)的大小
2> 文件系统可以跨多个磁盘, 因此文件系统大小不会受物理磁盘的限制
3> 可以增加新的磁盘到LVM的存储池VG中
4> 可以以镜像的方式冗余重要的数据到多个物理磁盘 -- LVM的快照,用于进行备份
5> 方便导出整个卷组到另外一台机器(基本用不到,了解即可)
缺点
1> 画个解藕图 硬件 - LVM - 文件系统 简单来说,LVM是处于分区与文件系统之间的一个软件!!
更高级了,但存取性能收到了影响
2> 当VG中的某个PV所在的磁盘空间坏了, 整个卷组都会受到影响
因为LV里面的PE是跨越磁盘的... 所以要尽量保证磁盘不会损坏..
解决方案: 底层用RAID + 上层LVM = 既有冗余又有动态扩展
# LVM的基本使用
简写逻辑: (大概只有我能一眼看懂 Hhhh)
sdb + sdc1 -- vg1 -- lv1_from_vg1(/test1)、lv2_from_vg1(/test2)
sdc2 + sdc3 -- vg2 -- lv1_from_vg2(/test3)、lv2_from_vg2(/test4)
# -- 先移除前面实验环境中添加的硬盘 新建20G 30G 40G三块硬盘sdb sdc sdd 虚拟机不支持热插拔 关机重启生效
# -- 在真实的实验环境中(真机) 多块硬盘需要做RAID; 云服务器不需要做RAID..
fdisk /dev/sdc # -- 制作5个分区 3主1扩1逻辑
[root@localhost ~]# lsblk /dev/sdc
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdc 8:32 0 30G 0 disk
├─sdc1 8:33 0 10G 0 part
├─sdc2 8:34 0 5G 0 part
├─sdc3 8:35 0 5G 0 part
├─sdc4 8:36 0 1K 0 part
└─sdc5 8:37 0 5G 0 part
"""-- 1.制作pv,可以对整块盘做,也可以对分区做 --"""
pvcreate /dev/sdb
pvcreate /dev/sdc1
pvcreate /dev/sdc2
pvcreate /dev/sdc3
"""-- 2.制作vg:将pv划入vg中 --"""
## vgcreate vg3 /dev/sdd 将做过pv的某一块盘或某一个分区单独做vg也可以
vgcreate vg1 /dev/sdb /dev/sdc1
vgcreate vg2 /dev/sdc2 /dev/sdc3
"""-- 3.创建逻辑卷lv --"""
## -L 大小 -n 名字
lvcreate -L 1G -n lv1_from_vg1 vg1
lvcreate -L 2G -n lv2_from_vg1 vg1
lvcreate -L 3G -n lv1_from_vg2 vg2
lvcreate -L 4G -n lv2_from_vg2 vg2
"""-- 查看 --"""
## -- 还可以使用 pvscan 命令
[root@localhost ~]# pvs
PV VG Fmt Attr PSize PFree
/dev/sda2 centos lvm2 a-- <19.00g 0 # -- 这个是安装centos时,linux自己弄的
/dev/sdb vg1 lvm2 a-- <20.00g <17.00g
/dev/sdc1 vg1 lvm2 a-- <10.00g <10.00g
/dev/sdc2 vg2 lvm2 a-- <5.00g <2.00g
/dev/sdc3 vg2 lvm2 a-- <5.00g 1020.00m
[root@localhost ~]# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root centos -wi-ao---- <17.00g
swap centos -wi-ao---- 2.00g
lv1_from_vg1 vg1 -wi-a----- 1.00g
lv2_from_vg1 vg1 -wi-a----- 2.00g
lv1_from_vg2 vg2 -wi-a----- 3.00g
lv2_from_vg2 vg2 -wi-a----- 4.00g
## -- 可以看到vg1由两个pv组成,划分了2个lv; vg1总大小为30G,减去2G和1G还剩27G..
[root@localhost ~]# vgs
VG #PV #LV #SN Attr VSize VFree
centos 1 2 0 wz--n- <19.00g 0
vg1 2 2 0 wz--n- 29.99g 26.99g
vg2 2 2 0 wz--n- 9.99g 2.99g
"""-- 4.格式化(制作文件系统)与挂载 --"""
## -- 创建的vg卷组会在/dev下面
mkfs.xfs /dev/vg1/lv1_from_vg1
mkfs.xfs /dev/vg1/lv2_from_vg1
mkfs.xfs /dev/vg2/lv1_from_vg2
mkfs.xfs /dev/vg2/lv2_from_vg2
mkdir /test1
mkdir /test2
mkdir /test3
mkdir /test4
mount /dev/vg1/lv1_from_vg1 /test1
mount /dev/vg1/lv2_from_vg1 /test2
mount /dev/vg2/lv1_from_vg2 /test3
mount /dev/vg2/lv2_from_vg2 /test4
[root@localhost ~]# mount | grep test
## -- /dev/mapper/vg1-lv1_from_vg1 就是 /dev/vg1/lv1_from_vg1 不要太在意..
/dev/mapper/vg1-lv1_from_vg1 on /test1 type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/vg1-lv2_from_vg1 on /test2 type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/vg2-lv1_from_vg2 on /test3 type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/vg2-lv2_from_vg2 on /test4 type xfs (rw,relatime,attr2,inode64,noquota)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 在线动态扩容
动态扩容即在不用卸载的情况下对LV进行扩容
lvextend -L [+]MGT /dev/VG_NAME/VL_NAME
注意: -L 100M 与 -L +100M不是一个意思.
前者代表扩容至100M(不能小于原来的大小), 后者代表在原有的基础上扩容100M
不要缩容!!!并且xfs文件系统不支持缩容...
# vg容量够
给1G大小的lv1_from_vg1扩容至5000M, 查看vg1容量是够的, 所以lv1_from_vg1可直接扩容
[root@localhost ~]# vgs | grep vg1
vg1 2 2 0 wz--n- 29.99g 26.99g
[root@localhost ~]# lvs | grep lv1_from_vg1
lv1_from_vg1 vg1 -wi-ao---- 1.00g
[root@localhost ~]# lvextend -L 5000M /dev/vg1/lv1_from_vg1
# 逻辑卷 vg1/lv1_from_vg1 的大小从 1.00 GiB(256 个扩展区) 更改为 4.88 GiB(1250 个扩展区).
# 逻辑卷 vg1/lv1_from_vg1 已成功调整大小
Size of logical volume vg1/lv1_from_vg1 changed from 1.00 GiB(256 extents) to 4.88 GiB(1250 extents). Logical volume vg1/lv1_from_vg1 successfully resized.
[root@localhost ~]# vgs | grep vg1
# 简单验算下 lv增加的等于vg减少的 4.88 - 1 = 26.99 - 23.11
vg1 2 2 0 wz--n- 29.99g <23.11g
[root@localhost ~]# lvs | grep lv1_from_vg1
lv1_from_vg1 vg1 -wi-ao---- 4.88g
xfs_growfs /dev/vg1/lv1_from_vg1 ## -!!! 扩展逻辑卷后需要更新xfs文件系统 df -h才能看到预期的结果
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# vg容量不够
给3G大小的lv1_from_vg2扩容至11G, 查看vg2容量为3G, 是不够的, 需要新增pv扩到vg2里
[root@localhost ~]# vgs | grep vg2
vg2 2 2 0 wz--n- 9.99g 2.99g
[root@localhost ~]# lvs | grep lv1_from_vg2
lv1_from_vg2 vg2 -wi-ao---- 3.00g
# -- lv1_from_vg2扩容至11G需要新增8G sdc5只有5个G 不得行. 所以我们使用40G容量的sdd
[root@localhost ~]# lsblk /dev/sdc5 /dev/sdd
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdc5 8:37 0 5G 0 part
sdd 8:48 0 40G 0 disk
pvcreate /dev/sdd
vgextend vg2 /dev/sdd
[root@localhost ~]# vgs | grep vg2
vg2 3 2 0 wz--n- <49.99g <42.99g
lvextend -L 10G /dev/vg2/lv1_from_vg2
lvextend -L +1G /dev/vg2/lv1_from_vg2
[root@localhost ~]# lvs | grep lv1_from_vg2
lv1_from_vg2 vg2 -wi-ao---- 11.00g
xfs_growfs /dev/vg2/lv1_from_vg2 ## -!!! 扩展逻辑卷后需要更新xfs文件系统 df -h才能看到预期的结果
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 删除
一句话, 先将vg中所有lv的挂载点都卸载, 再删除vg, 最后删除vg中的pv
""" -- 删除,讲究个顺序 lv先卸载挂载点然后删除 lv删干净后再删除vg 最后删除pv --"""
# 删除lv之前需要先卸载挂载点
[root@localhost ~]# umount /test3
[root@localhost ~]# lvremove /dev/vg2/lv1_from_vg2
# 因为挂载后,可能产生过数据,所以问你确定要删除吗?
Do you really want to remove active logical volume vg2/lv1_from_vg2? [y/n]: y
Logical volume "lv1_from_vg2" successfully removed
[root@localhost ~]# vgs
VG #PV #LV #SN Attr VSize VFree
centos 1 2 0 wz--n- <19.00g 0
vg1 2 2 0 wz--n- 29.99g <23.11g
vg2 3 1 0 wz--n- <49.99g <45.99g
# 因为vg2里还有个已经挂载的lv,所以删除vg2不成功
[root@localhost ~]# vgremove vg2
Do you really want to remove volume group "vg2" containing 1 logical volumes? [y/n]: y
# 逻辑卷 vg2/lv2_from_vg2 包含一个正在使用的文件系统
Logical volume vg2/lv2_from_vg2 contains a filesystem in use.
[root@localhost ~]# umount /test4
[root@localhost ~]# vgremove vg2
Do you really want to remove volume group "vg2" containing 1 logical volumes? [y/n]: y
# 相当于帮忙执行了 lvremove /dev/vg2/lv2_from_vg2 命令
Do you really want to remove active logical volume vg2/lv2_from_vg2? [y/n]: y
Logical volume "lv2_from_vg2" successfully removed
Volume group "vg2" successfully removed # -- 成功删除vg2
# 删pv:只能删掉那些不属于任何vg的pv
[root@localhost ~]# pvs
# 可以看到原来在vg2中的3个pv已经闲置啦
PV VG Fmt Attr PSize PFree
/dev/sda2 centos lvm2 a-- <19.00g 0
/dev/sdb vg1 lvm2 a-- <20.00g 13.11g
/dev/sdc1 vg1 lvm2 a-- <10.00g <10.00g
/dev/sdc2 lvm2 --- 5.00g 5.00g
/dev/sdc3 lvm2 --- 5.00g 5.00g
/dev/sdd lvm2 --- 40.00g 40.00g
pvremove /dev/sdb2
pvremove /dev/sdb3
pvremove /dev/sdd
# -- 卸载的pv可以不使用lvm按照传统的磁盘管理方式进行操作啦..
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
格外实验: sdb使用完了才会使用sdc1,实际上多少会用点sdc1,但很少显示不出来...
[root@localhost ~]# lsblk /dev/sdb /dev/sdc
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
# 当时很疑惑的一点,sdc1分区下面怎么没显示lv的名字呢?
sdb 8:16 0 20G 0 disk
├─vg1-lv1_from_vg1 253:2 0 4.9G 0 lvm /test1
└─vg1-lv2_from_vg1 253:3 0 2G 0 lvm /test2
sdc 8:32 0 30G 0 disk
├─sdc1 8:33 0 10G 0 part
├─sdc2 8:34 0 5G 0 part # -- pv删除了,划分的分区还是在的
├─sdc3 8:35 0 5G 0 part
├─sdc4 8:36 0 1K 0 part
└─sdc5 8:37 0 5G 0 part
"""
经过分析,sdb(20G)+sdc1(10G)总共30G,现目前,lv1_from_vg1 5G、lv2_from_vg1 2G
我们实验将lv1_from_vg1扩容至22G 超过sdb容量的20G
"""
lvextend -L 22G /dev/vg1/lv1_from_vg1
[root@localhost ~]# pvs
PV VG Fmt Attr PSize PFree
/dev/sda2 centos lvm2 a-- <19.00g 0
/dev/sdb vg1 lvm2 a-- <20.00g 0
/dev/sdc1 vg1 lvm2 a-- <10.00g 5.99g ## -- 20+10-22-2 = 6
/dev/sdd lvm2 --- 40.00g 40.00g
[root@localhost ~]# lsblk /dev/sdb /dev/sdc
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb 8:16 0 20G 0 disk
├─vg1-lv1_from_vg1 253:2 0 22G 0 lvm /test1
└─vg1-lv2_from_vg1 253:3 0 2G 0 lvm /test2
sdc 8:32 0 30G 0 disk
├─sdc1 8:33 0 10G 0 part
│ └─vg1-lv1_from_vg1 253:2 0 22G 0 lvm /test1 ## -- 看!!它出现了..sdb满了才使用sdc1
├─sdc2 8:34 0 5G 0 part
├─sdc3 8:35 0 5G 0 part
├─sdc4 8:36 0 1K 0 part
└─sdc5 8:37 0 5G 0 part
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# LVM快照
简单来说,做lvm快照就是给某个lv做备份
vm虚拟机也有快照,点击vm某一个快照,虚拟机就恢复到快照那一时刻的状态..在这一层面LVM快照是相同的..
# 制作快照
被做快照的lv: lv2_from_vg1 快照: lv2_from_vg1_snap
1> lvm快照的本质就是创建一个特殊的LV逻辑卷.. 快照与被做快照的lv在同一vg里
2> lv2_from_vg1 与 lv2_from_vg1_snap的UUID是一样的..
3> lv2_from_vg1里的内容改变后,lv2_from_vg1_snap快照里的内容是不会同步改变的!!
# -- /test2是lv2_from_vg1逻辑卷xfs格式化后的挂载点
[root@localhost ~]# echo 111 > /test2/1.txt
[root@localhost ~]# echo 222 > /test2/2.txt
[root@localhost ~]# echo 333 > /test2/3.txt
[root@localhost ~]# tree /test2
/test2
├── 1.txt
├── 2.txt
└── 3.txt
0 directories, 3 files
# -- 对vg1卷组下的lv2_from_vg1逻辑卷做快照 首先要保证vg1要有剩余空间
# -- vg1还剩6g的空间
[root@localhost ~]# vgs
VG #PV #LV #SN Attr VSize VFree
centos 1 2 0 wz--n- <19.00g 0
vg1 2 2 0 wz--n- 29.99g 5.99g
# -- 快照本质上也是制作一个lv. 对哪个lv做快照,就会向该lv所在的vg要空间.
# -s 即snapshot,表明是做快照
# -- lvcreate -L 快照大小 -s -n 快照名字 被做快照的lv的路径
# -- 快照先指定1G,不够的话,可以动态扩容嘛
[root@localhost ~]# lvcreate -L 1G -s -n lv2_from_vg1_snap /dev/vg1/lv2_from_vg1
Logical volume "lv2_from_vg1_snap" created.
[root@localhost ~]# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root centos -wi-ao---- <17.00g
swap centos -wi-ao---- 2.00g
lv1_from_vg1 vg1 -wi-ao---- 22.00g
# -- 可以看到快照与被做快照的lv在同一vg里!
lv2_from_vg1 vg1 owi-aos--- 2.00g
lv2_from_vg1_snap vg1 swi-a-s--- 1.00g lv2_from_vg1 0.01
# -- vg1-lv2_from_vg1与vg1-lv2_from_vg1_snap的磁盘/分区UUID是一样的!!
[root@localhost ~]# blkid | grep lv2_from_vg1
/dev/mapper/vg1-lv2_from_vg1: UUID="d0c4fc9b-3fea-409e-b7ab-d760c5c07c19" TYPE="xfs"
/dev/mapper/vg1-lv2_from_vg1_snap: UUID="d0c4fc9b-3fea-409e-b7ab-d760c5c07c19" TYPE="xfs"
# -- 同一个磁盘设备可以有多个挂载点,但有相同UUID的两个磁盘设备只能通过UUID挂载其中一个
# -- 可以回忆下永久挂载,在/etc/fstab配置文件中指定的就是磁盘设备的UUID
# -- So,lv2_from_vg1挂载后, 再mount挂载lv2_from_vg1_snap是失败的..
[root@localhost ~]# mount /dev/vg1/lv2_from_vg1_snap /opt
mount: 文件系统类型错误、选项错误、/dev/mapper/vg1-lv2_from_vg1_snap 上有坏超级块、
缺少代码页或助手程序,或其他错误
有些情况下在 syslog 中可以找到一些有用信息- 请尝试
dmesg | tail 这样的命令看看.
# -- 但是可以曲线救国,指定-o选项让快照不通过UUID挂载
# -- 可以察觉到,做完lv2_from_vg1_snap快照后,我们并没有对其格式化做文件系统,却依旧能挂载成功!!
[root@localhost ~]# mount -o nouuid /dev/vg1/lv2_from_vg1_snap /opt
[root@localhost ~]# mount | grep lv2_from_vg1
/dev/mapper/vg1-lv2_from_vg1 on /test2 type xfs (rw,relatime,attr2,inode64,noquota)
/dev/mapper/vg1-lv2_from_vg1_snap on /opt type xfs (rw,relatime,nouuid,attr2,inode64,noquota)
# -- /opt里的内容跟/test2里的内容一模一样
[root@localhost ~]# ls /opt
1.txt 2.txt 3.txt
[root@localhost ~]# cat /test2/1.txt
111
[root@localhost ~]# cat /opt/1.txt
111
# -- 但是 lv2_from_vg1里的内容改变后,lv2_from_vg1_snap快照里的内容是不会同步改变的!!
[root@localhost ~]# echo 123456 >> /test2/1.txt
[root@localhost ~]# cat /test2/1.txt
111
123456
[root@localhost ~]# cat /opt/1.txt
111
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# 快照恢复单个文件
# -- 平时没必要通过mount -o nouuid挂载快照,当被快照的lv里面的数据有问题了,才需要临时挂载快照进行数据恢复.
# -- 恢复单个文件数据
[root@localhost ~]# cp /opt/1.txt /test2/1.txt
cp:是否覆盖"/test2/1.txt"? y
[root@localhost ~]# cat /test2/1.txt
111
2
3
4
5
6
# 多个文件合并恢复
先卸载数据源与快照, 再进行合并,快照会自动删除,一次性的
# -- 恢复多个文件数据,可以合并,注意是一次性的!!(Ps:vm虚拟机里的快照恢复是永久的)
rm -rf /test2/2.txt
echo 333 >> /test2/3.txt
[root@localhost ~]# tree /test2
/test2
├── 1.txt # 111
└── 3.txt # 333 /n 333
[root@localhost ~]# tree /opt
/opt
├── 1.txt # 111
├── 2.txt # 222
└── 3.txt # 333
# -- 若umount: /test2:目标忙, 先查看哪个进程占用fuser -cu /test2,ps查看该进程,再kill -9
[root@localhost ~]# umount /opt
[root@localhost ~]# umount /test2
[root@localhost ~]# lvconvert --mergesnapshot /dev/vg1/lv2_from_vg1_snap
Merging of volume vg1/lv2_from_vg1_snap started.
vg1/lv2_from_vg1: Merged: 100.00%
# -- 可以发现/dev/vg1/lv2_from_vg1_snap快照文件没了
[root@localhost ~]# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root centos -wi-ao---- <17.00g
swap centos -wi-ao---- 2.00g
lv1_from_vg1 vg1 -wi-ao---- 22.00g
lv2_from_vg1 vg1 -wi-ao---- 2.00g
[root@localhost ~]# mount /dev/vg1/lv2_from_vg1 /test2/
[root@localhost ~]# ls /test2
1.txt 2.txt 3.txt
[root@localhost ~]# cat /test2/*
111
222
333
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
还有个思路是, cp -r 源文件夹/* 目标文件夹
lvcreate -L 1G -s -n lv2_from_vg1_snap /dev/vg1/lv2_from_vg1
rm -rf /test2/2.txt
echo 123456 >> /test2/1.txt
[root@localhost ~]# cat /test2/1.txt
111
123456
[root@localhost ~]# cat /test2/2.txt
cat: /test2/2.txt: 没有那个文件或目录
[root@localhost ~]# mount -o nouuid /dev/vg1/lv2_from_vg1_snap /opt
[root@localhost ~]# ls /opt
1.txt 2.txt 3.txt
[root@localhost ~]# cp -r /opt/* /test2
cp:是否覆盖"/test2/1.txt"? y
cp:是否覆盖"/test2/3.txt"? y
[root@localhost ~]# ls /test2
1.txt 2.txt 3.txt
[root@localhost ~]# cat /test2/*
111
222
333
# -- 快照文件还在
[root@localhost ~]# lvs | grep snap
lv2_from_vg1_snap vg1 swi-aos--- 1.00g lv2_from_vg1 0.20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 底层原理
为了便于阐述,在这里约定被制作快照的lv叫做原始卷..(不存在这个名词哈,我们自己创造的)
Q1: 我们lvcreate -L 1G
先分配了1G的空间给快照,将快照挂载后,能访问到跟原始卷里一样的数据...
实际上给快照分配的1G大小的空间几乎没有使用,也就是说快照刚建立好时是不占用空间的;矛盾的是里面却有数据. 很神奇吧,如何做到的呢?
A1: 快照刚建立好时,里面全是一堆原始卷的硬链接, 快照空间里是没有存放数据的..
正因为硬链接的创建不能跨区,所以快照跟原始卷不能跨区.. 专业一点来说, LVM 采用的写时复制, 是指当 LVM 快照创建的时候, 仅创建到实际数据的inode的硬链接(hark-link)而已.. 快照与原始卷共享很多PE 区块..
Q2: 再思考个问题,硬链接的特点是inode号相同,硬链接的源文件和目标文件内容的修改会同步..
但在实验中原始卷里的1.txt文件内容改变了,快照却没有影响.. 这又是为何呢?
实验了下,挂载的快照里的数据改了,对原始卷里的数据也没有影响..
A2: 我们知道 硬盘中的所有操作都是覆盖 (详见文件系统章节)!! lvm快照机制在处理原始卷的改动时,
会先将原始卷里改动的1.txt文件整个移动到快照空间中,然后再实现1.txt文件进行覆盖操作... So,原试卷改动,快照才会占用空间.
专业一点来说,只要实际的数据没有改变, 快照就只包含指向数据的inode的指针,而非数据本身! 快照会跟踪原始卷中块的改变, 一旦你更改了快照对应的文件或目录,这个时候原始卷上将要改变的数据会在改变之前拷贝到快照预留的空间.
随着时间的推移,假设原试卷里的文件都改动过了,那么全都会倒腾到快照空间中. 因而,快照空间的大小不会超过原始卷打快照时那一刻的大小!! 快照空间不够怎么办,动态扩容嘛!快照是原试卷那一时刻内容的复刻,只有原始卷里面的文件第一次改动时才会惊动快照空间..
注意哦, 备份不一定必须用LVM快照, 也可以用前面提及的xfsdump增量备份...